queuehandle.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:18k
- /*
- * Copyright (c) 2001 University of Southern California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Information Sciences
- * Institute of the University of Southern California.
- * 4. Neither the name of the University nor of the Institute may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
- #include <stdlib.h>
- #include <math.h>
- #ifdef WIN32
- #include <windows.h>
- #endif
- #include "netview.h"
- #include "node.h"
- #include "edge.h"
- #include "paint.h"
- #include "sincos.h"
- #include "queuehandle.h"
- #define PROPERTY_STRING_LENGTH 256
- static int g_queuehandle_number = 1;
- //----------------------------------------------------------------------
- // Wrapper for creating QueueHandles in OTcl
- //----------------------------------------------------------------------
- static class QueueHandleClass : public TclClass {
- public:
- QueueHandleClass() : TclClass("QueueHandle") {}
- TclObject* create(int argc, const char * const * argv) {
- const char * type;
- int id;
- double size;
- type = argv[4];
- id = strtol(argv[5], NULL, 10);
- size = strtod(argv[6], NULL);
-
- return (new QueueHandle(type, id, size));
- }
- } class_queuehandle;
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- QueueHandle::QueueHandle(const char* type, int id, double _size) :
- Animation(0, 0) {
- setDefaults();
- number_ = id;
- if (g_queuehandle_number++ <= id) {
- g_queuehandle_number = id + 1;
- }
- width_ = 50.0;
- height_ = size_/2.0;
- size_ = _size;
- size(_size);
- }
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- QueueHandle::QueueHandle(Edge * edge) :
- Animation(0, 0) {
- Node * node;
- setDefaults();
- edge_ = edge;
-
- number_ = g_queuehandle_number;
- g_queuehandle_number++;
- node = edge_->getSourceNode();
- if (node) {
- size(node->size());
- } else {
- size(10.0);
- }
- limit_ = 20;
-
- // FQ
- secsPerByte_ = 0.0;
- // Stocastic Fair Queue
- maxqueue_ = 40;
- buckets_ = 16;
- // DRR
- blimit_ = 2500;
- quantum_ = 250;
- mask_ = false;
- // RED
- bytes_ = false;
- queue_in_bytes_ = false;
- thresh_ = 5.0;
- maxthresh_ = 15.0;
- mean_pktsize_ = 500;
- q_weight_ = 0.002;
- wait_ = false;
- linterm_ = 30.0;
- setbit_ = false;
- drop_tail_ = false;
- }
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- void
- QueueHandle::setDefaults() {
- next_queue_handle_ = NULL;
- edge_ = NULL;
- x_ = 0.0;
- y_ = 0.0;
- angle_ = NO_ANGLE;
- color_ = "black";
- paint_ = Paint::instance()->thin();
- width_ = 10.0;
- height_ = 10.0;
- type_ = NULL;
- ns_type_ = NULL;
- setType("DropTail");
- }
- //----------------------------------------------------------------------
- // double
- // QueueHandle::distance(double x, double y) const {
- //----------------------------------------------------------------------
- double
- QueueHandle::distance(double x, double y) const {
- return sqrt((x_-x)*(x_-x) + (y_-y)*(y_-y));
- }
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- void
- QueueHandle::color(const char * name) {
- if (color_) {
- delete []color_;
- }
- color_ = new char[strlen(name) + 1];
- strcpy(color_, name);
- }
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- void QueueHandle::size(double s) {
- size_ = s;
- width_ = 10.0 + 25.0;
- height_ = s/2.0;
- update_bb();
- }
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- void QueueHandle::update_bb() {
- bb_.xmin = x_;
- bb_.ymin = y_;
- bb_.xmax = x_ + width_;
- bb_.ymax = y_ + height_;
- }
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- void QueueHandle::setType(const char* type) {
- const char * expanded_type;
- // Expand Ns Type Names
- if (!strcmp(type, "FQ")) {
- expanded_type = "FairQueue";
- } else if (!strcmp(type, "SFQ")) {
- expanded_type = "StocasticFairQueue";
- } else if (!strcmp(type, "DRR")) {
- expanded_type = "DeficitRoundRobin";
- } else {
- expanded_type = type;
- }
-
- // Deleted existing type strings
- if (type_) {
- delete[] type_;
- }
- if (ns_type_) {
- delete[] ns_type_;
- ns_type_ = NULL;
- }
- // Set type and ns type to new strings
- type_ = new char[strlen(expanded_type) + 1];
- strcpy(type_, expanded_type);
- if (!strcmp(expanded_type, "DropTail")) {
- ns_type_ = new char[strlen("DropTail") + 1];
- strcpy(ns_type_, "DropTail");
- } else if (!strcmp(expanded_type, "FairQueue")) {
- ns_type_ = new char[strlen("FQ") + 1];
- strcpy(ns_type_, "FQ");
- } else if (!strcmp(expanded_type, "StocasticFairQueue")) {
- ns_type_ = new char[strlen("SFQ") + 1];
- strcpy(ns_type_, "SFQ");
- } else if (!strcmp(expanded_type, "DeficitRoundRobin")) {
- ns_type_ = new char[strlen("DRR") + 1];
- strcpy(ns_type_, "DRR");
- } else if (!strcmp(expanded_type, "RED")) {
- ns_type_ = new char[strlen("RED") + 1];
- strcpy(ns_type_, "RED");
- }
- }
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- void QueueHandle::reset(double) {
- paint_ = Paint::instance()->thick();
- }
- //----------------------------------------------------------------------
- // void
- // QueueHandle::attach(Agent * agent)
- //----------------------------------------------------------------------
- void
- QueueHandle::attachTo(Edge * edge) {
- edge_ = edge;
- place();
- }
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- void QueueHandle::clearEdge() {
- edge_ = NULL;
- }
- //----------------------------------------------------------------------
- // void
- // QueueHandle::place()
- //----------------------------------------------------------------------
- void
- QueueHandle::place() {
- double sine, cosine, angle;
- if (edge_) {
- angle = edge_->angle();
- sine = sin(angle);
- cosine = cos(angle);
- if ((angle > 0.0 && angle < M_PI/2.0) ||
- (angle < M_PI/-2.0 && angle > -1.0*M_PI)) {
- x_ = edge_->x() + cosine * height_;
- y_ = edge_->y() + sine * height_ - height_;
- } else {
- x_ = edge_->x() + cosine * height_;
- y_ = edge_->y() + sine * height_;
- }
- }
- update_bb();
- }
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- const char* QueueHandle::info() const {
- static char text[128];
- sprintf(text, "Queue Type: %s %d->%d", type_, edge_->src(), edge_->dst());
- return (text);
- }
- //----------------------------------------------------------------------
- // int
- // QueueHandle::inside(double, float px, float py) const
- // - Check to see if point (px, py) is within the Loss Model box
- //----------------------------------------------------------------------
- int
- QueueHandle::inside(double, float px, float py) const {
- return (px >= x_ &&
- px <= (x_ + width_) &&
- py >= y_ &&
- py <= (y_ + height_));
- }
- //----------------------------------------------------------------------
- // void
- // QueueHandle::draw(View * view, double ) const
- // - Draw the Loss Model on its edge
- //----------------------------------------------------------------------
- void
- QueueHandle::draw(View * view, double time) {
- double label_width, label_height, label_x, label_y;
- char * label = "Q";
- if (edge_) {
- // Draw label centered inside of border
- // We have to keep calculting the label width and height because
- // we have no way of knowing if the user has zoomed in or out
- // on the current network view.
- label_height = 0.9 * height_;
- label_width = view->getStringWidth(label, label_height);
- // Add 10% of padding to width for the box
- setWidth(1.1 * label_width);
- // Center label in box
- label_x = x_ + (width_ - label_width);
- label_y = y_ + (height_ - label_height);
- view->string(label, label_x , label_y, label_height, NULL);
-
- update_bb();
- // Draw Rectangle Border
- view->rect(x_, y_, x_ + width_, y_ + height_ , paint_);
- }
- }
- //----------------------------------------------------------------------
- // int
- // QueueHandle::writeNsScript(FILE * file)
- // - outputs ns script format for creating loss models
- //----------------------------------------------------------------------
- int
- QueueHandle::writeNsScript(FILE * file) {
- if (edge_) {
- fprintf(file, "# Set Queue Properties for link %d->%dn", edge_->src(), edge_->dst());
- if (!strcmp(type_, "DropTail")) {
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set limit_ %dn", edge_->src(), edge_->dst(), limit_);
- } else if (!strcmp(type_, "FairQueue")) {
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set secsPerByte_ %fn", edge_->src(), edge_->dst(), secsPerByte_);
- } else if (!strcmp(type_, "StocasticFairQueue")) {
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set maxqueue_ %dn", edge_->src(), edge_->dst(), maxqueue_);
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set buckets_ %dn", edge_->src(), edge_->dst(), buckets_);
- } else if (!strcmp(type_, "DeficitRoundRobin")) {
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set buckets_ %dn", edge_->src(), edge_->dst(), buckets_);
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set blimit_ %dn", edge_->src(), edge_->dst(), blimit_);
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set quantum_ %dn", edge_->src(), edge_->dst(), quantum_);
- if (mask_) {
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set mask_ 1n", edge_->src(), edge_->dst());
- }
- } else if (!strcmp(type_, "RED")) {
- if (bytes_) {
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set bytes_ 1n", edge_->src(), edge_->dst());
- }
- if (queue_in_bytes_) {
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set queue_in_bytes_ 1n", edge_->src(), edge_->dst());
- }
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set thresh_ %fn", edge_->src(), edge_->dst(), thresh_);
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set maxthresh_ %fn", edge_->src(), edge_->dst(), maxthresh_);
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set mean_pktsize_ %dn", edge_->src(), edge_->dst(), mean_pktsize_);
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set q_weight_ %fn", edge_->src(), edge_->dst(), q_weight_);
- if (wait_) {
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set queue_in_bytes_ 1n", edge_->src(), edge_->dst());
- }
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set linterm_ %fn", edge_->src(), edge_->dst(), linterm_);
- if (setbit_) {
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set setbit_ 1n", edge_->src(), edge_->dst());
- }
- if (queue_in_bytes_) {
- fprintf(file, "[[$ns link $node(%d) $node(%d)] queue] set drop_tail_ 1n", edge_->src(), edge_->dst());
- }
- }
- }
- return 0;
- }
- //----------------------------------------------------------------------
- // QueueHandle::property()
- // - return the list of queue configuration parameters
- // (properties) to be shown in the property edit window
- //----------------------------------------------------------------------
- const char*
- QueueHandle::property() {
- return getProperties(type_);
- }
-
- //----------------------------------------------------------------------
- // QueueHandle::property()
- // - return the list of queue configuration parameters
- // (properties) to be shown in the property edit window
- // - This is used if the queue type is changed to a different type
- // so we can give the properties related to that specific type of
- // queue to which we have switched
- //----------------------------------------------------------------------
- const char *
- QueueHandle::getProperties(char * type) {
- static char text[PROPERTY_STRING_LENGTH];
- char * property_list;
- int total_written = 0;
- // object type, id and header info
- property_list = text;
- total_written = sprintf(text,
- "{"Queue: %s %d->%d" title title "QueueHandle %d-%d"} ",
- type_, edge_->src(), edge_->dst(), edge_->src(), edge_->dst());
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Queue Type" type_ drop_down_list {{%s} {DropTail FairQueue StocasticFairQueue DeficitRoundRobin RED}}} ", type);
- if (strcmp(type, "DropTail") == 0) {
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Maximum Queue Size" limit_ text %d} ",
- limit_);
- } else if (strcmp(type, "FairQueue") == 0) {
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Seconds Per Byte" secsPerByte_ text %f} ",
- secsPerByte_);
- } else if (strcmp(type, "StocasticFairQueue") == 0) {
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Maximum Queue Size" maxqueue_ text %d} ",
- maxqueue_);
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Number of Buckets" buckets_ text %d} ",
- buckets_);
- } else if (strcmp(type, "DeficitRoundRobin") == 0) {
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Number of Buckets" buckets_ text %d} ",
- buckets_);
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Shared Buffer Size" blimit_ text %d} ",
- blimit_);
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Flow Quantum" quantum_ text %d} ",
- quantum_);
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Exclude Port Number from Flow Identification" mask_ checkbox %d} ",
- mask_);
- } else if (strcmp(type, "RED") == 0) {
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Enable Byte Mode RED" bytes_ checkbox %d} ",
- bytes_);
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Queue in Bytes" queue_in_bytes_ checkbox %d} ",
- queue_in_bytes_);
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Wait Interval Between Drops" wait_ checkbox %d} ",
- wait_);
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Mark Packets for Congestion Instead of Dropping" setbit_ checkbox %d} ",
- setbit_);
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Use Drop Tail instead of Random Drop" drop_tail_ checkbox %d} ",
- drop_tail_);
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Minimum Threshhold for Average Queue Size" thresh_ text %g} ",
- thresh_);
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Maximum Threshhold for Average Queue Size" maxthresh_ text %g} ",
- maxthresh_);
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Estimate for Average Queue Size" mean_pktsize_ text %d} ",
- mean_pktsize_);
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Queue Weight" q_weight_ text %g} ",
- q_weight_);
- property_list = &text[strlen(text)];
- sprintf(property_list, "{"Maximum Drop Probability (1/linterm_)" linterm_ text %g} ",
- linterm_);
- }
- return(text);
- }
- //----------------------------------------------------------------------
- //----------------------------------------------------------------------
- int QueueHandle::command(int argc, const char * const * argv) {
- return TCL_OK;
- }