[svn-commits] file: branch file/rtp_engine r124370 - in /team/file/rtp_engine: channels/ in...

SVN commits to the Digium repositories svn-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 svn-commits mailing list