mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-23 22:45:39 +00:00
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
This commit is contained in:
@@ -16,8 +16,11 @@
|
|||||||
* at the top of the source tree.
|
* at the top of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*!
|
||||||
* Real-time Transport 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
|
#ifndef _ASTERISK_RTP_H
|
||||||
@@ -56,12 +59,39 @@ struct ast_rtp_protocol {
|
|||||||
struct ast_rtp_protocol *next;
|
struct ast_rtp_protocol *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief 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 [...]"
|
||||||
|
*
|
||||||
|
*/
|
||||||
struct ast_rtp;
|
struct ast_rtp;
|
||||||
|
|
||||||
typedef int (*ast_rtp_callback)(struct ast_rtp *rtp, struct ast_frame *f, void *data);
|
typedef int (*ast_rtp_callback)(struct ast_rtp *rtp, struct ast_frame *f, void *data);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializate a RTP session.
|
||||||
|
*
|
||||||
|
* \param sched
|
||||||
|
* \param io
|
||||||
|
* \param rtcpenable
|
||||||
|
* \param callbackmode
|
||||||
|
* \returns A representation (structure) of an RTP session.
|
||||||
|
*/
|
||||||
struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode);
|
struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializate a RTP session using an in_addr structure.
|
||||||
|
*
|
||||||
|
* This fuction gets called by ast_rtp_new().
|
||||||
|
*
|
||||||
|
* \param sched
|
||||||
|
* \param io
|
||||||
|
* \param rtcpenable
|
||||||
|
* \param callbackmode
|
||||||
|
* \param in
|
||||||
|
* \returns A representation (structure) of an RTP session.
|
||||||
|
*/
|
||||||
struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr in);
|
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);
|
void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them);
|
||||||
|
70
rtp.c
70
rtp.c
@@ -16,12 +16,11 @@
|
|||||||
* at the top of the source tree.
|
* at the top of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*!
|
||||||
*
|
* \file rtp.c
|
||||||
* Real-time Protocol Support
|
* \brief Supports RTP and RTCP with Symmetric RTP support for NAT traversal.
|
||||||
* Supports RTP and RTCP with Symmetric RTP support for NAT
|
|
||||||
* traversal
|
|
||||||
*
|
*
|
||||||
|
* RTP is deffined in RFC 3550.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -87,6 +86,7 @@ struct ast_rtp {
|
|||||||
char resp;
|
char resp;
|
||||||
struct ast_frame f;
|
struct ast_frame f;
|
||||||
unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET];
|
unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET];
|
||||||
|
/*! Synchronization source, RFC 3550, page 10. */
|
||||||
unsigned int ssrc;
|
unsigned int ssrc;
|
||||||
unsigned int lastts;
|
unsigned int lastts;
|
||||||
unsigned int lastdigitts;
|
unsigned int lastdigitts;
|
||||||
@@ -101,13 +101,16 @@ struct ast_rtp {
|
|||||||
unsigned int dtmfduration;
|
unsigned int dtmfduration;
|
||||||
int nat;
|
int nat;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
/*! Socket representation of the local endpoint. */
|
||||||
struct sockaddr_in us;
|
struct sockaddr_in us;
|
||||||
|
/*! Socket representation of the remote endpoint. */
|
||||||
struct sockaddr_in them;
|
struct sockaddr_in them;
|
||||||
struct timeval rxcore;
|
struct timeval rxcore;
|
||||||
struct timeval txcore;
|
struct timeval txcore;
|
||||||
struct timeval dtmfmute;
|
struct timeval dtmfmute;
|
||||||
struct ast_smoother *smoother;
|
struct ast_smoother *smoother;
|
||||||
int *ioid;
|
int *ioid;
|
||||||
|
/*! Sequence number, RFC 3550, page 13. */
|
||||||
unsigned short seqno;
|
unsigned short seqno;
|
||||||
unsigned short rxseqno;
|
unsigned short rxseqno;
|
||||||
struct sched_context *sched;
|
struct sched_context *sched;
|
||||||
@@ -115,16 +118,30 @@ struct ast_rtp {
|
|||||||
void *data;
|
void *data;
|
||||||
ast_rtp_callback callback;
|
ast_rtp_callback callback;
|
||||||
struct rtpPayloadType current_RTP_PT[MAX_RTP_PT];
|
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_code;
|
||||||
int rtp_lookup_code_cache_result;
|
int rtp_lookup_code_cache_result;
|
||||||
int rtp_offered_from_local;
|
int rtp_offered_from_local;
|
||||||
struct ast_rtcp *rtcp;
|
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 {
|
struct ast_rtcp {
|
||||||
int s; /* Socket */
|
/*! Socket */
|
||||||
|
int s;
|
||||||
|
/*! Socket representation of the local endpoint. */
|
||||||
struct sockaddr_in us;
|
struct sockaddr_in us;
|
||||||
|
/*! Socket representation of the remote endpoint. */
|
||||||
struct sockaddr_in them;
|
struct sockaddr_in them;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -230,9 +247,17 @@ static struct ast_frame *process_cisco_dtmf(struct ast_rtp *rtp, unsigned char *
|
|||||||
return f;
|
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)
|
static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len, unsigned int seqno)
|
||||||
{
|
{
|
||||||
unsigned int event;
|
unsigned int event;
|
||||||
@@ -282,8 +307,11 @@ static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *dat
|
|||||||
return f;
|
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)
|
static struct ast_frame *process_rfc3389(struct ast_rtp *rtp, unsigned char *data, int len)
|
||||||
{
|
{
|
||||||
@@ -862,6 +890,11 @@ static int rtp_socket(void)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initialize a new RTCP session.
|
||||||
|
*
|
||||||
|
* \returns The newly initialized RTCP session.
|
||||||
|
*/
|
||||||
static struct ast_rtcp *ast_rtcp_new(void)
|
static struct ast_rtcp *ast_rtcp_new(void)
|
||||||
{
|
{
|
||||||
struct ast_rtcp *rtcp;
|
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->sched = sched;
|
||||||
rtp->rtcp = ast_rtcp_new();
|
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 = (rand() % (rtpend-rtpstart)) + rtpstart;
|
||||||
x = x & ~1;
|
x = x & ~1;
|
||||||
|
/* Save it for future references. */
|
||||||
startplace = x;
|
startplace = x;
|
||||||
|
/* Iterate tring to bind that port and incrementing it otherwise untill a port was found or no ports are available. */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* Must be an even port number by RTP spec */
|
/* Must be an even port number by RTP spec */
|
||||||
rtp->us.sin_port = htons(x);
|
rtp->us.sin_port = htons(x);
|
||||||
rtp->us.sin_addr = addr;
|
rtp->us.sin_addr = addr;
|
||||||
|
/* If there's rtcp, initialize it as well. */
|
||||||
if (rtp->rtcp)
|
if (rtp->rtcp)
|
||||||
rtp->rtcp->us.sin_port = htons(x + 1);
|
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))) &&
|
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))))
|
(!rtp->rtcp || !bind(rtp->rtcp->s, (struct sockaddr *)&rtp->rtcp->us, sizeof(rtp->rtcp->us))))
|
||||||
break;
|
break;
|
||||||
@@ -922,6 +960,7 @@ struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io
|
|||||||
rtp->s = rtp_socket();
|
rtp->s = rtp_socket();
|
||||||
}
|
}
|
||||||
if (errno != EADDRINUSE) {
|
if (errno != EADDRINUSE) {
|
||||||
|
/* We got an error that wasn't expected, abort! */
|
||||||
ast_log(LOG_ERROR, "Unexpected bind error: %s\n", strerror(errno));
|
ast_log(LOG_ERROR, "Unexpected bind error: %s\n", strerror(errno));
|
||||||
close(rtp->s);
|
close(rtp->s);
|
||||||
if (rtp->rtcp) {
|
if (rtp->rtcp) {
|
||||||
@@ -931,10 +970,15 @@ struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io
|
|||||||
free(rtp);
|
free(rtp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
/* The port was used, increment it (by two). */
|
||||||
x += 2;
|
x += 2;
|
||||||
|
/* Did we go over the limit ? */
|
||||||
if (x > rtpend)
|
if (x > rtpend)
|
||||||
|
/* then, start from the begingig. */
|
||||||
x = (rtpstart + 1) & ~1;
|
x = (rtpstart + 1) & ~1;
|
||||||
|
/* Check if we reached the place were we started. */
|
||||||
if (x == startplace) {
|
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");
|
ast_log(LOG_ERROR, "No RTP ports remaining. Can't setup media stream for this call.\n");
|
||||||
close(rtp->s);
|
close(rtp->s);
|
||||||
if (rtp->rtcp) {
|
if (rtp->rtcp) {
|
||||||
|
Reference in New Issue
Block a user