00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "udp.h"
00027 #include "sa.h"
00028 #include "ip.h"
00029 #include "random.h"
00030
00031 #define SAMPLERATE 8000
00032
00033 SA_Agent::SA_Agent() : Agent(PT_UDP), trafgen_(0), rtd_(0), callback_(0),
00034 sa_timer_(this), nextPkttime_(-1), running_(0), seqno_(-1)
00035 {
00036 bind_bw("rate_",&rate_);
00037 bind("bucket_",&bucket_);
00038 bind("packetSize_", &size_);
00039 }
00040
00041 SA_Agent::~SA_Agent()
00042 {
00043 if (callback_)
00044 delete[] callback_;
00045
00046 }
00047
00048
00049 static class SA_AgentClass : public TclClass {
00050 public:
00051 SA_AgentClass() : TclClass("Agent/SA") {}
00052 TclObject* create(int, const char*const*) {
00053 return (new SA_Agent());
00054 }
00055 } class_signalsource_agent;
00056
00057 int SA_Agent::command(int argc, const char*const* argv)
00058 {
00059 Tcl& tcl = Tcl::instance();
00060 if (argc==3) {
00061 if (strcmp(argv[1], "target") == 0) {
00062 target_ = (NsObject*)TclObject::lookup(argv[2]);
00063 if (target_ == 0) {
00064 tcl.resultf("no such object %s", argv[2]);
00065 return (TCL_ERROR);
00066 }
00067 ctrl_target_=target_;
00068 return (TCL_OK);
00069 }
00070 else if (strcmp(argv[1],"ctrl-target")== 0) {
00071 ctrl_target_=(NsObject*)TclObject::lookup(argv[2]);
00072 if (ctrl_target_ == 0) {
00073 tcl.resultf("no such object %s", argv[2]);
00074 return (TCL_ERROR);
00075 }
00076 return (TCL_OK);
00077 }
00078 if (strcmp(argv[1], "stoponidle") == 0) {
00079 stoponidle(argv[2]);
00080 return(TCL_OK);
00081 }
00082 if (strcmp(argv[1], "attach-traffic") == 0) {
00083 trafgen_ =(TrafficGenerator*)TclObject::lookup(argv[2]);
00084 if (trafgen_ == 0) {
00085 tcl.resultf("no such node %s", argv[2]);
00086 return(TCL_ERROR);
00087 }
00088 return(TCL_OK);
00089 }
00090
00091 }
00092 if (argc == 2) {
00093 if (strcmp(argv[1], "start") == 0) {
00094 start();
00095 return(TCL_OK);
00096 } else if (strcmp(argv[1], "stop") == 0) {
00097 stop();
00098 return(TCL_OK);
00099 }
00100 }
00101 return (Agent::command(argc,argv));
00102 }
00103
00104
00105 void SA_Agent::start()
00106 {
00107
00108 if (trafgen_) {
00109 trafgen_->init();
00110
00111 sendreq();
00112 }
00113 }
00114
00115 void SA_Agent::stop()
00116 {
00117 sendteardown();
00118 if (running_ != 0) {
00119 sa_timer_.cancel();
00120 running_ =0;
00121 }
00122 }
00123
00124
00125 void SA_Agent::sendreq()
00126 {
00127 Packet *p = allocpkt();
00128 hdr_cmn* ch= hdr_cmn::access(p);
00129 ch->ptype()=PT_REQUEST;
00130 ch->size()=20;
00131
00132 hdr_resv* rv=hdr_resv::access(p);
00133 rv->decision() =1;
00134 rv->rate()=rate_;
00135 rv->bucket()=bucket_;
00136 ctrl_target_->recv(p);
00137 }
00138
00139 void SA_Agent::sendteardown()
00140 {
00141 Packet *p = allocpkt();
00142 hdr_cmn* ch= hdr_cmn::access(p);
00143 ch->ptype()=PT_TEARDOWN;
00144 ch->size()=20;
00145
00146 hdr_resv* rv=hdr_resv::access(p);
00147 rv->decision() =1;
00148 rv->rate()=rate_;
00149 rv->bucket()=bucket_;
00150 ctrl_target_->recv(p);
00151 }
00152
00153
00154 void SA_Agent::recv(Packet *p, Handler *)
00155 {
00156 hdr_cmn *ch= hdr_cmn::access(p);
00157 hdr_resv *rv=hdr_resv::access(p);
00158 hdr_ip * iph = hdr_ip::access(p);
00159 if ( ch->ptype() == PT_ACCEPT || ch->ptype() == PT_REJECT ) {
00160 ch->ptype() = PT_CONFIRM;
00161
00162
00163
00164 ns_addr_t tmp;
00165 tmp = iph->src();
00166 iph->src() = iph->dst();
00167 iph->dst() = tmp;
00168 ctrl_target_->recv(p);
00169 }
00170
00171
00172 if (rv->decision()) {
00173
00174 fflush(stdout);
00175 double t = trafgen_->next_interval(size_);
00176 running_=1;
00177 sa_timer_.resched(t);
00178 }
00179 else {
00180
00181 fflush(stdout);
00182
00183 running_=0;
00184 }
00185
00186 Tcl::instance().evalf("%s sched-stop %d",name(),rv->decision());
00187 }
00188
00189 void SA_Agent::stoponidle(const char *s)
00190 {
00191 callback_ = new char[strlen(s)+1];
00192 strcpy(callback_, s);
00193
00194 if (trafgen_->on()) {
00195
00196 rtd_ = 1;
00197 }
00198 else {
00199 stop();
00200 Tcl::instance().evalf("%s %s", name(), callback_);
00201 }
00202
00203 }
00204
00205 void SA_Timer::expire(Event* ) {
00206 a_->timeout(0);
00207 }
00208
00209 void SA_Agent::timeout(int)
00210 {
00211 if (running_) {
00212
00213 sendpkt();
00214
00215 nextPkttime_ = trafgen_->next_interval(size_);
00216
00217 sa_timer_.resched(nextPkttime_);
00218
00219
00220
00221
00222 if (rtd_) {
00223 if (trafgen_->on() == 0) {
00224 stop();
00225
00226
00227 Tcl::instance().evalf("%s sched-stop %d", name(), 0);
00228 }
00229 }
00230 }
00231 }
00232
00233 void SA_Agent::sendpkt()
00234 {
00235 Packet* p = allocpkt();
00236 hdr_rtp* rh = hdr_rtp::access(p);
00237 rh->seqno() = ++seqno_;
00238 rh->flags()=0;
00239
00240 double local_time=Scheduler::instance().clock();
00241
00242 hdr_cmn* ch = hdr_cmn::access(p);
00243 ch->timestamp()=(u_int32_t)(SAMPLERATE*local_time);
00244 ch->size()=size_;
00245 if ((nextPkttime_ != trafgen_->interval()) || (nextPkttime_ == -1))
00246 rh->flags() |= RTP_M;
00247
00248 target_->recv(p);
00249 }
00250
00251 void SA_Agent::sendmsg(int nbytes, const char* )
00252 {
00253 Packet *p;
00254 int n;
00255
00256 if (size_)
00257 n = nbytes / size_;
00258 else
00259 printf("Error: SA_Agent size = 0\n");
00260
00261 if (nbytes == -1) {
00262 start();
00263 return;
00264 }
00265 while (n-- > 0) {
00266 p = allocpkt();
00267 hdr_rtp* rh = hdr_rtp::access(p);
00268 rh->seqno() = seqno_;
00269 target_->recv(p);
00270 }
00271 n = nbytes % size_;
00272 if (n > 0) {
00273 p = allocpkt();
00274 hdr_rtp* rh = hdr_rtp::access(p);
00275 rh->seqno() = seqno_;
00276 target_->recv(p);
00277 }
00278 idle();
00279 }