00001
00034 #include <stdlib.h>
00035 #include "config.h"
00036 #include "agent.h"
00037 #include "random.h"
00038 #include "rtp.h"
00039
00040 class RTCPAgent;
00042 class RTCP_Timer : public TimerHandler {
00043 public:
00044 RTCP_Timer(RTCPAgent *a) : TimerHandler() { a_ = a; }
00045 protected:
00046 virtual void expire(Event *e);
00047 RTCPAgent *a_;
00048 };
00052 class RTCPAgent : public Agent {
00053 public:
00054 RTCPAgent();
00055 virtual void timeout(int);
00056 virtual void recv(Packet* p, Handler* h);
00057 int command(int argc, const char*const* argv);
00058 protected:
00059 void start();
00060 void stop();
00061 void sendpkt();
00062 int running_;
00063 int random_;
00064 int seqno_;
00065 double interval_;
00066 RTPSession* session_;
00067 RTCP_Timer rtcpup_timer_;
00068
00069 };
00073 static class RTCPAgentClass : public TclClass {
00074 public:
00075 RTCPAgentClass() : TclClass("Agent/RTCP") {}
00076 TclObject* create(int, const char*const*) {
00077 return (new RTCPAgent());
00078 }
00079 } class_rtcpup_agent;
00080
00082 RTCPAgent::RTCPAgent()
00083 : Agent(PT_RTCP), session_(0), rtcpup_timer_(this)
00084 {
00085 size_ = 128;
00086 bind_time("interval_", &interval_);
00087 bind("random_", &random_);
00088 bind("seqno_", &seqno_);
00089 running_ = 0;
00090
00091 }
00093 void RTCPAgent::start()
00094 {
00095 running_ = 1;
00096
00097 rtcpup_timer_.resched(interval_);
00098
00099 }
00101 void RTCPAgent::stop()
00102 {
00103 rtcpup_timer_.cancel();
00104 running_ = 0;
00105 }
00107 void RTCPAgent::recv(Packet* p, Handler*)
00108 {
00109 session_->recv_ctrl(p);
00110 }
00115 void RTCPAgent::sendpkt()
00116 {
00117 Packet* p = allocpkt();
00118 hdr_rtp* rh = hdr_rtp::access(p);
00119 hdr_rtp* tmp = new hdr_rtp;
00120 tmp = session_->access_hdr_rtp();
00121
00122 rh->seqno() = seqno_++;
00123 rh->srcid() = session_->srcid();
00124 rh->timestamp() = Scheduler::instance().clock();
00125 rh->sr_ = tmp->sr_;
00126 rh->rr_ = tmp->rr_;
00127 target_->recv(p);
00128 }
00129
00130
00138 void RTCPAgent::timeout(int)
00139 {
00140 if (running_) {
00141 size_ = session_->build_report(0);
00142 sendpkt();
00143 double t = interval_;
00144 if (random_)
00145
00146 t += interval_ * Random::uniform(-0.5, 0.5);
00147 rtcpup_timer_.resched(t);
00148
00149 Tcl::instance().evalf("%s rtcp_timeout", session_->name());
00150 }
00151 }
00153 int RTCPAgent::command(int argc, const char*const* argv)
00154 {
00155 if (argc == 2) {
00156 if (strcmp(argv[1], "start") == 0) {
00157 start();
00158 return (TCL_OK);
00159 }
00160 if (strcmp(argv[1], "stop") == 0) {
00161 stop();
00162 return (TCL_OK);
00163 }
00164 if (strcmp(argv[1], "bye") == 0) {
00165 size_ = session_->build_report(1);
00166 sendpkt();
00167 stop();
00168 return (TCL_OK);
00169 }
00170 } else if (argc == 3) {
00171 if (strcmp(argv[1], "session") == 0) {
00172 session_ = (RTPSession*)TclObject::lookup(argv[2]);
00173 return (TCL_OK);
00174 }
00175 }
00176
00177 return (Agent::command(argc, argv));
00178 }
00179
00180 void RTCP_Timer::expire(Event* ) {
00181 a_->timeout(0);
00182 }