📄 rtcp-packet.c
字号:
/* Gnome-o-Phone - A program for internet telephony Copyright (C) 1999 Roland Dreier This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: rtcp-packet.c 1.5 Sat, 04 Dec 1999 15:20:37 -0600 dreier $*/#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "rtcp-packet.h"#include "rtp.h"#include <glib.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/time.h>#include <netinet/in.h>#include <string.h>#include "gphone-lib.h"struct Rtcp_Packet { gpointer data; guint data_len; gboolean free_data;};struct Rtcp_Compound { gpointer data; guint data_len; guint max_len;};typedef struct Rtcp_Common_Header *Rtcp_Common_Header;typedef struct Rtcp_RR_Header *Rtcp_RR_Header;typedef struct Rtcp_SR_Header *Rtcp_SR_Header;typedef struct Rtcp_SDES_Header *Rtcp_SDES_Header;typedef struct Rtcp_BYE_Header *Rtcp_BYE_Header;typedef struct Rtcp_APP_Header *Rtcp_APP_Header;typedef struct SDES_Item *SDES_Item;typedef struct Rtcp_RR *Rtcp_RR;struct Rtcp_Common_Header {#if G_BYTE_ORDER == G_LITTLE_ENDIAN unsigned int count:5; /* varies by packet type */ unsigned int padding:1; /* padding flag */ unsigned int version:2; /* protocol version */#elif G_BYTE_ORDER == G_BIG_ENDIAN unsigned int version:2; /* protocol version */ unsigned int padding:1; /* padding flag */ unsigned int count:5; /* varies by packet type */#else#error "G_BYTE_ORDER should be big or little endian."#endif unsigned int packet_type:8; /* RTCP packet type */ guint16 length; /* pkt len in words, w/o this word */};struct Rtcp_RR { guint32 ssrc; /* data source being reported */ unsigned int fraction:8; /* fraction lost since last SR/RR */ int lost:24; /* cumul. no. pkts lost (signed!) */ guint32 last_seq; /* extended last seq. no. received */ guint32 jitter; /* interarrival jitter */ guint32 lsr; /* last SR packet from this source */ guint32 dlsr; /* delay since last SR packet */};struct Rtcp_SR_Header { guint32 ssrc; /* sender generating this report */ guint32 ntp_sec; /* NTP timestamp */ guint32 ntp_frac; guint32 rtp_ts; /* RTP timestamp */ guint32 psent; /* packets sent */ guint32 osent; /* octets sent */ struct Rtcp_RR rr[1]; /* variable-length list */};struct Rtcp_RR_Header { guint32 ssrc; /* receiver generating this report */ struct Rtcp_RR rr[1]; /* variable-length list */};struct SDES_Item { guint8 type; /* type of item (Rtcp_Sdes_Type) */ guint8 length; /* length of item (in octets) */ gchar data[1]; /* text, not null-terminated */};struct Rtcp_SDES_Header { guint32 src; /* first SSRC/CSRC */ struct SDES_Item item[1]; /* list of SDES items */}; struct Rtcp_BYE_Header { guint32 src[1]; /* list of sources */ gchar data[1]; /* reason for leaving */};struct Rtcp_APP_Header { guint32 ssrc; /* source */ gchar name[4]; /* name */ gchar data[1]; /* application data */};/* Functions for allocating and freeing packets*/Rtcp_Compoundrtcp_compound_new(void){ Rtcp_Compound compound; compound = g_malloc(sizeof *compound); compound -> data = NULL; compound -> data_len = 0; compound -> max_len = 0; return compound;}Rtcp_Compoundrtcp_compound_new_allocate(guint len){ Rtcp_Compound compound; compound = g_malloc(sizeof *compound); compound -> max_len = len; compound -> data_len = 0; compound -> data = g_malloc(len); return compound;}Rtcp_Compoundrtcp_compound_new_take_data(gpointer data, guint data_len){ Rtcp_Compound compound; g_return_val_if_fail(data_len < RTP_MTU, NULL); compound = g_malloc(sizeof *compound); compound -> data = data; compound -> data_len = data_len; compound -> max_len = data_len; return compound;}Rtcp_Compoundrtcp_compound_new_copy_data(gpointer data, guint data_len){ Rtcp_Compound compound; g_return_val_if_fail(data_len < RTP_MTU, NULL); compound = g_malloc(sizeof *compound); compound -> data = g_memdup(data, data_len); compound -> data_len = data_len; compound -> max_len = data_len; return compound;}voidrtcp_compound_free(Rtcp_Compound compound){ g_return_if_fail(compound != NULL); if (compound -> data != NULL) { g_free(compound -> data); } g_free(compound);}Rtcp_Compoundrtcp_compound_read(int fd, struct sockaddr_in *fromaddr){ int fromlen; int packlen; gpointer buf; buf = g_malloc(RTP_MTU); fromlen = sizeof *fromaddr; packlen = recvfrom(fd, buf, RTP_MTU, 0, (struct sockaddr *) fromaddr, &fromlen); if (packlen < 0) { gphone_perror_exit("*** rtcp_compound_read : recvfrom", 1); } return rtcp_compound_new_take_data(buf, packlen);}voidrtcp_compound_send(Rtcp_Compound compound, int fd, struct sockaddr_in *toaddr){ g_return_if_fail(compound != NULL); sendto(fd, (void *) compound -> data, compound -> data_len, 0, (struct sockaddr *) toaddr, sizeof (struct sockaddr_in));}Rtcp_Packetrtcp_packet_new(void){ Rtcp_Packet packet; packet = g_malloc(sizeof *packet); packet -> free_data = FALSE; packet -> data = NULL; packet -> data_len = 0; return packet;}Rtcp_Packetrtcp_packet_new_take_data(gpointer data, guint data_len){ Rtcp_Packet packet; g_return_val_if_fail(data_len < RTP_MTU, NULL); packet = g_malloc(sizeof *packet); packet -> free_data = TRUE; packet -> data = data; packet -> data_len = data_len; return packet;}Rtcp_Packetrtcp_packet_new_copy_data(gpointer data, guint data_len){ Rtcp_Packet packet; g_return_val_if_fail(data_len < RTP_MTU, NULL); packet = g_malloc(sizeof *packet); packet -> free_data = TRUE; packet -> data = g_memdup(data, data_len); packet -> data_len = data_len; return packet;}voidrtcp_packet_free(Rtcp_Packet packet){ g_return_if_fail(packet != NULL); if (packet -> free_data) { g_free(packet -> data); } g_free(packet);}/* Functions for processing packets*/void rtcp_compound_foreach(Rtcp_Compound compound, Rtcp_Foreach_Func func, gpointer data){ Rtcp_Packet packet; g_return_if_fail(compound != NULL); packet = rtcp_packet_new(); packet -> data = compound -> data; packet -> data_len = rtcp_packet_get_length(packet); while ((gint8 *) packet -> data - (gint8 *) compound -> data < compound -> data_len) { func(packet, data); packet -> data = (gpointer) ((gint8 *) packet -> data + packet -> data_len); packet -> data_len = rtcp_packet_get_length(packet); } rtcp_packet_free(packet);}voidrtcp_read_sdes(Rtcp_Packet packet, Rtcp_Find_Member_Func find_member, Rtcp_Member_SDES_Func member_sdes){ int count = rtcp_packet_get_count(packet); Rtcp_SDES_Header sd; SDES_Item rsp; SDES_Item end = (SDES_Item) ((gint8 *) rtcp_packet_get_data(packet)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -