sa.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/sa.cc,v 1.16 2005/08/26 05:05:28 tomh Exp $
00042  */
00043 
00044 //packets after it succeeds in a3-way handshake from the receiver
00045 // should be connected with Agent/SignalAck class
00046 
00047 #include "udp.h"
00048 #include "sa.h"
00049 #include "ip.h"
00050 #include "random.h"
00051 
00052 #define SAMPLERATE 8000
00053 
00054 SA_Agent::SA_Agent() : Agent(PT_UDP), trafgen_(0), rtd_(0), callback_(0), 
00055     sa_timer_(this), nextPkttime_(-1), running_(0), seqno_(-1)
00056 {
00057     bind_bw("rate_",&rate_);
00058     bind("bucket_",&bucket_);
00059     bind("packetSize_", &size_);
00060 }
00061 
00062 SA_Agent::~SA_Agent()
00063 {
00064         if (callback_) 
00065                 delete[] callback_;
00066 
00067 }
00068 
00069 
00070 static class SA_AgentClass : public TclClass {
00071 public:
00072     SA_AgentClass() : TclClass("Agent/SA") {}
00073     TclObject* create(int, const char*const*) {
00074         return (new SA_Agent());
00075     }
00076 } class_signalsource_agent;
00077 
00078 int SA_Agent::command(int argc, const char*const* argv)
00079 {
00080     Tcl& tcl = Tcl::instance();
00081     if (argc==3) {
00082         if (strcmp(argv[1], "target") == 0) {
00083             target_ = (NsObject*)TclObject::lookup(argv[2]);
00084             if (target_ == 0) {
00085                 tcl.resultf("no such object %s", argv[2]);
00086                 return (TCL_ERROR);
00087             }
00088             ctrl_target_=target_;
00089             return (TCL_OK);
00090         } 
00091         else if (strcmp(argv[1],"ctrl-target")== 0) {
00092             ctrl_target_=(NsObject*)TclObject::lookup(argv[2]);
00093             if (ctrl_target_ == 0) {
00094                 tcl.resultf("no such object %s", argv[2]);
00095                 return (TCL_ERROR);
00096             }
00097             return (TCL_OK);
00098         }
00099             if (strcmp(argv[1], "stoponidle") == 0) {
00100                 stoponidle(argv[2]);
00101             return(TCL_OK);
00102         }
00103                 if (strcmp(argv[1], "attach-traffic") == 0) {
00104                         trafgen_ =(TrafficGenerator*)TclObject::lookup(argv[2]);
00105                         if (trafgen_ == 0) {
00106                                 tcl.resultf("no such node %s", argv[2]);
00107                                 return(TCL_ERROR);
00108                         }
00109                         return(TCL_OK);
00110                 }
00111 
00112     }
00113         if (argc == 2) {
00114                 if (strcmp(argv[1], "start") == 0) {
00115                         start();
00116                         return(TCL_OK);
00117                 } else if (strcmp(argv[1], "stop") == 0) {
00118                         stop();
00119                         return(TCL_OK);
00120                 }
00121         }
00122     return (Agent::command(argc,argv));
00123 }
00124 
00125 
00126 void SA_Agent::start()
00127 {
00128     //send the request packet
00129     if (trafgen_) {
00130         trafgen_->init();
00131         //running_=1;
00132         sendreq();
00133     }
00134 }
00135 
00136 void SA_Agent::stop()
00137 {
00138     sendteardown();
00139     if (running_ != 0) {
00140         sa_timer_.cancel();
00141         running_ =0;
00142     }
00143 }
00144 
00145 
00146 void SA_Agent::sendreq()
00147 {
00148     Packet *p = allocpkt();
00149     hdr_cmn* ch= hdr_cmn::access(p);
00150     ch->ptype()=PT_REQUEST;
00151     ch->size()=20;
00152     //also put in the r,b parameters for the flow in the packet
00153     hdr_resv* rv=hdr_resv::access(p);
00154     rv->decision() =1;
00155     rv->rate()=rate_;
00156     rv->bucket()=bucket_;
00157     ctrl_target_->recv(p);
00158 }
00159 
00160 void SA_Agent::sendteardown()
00161 {
00162     Packet *p = allocpkt();
00163     hdr_cmn* ch= hdr_cmn::access(p);
00164     ch->ptype()=PT_TEARDOWN;
00165     ch->size()=20;
00166     //also put in the r,b parameters for the flow in the packet
00167     hdr_resv* rv=hdr_resv::access(p);
00168     rv->decision() =1;
00169     rv->rate()=rate_;
00170     rv->bucket()=bucket_;
00171     ctrl_target_->recv(p);
00172 }
00173 
00174 
00175 void SA_Agent::recv(Packet *p, Handler *) 
00176 {
00177     hdr_cmn *ch= hdr_cmn::access(p);
00178     hdr_resv *rv=hdr_resv::access(p);
00179     hdr_ip * iph = hdr_ip::access(p);
00180     if ( ch->ptype() == PT_ACCEPT || ch->ptype() == PT_REJECT ) {
00181         ch->ptype() = PT_CONFIRM;
00182 
00183         // turn the packet around by swapping src and dst
00184         // (address and port)
00185         ns_addr_t tmp;
00186         tmp = iph->src();
00187         iph->src() = iph->dst();
00188         iph->dst() = tmp;
00189         ctrl_target_->recv(p);
00190     }
00191     
00192     // put an additional check here to see if admission was granted
00193     if (rv->decision()) {
00194         //printf("Flow %d accepted @ %f\n",iph->flowid(),Scheduler::instance().clock());
00195         fflush(stdout);
00196         double t = trafgen_->next_interval(size_);
00197         running_=1;
00198         sa_timer_.resched(t);
00199     }
00200     else {
00201         //printf("Flow %d rejected @ %f\n",iph->flowid(),Scheduler::instance().clock());
00202         fflush(stdout);
00203         //Currently the flow is stopped if rejected
00204         running_=0;
00205     }
00206     //make an upcall to sched a stoptime for this flow from now
00207     Tcl::instance().evalf("%s sched-stop %d",name(),rv->decision());
00208 }
00209 
00210 void SA_Agent::stoponidle(const char *s)
00211 {
00212         callback_ = new char[strlen(s)+1];
00213         strcpy(callback_, s);
00214 
00215         if (trafgen_->on()) {
00216                 // Tcl::instance().evalf("puts \"%s waiting for burst at %f\"", name(), Scheduler::instance().clock());
00217                 rtd_ = 1;
00218         }
00219         else {
00220                 stop();
00221                 Tcl::instance().evalf("%s %s", name(), callback_);
00222         }
00223 
00224 }
00225 
00226 void SA_Timer::expire(Event* /*e*/) {
00227         a_->timeout(0);
00228 }
00229 
00230 void SA_Agent::timeout(int)
00231 {
00232         if (running_) {
00233                 /* send a packet */
00234                 sendpkt();
00235                 /* figure out when to send the next one */
00236                 nextPkttime_ = trafgen_->next_interval(size_);
00237                 /* schedule it */
00238                 sa_timer_.resched(nextPkttime_);
00239 
00240                 /* hack: if we are waiting for a current burst to end
00241                  * before stopping . . .
00242                  */
00243                 if (rtd_) {
00244                         if (trafgen_->on() == 0) {
00245                                 stop();
00246                                 //Tcl::instance().evalf("puts \"%s burst over at %f\"",
00247                                 // name(), Scheduler::instance().clock());
00248                                 Tcl::instance().evalf("%s sched-stop %d", name(), 0);
00249                         }
00250                 }
00251         }
00252 }
00253 
00254 void SA_Agent::sendpkt()
00255 {
00256         Packet* p = allocpkt();
00257         hdr_rtp* rh = hdr_rtp::access(p);
00258         rh->seqno() = ++seqno_;
00259         rh->flags()=0;
00260 
00261         double local_time=Scheduler::instance().clock();
00262         /*put in "rtp timestamps" and begining of talkspurt labels */
00263         hdr_cmn* ch = hdr_cmn::access(p);
00264         ch->timestamp()=(u_int32_t)(SAMPLERATE*local_time);
00265         ch->size()=size_;
00266         if ((nextPkttime_ != trafgen_->interval()) || (nextPkttime_ == -1))
00267                 rh->flags() |= RTP_M;
00268 
00269         target_->recv(p);
00270 }
00271 
00272 void SA_Agent::sendmsg(int nbytes, const char* /*flags*/)
00273 {
00274         Packet *p;
00275         int n;
00276 
00277     assert (size_ > 0);
00278 
00279     n = nbytes / size_;
00280 
00281         if (nbytes == -1) {
00282                 start();
00283                 return;
00284         }
00285         while (n-- > 0) {
00286             p = allocpkt();
00287                 hdr_rtp* rh = hdr_rtp::access(p);
00288                 rh->seqno() = seqno_;
00289                 target_->recv(p);
00290         }
00291         n = nbytes % size_;
00292         if (n > 0) {
00293             p = allocpkt();
00294             hdr_rtp* rh = hdr_rtp::access(p);
00295             rh->seqno() = seqno_;
00296             target_->recv(p);
00297         }
00298         idle();
00299 }

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