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
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef lint
00036 static const char rcsid[] =
00037 "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/tcp/rtcp.cc,v 1.17 2000/09/01 03:04:06 haoboy Exp $";
00038 #endif
00039
00040 #include <stdlib.h>
00041
00042 #include "config.h"
00043 #include "agent.h"
00044 #include "random.h"
00045 #include "rtp.h"
00046
00047 class RTCPAgent;
00048
00049 class RTCP_Timer : public TimerHandler {
00050 public:
00051 RTCP_Timer(RTCPAgent *a) : TimerHandler() { a_ = a; }
00052 protected:
00053 virtual void expire(Event *e);
00054 RTCPAgent *a_;
00055 };
00056
00057 class RTCPAgent : public Agent {
00058 public:
00059 RTCPAgent();
00060 virtual void timeout(int);
00061 virtual void recv(Packet* p, Handler* h);
00062 int command(int argc, const char*const* argv);
00063 protected:
00064 void start();
00065 void stop();
00066 void sendpkt();
00067
00068 int running_;
00069 int random_;
00070 int seqno_;
00071 double interval_;
00072 RTPSession* session_;
00073
00074 RTCP_Timer rtcp_timer_;
00075 };
00076
00077 static class RTCPAgentClass : public TclClass {
00078 public:
00079 RTCPAgentClass() : TclClass("Agent/RTCP") {}
00080 TclObject* create(int, const char*const*) {
00081 return (new RTCPAgent());
00082 }
00083 } class_rtcp_agent;
00084
00085
00086 RTCPAgent::RTCPAgent()
00087 : Agent(PT_RTCP), session_(0), rtcp_timer_(this)
00088 {
00089 size_ = 128;
00090 bind_time("interval_", &interval_);
00091 bind("random_", &random_);
00092 bind("seqno_", &seqno_);
00093 running_ = 0;
00094 }
00095
00096 void RTCPAgent::start()
00097 {
00098 running_ = 1;
00099 rtcp_timer_.resched(interval_);
00100 }
00101
00102 void RTCPAgent::stop()
00103 {
00104 rtcp_timer_.cancel();
00105 running_ = 0;
00106 }
00107
00108 void RTCPAgent::recv(Packet* p, Handler*)
00109 {
00110 session_->recv_ctrl(p);
00111 }
00112
00113 void RTCPAgent::sendpkt()
00114 {
00115 Packet* p = allocpkt();
00116 hdr_rtp* rh = hdr_rtp::access(p);
00117
00118
00119 rh->seqno() = seqno_++;
00120 rh->srcid() = session_->srcid();
00121 target_->recv(p);
00122 }
00123
00124 void RTCPAgent::timeout(int)
00125 {
00126 if (running_) {
00127 size_ = session_->build_report(0);
00128 sendpkt();
00129 double t = interval_;
00130 if (random_)
00131
00132 t += interval_ * Random::uniform(-0.5, 0.5);
00133 rtcp_timer_.resched(t);
00134
00135 Tcl::instance().evalf("%s rtcp_timeout", session_->name());
00136 }
00137 }
00138
00139 int RTCPAgent::command(int argc, const char*const* argv)
00140 {
00141 if (argc == 2) {
00142 if (strcmp(argv[1], "start") == 0) {
00143 start();
00144 return (TCL_OK);
00145 }
00146 if (strcmp(argv[1], "stop") == 0) {
00147 stop();
00148 return (TCL_OK);
00149 }
00150 if (strcmp(argv[1], "bye") == 0) {
00151 size_ = session_->build_report(1);
00152 sendpkt();
00153 stop();
00154 return (TCL_OK);
00155 }
00156 } else if (argc == 3) {
00157 if (strcmp(argv[1], "session") == 0) {
00158 session_ = (RTPSession*)TclObject::lookup(argv[2]);
00159 return (TCL_OK);
00160 }
00161 }
00162
00163 return (Agent::command(argc, argv));
00164 }
00165
00166 void RTCP_Timer::expire(Event* ) {
00167 a_->timeout(0);
00168 }