www.pudn.com > streamrtp.rar > rtcprecv.c


/*-------------------------------------------------------------------------
 * rtcprecv.c - rtcprecv, processrtcp
 *-------------------------------------------------------------------------
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 

/*------------------------------------------------------------------------
 * rtcprecv - receive and process a (compound) RTCP packet
 *------------------------------------------------------------------------
 */
int
rtcprecv(struct session *psn)
{

	struct rtcp		*prtcp, *prtcp2;
	struct sockaddr_in	from;
	int			fromlen, len;
	char			rtcpbuf[RTCP_MAXPACKETSZ];

	prtcp = (struct rtcp *) rtcpbuf;

	fromlen = sizeof(from);
	len = recvfrom(psn->sn_rtcpfd, (char *) prtcp, RTCP_MAXPACKETSZ, 0, (struct sockaddr *) &from, &fromlen);

	if (len < 0)
		return ERROR;

	/*
	 * Extract source address as RTCP destination for unicast session
	 * if not already learned.
	 */
	if (psn->sn_rtcpto.sin_addr.s_addr == INADDR_ANY)
		psn->sn_rtcpto.sin_addr = from.sin_addr;

	/*
	 * Iterate over the compound packet. stop if we discover packet 
	 * is truncated due to the use of fixed-sized buffers.
	 */

	prtcp2 = prtcp;
	while(len > RTCP_HEADERSZ) {
		prtcp2->rtcp_length = ntohs(prtcp2->rtcp_length);
		if (len < RTCP_LENGTH_BYTE(prtcp2))
			break;

		rtcpprocess(psn, prtcp2);

		len -= RTCP_LENGTH_BYTE(prtcp2);
		prtcp2 = (struct rtcp *) ((char *) prtcp2 + RTCP_LENGTH_BYTE(prtcp2));
	}
	return OK;
}

/*------------------------------------------------------------------------
 * processrtcp - process a single RTCP packet by dispatching the
 * the appropriate function.
 *------------------------------------------------------------------------
 */
int
rtcpprocess(struct session *psn, struct rtcp *prtcp)
{

	if (prtcp->rtcp_ver != RTP_CURRVERS) 
		return ERROR;

	switch (prtcp->rtcp_type) {
	case RTCP_SR:
		return rtcpsr(psn, prtcp);
	case RTCP_RR:
		return rtcprr(psn, prtcp);
	case RTCP_SDES:
		return rtcpsdes(psn, prtcp);
	case RTCP_BYE:
		return rtcpbye(psn, prtcp);
	case RTCP_APP:
		return rtcpapp(psn, prtcp);
	default:
		return ERROR;
	}
}