From 8e5d45f3aca4d636d426536f5a76270ca780bf9e Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Wed, 12 Oct 2005 20:45:18 +0000 Subject: fix some formatting and add some comments (issue #5403) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@6752 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- rtp.c | 118 +++++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 37 deletions(-) (limited to 'rtp.c') diff --git a/rtp.c b/rtp.c index f28355331..c3465fda3 100755 --- a/rtp.c +++ b/rtp.c @@ -16,12 +16,11 @@ * at the top of the source tree. */ -/* - * - * Real-time Protocol Support - * Supports RTP and RTCP with Symmetric RTP support for NAT - * traversal +/*! + * \file rtp.c + * \brief Supports RTP and RTCP with Symmetric RTP support for NAT traversal. * + * RTP is deffined in RFC 3550. */ #include @@ -59,7 +58,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #define RTP_MTU 1200 -static int dtmftimeout = 3000; /* 3000 samples */ +static int dtmftimeout = 3000; /* 3000 samples */ static int rtpstart = 0; static int rtpend = 0; @@ -87,6 +86,7 @@ struct ast_rtp { char resp; struct ast_frame f; unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET]; + /*! Synchronization source, RFC 3550, page 10. */ unsigned int ssrc; unsigned int lastts; unsigned int lastdigitts; @@ -101,13 +101,16 @@ struct ast_rtp { unsigned int dtmfduration; int nat; unsigned int flags; + /*! Socket representation of the local endpoint. */ struct sockaddr_in us; + /*! Socket representation of the remote endpoint. */ struct sockaddr_in them; struct timeval rxcore; struct timeval txcore; struct timeval dtmfmute; struct ast_smoother *smoother; int *ioid; + /*! Sequence number, RFC 3550, page 13. */ unsigned short seqno; unsigned short rxseqno; struct sched_context *sched; @@ -115,16 +118,30 @@ struct ast_rtp { void *data; ast_rtp_callback callback; struct rtpPayloadType current_RTP_PT[MAX_RTP_PT]; - int rtp_lookup_code_cache_isAstFormat; /* a cache for the result of rtp_lookup_code(): */ + /*! a cache for the result of rtp_lookup_code(): */ + int rtp_lookup_code_cache_isAstFormat; int rtp_lookup_code_cache_code; int rtp_lookup_code_cache_result; int rtp_offered_from_local; struct ast_rtcp *rtcp; }; +/*! + * \brief Structure defining an RTCP session. + * + * The concept "RTCP session" is not defined in RFC 3550, but since + * this structure is analogous to ast_rtp, which tracks a RTP session, + * it is logical to think of this as a RTCP session. + * + * RTCP packet is defined on page 9 of RFC 3550. + * + */ struct ast_rtcp { - int s; /* Socket */ + /*! Socket */ + int s; + /*! Socket representation of the local endpoint. */ struct sockaddr_in us; + /*! Socket representation of the remote endpoint. */ struct sockaddr_in them; }; @@ -230,9 +247,17 @@ static struct ast_frame *process_cisco_dtmf(struct ast_rtp *rtp, unsigned char * return f; } -/* process_rfc2833: Process RTP DTMF and events according to RFC 2833: - "RTP Payload for DTMF Digits, Telephony Tones and Telephony Signals" -*/ +/*! + * \brief Process RTP DTMF and events according to RFC 2833. + * + * RFC 2833 is "RTP Payload for DTMF Digits, Telephony Tones and Telephony Signals". + * + * \param rtp + * \param data + * \param len + * \param seqno + * \returns + */ static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len, unsigned int seqno) { unsigned int event; @@ -282,8 +307,11 @@ static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *dat return f; } -/*--- process_rfc3389: Process Comfort Noise RTP. - This is incomplete at the moment. +/*! + * \brief Process Comfort Noise RTP. + * + * This is incomplete at the moment. + * */ static struct ast_frame *process_rfc3389(struct ast_rtp *rtp, unsigned char *data, int len) { @@ -483,7 +511,7 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp) ast_verbose("Got RTP packet from %s:%d (type %d, seq %d, ts %d, len %d)\n" , ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen); - rtpPT = ast_rtp_lookup_pt(rtp, payloadtype); + rtpPT = ast_rtp_lookup_pt(rtp, payloadtype); if (!rtpPT.isAstFormat) { /* This is special in-band data that's not one of our codecs */ if (rtpPT.code == AST_RTP_DTMF) { @@ -503,37 +531,37 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp) duration &= 0xFFFF; ast_verbose("Got rfc2833 RTP packet from %s:%d (type %d, seq %d, ts %d, len %d, mark %d, event %08x, end %d, duration %d) \n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp, res - hdrlen, (mark?1:0), event, ((event_end & 0x80)?1:0), duration); } - if (rtp->lasteventseqn <= seqno || rtp->resp == 0 || (rtp->lasteventseqn >= 65530 && seqno <= 6)) { - f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen, seqno); - rtp->lasteventseqn = seqno; - } else + if (rtp->lasteventseqn <= seqno || rtp->resp == 0 || (rtp->lasteventseqn >= 65530 && seqno <= 6)) { + f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen, seqno); + rtp->lasteventseqn = seqno; + } else f = NULL; - if (f) - return f; - else + if (f) + return f; + else return &null_frame; - } else if (rtpPT.code == AST_RTP_CISCO_DTMF) { - /* It's really special -- process it the Cisco way */ - if (rtp->lasteventseqn <= seqno || rtp->resp == 0 || (rtp->lasteventseqn >= 65530 && seqno <= 6)) { - f = process_cisco_dtmf(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen); - rtp->lasteventseqn = seqno; - } else + } else if (rtpPT.code == AST_RTP_CISCO_DTMF) { + /* It's really special -- process it the Cisco way */ + if (rtp->lasteventseqn <= seqno || rtp->resp == 0 || (rtp->lasteventseqn >= 65530 && seqno <= 6)) { + f = process_cisco_dtmf(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen); + rtp->lasteventseqn = seqno; + } else f = NULL; - if (f) + if (f) return f; else return &null_frame; - } else if (rtpPT.code == AST_RTP_CN) { - /* Comfort Noise */ - f = process_rfc3389(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen); - if (f) + } else if (rtpPT.code == AST_RTP_CN) { + /* Comfort Noise */ + f = process_rfc3389(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen); + if (f) return f; else return &null_frame; - } else { - ast_log(LOG_NOTICE, "Unknown RTP codec %d received\n", payloadtype); - return &null_frame; - } + } else { + ast_log(LOG_NOTICE, "Unknown RTP codec %d received\n", payloadtype); + return &null_frame; + } } rtp->f.subclass = rtpPT.code; if (rtp->f.subclass < AST_FORMAT_MAX_AUDIO) @@ -862,6 +890,11 @@ static int rtp_socket(void) return s; } +/*! + * \brief Initialize a new RTCP session. + * + * \returns The newly initialized RTCP session. + */ static struct ast_rtcp *ast_rtcp_new(void) { struct ast_rtcp *rtcp; @@ -903,16 +936,21 @@ struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io rtp->sched = sched; rtp->rtcp = ast_rtcp_new(); } - /* Find us a place */ + + /* Select a random port number in the range of possible RTP */ x = (rand() % (rtpend-rtpstart)) + rtpstart; x = x & ~1; + /* Save it for future references. */ startplace = x; + /* Iterate tring to bind that port and incrementing it otherwise untill a port was found or no ports are available. */ for (;;) { /* Must be an even port number by RTP spec */ rtp->us.sin_port = htons(x); rtp->us.sin_addr = addr; + /* If there's rtcp, initialize it as well. */ if (rtp->rtcp) rtp->rtcp->us.sin_port = htons(x + 1); + /* Try to bind it/them. */ if (!(first = bind(rtp->s, (struct sockaddr *)&rtp->us, sizeof(rtp->us))) && (!rtp->rtcp || !bind(rtp->rtcp->s, (struct sockaddr *)&rtp->rtcp->us, sizeof(rtp->rtcp->us)))) break; @@ -922,6 +960,7 @@ struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io rtp->s = rtp_socket(); } if (errno != EADDRINUSE) { + /* We got an error that wasn't expected, abort! */ ast_log(LOG_ERROR, "Unexpected bind error: %s\n", strerror(errno)); close(rtp->s); if (rtp->rtcp) { @@ -931,10 +970,15 @@ struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io free(rtp); return NULL; } + /* The port was used, increment it (by two). */ x += 2; + /* Did we go over the limit ? */ if (x > rtpend) + /* then, start from the begingig. */ x = (rtpstart + 1) & ~1; + /* Check if we reached the place were we started. */ if (x == startplace) { + /* If so, there's no ports available. */ ast_log(LOG_ERROR, "No RTP ports remaining. Can't setup media stream for this call.\n"); close(rtp->s); if (rtp->rtcp) { -- cgit v1.2.3