? Doxyfile ? asterisk.kdevelop ? asterisk.kdevelop.filelist ? asterisk.kdevelop.pcs ? asterisk.kdevses ? meetme_volume_rev1.diff ? rtp-indentation-and-documentation.patch ? rtp-indentation.patch ? doc/api Index: rtp.c =================================================================== RCS file: /usr/cvsroot/asterisk/rtp.c,v retrieving revision 1.146 diff -u -r1.146 rtp.c --- rtp.c 14 Sep 2005 20:46:49 -0000 1.146 +++ rtp.c 7 Oct 2005 20:57:17 -0000 @@ -17,11 +17,7 @@ */ /* - * - * Real-time Protocol Support - * Supports RTP and RTCP with Symmetric RTP support for NAT - * traversal - * + * Real-time Transport Protocol support */ #include @@ -87,7 +83,7 @@ char resp; struct ast_frame f; unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET]; - unsigned int ssrc; + unsigned int ssrc; /**< Synchronization source, RFC 3550, page 10. */ unsigned int lastts; unsigned int lastdigitts; unsigned int lastrxts; @@ -101,31 +97,37 @@ unsigned int dtmfduration; int nat; unsigned int flags; - struct sockaddr_in us; - struct sockaddr_in them; + struct sockaddr_in us; /**< Socket representation of the local endpoint. */ + struct sockaddr_in them; /**< Socket representation of the remote endpoint. */ struct timeval rxcore; struct timeval txcore; struct timeval dtmfmute; struct ast_smoother *smoother; int *ioid; - unsigned short seqno; + unsigned short seqno; /**< Sequence number, RFC 3550, page 13. */ unsigned short rxseqno; struct sched_context *sched; struct io_context *io; 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(): */ + int rtp_lookup_code_cache_isAstFormat; /**< a cache for the result of rtp_lookup_code(): */ int rtp_lookup_code_cache_code; int rtp_lookup_code_cache_result; int rtp_offered_from_local; struct ast_rtcp *rtcp; }; +/** + * 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. + * @sa ast_rtp + */ struct ast_rtcp { - int s; /* Socket */ - struct sockaddr_in us; - struct sockaddr_in them; + int s; /**< Socket? */ + struct sockaddr_in us; /**< Socket representation of the local endpoint. */ + struct sockaddr_in them; /**< Socket representation of the remote endpoint. */ }; static struct ast_rtp_protocol *protos = NULL; @@ -230,9 +232,13 @@ return f; } -/* process_rfc2833: Process RTP DTMF and events according to RFC 2833: - "RTP Payload for DTMF Digits, Telephony Tones and Telephony Signals" -*/ +/** Process RTP DTMF and events according to RFC 2833: "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 +288,13 @@ return f; } -/*--- process_rfc3389: Process Comfort Noise RTP. - This is incomplete at the moment. +/** + * Process Comfort Noise RTP. + * This is incomplete at the moment. + * @param rtp + * @param data + * @param len + * @returns */ static struct ast_frame *process_rfc3389(struct ast_rtp *rtp, unsigned char *data, int len) { @@ -483,7 +494,7 @@ 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 +514,37 @@ 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 +873,11 @@ return s; } +/** + * Initialize a new RTCP session. + * @returns The newly initialized RTCP session. + * @sa ast_rtcp + */ static struct ast_rtcp *ast_rtcp_new(void) { struct ast_rtcp *rtcp; @@ -903,16 +919,21 @@ 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 +943,7 @@ 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 +953,15 @@ 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) { Index: include/asterisk/rtp.h =================================================================== RCS file: /usr/cvsroot/asterisk/include/asterisk/rtp.h,v retrieving revision 1.24 diff -u -r1.24 rtp.h --- include/asterisk/rtp.h 9 Sep 2005 19:54:34 -0000 1.24 +++ include/asterisk/rtp.h 7 Oct 2005 20:57:17 -0000 @@ -16,8 +16,12 @@ * at the top of the source tree. */ -/* - * Real-time Transport Protocol support +/** + * Real-time Protocol Support + * + * @file rtp.h + * @brief Supports RTP and RTCP with Symmetric RTP support for NAT traversal. + * RTP is deffined in RFC 3550. */ #ifndef _ASTERISK_RTP_H @@ -56,12 +60,24 @@ struct ast_rtp_protocol *next; }; +/** + * Structure representing a RTP session. + * RTP session is defined on page 9 of RFC 3550: "An association among a set of participants communicating with RTP. A participant may be involved in multiple RTP sessions at the same time [...]" + * @sa ast_rtcp. + */ struct ast_rtp; typedef int (*ast_rtp_callback)(struct ast_rtp *rtp, struct ast_frame *f, void *data); struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode); +/** + * Initializate a RTP session. + * @param sched ? + * @param io ? + * @returns A representation (structure) of an RTP session. + * @sa ast_rtp. + */ struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr in); void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them);