session-rtp.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:5k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (c) 1997 Regents of the University of California.
  4.  * All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  *  This product includes software developed by the MASH Research
  17.  *  Group at the University of California Berkeley.
  18.  * 4. Neither the name of the University nor of the Research Group may be
  19.  *    used to endorse or promote products derived from this software without
  20.  *    specific prior written permission.
  21.  * 
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  */
  34. #ifndef lint
  35. static const char rcsid[] =
  36.     "@(#) $Header: /cvsroot/nsnam/ns-2/common/session-rtp.cc,v 1.13 2000/09/01 03:04:07 haoboy Exp $";
  37. #endif
  38. #include <stdlib.h>
  39. #include "packet.h"
  40. #include "ip.h"
  41. #include "rtp.h"
  42. static class RTPSourceClass : public TclClass {
  43. public:
  44. RTPSourceClass() : TclClass("RTPSource") {}
  45. TclObject* create(int argc, const char*const* argv) {
  46. if (argc >= 5)
  47. return (new RTPSource(atoi(argv[4])));
  48. return 0;
  49. }
  50. } class_rtp_source;
  51. static class RTPSessionClass : public TclClass {
  52. public:
  53. RTPSessionClass() : TclClass("Session/RTP") {}
  54. TclObject* create(int, const char*const*) {
  55. return (new RTPSession());
  56. }
  57. } class_rtp_session;
  58. RTPSession::RTPSession() 
  59. : allsrcs_(0), localsrc_(0), last_np_(0)
  60. {
  61. }
  62. RTPSession::~RTPSession() 
  63. {
  64. while (allsrcs_ != 0) {
  65. RTPSource* p = allsrcs_;
  66. allsrcs_ = allsrcs_->next;
  67. delete p;
  68. }
  69. delete localsrc_;
  70. }
  71. void RTPSession::localsrc_update(int)
  72. {
  73. localsrc_->np(1);
  74. }
  75. #define RTCP_HDRSIZE 8
  76. #define RTCP_SR_SIZE 20
  77. #define RTCP_RR_SIZE 48
  78. int RTPSession::build_report(int bye)
  79. {
  80. int nsrc = 0;
  81. int nrr = 0;
  82. int len = RTCP_HDRSIZE;
  83. int we_sent = 0;
  84. if (localsrc_->np() != last_np_) {
  85. last_np_ = localsrc_->np();
  86. we_sent = 1;
  87. len += RTCP_SR_SIZE;
  88. }
  89. for (RTPSource* sp = allsrcs_; sp != 0; sp = sp->next) {
  90. ++nsrc;
  91.         int received = sp->np() - sp->snp();
  92. if (received == 0) {
  93. continue;
  94. }
  95. sp->snp(sp->np());
  96. len += RTCP_RR_SIZE;
  97. if (++nrr >= 31)
  98. break;
  99. }
  100. if (bye) 
  101. len += build_bye();
  102. else 
  103. len += build_sdes();
  104. Tcl::instance().evalf("%s adapt-timer %d %d %d", name(), 
  105.       nsrc, nrr, we_sent);
  106. Tcl::instance().evalf("%s sample-size %d", name(), len);
  107. return (len);
  108. }
  109. int RTPSession::build_bye() 
  110. {
  111. return (8);
  112. }
  113. int RTPSession::build_sdes()
  114. {
  115. /* XXX We'll get to this later... */
  116. return (20);
  117. }
  118. void RTPSession::recv(Packet* p, Handler*)
  119. {
  120. hdr_rtp *rh = hdr_rtp::access(p);
  121. u_int32_t srcid = rh->srcid();
  122. RTPSource* s = lookup(srcid);
  123. if (s == 0) {
  124. Tcl& tcl = Tcl::instance();
  125. tcl.evalf("%s new-source %d", name(), srcid);
  126. s = (RTPSource*)TclObject::lookup(tcl.result());
  127. }
  128. s->np(1);
  129. s->ehsr(rh->seqno());
  130. Packet::free(p);
  131. }
  132. void RTPSession::recv_ctrl(Packet* p)
  133. {
  134. hdr_cmn* ch = hdr_cmn::access(p);
  135. Tcl::instance().evalf("%s sample-size %d", name(), ch->size());
  136. Packet::free(p);
  137. }
  138. /* XXX Should hash this... */
  139. RTPSource* RTPSession::lookup(u_int32_t srcid)
  140. {
  141. RTPSource *p;
  142. for (p = allsrcs_; p != 0; p = p->next)
  143. if (p->srcid() == srcid)
  144. return (p);
  145. return (0);
  146. }
  147. void RTPSession::enter(RTPSource* s)
  148. {
  149. s->next = allsrcs_;
  150. allsrcs_ = s;
  151. }
  152. int RTPSession::command(int argc, const char*const* argv)
  153. {
  154. if (argc == 3) {
  155. if (strcmp(argv[1], "enter") == 0) {
  156. RTPSource* s = (RTPSource*)TclObject::lookup(argv[2]);
  157. enter(s);
  158. return (TCL_OK);
  159. }
  160. if (strcmp(argv[1], "localsrc") == 0) {
  161. localsrc_ = (RTPSource*)TclObject::lookup(argv[2]);
  162. enter(localsrc_);
  163. return (TCL_OK);
  164. }
  165. }
  166. return (TclObject::command(argc, argv));
  167. }
  168. RTPSource::RTPSource(u_int32_t srcid)
  169. : next(0), np_(0), snp_(0), ehsr_(-1)
  170. {
  171. bind("srcid_", (int*)&srcid_);
  172. srcid_ = srcid;
  173. }