ns-allinone-2.30/ns-2.30/rtp/rtp.cc

00001 
00035 #include <stdlib.h>
00036 #include "config.h"
00037 #include "agent.h"
00038 #include "random.h"
00039 #include "rtp.h"
00040 
00041 
00042 int hdr_rtp::offset_;
00044 class RTPHeaderClass : public PacketHeaderClass {
00045 public: 
00046         RTPHeaderClass() : PacketHeaderClass("PacketHeader/RTP",
00047                                              sizeof(hdr_rtp)) {
00048                 bind_offset(&hdr_rtp::offset_);
00049         }
00050 } class_rtphdr;
00054 static class RTPAgentClass : public TclClass {
00055 public:
00056         RTPAgentClass() : TclClass("Agent/RTP") {}
00057         TclObject* create(int, const char*const*) {
00058                 return (new RTPAgent());
00059 
00060         }
00061 } class_rtp_agent;
00062 
00066 RTPAgent::RTPAgent() : Agent(PT_RTP), session_(0), lastpkttime_(-1e6),
00067     running_(0),  rtp_timer_(this)
00068 {
00069         bind("seqno_", &seqno_);
00070         bind_time("interval_", &interval_);
00071         bind("packetSize_", &size_);
00072         bind("maxpkts_", &maxpkts_);
00073         bind("random_", &random_);
00074         timestamp_ = 0;
00075         
00076 }
00078 void RTPAgent::start()
00079 {
00080         running_ = 1;
00081         sendpkt();
00082         rtp_timer_.resched(interval_);
00083 }
00084 
00086 void RTPAgent::stop()
00087 {
00088 //      printf("inside stop localsrc_ %d\n", session_->localsrc_->srcid());
00089         rtp_timer_.force_cancel();
00090         finish();
00091 }
00092 
00094 void RTPAgent::sendmsg(int nbytes, const char* )
00095 {
00096         Packet *p;
00097         int n;
00098 
00099         assert (size_ > 0);
00100 
00101         if (++seqno_ < maxpkts_) {
00102                 n = nbytes / size_;
00103         
00104                 if (nbytes == -1) {
00105                         start();
00106                         return;
00107                 }
00108                 while (n-- > 0) {
00109                         p = allocpkt();
00110                         hdr_rtp* rh = hdr_rtp::access(p);
00111                         rh->seqno() = seqno_;
00112                         target_->recv(p);
00113                 }
00114                 n = nbytes % size_;
00115                 if (n > 0) {
00116                         p = allocpkt();
00117                         hdr_rtp* rh = hdr_rtp::access(p);
00118                         rh->seqno() = seqno_;
00119                         target_->recv(p);
00120                 }
00121                 idle();
00122         } else {
00123                 finish();
00124                 // xxx: should we deschedule the timer here? */
00125         };
00126 }
00127 
00132 void RTPAgent::timeout(int)
00133 {
00134         if (running_) {
00135                 sendpkt();
00136                 if (session_)
00137                         session_->localsrc_update(size_);
00138                         session_->localsrc_update_nbytes(size_);
00139                         
00140                 double t = interval_;
00141                 if (random_)
00142                         /* add some zero-mean white noise */
00143                         t += interval_ * Random::uniform(-0.5, 0.5);
00144                 rtp_timer_.resched(t);
00145         }
00146 }
00147 
00152 void RTPAgent::finish()
00153 {
00154         running_ = 0;
00155         Tcl::instance().evalf("%s done", this->name());
00156 }
00157 
00162 void RTPAgent::advanceby(int delta)
00163 {
00164         maxpkts_ += delta;
00165         if (seqno_ < maxpkts_ && !running_)
00166                 start();
00167 }               
00168 
00173 void RTPAgent::recv(Packet* p, Handler*)
00174 {
00175         if (session_)
00176                 session_->recv(p, 0);
00177         else
00178                 Packet::free(p);
00179 }
00180 /* to handle events from the TCL classes or the TCL scripts */
00181 int RTPAgent::command(int argc, const char*const* argv)
00182 {
00183         if (argc == 2) {
00184                 if (strcmp(argv[1], "rate-change") == 0) {
00185                         rate_change();
00186                         return (TCL_OK);
00187                 } else if (strcmp(argv[1], "start") == 0) {
00188                         start();
00189                         return (TCL_OK);
00190                 } else if (strcmp(argv[1], "stop") == 0) {
00191                         stop();
00192                         return (TCL_OK);
00193                 }
00194         } else if (argc == 3) {
00195                 if (strcmp(argv[1], "session") == 0) {
00196                         session_ = (RTPSession*)TclObject::lookup(argv[2]);
00197                         return (TCL_OK);
00198                 } else if (strcmp(argv[1], "advance") == 0) {
00199                         int newseq = atoi(argv[2]);
00200                         advanceby(newseq - seqno_);
00201                         return (TCL_OK); 
00202                 } else if (strcmp(argv[1], "advanceby") == 0) {
00203                         advanceby(atoi(argv[2]));
00204                         return (TCL_OK);
00205                 }       
00206         }
00207         return (Agent::command(argc, argv));
00208 }
00209 
00216 void RTPAgent::rate_change()
00217 {
00218         rtp_timer_.force_cancel();
00219         
00220         double t = lastpkttime_ + interval_;
00221         
00222         double now = Scheduler::instance().clock();
00223         if ( t > now)
00224                 rtp_timer_.resched(t - now);
00225         else {
00226                 sendpkt();
00227                 rtp_timer_.resched(interval_);
00228         }
00229 }
00231 void RTPAgent::sendpkt()
00232 {
00233         Packet* p = allocpkt();
00234         lastpkttime_ = Scheduler::instance().clock();
00235         timestamp_ = lastpkttime_;
00236         makepkt(p);
00237         target_->recv(p, (Handler*)0);
00238 }
00240 void RTPAgent::makepkt(Packet* p)
00241 {
00242         
00243         hdr_rtp *rh = hdr_rtp::access(p);
00244         /* Fill in srcid_ and seqno */
00245         rh->seqno() = seqno_++;
00246         rh->srcid() = session_ ? session_->srcid() : 0;
00247         rh->timestamp()= timestamp_;
00248         
00249         
00250 }
00251 
00252 void RTPTimer::expire(Event* /*e*/) {
00253         a_->timeout(0);
00254 }
00255 
00256 

Generated on Sat Mar 8 18:04:09 2008 for RTP by  doxygen 1.5.1