summaryrefslogtreecommitdiffstats
path: root/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcpparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcpparse.c')
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcpparse.c218
1 files changed, 218 insertions, 0 deletions
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcpparse.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcpparse.c
new file mode 100644
index 00000000..77e38245
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcpparse.c
@@ -0,0 +1,218 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This source code file was written by Nicola Baldo as an extension of
+ the oRTP library. Copyright (C) 2005 Nicola Baldo nicola@baldo.biz
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#include <ortp.h>
+
+
+
+void report_block_parse(RtpSession *session, report_block_t *rb, struct timeval rcv_time_tv)
+{
+ rb->ssrc = ntohl(rb->ssrc);
+
+ if ( rb->ssrc != session->send_ssrc )
+
+ {
+ ortp_debug("Received rtcp report block related to unknown ssrc (not from us)... discarded");
+ return;
+ }
+
+ else
+
+ {
+ guint32 rcv_time_msw;
+ guint32 rcv_time_lsw;
+ guint32 rcv_time;
+ double rtt;
+
+ rcv_time_msw = rcv_time_tv.tv_sec;
+ rcv_time_lsw = (guint32) ((double)rcv_time_tv.tv_usec*(double)(1LL<<32)*1.0e-6);
+ rcv_time = (rcv_time_msw<<16) | (rcv_time_lsw >> 16);
+
+ rb->cum_num_packet_lost = ntoh24(rb->cum_num_packet_lost);
+ rb->ext_high_seq_num_rec = ntohl(rb->ext_high_seq_num_rec);
+ rb->interarrival_jitter = ntohl(rb->interarrival_jitter);
+ rb->lsr = ntohl(rb->lsr);
+ rb->delay_snc_last_sr = ntohl(rb->delay_snc_last_sr);
+
+
+ /* calculating Round Trip Time*/
+ if (rb->lsr != 0)
+ {
+ rtt = (double) (rcv_time - rb->delay_snc_last_sr - rb->lsr);
+ rtt = rtt/65536;
+ //printf("RTT = %f s\n",rtt);
+ }
+
+ }
+
+}
+
+
+void rtcp_parse(RtpSession *session, mblk_t *mp)
+{
+ rtcp_common_header_t *rtcp;
+ int msgsize;
+ int rtcp_pk_size;
+ RtpStream *rtpstream=&session->rtp;
+ struct timeval rcv_time_tv;
+
+
+ gettimeofday(&rcv_time_tv,NULL);
+
+ g_return_if_fail(mp!=NULL);
+
+ msgsize=mp->b_wptr-mp->b_rptr;
+
+
+
+ if (msgsize < RTCP_COMMON_HEADER_SIZE)
+ {
+ ortp_debug("Receiving too short rtcp packet... discarded");
+ return;
+ }
+
+ rtcp=(rtcp_common_header_t *)mp->b_rptr;
+
+
+ /* compound rtcp packet can be composed by more than one rtcp message */
+ while (msgsize >= RTCP_COMMON_HEADER_SIZE)
+
+ {
+
+ if (rtcp->version!=2)
+ {
+ ortp_debug("Receiving rtcp packet with version number !=2...discarded");
+ return;
+ }
+
+ /* convert header data from network order to host order */
+ rtcp->length = ntohs(rtcp->length);
+
+
+ switch (rtcp->packet_type)
+
+ {
+
+ case RTCP_SR:
+
+ {
+ rtcp_sr_t *sr = (rtcp_sr_t *) rtcp;
+ report_block_t *rb;
+ int i;
+
+ if ( ntohl(sr->ssrc) != session->recv_ssrc )
+ {
+ ortp_debug("Receiving rtcp sr packet from unknown ssrc.. discarded");
+ return;
+ }
+
+ if (msgsize < RTCP_COMMON_HEADER_SIZE + RTCP_SSRC_FIELD_SIZE + RTCP_SENDER_INFO_SIZE + (RTCP_REPORT_BLOCK_SIZE*sr->ch.rc))
+ {
+ ortp_debug("Receiving too short rtcp sr packet... discarded");
+ return;
+ }
+
+ /* parsing RTCP Sender Info */
+ sr->si.ntp_timestamp_msw = ntohl(sr->si.ntp_timestamp_msw);
+ sr->si.ntp_timestamp_lsw = ntohl(sr->si.ntp_timestamp_lsw);
+ sr->si.rtp_timestamp = ntohl(sr->si.rtp_timestamp);
+ sr->si.senders_packet_count = ntohl(sr->si.senders_packet_count);
+ sr->si.senders_octet_count = ntohl(sr->si.senders_octet_count);
+
+ /* saving data to fill LSR and DLSR field in next RTCP report to be transmitted */
+ rtpstream->last_rcv_SR_ts = (sr->si.ntp_timestamp_msw << 16) | (sr->si.ntp_timestamp_lsw >> 16);
+ rtpstream->last_rcv_SR_time.tv_usec = rcv_time_tv.tv_usec;
+ rtpstream->last_rcv_SR_time.tv_sec = rcv_time_tv.tv_sec;
+
+
+ /* parsing all RTCP report blocks */
+ for (i=0; i<sr->ch.rc; i++)
+ {
+ rb = &(sr->rb[i]);
+ report_block_parse(session, rb, rcv_time_tv);
+ }
+
+ }
+ break;
+
+
+
+ case RTCP_RR:
+
+ {
+ rtcp_rr_t *rr = (rtcp_rr_t *) rtcp;
+ report_block_t *rb;
+ int i;
+
+ if ( ntohl(rr->ssrc) != session->recv_ssrc )
+ {
+ ortp_debug("Receiving rtcp rr packet from unknown ssrc.. discarded");
+ return;
+ }
+
+ if (msgsize < RTCP_COMMON_HEADER_SIZE + RTCP_SSRC_FIELD_SIZE + (RTCP_REPORT_BLOCK_SIZE*rr->ch.rc))
+ {
+ ortp_debug("Receiving too short rtcp sr packet... discarded");
+ return;
+ }
+
+ /* parsing all RTCP report blocks */
+ for (i=0; i<rr->ch.rc; i++)
+ {
+ rb = &(rr->rb[i]);
+ report_block_parse(session, rb, rcv_time_tv);
+ }
+
+ }
+ break;
+
+
+ case RTCP_SDES:
+ /* to be implemented */
+ break;
+
+
+ case RTCP_BYE:
+ /* to be implemented */
+ break;
+
+
+ case RTCP_APP:
+ /* to be implemented */
+ break;
+
+
+ default:
+
+ ortp_debug("Receiving unknown rtcp packet type... discarded");
+ return;
+
+ }
+
+
+ rtcp_pk_size = ((rtcp->length)+1)*4; /* current RTCP packet size, in octets */
+ msgsize -= rtcp_pk_size; /* size of unparsed portion of UDP packet, in octets */
+ rtcp = (rtcp_common_header_t *) (rtcp_pk_size + (char *) rtcp); /* pointer to next RTCP packet in current UDP packet */
+
+ }
+}