00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00028 #include "rtcp.h"
00029 #include "comm.h"
00030 #include "utils.h"
00031
00038 int rtcp_build_rr(rtp_session * rtp_sess, rtcp_pkt * pkt)
00039 {
00040 struct timeval now, offset;
00041 uint32_t linear;
00042 rtp_ssrc *stm_src;
00043 rtcp_rr_t *rr;
00044 uint32_t expected, expected_interval, received_interval, lost_interval;
00045 int32_t lost;
00046
00047 rr = pkt->r.rr.rr;
00048 pkt->common.len = 0;
00049
00050 for (stm_src = rtp_sess->ssrc_queue; stm_src; stm_src = stm_src->next) {
00051 if ((pkt->common.len * 4 + 2) > (MAX_PKT_SIZE - 4 * 6))
00052
00053 break;
00054 if (stm_src->ssrc_stats.received_prior !=
00055 stm_src->ssrc_stats.received) {
00056 pkt->common.count++;
00057 rr->ssrc = htonl(stm_src->ssrc);
00058
00059 expected =
00060 stm_src->ssrc_stats.cycles +
00061 stm_src->ssrc_stats.max_seq -
00062 stm_src->ssrc_stats.base_seq + 1;
00063 expected_interval =
00064 expected - stm_src->ssrc_stats.expected_prior;
00065 stm_src->ssrc_stats.expected_prior = expected;
00066 received_interval =
00067 stm_src->ssrc_stats.received -
00068 stm_src->ssrc_stats.received_prior;
00069 stm_src->ssrc_stats.received_prior =
00070 stm_src->ssrc_stats.received;
00071 lost_interval = expected_interval - received_interval;
00072
00073 if ((expected_interval == 0) || (lost_interval <= 0))
00074 rr->fraction = 0;
00075 else
00076 rr->fraction =
00077 (uint8_t) ((lost_interval << 8) /
00078 expected_interval);
00079
00080 lost = min((int32_t)
00081 (expected - stm_src->ssrc_stats.received -
00082 1), 0x7fffff);
00083 lost = max(lost, -(1 << 23));
00084 rr->lost = ((lost&0xff) << 16) |
00085 (lost&0xff00) |
00086 ((lost&0xff0000)>>16);
00087
00088 rr->last_seq =
00089 htonl(stm_src->ssrc_stats.cycles +
00090 stm_src->ssrc_stats.max_seq);
00091 rr->jitter =
00092 htonl((uint32_t) stm_src->ssrc_stats.jitter);
00093 rr->last_sr =
00094 htonl(((stm_src->ssrc_stats.
00095 ntplastsr[0] & 0x0000ffff) << 16) |
00096 ((stm_src->ssrc_stats.
00097 ntplastsr[1] & 0xffff0000)
00098 >> 16));
00099
00100 gettimeofday(&now, NULL);
00101 nms_timeval_subtract(&offset, &now,
00102 &(stm_src->ssrc_stats.lastsr));
00103 linear =
00104 (offset.tv_sec +
00105 (float) offset.tv_usec / 1000000) * (1 << 16);
00106 rr->dlsr =
00107 ((stm_src->ssrc_stats.lastsr.tv_sec !=
00108 0) ? htonl(linear) : 0);
00109
00110 rr++;
00111 }
00112 }
00113
00114 pkt->common.ver = RTP_VERSION;
00115 pkt->common.pad = 0;
00116 pkt->common.pt = RTCP_RR;
00117 pkt->common.len = htons(pkt->common.count * 6 + 1);
00118 pkt->r.rr.ssrc = htonl(rtp_sess->local_ssrc);
00119
00120 return (pkt->common.count * 6 + 2);
00121 }
00122
00128 int rtcp_send_rr(rtp_session * rtp_sess)
00129 {
00130 rtcp_pkt *pkt;
00131 int len;
00132 uint32_t rr_buff[MAX_PKT_SIZE];
00133 rtp_ssrc *stm_src;
00134
00135 memset(rr_buff, 0, MAX_PKT_SIZE * sizeof(uint32_t));
00136 pkt = (rtcp_pkt *) rr_buff;
00137
00138 len = rtcp_build_rr(rtp_sess, pkt);
00139 pkt = (rtcp_pkt *) (rr_buff + len);
00140 len += rtcp_build_sdes(rtp_sess, pkt, (MAX_PKT_SIZE >> 2) - len);
00141
00142 for (stm_src = rtp_sess->ssrc_queue; stm_src; stm_src = stm_src->next)
00143 if ( !(stm_src->no_rtcp) && stm_src->rtp_sess->transport.RTCP.sock.fd > 0) {
00144 switch(stm_src->rtp_sess->transport.type) {
00145 case UDP:
00146 if (sendto(stm_src->rtp_sess->transport.RTCP.sock.fd,
00147 rr_buff, (len << 2), 0, stm_src->rtcp_from.addr,
00148 stm_src->rtcp_from.addr_len) < 0)
00149 nms_printf(NMSML_WARN,
00150 "WARNING! Error while sending UDP RTCP pkt\n");
00151 else
00152 nms_printf(NMSML_DBG3,
00153 "RTCP RR packet sent\n");
00154 break;
00155 case SCTP:
00156 case TCP:
00157 if (send(stm_src->rtp_sess->transport.RTCP.sock.fd,
00158 rr_buff, (len << 2), 0) < 0)
00159 nms_printf(NMSML_WARN,
00160 "WARNING! Error while sending local RTCP pkt\n");
00161 else
00162 nms_printf(NMSML_DBG3,
00163 "RTCP RR packet sent\n");
00164 break;
00165 default:
00166 nms_printf(NMSML_WARN, "Unsupported transport type on send_rr\n");
00167 break;
00168 }
00169 }
00170
00171 return len;
00172 }
00173
00177 int rtcp_parse_rr(rtcp_pkt * pkt)
00178 {
00179
00180 nms_printf(NMSML_DBG3, "Received RR from SSRC: %u\n", pkt->r.rr.ssrc);
00181 return 0;
00182 }
00183
00191 int rtcp_parse_sr(rtp_ssrc * stm_src, rtcp_pkt * pkt)
00192 {
00193 nms_printf(NMSML_DBG3, "Received SR from SSRC: %u\n", pkt->r.sr.ssrc);
00194 gettimeofday(&(stm_src->ssrc_stats.lastsr), NULL);
00195 stm_src->ssrc_stats.ntplastsr[0] = ntohl(pkt->r.sr.si.ntp_seq);
00196 stm_src->ssrc_stats.ntplastsr[1] = ntohl(pkt->r.sr.si.ntp_frac);
00197
00198
00199
00200 return 0;
00201 }