salink.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 /*
00003  * Copyright (c) Xerox Corporation 1997. All rights reserved.
00004  *
00005  * This program is free software; you can redistribute it and/or modify it
00006  * under the terms of the GNU General Public License as published by the
00007  * Free Software Foundation; either version 2 of the License, or (at your
00008  * option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License along
00016  * with this program; if not, write to the Free Software Foundation, Inc.,
00017  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018  *
00019  * Linking this file statically or dynamically with other modules is making
00020  * a combined work based on this file.  Thus, the terms and conditions of
00021  * the GNU General Public License cover the whole combination.
00022  *
00023  * In addition, as a special exception, the copyright holders of this file
00024  * give you permission to combine this file with free software programs or
00025  * libraries that are released under the GNU LGPL and with code included in
00026  * the standard release of ns-2 under the Apache 2.0 license or under
00027  * otherwise-compatible licenses with advertising requirements (or modified
00028  * versions of such code, with unchanged license).  You may copy and
00029  * distribute such a system following the terms of the GNU GPL for this
00030  * file and the licenses of the other code concerned, provided that you
00031  * include the source code of that other code when and as the GNU GPL
00032  * requires distribution of source code.
00033  *
00034  * Note that people who make modified versions of this file are not
00035  * obligated to grant this special exception for their modified versions;
00036  * it is their choice whether to do so.  The GNU General Public License
00037  * gives permission to release a modified version without this exception;
00038  * this exception also makes it possible to release a modified version
00039  * which carries forward this exception.
00040  *
00041  * $Header: /nfs/jade/vint/CVSROOT/ns-2/adc/salink.cc,v 1.6 2005/08/26 05:05:28 tomh Exp $
00042  */
00043 
00044 #include "packet.h"
00045 #include "ip.h"
00046 #include "resv.h"
00047 #include "connector.h"
00048 #include "adc.h"
00049 #include "salink.h"
00050 
00051 static class SALinkClass : public TclClass {
00052 public:
00053     SALinkClass() : TclClass("SALink") {}
00054     TclObject* create(int, const char*const*) {
00055         return (new SALink());
00056     }
00057 }class_salink;
00058 
00059 SALink::SALink() : adc_(0), numfl_(-1), tchan_(0), onumfl_(0), last_(-1)
00060 {
00061     int i;
00062     for (i=0;i<NFLOWS;i++) {
00063         pending_[i].flowid=-1;
00064         pending_[i].status=0;
00065     }
00066     bind("src_", &src_);
00067     bind("dst_", &dst_);
00068 
00069     numfl_.tracer(this);
00070     numfl_.name("\"Admitted Flows\"");
00071 }
00072 
00073 
00074 void SALink::recv(Packet *p, Handler *h)
00075 {
00076     int decide;
00077     int j;
00078     
00079     hdr_cmn *ch=hdr_cmn::access(p);
00080     hdr_ip *iph=hdr_ip::access(p);
00081     hdr_resv *rv=hdr_resv::access(p);
00082     
00083     //CLEAN THIS UP
00084     int cl=(iph->flowid())?1:0;
00085     
00086     switch(ch->ptype()) {
00087     case PT_REQUEST:
00088         decide=adc_->admit_flow(cl,rv->rate(),rv->bucket());
00089         if (tchan_)
00090             if (last_ != decide) {
00091                 int n;
00092                 char wrk[50];
00093                 double t = Scheduler::instance().clock();
00094                 sprintf(wrk, "l -t %g -s %d -d %d -S COLOR -c %s", 
00095                     t, src_, dst_, decide ? "MediumBlue" : "red" );
00096                 n = strlen(wrk);
00097                 wrk[n] = '\n';
00098                 wrk[n+1] = 0;
00099                 (void)Tcl_Write(tchan_, wrk, n+1);
00100                 last_ = decide;
00101             }
00102         //put decide in the packet
00103         rv->decision() &= decide;
00104         if (decide) {
00105             j=get_nxt();
00106             pending_[j].flowid=iph->flowid();
00107             //pending_[j].status=decide;
00108             numfl_++;
00109         }
00110         break;
00111     case PT_ACCEPT:
00112     case PT_REJECT:
00113         break;
00114     case PT_CONFIRM:
00115         {
00116             j=lookup(iph->flowid());
00117             if (j!=-1) {
00118                 if (!rv->decision()) {
00119                     //decrease the avload for this class 
00120                     adc_->rej_action(cl,rv->rate(),rv->bucket());
00121                     numfl_--;
00122                 }
00123                 pending_[j].flowid=-1;
00124             }
00125             break;
00126         }
00127     case PT_TEARDOWN:
00128         {
00129             adc_->teardown_action(cl,rv->rate(),rv->bucket());
00130             numfl_--;
00131             break;
00132         }
00133     default:
00134 #ifdef notdef
00135         error("unknown signalling message type : %d",ch->ptype());
00136         abort();
00137 #endif
00138         break;
00139     }
00140     send(p,h);
00141 }
00142 
00143 int SALink::command(int argc, const char*const* argv)
00144 {
00145     Tcl& tcl = Tcl::instance();
00146     char wrk[500];
00147     
00148     if (argc ==3) {
00149         if (strcmp(argv[1],"attach-adc") == 0 ) {
00150             adc_=(ADC *)TclObject::lookup(argv[2]);
00151             if (adc_ ==0 ) {
00152                 tcl.resultf("no such node %s", argv[2]);
00153                 return(TCL_ERROR);
00154             }
00155             return(TCL_OK);
00156         }
00157         if (strcmp(argv[1], "attach") == 0) {
00158             int mode;
00159             const char* id = argv[2];
00160             tchan_ = Tcl_GetChannel(tcl.interp(), (char*)id, &mode);
00161             if (tchan_ == 0) {
00162                 tcl.resultf("SALink: trace: can't attach %s for writing", id);
00163                 return (TCL_ERROR);
00164             }
00165             return (TCL_OK);
00166         }
00167     }
00168     if (argc == 2) {
00169         if (strcmp(argv[1], "add-trace") == 0) {
00170             if (tchan_) {
00171                 sprintf(wrk, "a -t * -n %s:%d-%d -s %d",
00172                     adc_->type(), src_, dst_, src_);
00173                 int n = strlen(wrk);
00174                 wrk[n] = '\n';
00175                 wrk[n+1] = 0;
00176                 (void)Tcl_Write(tchan_, wrk, n+1);
00177                 numfl_ = 0;
00178             }
00179             return (TCL_OK);
00180         }
00181     }
00182     return Connector::command(argc,argv);
00183 }
00184 
00185 int SALink::lookup(int flowid)
00186 {
00187     int i;
00188     for (i=0;i<NFLOWS;i++)
00189         if (pending_[i].flowid==flowid)
00190             return i;
00191     return(-1);
00192 }
00193 
00194 int SALink::get_nxt()
00195 {
00196     int i;
00197     for (i=0;i<NFLOWS;i++)
00198         {
00199             if (pending_[i].flowid==-1)
00200                 return i;
00201         }
00202     printf("Ran out of pending space \n");
00203     exit(1);
00204     return i;
00205 }
00206 
00207 void SALink::trace(TracedVar* v)
00208 {
00209 
00210     char wrk[500];
00211     int *p, newval;
00212 
00213     if (strcmp(v->name(), "\"Admitted Flows\"") == 0) {
00214         p = &onumfl_;
00215     }
00216     else {
00217         fprintf(stderr, "SALink: unknown trace var %s\n", v->name());
00218         return;
00219     }
00220 
00221     newval = int(*((TracedInt*)v));
00222 
00223     if (tchan_) {
00224         int n;
00225         double t = Scheduler::instance().clock();
00226         /* f -t 0.0 -s 1 -a SA -T v -n Num -v 0 -o 0 */
00227         sprintf(wrk, "f -t %g -s %d -a %s:%d-%d -T v -n %s -v %d -o %d",
00228             t, src_, adc_->type(), src_, dst_, v->name(), newval, *p);
00229         n = strlen(wrk);
00230         wrk[n] = '\n';
00231         wrk[n+1] = 0;
00232         (void)Tcl_Write(tchan_, wrk, n+1);
00233         
00234     }
00235 
00236     *p = newval;
00237 
00238     return;
00239 }

Generated on Tue Mar 6 16:47:50 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6