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

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 2001 University of Southern California.
  3.  * All rights reserved.
  4.  *
  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 Information Sciences
  16.  *      Institute of the University of Southern California.
  17.  * 4. Neither the name of the University nor of the Institute may be used
  18.  *    to endorse or promote products derived from this software without
  19.  *    specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  */
  34. #include <stdlib.h>
  35. #include <math.h>
  36. #ifdef WIN32
  37. #include <windows.h>
  38. #endif
  39. #include "netview.h"
  40. #include "edge.h"
  41. #include "paint.h"
  42. #include "sincos.h"
  43. #include "lossmodel.h"
  44. #include "queuehandle.h"
  45. #define PROPERTY_STRING_LENGTH 256
  46. static int g_lossmodel_number = 1;
  47. //----------------------------------------------------------------------
  48. //  Wrapper for creating LossModels in OTcl
  49. //----------------------------------------------------------------------
  50. static class LossModelClass : public TclClass {
  51. public:
  52.   LossModelClass() : TclClass("LossModel") {}
  53.   TclObject* create(int argc, const char * const * argv) {
  54.     const char * type;
  55.     int id;
  56.     double size;
  57.     type = argv[4];
  58.     id = strtol(argv[5], NULL, 10);
  59.     size = strtod(argv[6], NULL);
  60.     
  61.     return (new LossModel(type, id, size));
  62.   }
  63. } class_lossmodel;
  64. //----------------------------------------------------------------------
  65. //----------------------------------------------------------------------
  66. LossModel::LossModel(const char* type, int id, double _size) :
  67.   Animation(0, 0) {
  68.   setDefaults();
  69.   number_ = id;
  70.   if (g_lossmodel_number++ <= id) {
  71.     g_lossmodel_number = id + 1;
  72.   }
  73.   label_ = new char[strlen(type) + 1];
  74.   strcpy(label_, type);
  75.   width_ = 50.0 * strlen(type);
  76.   height_ = size_/2.0;
  77.   size_ = _size;
  78.   size(_size);
  79. }
  80. //----------------------------------------------------------------------
  81. //----------------------------------------------------------------------
  82. LossModel::LossModel(const char* name, double _size) :
  83.   Animation(0, 0) {
  84.   setDefaults();
  85.   
  86.   number_ = g_lossmodel_number;
  87.   g_lossmodel_number++;
  88.   width_ = 50.0 * strlen(name);
  89.   height_ = size_/2.0;
  90.   size_ = _size;
  91.   label_ = new char[strlen(name) + 1];
  92.   strcpy(label_, name);
  93.   size(_size);
  94. }
  95. //----------------------------------------------------------------------
  96. //----------------------------------------------------------------------
  97. void
  98. LossModel::setDefaults() {
  99.   next_lossmodel_ = NULL;
  100.   edge_ = NULL;
  101.   x_ = 0.0;
  102.   y_ = 0.0;
  103.   angle_ = NO_ANGLE;
  104.   color_ = "black";
  105.   paint_ = Paint::instance()->thin();
  106.   loss_unit_ = NULL;
  107.   setLossUnit("pkt");
  108.   // Periodic Parameters
  109.   period_ = 1.0;
  110.   offset_ = 0.0;
  111.   burstlen_ = 0.0;
  112.   // Uniform Parameters
  113.   rate_ = 0.1;
  114. }
  115. //----------------------------------------------------------------------
  116. // double 
  117. // LossModel::distance(double x, double y) const {
  118. //----------------------------------------------------------------------
  119. double
  120. LossModel::distance(double x, double y) const {
  121.   return sqrt((x_-x)*(x_-x) + (y_-y)*(y_-y));
  122. }
  123. //----------------------------------------------------------------------
  124. //----------------------------------------------------------------------
  125. void
  126. LossModel::color(const char * name) {
  127.   if (color_) {
  128.     delete []color_;
  129.   }
  130.   color_ = new char[strlen(name) + 1];
  131.   strcpy(color_, name);
  132. }
  133. //----------------------------------------------------------------------
  134. //----------------------------------------------------------------------
  135. void LossModel::size(double s) {
  136.   size_ = s;
  137.   width_ = 10.0 + 25.0*strlen(label_);
  138.   height_ = s/2.0;
  139.   update_bb();
  140. }
  141. //----------------------------------------------------------------------
  142. //----------------------------------------------------------------------
  143. void LossModel::update_bb() {
  144.   bb_.xmin = x_;
  145.   bb_.ymin = y_;
  146.   bb_.xmax = x_ + width_;
  147.   bb_.ymax = y_ + height_;
  148. }
  149. //----------------------------------------------------------------------
  150. //----------------------------------------------------------------------
  151. void LossModel::label(const char* name) {
  152.   if (label_) {
  153.     delete label_;
  154.   }
  155.   label_ = new char[strlen(name) + 1];
  156.   strcpy(label_, name);
  157. }
  158. //----------------------------------------------------------------------
  159. //----------------------------------------------------------------------
  160. void LossModel::reset(double) {
  161.   paint_ = Paint::instance()->thick();
  162. }
  163. //----------------------------------------------------------------------
  164. // void
  165. // LossModel::attach(Agent * agent)
  166. //   - Attach this loss model to an edge
  167. //----------------------------------------------------------------------
  168. void
  169. LossModel::attachTo(Edge * edge) {
  170.   edge_ = edge; 
  171.   place();
  172. }
  173. //----------------------------------------------------------------------
  174. //----------------------------------------------------------------------
  175. void LossModel::clearEdge() {
  176.   edge_->clearLossModel();
  177.   edge_ = NULL;
  178. }
  179. //----------------------------------------------------------------------
  180. // void
  181. // LossModel::place()  
  182. //   - place the loss model on the edge to which it is attached.
  183. //----------------------------------------------------------------------
  184. void
  185. LossModel::place() {
  186.   QueueHandle * queue_handle;
  187.   if (edge_) {
  188.     // Place loss model on top of the queue handle
  189.     queue_handle = edge_->getQueueHandle();
  190.     
  191.     // Place loss model on top of queue handle
  192.     x_ = queue_handle->x();
  193.     y_ = queue_handle->y() + queue_handle->height(); 
  194.     // Place loss model to the right of queue handle
  195.     //x_ = queue_handle->x() + queue_handle->width();
  196.     //y_ = queue_handle->y(); 
  197.   }
  198. }
  199. //----------------------------------------------------------------------
  200. //----------------------------------------------------------------------
  201. const char* LossModel::info() const {
  202.   static char text[128];
  203.   sprintf(text, "Loss Model: %s %d->%d", label_, edge_->src(), edge_->dst());
  204.   return (text);
  205. }
  206. //----------------------------------------------------------------------
  207. //----------------------------------------------------------------------
  208. const char* LossModel::getname() const
  209. {
  210.   static char text[128];
  211.   sprintf(text, "a %s", label_);
  212.   return (text);
  213. }
  214. //----------------------------------------------------------------------
  215. // int 
  216. // LossModel::inside(double, float px, float py) const 
  217. //   - Check to see if point (px, py) is within the Loss Model box
  218. //----------------------------------------------------------------------
  219. int 
  220. LossModel::inside(double, float px, float py) const {
  221.   return (px >= x_ && 
  222.           px <= (x_ + width_) &&
  223.           py >= y_ && 
  224.           py <= (y_ + height_));
  225. }
  226. //----------------------------------------------------------------------
  227. // void
  228. // LossModel::draw(View * view, double ) const
  229. //   - Draw the Loss Model on its edge
  230. //----------------------------------------------------------------------
  231. void
  232. LossModel::draw(View * view, double time) {
  233. double label_width, label_height, label_x, label_y;
  234. static char full_label[128];
  235. // Draw label centered inside of border
  236. if (label_) {
  237. //sprintf(full_label, "%s: %d->%d", label_, edge_->src(), edge_->dst());
  238. sprintf(full_label, "%s", label_);
  239. // We have to keep calculting the label width and height because
  240. // we have no way of knowing if the user has zoomed in or out 
  241. // on the current network view.
  242. label_height = 0.9 * height_;
  243. label_width = view->getStringWidth(full_label, label_height);
  244. // Add 10% of padding to width for the box
  245. setWidth(1.1 * label_width);
  246. // Center label in box
  247. label_x = x_ + (width_ - label_width);
  248. label_y = y_ + (height_ - label_height);
  249. view->string(full_label, label_x , label_y, label_height, NULL);
  250. update_bb();
  251. }
  252. // Draw Rectangle Border
  253. view->rect(x_, y_, x_ + width_, y_ + height_ , paint_);
  254. }
  255. //----------------------------------------------------------------------
  256. // int
  257. // LossModel::writeNsDefinitionScript(FILE * file)
  258. //  - outputs ns script format for creating loss models
  259. //----------------------------------------------------------------------
  260. int
  261. LossModel::writeNsDefinitionScript(FILE * file) {
  262.   if (!strcmp(name(), "Periodic")) {
  263.     fprintf(file, "set loss_model(%d) [new ErrorModel/%s]n",
  264.                    number_, label_);
  265.     // Connect loss model to edge
  266.     fprintf(file, "$ns lossmodel $loss_model(%d) $node(%d) $node(%d)n", number_,
  267.             edge_->src(), edge_->dst());
  268.     // Set Properties
  269.     fprintf(file, "$loss_model(%d) unit %sn", number_, loss_unit_);
  270.     fprintf(file, "$loss_model(%d) set period_ %fn", number_, period_);
  271.     fprintf(file, "$loss_model(%d) set offset_ %fn", number_, offset_);
  272.     fprintf(file, "$loss_model(%d) set burstlen_ %fn", number_, burstlen_);
  273.     // Set Drop Target
  274.     fprintf(file, "$loss_model(%d) drop-target [new Agent/Null]n", number_);
  275.   } else if (!strcmp(name(), "Expo")) {
  276.   } else if (!strcmp(name(), "Uniform")) {
  277.     fprintf(file, "set loss_model(%d) [new ErrorModel/%s %f %s]n",
  278.                    number_, label_, rate_, loss_unit_);
  279.     
  280.     // Connect loss model to edge
  281.     fprintf(file, "$ns lossmodel $loss_model(%d) $node(%d) $node(%d)n", number_,
  282.             edge_->src(), edge_->dst());
  283.     // Set Drop Target
  284.     fprintf(file, "$loss_model(%d) drop-target [new Agent/Null]n", number_);
  285.   } else {
  286.     fprintf(stderr, "Unknown loss model %s needs to be implemented.n", label_);
  287.   }
  288.                           
  289.   return 0;
  290. }
  291. //----------------------------------------------------------------------
  292. // LossModel::property()
  293. //   - return the list of loss model configuration parameters
  294. //     (properties) to be shown in the property edit window
  295. //----------------------------------------------------------------------
  296. const char*
  297. LossModel::property() {
  298.   static char text[PROPERTY_STRING_LENGTH];
  299.   char * property_list;
  300.   int total_written = 0;
  301.   property_list = text;
  302.   total_written = sprintf(text, 
  303.           "{"Loss Model: %s %d->%d" title title "LossModel %d"} ",
  304.           name(), edge_->src(), edge_->dst(), number_);
  305.   if (strcmp(name(), "Periodic") == 0) {
  306.       property_list = &text[strlen(text)];
  307.       sprintf(property_list, "{"Period" period_ text %f} ", period_);
  308.       property_list = &text[strlen(text)];
  309.       sprintf(property_list, "{"Offset" offset_ text %f} ", offset_); 
  310.       property_list = &text[strlen(text)];
  311.       sprintf(property_list, "{"Burst Length" burstlen_ text %f} ", burstlen_);
  312.   } else if (strcmp(name(), "Expo") == 0) {
  313.   } else if (strcmp(name(), "Uniform") == 0) {
  314.       property_list = &text[strlen(text)];
  315.       sprintf(property_list, "{"Loss Rate" rate_ text %f} ", rate_);
  316.   }
  317.   return(text);
  318. }
  319. //----------------------------------------------------------------------
  320. //----------------------------------------------------------------------
  321. int LossModel::command(int argc, const char * const * argv) {
  322.   int length = strlen(argv[1]);
  323.   if (strncmp(argv[1], "setRate", length) == 0) {
  324.     setRate(strtod(argv[2],NULL));
  325.   } else if (strncmp(argv[1], "setLossUnit", length) == 0) {
  326.     setLossUnit(argv[2]);
  327.   }
  328.   return TCL_OK;
  329. }
  330. //----------------------------------------------------------------------
  331. // void
  332. // LossModel::setLossUnit(const char * unit) 
  333. //   - sets the loss model's loss unit type (byte, pkt, etc...)
  334. //----------------------------------------------------------------------
  335. void
  336. LossModel::setLossUnit(const char * unit) {
  337.   if (loss_unit_) {
  338.     delete []loss_unit_;
  339.   }
  340.   loss_unit_ = new char[strlen(unit) + 1];
  341.   strcpy(loss_unit_, unit);
  342. }