[asterisk-commits] file: branch file/rtp_engine r124370 - in /team/file/rtp_engine: channels/ in...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Jun 20 15:34:09 CDT 2008
Author: file
Date: Fri Jun 20 15:34:08 2008
New Revision: 124370
URL: http://svn.digium.com/view/asterisk?view=rev&rev=124370
Log:
Break STUN support out into a separate source file and header, away from the RTP stack.
Added:
team/file/rtp_engine/include/asterisk/stun.h
- copied, changed from r124314, team/file/rtp_engine/include/asterisk/rtp.h
team/file/rtp_engine/main/stun.c
- copied, changed from r124314, team/file/rtp_engine/main/rtp.c
Modified:
team/file/rtp_engine/channels/chan_sip.c
team/file/rtp_engine/include/asterisk/rtp.h
team/file/rtp_engine/main/asterisk.c
Modified: team/file/rtp_engine/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/channels/chan_sip.c?view=diff&rev=124370&r1=124369&r2=124370
==============================================================================
--- team/file/rtp_engine/channels/chan_sip.c (original)
+++ team/file/rtp_engine/channels/chan_sip.c Fri Jun 20 15:34:08 2008
@@ -196,6 +196,8 @@
#include "asterisk/ast_version.h"
#include "asterisk/event.h"
#include "asterisk/tcptls.h"
+#include "asterisk/rtp_engine.h"
+#include "asterisk/stun.h"
#ifndef FALSE
#define FALSE 0
Modified: team/file/rtp_engine/include/asterisk/rtp.h
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/include/asterisk/rtp.h?view=diff&rev=124370&r1=124369&r2=124370
==============================================================================
--- team/file/rtp_engine/include/asterisk/rtp.h (original)
+++ team/file/rtp_engine/include/asterisk/rtp.h Fri Jun 20 15:34:08 2008
@@ -231,24 +231,6 @@
/*! \brief Enable STUN capability */
void ast_rtp_setstun(struct ast_rtp *rtp, int stun_enable);
-/*! \brief Generic STUN request
- * send a generic stun request to the server specified.
- * \param s the socket used to send the request
- * \param dst the address of the STUN server
- * \param username if non null, add the username in the request
- * \param answer if non null, the function waits for a response and
- * puts here the externally visible address.
- * \return 0 on success, other values on error.
- * The interface it may change in the future.
- */
-int ast_stun_request(int s, struct sockaddr_in *dst,
- const char *username, struct sockaddr_in *answer);
-
-/*! \brief Send STUN request for an RTP socket
- * Deprecated, this is just a wrapper for ast_rtp_stun_request()
- */
-void ast_rtp_stun_request(struct ast_rtp *rtp, struct sockaddr_in *suggestion, const char *username);
-
/*! \brief The RTP bridge.
\arg \ref AstRTPbridge
*/
Copied: team/file/rtp_engine/include/asterisk/stun.h (from r124314, team/file/rtp_engine/include/asterisk/rtp.h)
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/include/asterisk/stun.h?view=diff&rev=124370&p1=team/file/rtp_engine/include/asterisk/rtp.h&r1=124314&p2=team/file/rtp_engine/include/asterisk/stun.h&r2=124370
==============================================================================
--- team/file/rtp_engine/include/asterisk/rtp.h (original)
+++ team/file/rtp_engine/include/asterisk/stun.h Fri Jun 20 15:34:08 2008
@@ -1,7 +1,7 @@
/*
* Asterisk -- An open source telephony toolkit.
*
- * Copyright (C) 1999 - 2006, Digium, Inc.
+ * Copyright (C) 1999 - 2008, Digium, Inc.
*
* Mark Spencer <markster at digium.com>
*
@@ -17,219 +17,27 @@
*/
/*!
- * \file rtp.h
- * \brief Supports RTP and RTCP with Symmetric RTP support for NAT traversal.
+ * \file stun.h
+ * \brief STUN support.
*
- * RTP is defined in RFC 3550.
+ * STUN is defined in RFC 3489.
*/
-#ifndef _ASTERISK_RTP_H
-#define _ASTERISK_RTP_H
+#ifndef _ASTERISK_STUN_H
+#define _ASTERISK_STUN_H
#include "asterisk/network.h"
-
-#include "asterisk/frame.h"
-#include "asterisk/io.h"
-#include "asterisk/sched.h"
-#include "asterisk/channel.h"
-#include "asterisk/linkedlists.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
-/* Codes for RTP-specific data - not defined by our AST_FORMAT codes */
-/*! DTMF (RFC2833) */
-#define AST_RTP_DTMF (1 << 0)
-/*! 'Comfort Noise' (RFC3389) */
-#define AST_RTP_CN (1 << 1)
-/*! DTMF (Cisco Proprietary) */
-#define AST_RTP_CISCO_DTMF (1 << 2)
-/*! Maximum RTP-specific code */
-#define AST_RTP_MAX AST_RTP_CISCO_DTMF
-
-/*! Maxmum number of payload defintions for a RTP session */
-#define MAX_RTP_PT 256
-
-/*! T.140 Redundancy Maxium number of generations */
-#define RED_MAX_GENERATION 5
-
-#define FLAG_3389_WARNING (1 << 0)
-
-enum ast_rtp_options {
- AST_RTP_OPT_G726_NONSTANDARD = (1 << 0),
+enum ast_stun_result {
+ AST_STUN_IGNORE = 0,
+ AST_STUN_ACCEPT,
};
-enum ast_rtp_get_result {
- /*! Failed to find the RTP structure */
- AST_RTP_GET_FAILED = 0,
- /*! RTP structure exists but true native bridge can not occur so try partial */
- AST_RTP_TRY_PARTIAL,
- /*! RTP structure exists and native bridge can occur */
- AST_RTP_TRY_NATIVE,
-};
-
-struct ast_rtp;
-/*! T.140 Redundancy structure*/
-struct rtp_red;
-
-/*! \brief This is the structure that binds a channel (SIP/Jingle/H.323) to the RTP subsystem
-*/
-struct ast_rtp_protocol {
- /*! Get RTP struct, or NULL if unwilling to transfer */
- enum ast_rtp_get_result (* const get_rtp_info)(struct ast_channel *chan, struct ast_rtp **rtp);
- /*! Get RTP struct, or NULL if unwilling to transfer */
- enum ast_rtp_get_result (* const get_vrtp_info)(struct ast_channel *chan, struct ast_rtp **rtp);
- /*! Get RTP struct, or NULL if unwilling to transfer */
- enum ast_rtp_get_result (* const get_trtp_info)(struct ast_channel *chan, struct ast_rtp **rtp);
- /*! Set RTP peer */
- int (* const set_rtp_peer)(struct ast_channel *chan, struct ast_rtp *peer, struct ast_rtp *vpeer, struct ast_rtp *tpeer, int codecs, int nat_active);
- int (* const get_codec)(struct ast_channel *chan);
- const char * const type;
- AST_LIST_ENTRY(ast_rtp_protocol) list;
-};
-
-enum ast_rtp_quality_type {
- RTPQOS_SUMMARY = 0,
- RTPQOS_JITTER,
- RTPQOS_LOSS,
- RTPQOS_RTT
-};
-
-/*! \brief RTCP quality report storage */
-struct ast_rtp_quality {
- unsigned int local_ssrc; /*!< Our SSRC */
- unsigned int local_lostpackets; /*!< Our lost packets */
- double local_jitter; /*!< Our calculated jitter */
- unsigned int local_count; /*!< Number of received packets */
- unsigned int remote_ssrc; /*!< Their SSRC */
- unsigned int remote_lostpackets; /*!< Their lost packets */
- double remote_jitter; /*!< Their reported jitter */
- unsigned int remote_count; /*!< Number of transmitted packets */
- double rtt; /*!< Round trip time */
-};
-
-/*! RTP callback structure */
-typedef int (*ast_rtp_callback)(struct ast_rtp *rtp, struct ast_frame *f, void *data);
-
-/*!
- * \brief Get the amount of space required to hold an RTP session
- * \return number of bytes required
- */
-size_t ast_rtp_alloc_size(void);
-
-/*!
- * \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);
-
-/*!
- * \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);
-
-void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them);
-
-/* Copies from rtp to them and returns 1 if there was a change or 0 if it was already the same */
-int ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them);
-
-void ast_rtp_get_us(struct ast_rtp *rtp, struct sockaddr_in *us);
-
-struct ast_rtp *ast_rtp_get_bridged(struct ast_rtp *rtp);
-
-/*! Destroy RTP session */
-void ast_rtp_destroy(struct ast_rtp *rtp);
-
-void ast_rtp_reset(struct ast_rtp *rtp);
-
-/*! Stop RTP session, do not destroy structure */
-void ast_rtp_stop(struct ast_rtp *rtp);
-
-void ast_rtp_set_callback(struct ast_rtp *rtp, ast_rtp_callback callback);
-
-void ast_rtp_set_data(struct ast_rtp *rtp, void *data);
-
-int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *f);
-
-struct ast_frame *ast_rtp_read(struct ast_rtp *rtp);
-
-struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp);
-
-int ast_rtp_fd(struct ast_rtp *rtp);
-
-int ast_rtcp_fd(struct ast_rtp *rtp);
-
-int ast_rtp_senddigit_begin(struct ast_rtp *rtp, char digit);
-
-int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit);
-
-int ast_rtp_sendcng(struct ast_rtp *rtp, int level);
-
-int ast_rtp_setqos(struct ast_rtp *rtp, int tos, int cos, char *desc);
-
-void ast_rtp_new_source(struct ast_rtp *rtp);
-
-/*! \brief Setting RTP payload types from lines in a SDP description: */
-void ast_rtp_pt_clear(struct ast_rtp* rtp);
-/*! \brief Set payload types to defaults */
-void ast_rtp_pt_default(struct ast_rtp* rtp);
-
-/*! \brief Copy payload types between RTP structures */
-void ast_rtp_pt_copy(struct ast_rtp *dest, struct ast_rtp *src);
-
-/*! \brief Activate payload type */
-void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt);
-
-/*! \brief clear payload type */
-void ast_rtp_unset_m_type(struct ast_rtp* rtp, int pt);
-
-/*! \brief Initiate payload type to a known MIME media type for a codec */
-int ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,
- char *mimeType, char *mimeSubtype,
- enum ast_rtp_options options);
-
-/*! \brief Mapping between RTP payload format codes and Asterisk codes: */
-struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt);
-int ast_rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code);
-
-void ast_rtp_get_current_formats(struct ast_rtp* rtp,
- int* astFormats, int* nonAstFormats);
-
-/*! \brief Mapping an Asterisk code into a MIME subtype (string): */
-const char *ast_rtp_lookup_mime_subtype(int isAstFormat, int code,
- enum ast_rtp_options options);
-
-/*! \brief Build a string of MIME subtype names from a capability list */
-char *ast_rtp_lookup_mime_multiple(char *buf, size_t size, const int capability,
- const int isAstFormat, enum ast_rtp_options options);
-
-void ast_rtp_setnat(struct ast_rtp *rtp, int nat);
-
-int ast_rtp_getnat(struct ast_rtp *rtp);
-
-/*! \brief Indicate whether this RTP session is carrying DTMF or not */
-void ast_rtp_setdtmf(struct ast_rtp *rtp, int dtmf);
-
-/*! \brief Compensate for devices that send RFC2833 packets all at once */
-void ast_rtp_setdtmfcompensate(struct ast_rtp *rtp, int compensate);
-
-/*! \brief Enable STUN capability */
-void ast_rtp_setstun(struct ast_rtp *rtp, int stun_enable);
+struct stun_attr;
/*! \brief Generic STUN request
* send a generic stun request to the server specified.
@@ -241,106 +49,26 @@
* \return 0 on success, other values on error.
* The interface it may change in the future.
*/
-int ast_stun_request(int s, struct sockaddr_in *dst,
- const char *username, struct sockaddr_in *answer);
+int ast_stun_request(int s, struct sockaddr_in *dst, const char *username, struct sockaddr_in *answer);
-/*! \brief Send STUN request for an RTP socket
- * Deprecated, this is just a wrapper for ast_rtp_stun_request()
+/*! \brief callback type to be invoked on stun responses. */
+typedef int (stun_cb_f)(struct stun_attr *attr, void *arg);
+
+/*! \brief handle an incoming STUN message.
+ *
+ * Do some basic sanity checks on packet size and content,
+ * try to extract a bit of information, and possibly reply.
+ * At the moment this only processes BIND requests, and returns
+ * the externally visible address of the request.
+ * If a callback is specified, invoke it with the attribute.
*/
-void ast_rtp_stun_request(struct ast_rtp *rtp, struct sockaddr_in *suggestion, const char *username);
+int ast_stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *data, size_t len, stun_cb_f *stun_cb, void *arg);
-/*! \brief The RTP bridge.
- \arg \ref AstRTPbridge
-*/
-int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
-
-/*! \brief Register an RTP channel client */
-int ast_rtp_proto_register(struct ast_rtp_protocol *proto);
-
-/*! \brief Unregister an RTP channel client */
-void ast_rtp_proto_unregister(struct ast_rtp_protocol *proto);
-
-int ast_rtp_make_compatible(struct ast_channel *dest, struct ast_channel *src, int media);
-
-/*! \brief If possible, create an early bridge directly between the devices without
- having to send a re-invite later */
-int ast_rtp_early_bridge(struct ast_channel *c0, struct ast_channel *c1);
-
-/*! \brief Get QOS stats on a RTP channel */
-int ast_rtp_get_qos(struct ast_rtp *rtp, const char *qos, char *buf, unsigned int buflen);
-/*! \brief Set RTPAUDIOQOS(...) variables on a channel when it is being hung up */
-void ast_rtp_set_vars(struct ast_channel *chan, struct ast_rtp *rtp);
-
-/*! \brief Return RTCP quality string
- *
- * \param rtp An rtp structure to get qos information about.
- *
- * \param qual An (optional) rtp quality structure that will be
- * filled with the quality information described in
- * the ast_rtp_quality structure. This structure is
- * not dependent on any qtype, so a call for any
- * type of information would yield the same results
- * because ast_rtp_quality is not a data type
- * specific to any qos type.
- *
- * \param qtype The quality type you'd like, default should be
- * RTPQOS_SUMMARY which returns basic information
- * about the call. The return from RTPQOS_SUMMARY
- * is basically ast_rtp_quality in a string. The
- * other types are RTPQOS_JITTER, RTPQOS_LOSS and
- * RTPQOS_RTT which will return more specific
- * statistics.
- */
-char *ast_rtp_get_quality(struct ast_rtp *rtp, struct ast_rtp_quality *qual, enum ast_rtp_quality_type qtype);
-/*! \brief Send an H.261 fast update request. Some devices need this rather than the XML message in SIP */
-int ast_rtcp_send_h261fur(void *data);
-
-void ast_rtp_init(void); /*! Initialize RTP subsystem */
-int ast_rtp_reload(void); /*! reload rtp configuration */
-void ast_rtp_new_init(struct ast_rtp *rtp);
-
-/*! \brief Set codec preference */
-void ast_rtp_codec_setpref(struct ast_rtp *rtp, struct ast_codec_pref *prefs);
-
-/*! \brief Get codec preference */
-struct ast_codec_pref *ast_rtp_codec_getpref(struct ast_rtp *rtp);
-
-/*! \brief get format from predefined dynamic payload format */
-int ast_rtp_codec_getformat(int pt);
-
-/*! \brief Set rtp timeout */
-void ast_rtp_set_rtptimeout(struct ast_rtp *rtp, int timeout);
-/*! \brief Set rtp hold timeout */
-void ast_rtp_set_rtpholdtimeout(struct ast_rtp *rtp, int timeout);
-/*! \brief set RTP keepalive interval */
-void ast_rtp_set_rtpkeepalive(struct ast_rtp *rtp, int period);
-/*! \brief Get RTP keepalive interval */
-int ast_rtp_get_rtpkeepalive(struct ast_rtp *rtp);
-/*! \brief Get rtp hold timeout */
-int ast_rtp_get_rtpholdtimeout(struct ast_rtp *rtp);
-/*! \brief Get rtp timeout */
-int ast_rtp_get_rtptimeout(struct ast_rtp *rtp);
-/* \brief Put RTP timeout timers on hold during another transaction, like T.38 */
-void ast_rtp_set_rtptimers_onhold(struct ast_rtp *rtp);
-
-/*! \brief Initalize t.140 redudancy
- * \param ti time between each t140red frame is sent
- * \param red_pt payloadtype for RTP packet
- * \param pt payloadtype numbers for each generation including primary data
- * \param num_gen number of redundant generations, primary data excluded
- */
-int rtp_red_init(struct ast_rtp *rtp, int ti, int *pt, int num_gen);
-
-void red_init(struct rtp_red *red, const struct ast_frame *f);
-
-
-/*! \brief Buffer t.140 data */
-void red_buffer_t140(struct ast_rtp *rtp, struct ast_frame *f);
-
-
+/*! \brief Initialize STUN */
+void ast_stun_init(void);
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
-#endif /* _ASTERISK_RTP_H */
+#endif /* _ASTERISK_STUN_H */
Modified: team/file/rtp_engine/main/asterisk.c
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/main/asterisk.c?view=diff&rev=124370&r1=124369&r2=124370
==============================================================================
--- team/file/rtp_engine/main/asterisk.c (original)
+++ team/file/rtp_engine/main/asterisk.c Fri Jun 20 15:34:08 2008
@@ -111,6 +111,7 @@
#include "asterisk/pbx.h"
#include "asterisk/enum.h"
#include "asterisk/rtp.h"
+#include "asterisk/stun.h"
#include "asterisk/http.h"
#include "asterisk/udptl.h"
#include "asterisk/app.h"
@@ -3344,6 +3345,7 @@
}
ast_rtp_init();
+ ast_stun_init();
ast_dsp_init();
ast_udptl_init();
Copied: team/file/rtp_engine/main/stun.c (from r124314, team/file/rtp_engine/main/rtp.c)
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/main/stun.c?view=diff&rev=124370&p1=team/file/rtp_engine/main/rtp.c&r1=124314&p2=team/file/rtp_engine/main/stun.c&r2=124370
==============================================================================
--- team/file/rtp_engine/main/rtp.c (original)
+++ team/file/rtp_engine/main/stun.c Fri Jun 20 15:34:08 2008
@@ -1,7 +1,7 @@
/*
* Asterisk -- An open source telephony toolkit.
*
- * Copyright (C) 1999 - 2006, Digium, Inc.
+ * Copyright (C) 1999 - 2008, Digium, Inc.
*
* Mark Spencer <markster at digium.com>
*
@@ -19,272 +19,22 @@
/*!
* \file
*
- * \brief Supports RTP and RTCP with Symmetric RTP support for NAT traversal.
+ * \brief STUN Support
*
* \author Mark Spencer <markster at digium.com>
*
- * \note RTP is defined in RFC 3550.
+ * \note STUN is defined in RFC 3489.
*/
#include "asterisk.h"
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#include <sys/time.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <math.h>
-
#include "asterisk/rtp.h"
-#include "asterisk/pbx.h"
-#include "asterisk/frame.h"
-#include "asterisk/channel.h"
-#include "asterisk/acl.h"
-#include "asterisk/config.h"
-#include "asterisk/lock.h"
-#include "asterisk/utils.h"
-#include "asterisk/netsock.h"
+#include "asterisk/stun.h"
#include "asterisk/cli.h"
-#include "asterisk/manager.h"
-#include "asterisk/unaligned.h"
-
-#define MAX_TIMESTAMP_SKEW 640
-
-#define RTP_SEQ_MOD (1<<16) /*!< A sequence number can't be more than 16 bits */
-#define RTCP_DEFAULT_INTERVALMS 5000 /*!< Default milli-seconds between RTCP reports we send */
-#define RTCP_MIN_INTERVALMS 500 /*!< Min milli-seconds between RTCP reports we send */
-#define RTCP_MAX_INTERVALMS 60000 /*!< Max milli-seconds between RTCP reports we send */
-
-#define RTCP_PT_FUR 192
-#define RTCP_PT_SR 200
-#define RTCP_PT_RR 201
-#define RTCP_PT_SDES 202
-#define RTCP_PT_BYE 203
-#define RTCP_PT_APP 204
-
-#define RTP_MTU 1200
-
-#define DEFAULT_DTMF_TIMEOUT 3000 /*!< samples */
-
-static int dtmftimeout = DEFAULT_DTMF_TIMEOUT;
-
-static int rtpstart; /*!< First port for RTP sessions (set in rtp.conf) */
-static int rtpend; /*!< Last port for RTP sessions (set in rtp.conf) */
-static int rtpdebug; /*!< Are we debugging? */
-static int rtcpdebug; /*!< Are we debugging RTCP? */
-static int rtcpstats; /*!< Are we debugging RTCP? */
-static int rtcpinterval = RTCP_DEFAULT_INTERVALMS; /*!< Time between rtcp reports in millisecs */
+
static int stundebug; /*!< Are we debugging stun? */
-static struct sockaddr_in rtpdebugaddr; /*!< Debug packets to/from this host */
-static struct sockaddr_in rtcpdebugaddr; /*!< Debug RTCP packets to/from this host */
-#ifdef SO_NO_CHECK
-static int nochecksums;
-#endif
-static int strictrtp;
-
-enum strict_rtp_state {
- STRICT_RTP_OPEN = 0, /*! No RTP packets should be dropped, all sources accepted */
- STRICT_RTP_LEARN, /*! Accept next packet as source */
- STRICT_RTP_CLOSED, /*! Drop all RTP packets not coming from source that was learned */
-};
-
-/* Uncomment this to enable more intense native bridging, but note: this is currently buggy */
-/* #define P2P_INTENSE */
-
-/*!
- * \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 [...]"
- *
- */
-/*! \brief The value of each payload format mapping: */
-struct rtpPayloadType {
- int isAstFormat; /*!< whether the following code is an AST_FORMAT */
- int code;
-};
-
-
-/*! \brief RTP session description */
-struct ast_rtp {
- int s;
- struct ast_frame f;
- unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET];
- unsigned int ssrc; /*!< Synchronization source, RFC 3550, page 10. */
- unsigned int themssrc; /*!< Their SSRC */
- unsigned int rxssrc;
- unsigned int lastts;
- unsigned int lastrxts;
- unsigned int lastividtimestamp;
- unsigned int lastovidtimestamp;
- unsigned int lastitexttimestamp;
- unsigned int lastotexttimestamp;
- unsigned int lasteventseqn;
- int lastrxseqno; /*!< Last received sequence number */
- unsigned short seedrxseqno; /*!< What sequence number did they start with?*/
- unsigned int seedrxts; /*!< What RTP timestamp did they start with? */
- unsigned int rxcount; /*!< How many packets have we received? */
- unsigned int rxoctetcount; /*!< How many octets have we received? should be rxcount *160*/
- unsigned int txcount; /*!< How many packets have we sent? */
- unsigned int txoctetcount; /*!< How many octets have we sent? (txcount*160)*/
- unsigned int cycles; /*!< Shifted count of sequence number cycles */
- double rxjitter; /*!< Interarrival jitter at the moment */
- double rxtransit; /*!< Relative transit time for previous packet */
- int lasttxformat;
- int lastrxformat;
-
- int rtptimeout; /*!< RTP timeout time (negative or zero means disabled, negative value means temporarily disabled) */
- int rtpholdtimeout; /*!< RTP timeout when on hold (negative or zero means disabled, negative value means temporarily disabled). */
- int rtpkeepalive; /*!< Send RTP comfort noice packets for keepalive */
-
- /* DTMF Reception Variables */
- char resp;
- unsigned int lastevent;
- int dtmfcount;
- unsigned int dtmfsamples;
- /* DTMF Transmission Variables */
- unsigned int lastdigitts;
- char sending_digit; /*!< boolean - are we sending digits */
- char send_digit; /*!< digit we are sending */
- int send_payload;
- int send_duration;
- int nat;
- unsigned int flags;
- 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;
- double drxcore; /*!< The double representation of the first received packet */
- struct timeval lastrx; /*!< timeval when we last received a packet */
- struct timeval dtmfmute;
- struct ast_smoother *smoother;
- int *ioid;
- 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;
-#ifdef P2P_INTENSE
- ast_mutex_t bridge_lock;
-#endif
- 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_code;
- int rtp_lookup_code_cache_result;
- struct ast_rtcp *rtcp;
- struct ast_codec_pref pref;
- struct ast_rtp *bridged; /*!< Who we are Packet bridged to */
-
- enum strict_rtp_state strict_rtp_state; /*!< Current state that strict RTP protection is in */
- struct sockaddr_in strict_rtp_address; /*!< Remote address information for strict RTP purposes */
-
- int set_marker_bit:1; /*!< Whether to set the marker bit or not */
- struct rtp_red *red;
-};
-
-static struct ast_frame *red_t140_to_red(struct rtp_red *red);
-static int red_write(const void *data);
-
-struct rtp_red {
- struct ast_frame t140; /*!< Primary data */
- struct ast_frame t140red; /*!< Redundant t140*/
- unsigned char pt[RED_MAX_GENERATION]; /*!< Payload types for redundancy data */
- unsigned char ts[RED_MAX_GENERATION]; /*!< Time stamps */
- unsigned char len[RED_MAX_GENERATION]; /*!< length of each generation */
- int num_gen; /*!< Number of generations */
- int schedid; /*!< Timer id */
- int ti; /*!< How long to buffer data before send */
- unsigned char t140red_data[64000];
- unsigned char buf_data[64000]; /*!< buffered primary data */
- int hdrlen;
- long int prev_ts;
-};
-
-/* Forward declarations */
-static int ast_rtcp_write(const void *data);
-static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw);
-static int ast_rtcp_write_sr(const void *data);
-static int ast_rtcp_write_rr(const void *data);
-static unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp);
-static int ast_rtp_senddigit_continuation(struct ast_rtp *rtp);
-int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit);
-
-#define FLAG_3389_WARNING (1 << 0)
-#define FLAG_NAT_ACTIVE (3 << 1)
-#define FLAG_NAT_INACTIVE (0 << 1)
-#define FLAG_NAT_INACTIVE_NOWARN (1 << 1)
-#define FLAG_HAS_DTMF (1 << 3)
-#define FLAG_P2P_SENT_MARK (1 << 4)
-#define FLAG_P2P_NEED_DTMF (1 << 5)
-#define FLAG_CALLBACK_MODE (1 << 6)
-#define FLAG_DTMF_COMPENSATE (1 << 7)
-#define FLAG_HAS_STUN (1 << 8)
-
-/*!
- * \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 rtcp_info;
- int s; /*!< Socket */
- struct sockaddr_in us; /*!< Socket representation of the local endpoint. */
- struct sockaddr_in them; /*!< Socket representation of the remote endpoint. */
- unsigned int soc; /*!< What they told us */
- unsigned int spc; /*!< What they told us */
- unsigned int themrxlsr; /*!< The middle 32 bits of the NTP timestamp in the last received SR*/
- struct timeval rxlsr; /*!< Time when we got their last SR */
- struct timeval txlsr; /*!< Time when we sent or last SR*/
- unsigned int expected_prior; /*!< no. packets in previous interval */
- unsigned int received_prior; /*!< no. packets received in previous interval */
- int schedid; /*!< Schedid returned from ast_sched_add() to schedule RTCP-transmissions*/
- unsigned int rr_count; /*!< number of RRs we've sent, not including report blocks in SR's */
- unsigned int sr_count; /*!< number of SRs we've sent */
- unsigned int lastsrtxcount; /*!< Transmit packet count when last SR sent */
- double accumulated_transit; /*!< accumulated a-dlsr-lsr */
- double rtt; /*!< Last reported rtt */
- unsigned int reported_jitter; /*!< The contents of their last jitter entry in the RR */
- unsigned int reported_lost; /*!< Reported lost packets in their RR */
- char quality[AST_MAX_USER_FIELD];
- char quality_jitter[AST_MAX_USER_FIELD];
- char quality_loss[AST_MAX_USER_FIELD];
- char quality_rtt[AST_MAX_USER_FIELD];
-
- double reported_maxjitter;
- double reported_minjitter;
- double reported_normdev_jitter;
- double reported_stdev_jitter;
- unsigned int reported_jitter_count;
-
- double reported_maxlost;
- double reported_minlost;
- double reported_normdev_lost;
- double reported_stdev_lost;
-
- double rxlost;
- double maxrxlost;
- double minrxlost;
- double normdev_rxlost;
- double stdev_rxlost;
- unsigned int rxlost_count;
-
- double maxrxjitter;
- double minrxjitter;
- double normdev_rxjitter;
- double stdev_rxjitter;
- unsigned int rxjitter_count;
- double maxrtt;
- double minrtt;
- double normdevrtt;
- double stdevrtt;
- unsigned int rtt_count;
- int sendfur;
-};
/*!
* \brief STUN support code
@@ -336,9 +86,6 @@
unsigned short port;
unsigned int addr;
} __attribute__((packed));
-
-#define STUN_IGNORE (0)
-#define STUN_ACCEPT (1)
/*! \brief STUN message types
* 'BIND' refers to transactions used to determine the externally
@@ -493,14 +240,6 @@
req->id.id[x] = ast_random();
}
-size_t ast_rtp_alloc_size(void)
-{
- return sizeof(struct ast_rtp);
-}
-
-/*! \brief callback type to be invoked on stun responses. */
-typedef int (stun_cb_f)(struct stun_attr *attr, void *arg);
-
/*! \brief handle an incoming STUN message.
*
* Do some basic sanity checks on packet size and content,
@@ -509,13 +248,12 @@
* the externally visible address of the request.
* If a callback is specified, invoke it with the attribute.
*/
-static int stun_handle_packet(int s, struct sockaddr_in *src,
- unsigned char *data, size_t len, stun_cb_f *stun_cb, void *arg)
+int ast_stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *data, size_t len, stun_cb_f *stun_cb, void *arg)
{
struct stun_header *hdr = (struct stun_header *)data;
struct stun_attr *attr;
struct stun_state st;
- int ret = STUN_IGNORE;
+ int ret = AST_STUN_IGNORE;
int x;
/* On entry, 'len' is the length of the udp payload. After the
@@ -593,7 +331,7 @@
resp->msglen = htons(resplen);
resp->msgtype = htons(STUN_BINDRESP);
stun_send(s, src, resp);
- ret = STUN_ACCEPT;
+ ret = AST_STUN_ACCEPT;
break;
default:
if (stundebug)
@@ -688,3901 +426,12 @@
continue;
}
bzero(answer, sizeof(struct sockaddr_in));
- stun_handle_packet(s, &src, reply_buf, res,
+ ast_stun_handle_packet(s, &src, reply_buf, res,
stun_get_mapped, answer);
res = 0; /* signal regular exit */
break;
}
return res;
-}
-
-/*! \brief send a STUN BIND request to the given destination.
- * Optionally, add a username if specified.
- */
-void ast_rtp_stun_request(struct ast_rtp *rtp, struct sockaddr_in *suggestion, const char *username)
-{
- ast_stun_request(rtp->s, suggestion, username, NULL);
-}
-
-/*! \brief List of current sessions */
-static AST_RWLIST_HEAD_STATIC(protos, ast_rtp_protocol);
-
-static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw)
-{
- unsigned int sec, usec, frac;
- sec = tv.tv_sec + 2208988800u; /* Sec between 1900 and 1970 */
- usec = tv.tv_usec;
- frac = (usec << 12) + (usec << 8) - ((usec * 3650) >> 6);
- *msw = sec;
- *lsw = frac;
-}
-
-int ast_rtp_fd(struct ast_rtp *rtp)
-{
- return rtp->s;
-}
-
-int ast_rtcp_fd(struct ast_rtp *rtp)
-{
- if (rtp->rtcp)
- return rtp->rtcp->s;
- return -1;
-}
-
-unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp)
-{
- unsigned int interval;
- /*! \todo XXX Do a more reasonable calculation on this one
- * Look in RFC 3550 Section A.7 for an example*/
- interval = rtcpinterval;
- return interval;
-}
-
-/* \brief Put RTP timeout timers on hold during another transaction, like T.38 */
-void ast_rtp_set_rtptimers_onhold(struct ast_rtp *rtp)
-{
- rtp->rtptimeout = (-1) * rtp->rtptimeout;
- rtp->rtpholdtimeout = (-1) * rtp->rtpholdtimeout;
-}
-
-/*! \brief Set rtp timeout */
-void ast_rtp_set_rtptimeout(struct ast_rtp *rtp, int timeout)
-{
- rtp->rtptimeout = timeout;
-}
-
-/*! \brief Set rtp hold timeout */
-void ast_rtp_set_rtpholdtimeout(struct ast_rtp *rtp, int timeout)
-{
- rtp->rtpholdtimeout = timeout;
-}
-
-/*! \brief set RTP keepalive interval */
-void ast_rtp_set_rtpkeepalive(struct ast_rtp *rtp, int period)
-{
- rtp->rtpkeepalive = period;
-}
-
-/*! \brief Get rtp timeout */
-int ast_rtp_get_rtptimeout(struct ast_rtp *rtp)
-{
- if (rtp->rtptimeout < 0) /* We're not checking, but remembering the setting (during T.38 transmission) */
- return 0;
- return rtp->rtptimeout;
-}
-
-/*! \brief Get rtp hold timeout */
-int ast_rtp_get_rtpholdtimeout(struct ast_rtp *rtp)
-{
- if (rtp->rtptimeout < 0) /* We're not checking, but remembering the setting (during T.38 transmission) */
- return 0;
- return rtp->rtpholdtimeout;
-}
-
-/*! \brief Get RTP keepalive interval */
-int ast_rtp_get_rtpkeepalive(struct ast_rtp *rtp)
-{
- return rtp->rtpkeepalive;
-}
-
-void ast_rtp_set_data(struct ast_rtp *rtp, void *data)
-{
- rtp->data = data;
-}
-
-void ast_rtp_set_callback(struct ast_rtp *rtp, ast_rtp_callback callback)
-{
- rtp->callback = callback;
-}
-
-void ast_rtp_setnat(struct ast_rtp *rtp, int nat)
-{
- rtp->nat = nat;
-}
-
-int ast_rtp_getnat(struct ast_rtp *rtp)
-{
- return ast_test_flag(rtp, FLAG_NAT_ACTIVE);
-}
-
-void ast_rtp_setdtmf(struct ast_rtp *rtp, int dtmf)
-{
- ast_set2_flag(rtp, dtmf ? 1 : 0, FLAG_HAS_DTMF);
-}
-
-void ast_rtp_setdtmfcompensate(struct ast_rtp *rtp, int compensate)
-{
- ast_set2_flag(rtp, compensate ? 1 : 0, FLAG_DTMF_COMPENSATE);
-}
-
-void ast_rtp_setstun(struct ast_rtp *rtp, int stun_enable)
-{
- ast_set2_flag(rtp, stun_enable ? 1 : 0, FLAG_HAS_STUN);
-}
-
-static void rtp_bridge_lock(struct ast_rtp *rtp)
-{
-#ifdef P2P_INTENSE
- ast_mutex_lock(&rtp->bridge_lock);
-#endif
- return;
-}
-
-static void rtp_bridge_unlock(struct ast_rtp *rtp)
-{
-#ifdef P2P_INTENSE
- ast_mutex_unlock(&rtp->bridge_lock);
-#endif
- return;
-}
-
-/*! \brief Calculate normal deviation */
-static double normdev_compute(double normdev, double sample, unsigned int sample_count)
-{
- normdev = normdev * sample_count + sample;
- sample_count++;
-
- return normdev / sample_count;
-}
-
-static double stddev_compute(double stddev, double sample, double normdev, double normdev_curent, unsigned int sample_count)
-{
-/*
- for the formula check http://www.cs.umd.edu/~austinjp/constSD.pdf
- return sqrt( (sample_count*pow(stddev,2) + sample_count*pow((sample-normdev)/(sample_count+1),2) + pow(sample-normdev_curent,2)) / (sample_count+1));
- we can compute the sigma^2 and that way we would have to do the sqrt only 1 time at the end and would save another pow 2 compute
- optimized formula
-*/
-#define SQUARE(x) ((x) * (x))
-
- stddev = sample_count * stddev;
- sample_count++;
-
- return stddev +
- ( sample_count * SQUARE( (sample - normdev) / sample_count ) ) +
- ( SQUARE(sample - normdev_curent) / sample_count );
-
-#undef SQUARE
-}
-
-static struct ast_frame *send_dtmf(struct ast_rtp *rtp, enum ast_frame_type type)
-{
- if (((ast_test_flag(rtp, FLAG_DTMF_COMPENSATE) && type == AST_FRAME_DTMF_END) ||
- (type == AST_FRAME_DTMF_BEGIN)) && ast_tvcmp(ast_tvnow(), rtp->dtmfmute) < 0) {
- ast_debug(1, "Ignore potential DTMF echo from '%s'\n", ast_inet_ntoa(rtp->them.sin_addr));
- rtp->resp = 0;
- rtp->dtmfsamples = 0;
- return &ast_null_frame;
- }
- ast_debug(1, "Sending dtmf: %d (%c), at %s\n", rtp->resp, rtp->resp, ast_inet_ntoa(rtp->them.sin_addr));
- if (rtp->resp == 'X') {
- rtp->f.frametype = AST_FRAME_CONTROL;
- rtp->f.subclass = AST_CONTROL_FLASH;
- } else {
- rtp->f.frametype = type;
- rtp->f.subclass = rtp->resp;
- }
- rtp->f.datalen = 0;
- rtp->f.samples = 0;
- rtp->f.mallocd = 0;
- rtp->f.src = "RTP";
- return &rtp->f;
-
-}
-
-static inline int rtp_debug_test_addr(struct sockaddr_in *addr)
-{
- if (rtpdebug == 0)
- return 0;
- if (rtpdebugaddr.sin_addr.s_addr) {
- if (((ntohs(rtpdebugaddr.sin_port) != 0)
- && (rtpdebugaddr.sin_port != addr->sin_port))
- || (rtpdebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
- return 0;
- }
- return 1;
-}
-
-static inline int rtcp_debug_test_addr(struct sockaddr_in *addr)
-{
- if (rtcpdebug == 0)
- return 0;
- if (rtcpdebugaddr.sin_addr.s_addr) {
- if (((ntohs(rtcpdebugaddr.sin_port) != 0)
- && (rtcpdebugaddr.sin_port != addr->sin_port))
- || (rtcpdebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
- return 0;
- }
- return 1;
-}
-
-
-static struct ast_frame *process_cisco_dtmf(struct ast_rtp *rtp, unsigned char *data, int len)
-{
- unsigned int event;
- char resp = 0;
- struct ast_frame *f = NULL;
- unsigned char seq;
- unsigned int flags;
- unsigned int power;
-
- /* We should have at least 4 bytes in RTP data */
- if (len < 4)
- return f;
-
- /* The format of Cisco RTP DTMF packet looks like next:
- +0 - sequence number of DTMF RTP packet (begins from 1,
- wrapped to 0)
- +1 - set of flags
- +1 (bit 0) - flaps by different DTMF digits delimited by audio
- or repeated digit without audio???
- +2 (+4,+6,...) - power level? (rises from 0 to 32 at begin of tone
- then falls to 0 at its end)
- +3 (+5,+7,...) - detected DTMF digit (0..9,*,#,A-D,...)
- Repeated DTMF information (bytes 4/5, 6/7) is history shifted right
- by each new packet and thus provides some redudancy.
-
- Sample of Cisco RTP DTMF packet is (all data in hex):
- 19 07 00 02 12 02 20 02
- showing end of DTMF digit '2'.
-
- The packets
- 27 07 00 02 0A 02 20 02
- 28 06 20 02 00 02 0A 02
- shows begin of new digit '2' with very short pause (20 ms) after
- previous digit '2'. Bit +1.0 flips at begin of new digit.
-
- Cisco RTP DTMF packets comes as replacement of audio RTP packets
- so its uses the same sequencing and timestamping rules as replaced
- audio packets. Repeat interval of DTMF packets is 20 ms and not rely
- on audio framing parameters. Marker bit isn't used within stream of
- DTMFs nor audio stream coming immediately after DTMF stream. Timestamps
- are not sequential at borders between DTMF and audio streams,
- */
-
- seq = data[0];
- flags = data[1];
- power = data[2];
- event = data[3] & 0x1f;
-
- if (option_debug > 2 || rtpdebug)
- ast_debug(0, "Cisco DTMF Digit: %02x (len=%d, seq=%d, flags=%02x, power=%d, history count=%d)\n", event, len, seq, flags, power, (len - 4) / 2);
- if (event < 10) {
- resp = '0' + event;
- } else if (event < 11) {
- resp = '*';
- } else if (event < 12) {
- resp = '#';
- } else if (event < 16) {
- resp = 'A' + (event - 12);
- } else if (event < 17) {
- resp = 'X';
- }
- if ((!rtp->resp && power) || (rtp->resp && (rtp->resp != resp))) {
- rtp->resp = resp;
- /* Why we should care on DTMF compensation at reception? */
- if (!ast_test_flag(rtp, FLAG_DTMF_COMPENSATE)) {
- f = send_dtmf(rtp, AST_FRAME_DTMF_BEGIN);
- rtp->dtmfsamples = 0;
- }
- } else if ((rtp->resp == resp) && !power) {
- f = send_dtmf(rtp, AST_FRAME_DTMF_END);
- f->samples = rtp->dtmfsamples * 8;
- rtp->resp = 0;
- } else if (rtp->resp == resp)
- rtp->dtmfsamples += 20 * 8;
- rtp->dtmfcount = dtmftimeout;
- return f;
-}
-
-/*!
- * \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
- * \param timestamp
- * \returns
- */
-static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp)
-{
- unsigned int event;
- unsigned int event_end;
- unsigned int samples;
- char resp = 0;
- struct ast_frame *f = NULL;
-
- /* Figure out event, event end, and samples */
- event = ntohl(*((unsigned int *)(data)));
- event >>= 24;
- event_end = ntohl(*((unsigned int *)(data)));
- event_end <<= 8;
- event_end >>= 24;
- samples = ntohl(*((unsigned int *)(data)));
- samples &= 0xFFFF;
-
- /* Print out debug if turned on */
- if (rtpdebug || option_debug > 2)
- ast_debug(0, "- RTP 2833 Event: %08x (len = %d)\n", event, len);
-
- /* Figure out what digit was pressed */
- if (event < 10) {
- resp = '0' + event;
- } else if (event < 11) {
- resp = '*';
- } else if (event < 12) {
- resp = '#';
- } else if (event < 16) {
- resp = 'A' + (event - 12);
- } else if (event < 17) { /* Event 16: Hook flash */
- resp = 'X';
- } else {
- /* Not a supported event */
[... 3758 lines stripped ...]
More information about the asterisk-commits
mailing list