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 }
00114 void RTCPAgent::sendpkt()
00115 {
00116 Packet* p = allocpkt();
00117 hdr_rtp* rh = hdr_rtp::access(p);
00118 hdr_rtp* tmp = new hdr_rtp;
00119 tmp = session_->access_hdr_rtp();
00120
00121 rh->seqno() = seqno_++;
00122 rh->srcid() = session_->srcid();
00123 rh->timestamp() = Scheduler::instance().clock();
00124 rh->sr_ = tmp->sr_;
00125 rh->rr_ = tmp->rr_;
00126 target_->recv(p);
00127 }
00128
00129
00137 void RTCPAgent::timeout(int)
00138 {
00139 if (running_) {
00140 size_ = session_->build_report(0);
00141 sendpkt();
00142 double t = interval_;
00143 if (random_)
00144
00145 t += interval_ * Random::uniform(-0.5, 0.5);
00146 rtcpup_timer_.resched(t);
00147
00148 Tcl::instance().evalf("%s rtcp_timeout", session_->name());
00149 }
00150 }
00152 int RTCPAgent::command(int argc, const char*const* argv)
00153 {
00154 if (argc == 2) {
00155 if (strcmp(argv[1], "start") == 0) {
00156 start();
00157 return (TCL_OK);
00158 }
00159 if (strcmp(argv[1], "stop") == 0) {
00160 stop();
00161 return (TCL_OK);
00162 }
00163 if (strcmp(argv[1], "bye") == 0) {
00164 size_ = session_->build_report(1);
00165 sendpkt();
00166 stop();
00167 return (TCL_OK);
00168 }
00169 } else if (argc == 3) {
00170 if (strcmp(argv[1], "session") == 0) {
00171 session_ = (RTPSession*)TclObject::lookup(argv[2]);
00172 return (TCL_OK);
00173 }
00174 }
00175
00176 return (Agent::command(argc, argv));
00177 }
00178
00179 void RTCP_Timer::expire(Event* ) {
00180 a_->timeout(0);
00181 }