From 0eb1480fe02b28de9d0d67bbd8779d7296639cc1 Mon Sep 17 00:00:00 2001 From: file Date: Thu, 2 Apr 2009 17:20:52 +0000 Subject: Merge in the RTP engine API. This API provides a generic way for multiple RTP stacks to be integrated into Asterisk. Right now there is only one present, res_rtp_asterisk, which is the existing Asterisk RTP stack. Functionality wise this commit performs the same as previously. API documentation can be viewed in the rtp_engine.h header file. Review: http://reviewboard.digium.com/r/209/ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@186078 f38db490-d61c-443f-a65b-d21fe96a405b --- include/asterisk/_private.h | 1 + include/asterisk/rtp.h | 416 ----------- include/asterisk/rtp_engine.h | 1594 +++++++++++++++++++++++++++++++++++++++++ include/asterisk/stun.h | 71 ++ 4 files changed, 1666 insertions(+), 416 deletions(-) delete mode 100644 include/asterisk/rtp.h create mode 100644 include/asterisk/rtp_engine.h create mode 100644 include/asterisk/stun.h (limited to 'include/asterisk') diff --git a/include/asterisk/_private.h b/include/asterisk/_private.h index c709b1f15..c7e195fe6 100644 --- a/include/asterisk/_private.h +++ b/include/asterisk/_private.h @@ -41,6 +41,7 @@ int ast_tps_init(void); /*!< Provided by taskprocessor.c */ int ast_timing_init(void); /*!< Provided by timing.c */ int ast_indications_init(void); /*!< Provided by indications.c */ int ast_indications_reload(void);/*!< Provided by indications.c */ +void ast_stun_init(void); /*!< Provided by stun.c */ /*! * \brief Reload asterisk modules. diff --git a/include/asterisk/rtp.h b/include/asterisk/rtp.h deleted file mode 100644 index c42906a06..000000000 --- a/include/asterisk/rtp.h +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 1999 - 2006, Digium, Inc. - * - * Mark Spencer - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! - * \file rtp.h - * \brief Supports RTP and RTCP with Symmetric RTP support for NAT traversal. - * - * RTP is defined in RFC 3550. - */ - -#ifndef _ASTERISK_RTP_H -#define _ASTERISK_RTP_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_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, -}; - -/*! \brief Variables used in ast_rtcp_get function */ -enum ast_rtp_qos_vars { - AST_RTP_TXCOUNT, - AST_RTP_RXCOUNT, - AST_RTP_TXJITTER, - AST_RTP_RXJITTER, - AST_RTP_RXPLOSS, - AST_RTP_TXPLOSS, - AST_RTP_RTT -}; - -struct ast_rtp; -/*! T.140 Redundancy structure*/ -struct rtp_red; - -/*! \brief The value of each payload format mapping: */ -struct rtpPayloadType { - int isAstFormat; /*!< whether the following code is an AST_FORMAT */ - int code; -}; - -/*! \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 - * \return 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 - * \return 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 Set payload type to a known MIME media type for a codec - * - * \param rtp RTP structure to modify - * \param pt Payload type entry to modify - * \param mimeType top-level MIME type of media stream (typically "audio", "video", "text", etc.) - * \param mimeSubtype MIME subtype of media stream (typically a codec name) - * \param options Zero or more flags from the ast_rtp_options enum - * - * This function 'fills in' an entry in the list of possible formats for - * a media stream associated with an RTP structure. - * - * \retval 0 on success - * \retval -1 if the payload type is out of range - * \retval -2 if the mimeType/mimeSubtype combination was not found - */ -int ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt, - char *mimeType, char *mimeSubtype, - enum ast_rtp_options options); - -/*! \brief Set payload type to a known MIME media type for a codec with a specific sample rate - * - * \param rtp RTP structure to modify - * \param pt Payload type entry to modify - * \param mimeType top-level MIME type of media stream (typically "audio", "video", "text", etc.) - * \param mimeSubtype MIME subtype of media stream (typically a codec name) - * \param options Zero or more flags from the ast_rtp_options enum - * \param sample_rate The sample rate of the media stream - * - * This function 'fills in' an entry in the list of possible formats for - * a media stream associated with an RTP structure. - * - * \retval 0 on success - * \retval -1 if the payload type is out of range - * \retval -2 if the mimeType/mimeSubtype combination was not found - */ -int ast_rtp_set_rtpmap_type_rate(struct ast_rtp* rtp, int pt, - char *mimeType, char *mimeSubtype, - enum ast_rtp_options options, - unsigned int sample_rate); - -/*! \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 Get the sample rate associated with known RTP payload types - * - * \param isAstFormat True if the value in the 'code' parameter is an AST_FORMAT value - * \param code Format code, either from AST_FORMAT list or from AST_RTP list - * - * \return the sample rate if the format was found, zero if it was not found - */ -unsigned int ast_rtp_lookup_sample_rate(int isAstFormat, int code); - -/*! \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); - -/*! \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 -*/ -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 - * \since 1.6.1 - */ -int ast_rtp_get_qos(struct ast_rtp *rtp, const char *qos, char *buf, unsigned int buflen); - -/*! \brief Return RTP and RTCP QoS values - * \since 1.6.1 - */ -unsigned int ast_rtp_get_qosvalue(struct ast_rtp *rtp, enum ast_rtp_qos_vars value); - -/*! \brief Set RTPAUDIOQOS(...) variables on a channel when it is being hung up - * \since 1.6.1 - */ -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. - * \version 1.6.1 added qtype parameter - */ -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 - * \since 1.6.1 - */ -int ast_rtp_red_init(struct ast_rtp *rtp, int ti, int *pt, int num_gen); - -/*! \brief Buffer t.140 data */ -void ast_red_buffer_t140(struct ast_rtp *rtp, struct ast_frame *f); - - - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* _ASTERISK_RTP_H */ diff --git a/include/asterisk/rtp_engine.h b/include/asterisk/rtp_engine.h new file mode 100644 index 000000000..edd7d1c47 --- /dev/null +++ b/include/asterisk/rtp_engine.h @@ -0,0 +1,1594 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 1999 - 2009, Digium, Inc. + * + * Mark Spencer + * Joshua Colp + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * \brief Pluggable RTP Architecture + * \author Joshua Colp + * \ref AstRTPEngine + */ + +/*! + * \page AstRTPEngine Asterisk RTP Engine API + * + * The purpose of this API is to provide a way for multiple RTP stacks to be used inside + * of Asterisk without any module that uses RTP knowing any different. To the module each RTP + * stack behaves the same. + * + * An RTP session is called an instance and is made up of a combination of codec information, + * RTP engine, RTP properties, and address information. An engine name may be passed in to explicitly + * choose an RTP stack to be used but a default one will be used if none is provided. An address to use + * for RTP may also be provided but the underlying RTP engine may choose a different address depending on + * it's configuration. + * + * An RTP engine is the layer between the RTP engine core and the RTP stack itself. The RTP engine core provides + * a set of callbacks to do various things (such as write audio out) that the RTP engine has to have implemented. + * + * Glue is what binds an RTP instance to a channel. It is used to retrieve RTP instance information when + * performing remote or local bridging and is used to have the channel driver tell the remote side to change + * destination of the RTP stream. + * + * Statistics from an RTP instance can be retrieved using the ast_rtp_instance_get_stats API call. This essentially + * asks the RTP engine in use to fill in a structure with the requested values. It is not required for an RTP engine + * to support all statistic values. + * + * Properties allow behavior of the RTP engine and RTP engine core to be changed. For example, there is a property named + * AST_RTP_PROPERTY_NAT which is used to tell the RTP engine to enable symmetric RTP if it supports it. It is not required + * for an RTP engine to support all properties. + * + * Codec information is stored using a separate data structure which has it's own set of API calls to add/remove/retrieve + * information. They are used by the module after an RTP instance is created so that payload information is available for + * the RTP engine. + */ + +#ifndef _ASTERISK_RTP_ENGINE_H +#define _ASTERISK_RTP_ENGINE_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include "asterisk/astobj2.h" + +/* Maximum number of payloads supported */ +#define AST_RTP_MAX_PT 256 + +/* Maximum number of generations */ +#define AST_RED_MAX_GENERATION 5 + +struct ast_rtp_instance; +struct ast_rtp_glue; + +/*! RTP Properties that can be set on an RTP instance */ +enum ast_rtp_property { + /*! Enable symmetric RTP support */ + AST_RTP_PROPERTY_NAT = 0, + /*! RTP instance will be carrying DTMF (using RFC2833) */ + AST_RTP_PROPERTY_DTMF, + /*! Expect unreliable DTMF from remote party */ + AST_RTP_PROPERTY_DTMF_COMPENSATE, + /*! Enable STUN support */ + AST_RTP_PROPERTY_STUN, + /*! Enable RTCP support */ + AST_RTP_PROPERTY_RTCP, + /*! Maximum number of RTP properties supported */ + AST_RTP_PROPERTY_MAX, +}; + +/*! Additional RTP options */ +enum ast_rtp_options { + /*! Remote side is using non-standard G.726 */ + AST_RTP_OPT_G726_NONSTANDARD = (1 << 0), +}; + +/*! RTP DTMF Modes */ +enum ast_rtp_dtmf_mode { + /*! No DTMF is being carried over the RTP stream */ + AST_RTP_DTMF_MODE_NONE = 0, + /*! DTMF is being carried out of band using RFC2833 */ + AST_RTP_DTMF_MODE_RFC2833, + /*! DTMF is being carried inband over the RTP stream */ + AST_RTP_DTMF_MODE_INBAND, +}; + +/*! Result codes when RTP glue is queried for information */ +enum ast_rtp_glue_result { + /*! No remote or local bridging is permitted */ + AST_RTP_GLUE_RESULT_FORBID = 0, + /*! Move RTP stream to be remote between devices directly */ + AST_RTP_GLUE_RESULT_REMOTE, + /*! Perform RTP engine level bridging if possible */ + AST_RTP_GLUE_RESULT_LOCAL, +}; + +/*! Field statistics that can be retrieved from an RTP instance */ +enum ast_rtp_instance_stat_field { + /*! Retrieve quality information */ + AST_RTP_INSTANCE_STAT_FIELD_QUALITY = 0, + /*! Retrieve quality information about jitter */ + AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, + /*! Retrieve quality information about packet loss */ + AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, + /*! Retrieve quality information about round trip time */ + AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, +}; + +/*! Statistics that can be retrieved from an RTP instance */ +enum ast_rtp_instance_stat { + /*! Retrieve all statistics */ + AST_RTP_INSTANCE_STAT_ALL = 0, + /*! Retrieve number of packets transmitted */ + AST_RTP_INSTANCE_STAT_TXCOUNT, + /*! Retrieve number of packets received */ + AST_RTP_INSTANCE_STAT_RXCOUNT, + /*! Retrieve ALL statistics relating to packet loss */ + AST_RTP_INSTANCE_STAT_COMBINED_LOSS, + /*! Retrieve number of packets lost for transmitting */ + AST_RTP_INSTANCE_STAT_TXPLOSS, + /*! Retrieve number of packets lost for receiving */ + AST_RTP_INSTANCE_STAT_RXPLOSS, + /*! Retrieve maximum number of packets lost on remote side */ + AST_RTP_INSTANCE_STAT_REMOTE_MAXRXPLOSS, + /*! Retrieve minimum number of packets lost on remote side */ + AST_RTP_INSTANCE_STAT_REMOTE_MINRXPLOSS, + /*! Retrieve average number of packets lost on remote side */ + AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVRXPLOSS, + /*! Retrieve standard deviation of packets lost on remote side */ + AST_RTP_INSTANCE_STAT_REMOTE_STDEVRXPLOSS, + /*! Retrieve maximum number of packets lost on local side */ + AST_RTP_INSTANCE_STAT_LOCAL_MAXRXPLOSS, + /*! Retrieve minimum number of packets lost on local side */ + AST_RTP_INSTANCE_STAT_LOCAL_MINRXPLOSS, + /*! Retrieve average number of packets lost on local side */ + AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVRXPLOSS, + /*! Retrieve standard deviation of packets lost on local side */ + AST_RTP_INSTANCE_STAT_LOCAL_STDEVRXPLOSS, + /*! Retrieve ALL statistics relating to jitter */ + AST_RTP_INSTANCE_STAT_COMBINED_JITTER, + /*! Retrieve jitter on transmitted packets */ + AST_RTP_INSTANCE_STAT_TXJITTER, + /*! Retrieve jitter on received packets */ + AST_RTP_INSTANCE_STAT_RXJITTER, + /*! Retrieve maximum jitter on remote side */ + AST_RTP_INSTANCE_STAT_REMOTE_MAXJITTER, + /*! Retrieve minimum jitter on remote side */ + AST_RTP_INSTANCE_STAT_REMOTE_MINJITTER, + /*! Retrieve average jitter on remote side */ + AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVJITTER, + /*! Retrieve standard deviation jitter on remote side */ + AST_RTP_INSTANCE_STAT_REMOTE_STDEVJITTER, + /*! Retrieve maximum jitter on local side */ + AST_RTP_INSTANCE_STAT_LOCAL_MAXJITTER, + /*! Retrieve minimum jitter on local side */ + AST_RTP_INSTANCE_STAT_LOCAL_MINJITTER, + /*! Retrieve average jitter on local side */ + AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVJITTER, + /*! Retrieve standard deviation jitter on local side */ + AST_RTP_INSTANCE_STAT_LOCAL_STDEVJITTER, + /*! Retrieve ALL statistics relating to round trip time */ + AST_RTP_INSTANCE_STAT_COMBINED_RTT, + /*! Retrieve round trip time */ + AST_RTP_INSTANCE_STAT_RTT, + /*! Retrieve maximum round trip time */ + AST_RTP_INSTANCE_STAT_MAX_RTT, + /*! Retrieve minimum round trip time */ + AST_RTP_INSTANCE_STAT_MIN_RTT, + /*! Retrieve average round trip time */ + AST_RTP_INSTANCE_STAT_NORMDEVRTT, + /*! Retrieve standard deviation round trip time */ + AST_RTP_INSTANCE_STAT_STDEVRTT, + /*! Retrieve local SSRC */ + AST_RTP_INSTANCE_STAT_LOCAL_SSRC, + /*! Retrieve remote SSRC */ + AST_RTP_INSTANCE_STAT_REMOTE_SSRC, +}; + +/* 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 + +/*! Structure that represents a payload */ +struct ast_rtp_payload_type { + /*! Is this an Asterisk value */ + int asterisk_format; + /*! Actual internal value of the payload */ + int code; +}; + +/*! Structure that represents statistics from an RTP instance */ +struct ast_rtp_instance_stats { + /*! Number of packets transmitted */ + unsigned int txcount; + /*! Number of packets received */ + unsigned int rxcount; + /*! Jitter on transmitted packets */ + unsigned int txjitter; + /*! Jitter on received packets */ + unsigned int rxjitter; + /*! Maximum jitter on remote side */ + double remote_maxjitter; + /*! Minimum jitter on remote side */ + double remote_minjitter; + /*! Average jitter on remote side */ + double remote_normdevjitter; + /*! Standard deviation jitter on remote side */ + double remote_stdevjitter; + /*! Maximum jitter on local side */ + double local_maxjitter; + /*! Minimum jitter on local side */ + double local_minjitter; + /*! Average jitter on local side */ + double local_normdevjitter; + /*! Standard deviation jitter on local side */ + double local_stdevjitter; + /*! Number of transmitted packets lost */ + unsigned int txploss; + /*! Number of received packets lost */ + unsigned int rxploss; + /*! Maximum number of packets lost on remote side */ + double remote_maxrxploss; + /*! Minimum number of packets lost on remote side */ + double remote_minrxploss; + /*! Average number of packets lost on remote side */ + double remote_normdevrxploss; + /*! Standard deviation packets lost on remote side */ + double remote_stdevrxploss; + /*! Maximum number of packets lost on local side */ + double local_maxrxploss; + /*! Minimum number of packets lost on local side */ + double local_minrxploss; + /*! Average number of packets lost on local side */ + double local_normdevrxploss; + /*! Standard deviation packets lost on local side */ + double local_stdevrxploss; + /*! Total round trip time */ + unsigned int rtt; + /*! Maximum round trip time */ + double maxrtt; + /*! Minimum round trip time */ + double minrtt; + /*! Average round trip time */ + double normdevrtt; + /*! Standard deviation round trip time */ + double stdevrtt; + /*! Our SSRC */ + unsigned int local_ssrc; + /*! Their SSRC */ + unsigned int remote_ssrc; +}; + +#define AST_RTP_STAT_SET(current_stat, combined, placement, value) \ +if (stat == current_stat || stat == AST_RTP_INSTANCE_STAT_ALL || (combined >= 0 && combined == current_stat)) { \ +placement = value; \ +if (stat == current_stat) { \ +return 0; \ +} \ +} + +#define AST_RTP_STAT_TERMINATOR(combined) \ +if (stat == combined) { \ +return 0; \ +} + +/*! Structure that represents an RTP stack (engine) */ +struct ast_rtp_engine { + /*! Name of the RTP engine, used when explicitly requested */ + const char *name; + /*! Module this RTP engine came from, used for reference counting */ + struct ast_module *mod; + /*! Callback for setting up a new RTP instance */ + int (*new)(struct ast_rtp_instance *instance, struct sched_context *sched, struct sockaddr_in *sin, void *data); + /*! Callback for destroying an RTP instance */ + int (*destroy)(struct ast_rtp_instance *instance); + /*! Callback for writing out a frame */ + int (*write)(struct ast_rtp_instance *instance, struct ast_frame *frame); + /*! Callback for stopping the RTP instance */ + void (*stop)(struct ast_rtp_instance *instance); + /*! Callback for starting RFC2833 DTMF transmission */ + int (*dtmf_begin)(struct ast_rtp_instance *instance, char digit); + /*! Callback for stopping RFC2833 DTMF transmission */ + int (*dtmf_end)(struct ast_rtp_instance *instance, char digit); + /*! Callback to indicate that a new source of media has come in */ + void (*new_source)(struct ast_rtp_instance *instance); + /*! Callback for setting an extended RTP property */ + int (*extended_prop_set)(struct ast_rtp_instance *instance, int property, void *value); + /*! Callback for getting an extended RTP property */ + void *(*extended_prop_get)(struct ast_rtp_instance *instance, int property); + /*! Callback for setting an RTP property */ + void (*prop_set)(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value); + /*! Callback for setting a payload */ + void (*payload_set)(struct ast_rtp_instance *instance, int payload, int astformat, int format); + /*! Callback for setting packetization preferences */ + void (*packetization_set)(struct ast_rtp_instance *instance, struct ast_codec_pref *pref); + /*! Callback for setting the remote address that RTP is to be sent to */ + void (*remote_address_set)(struct ast_rtp_instance *instance, struct sockaddr_in *sin); + /*! Callback for changing DTMF mode */ + int (*dtmf_mode_set)(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode); + /*! Callback for retrieving statistics */ + int (*get_stat)(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat); + /*! Callback for setting QoS values */ + int (*qos)(struct ast_rtp_instance *instance, int tos, int cos, const char *desc); + /*! Callback for retrieving a file descriptor to poll on, not always required */ + int (*fd)(struct ast_rtp_instance *instance, int rtcp); + /*! Callback for initializing RED support */ + int (*red_init)(struct ast_rtp_instance *instance, int buffer_time, int *payloads, int generations); + /*! Callback for buffering a frame using RED */ + int (*red_buffer)(struct ast_rtp_instance *instance, struct ast_frame *frame); + /*! Callback for reading a frame from the RTP engine */ + struct ast_frame *(*read)(struct ast_rtp_instance *instance, int rtcp); + /*! Callback to locally bridge two RTP instances */ + int (*local_bridge)(struct ast_rtp_instance *instance0, struct ast_rtp_instance *instance1); + /*! Callback to set the read format */ + int (*set_read_format)(struct ast_rtp_instance *instance, int format); + /*! Callback to set the write format */ + int (*set_write_format)(struct ast_rtp_instance *instance, int format); + /*! Callback to make two instances compatible */ + int (*make_compatible)(struct ast_channel *chan0, struct ast_rtp_instance *instance0, struct ast_channel *chan1, struct ast_rtp_instance *instance1); + /*! Callback to see if two instances are compatible with DTMF */ + int (*dtmf_compatible)(struct ast_channel *chan0, struct ast_rtp_instance *instance0, struct ast_channel *chan1, struct ast_rtp_instance *instance1); + /*! Callback to indicate that packets will now flow */ + int (*activate)(struct ast_rtp_instance *instance); + /*! Callback to request that the RTP engine send a STUN BIND request */ + void (*stun_request)(struct ast_rtp_instance *instance, struct sockaddr_in *suggestion, const char *username); + /*! Linked list information */ + AST_RWLIST_ENTRY(ast_rtp_engine) entry; +}; + +/*! Structure that represents codec and packetization information */ +struct ast_rtp_codecs { + /*! Codec packetization preferences */ + struct ast_codec_pref pref; + /*! Payloads present */ + struct ast_rtp_payload_type payloads[AST_RTP_MAX_PT]; +}; + +/*! Structure that represents the glue that binds an RTP instance to a channel */ +struct ast_rtp_glue { + /*! Name of the channel driver that this glue is responsible for */ + const char *type; + /*! Module that the RTP glue came from */ + struct ast_module *mod; + /*! + * \brief Callback for retrieving the RTP instance carrying audio + * \note This function increases the reference count on the returned RTP instance. + */ + enum ast_rtp_glue_result (*get_rtp_info)(struct ast_channel *chan, struct ast_rtp_instance **instance); + /*! + * \brief Callback for retrieving the RTP instance carrying video + * \note This function increases the reference count on the returned RTP instance. + */ + enum ast_rtp_glue_result (*get_vrtp_info)(struct ast_channel *chan, struct ast_rtp_instance **instance); + /*! + * \brief Callback for retrieving the RTP instance carrying text + * \note This function increases the reference count on the returned RTP instance. + */ + enum ast_rtp_glue_result (*get_trtp_info)(struct ast_channel *chan, struct ast_rtp_instance **instance); + /*! Callback for updating the destination that the remote side should send RTP to */ + int (*update_peer)(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, int codecs, int nat_active); + /*! Callback for retrieving codecs that the channel can do */ + int (*get_codec)(struct ast_channel *chan); + /*! Linked list information */ + AST_RWLIST_ENTRY(ast_rtp_glue) entry; +}; + +#define ast_rtp_engine_register(engine) ast_rtp_engine_register2(engine, ast_module_info->self) + +/*! + * \brief Register an RTP engine + * + * \param engine Structure of the RTP engine to register + * \param module Module that the RTP engine is part of + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_engine_register2(&example_rtp_engine, NULL); + * \endcode + * + * This registers the RTP engine declared as example_rtp_engine with the RTP engine core, but does not + * associate a module with it. + * + * \note It is recommended that you use the ast_rtp_engine_register macro so that the module is + * associated with the RTP engine and use counting is performed. + * + * \since 1.6.3 + */ +int ast_rtp_engine_register2(struct ast_rtp_engine *engine, struct ast_module *module); + +/*! + * \brief Unregister an RTP engine + * + * \param engine Structure of the RTP engine to unregister + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_engine_unregister(&example_rtp_engine); + * \endcode + * + * This unregisters the RTP engine declared as example_rtp_engine from the RTP engine core. If a module + * reference was provided when it was registered then this will only be called once the RTP engine is no longer in use. + * + * \since 1.6.3 + */ +int ast_rtp_engine_unregister(struct ast_rtp_engine *engine); + +#define ast_rtp_glue_register(glue) ast_rtp_glue_register2(glue, ast_module_info->self) + +/*! + * \brief Register RTP glue + * + * \param glue The glue to register + * \param module Module that the RTP glue is part of + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_glue_register2(&example_rtp_glue, NULL); + * \endcode + * + * This registers the RTP glue declared as example_rtp_glue with the RTP engine core, but does not + * associate a module with it. + * + * \note It is recommended that you use the ast_rtp_glue_register macro so that the module is + * associated with the RTP glue and use counting is performed. + * + * \since 1.6.3 + */ +int ast_rtp_glue_register2(struct ast_rtp_glue *glue, struct ast_module *module); + +/*! + * \brief Unregister RTP glue + * + * \param glue The glue to unregister + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_glue_unregister(&example_rtp_glue); + * \endcode + * + * This unregisters the RTP glue declared as example_rtp_gkue from the RTP engine core. If a module + * reference was provided when it was registered then this will only be called once the RTP engine is no longer in use. + * + * \since 1.6.3 + */ +int ast_rtp_glue_unregister(struct ast_rtp_glue *glue); + +/*! + * \brief Create a new RTP instance + * + * \param engine_name Name of the engine to use for the RTP instance + * \param sched Scheduler context that the RTP engine may want to use + * \param sin Address we want to bind to + * \param data Unique data for the engine + * + * \retval non-NULL success + * \retval NULL failure + * + * Example usage: + * + * \code + * struct ast_rtp_instance *instance = NULL; + * instance = ast_rtp_instance_new(NULL, sched, &sin, NULL); + * \endcode + * + * This creates a new RTP instance using the default engine and asks the RTP engine to bind to the address given + * in the sin structure. + * + * \note The RTP engine does not have to use the address provided when creating an RTP instance. It may choose to use + * another depending on it's own configuration. + * + * \since 1.6.3 + */ +struct ast_rtp_instance *ast_rtp_instance_new(const char *engine_name, struct sched_context *sched, struct sockaddr_in *sin, void *data); + +/*! + * \brief Destroy an RTP instance + * + * \param instance The RTP instance to destroy + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_instance_destroy(instance); + * \endcode + * + * This destroys the RTP instance pointed to by instance. Once this function returns instance no longer points to valid + * memory and may not be used again. + * + * \since 1.6.3 + */ +int ast_rtp_instance_destroy(struct ast_rtp_instance *instance); + +/*! + * \brief Set the data portion of an RTP instance + * + * \param instance The RTP instance to manipulate + * \param data Pointer to data + * + * Example usage: + * + * \code + * ast_rtp_instance_set_data(instance, blob); + * \endcode + * + * This sets the data pointer on the RTP instance pointed to by 'instance' to + * blob. + * + * \since 1.6.3 + */ +void ast_rtp_instance_set_data(struct ast_rtp_instance *instance, void *data); + +/*! + * \brief Get the data portion of an RTP instance + * + * \param instance The RTP instance we want the data portion from + * + * Example usage: + * + * \code + * struct *blob = ast_rtp_instance_get_data(instance); + ( \endcode + * + * This gets the data pointer on the RTP instance pointed to by 'instance'. + * + * \since 1.6.3 + */ +void *ast_rtp_instance_get_data(struct ast_rtp_instance *instance); + +/*! + * \brief Send a frame out over RTP + * + * \param instance The RTP instance to send frame out on + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_instance_write(instance, frame); + * \endcode + * + * This gives the frame pointed to by frame to the RTP engine being used for the instance + * and asks that it be transmitted to the current remote address set on the RTP instance. + * + * \since 1.6.3 + */ +int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame); + +/*! + * \brief Receive a frame over RTP + * + * \param instance The RTP instance to receive frame on + * \param rtcp Whether to read in RTCP or not + * + * \retval non-NULL success + * \retval NULL failure + * + * Example usage: + * + * \code + * struct ast_frame *frame; + * frame = ast_rtp_instance_read(instance, 0); + * \endcode + * + * This asks the RTP engine to read in RTP from the instance and return it as an Asterisk frame. + * + * \since 1.6.3 + */ +struct ast_frame *ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp); + +/*! + * \brief Set the address of the remote endpoint that we are sending RTP to + * + * \param instance The RTP instance to change the address on + * \param address Address to set it to + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_instance_set_remote_address(instance, &sin); + * \endcode + * + * This changes the remote address that RTP will be sent to on instance to the address given in the sin + * structure. + * + * \since 1.6.3 + */ +int ast_rtp_instance_set_remote_address(struct ast_rtp_instance *instance, struct sockaddr_in *address); + +/*! + * \brief Set the address that we are expecting to receive RTP on + * + * \param instance The RTP instance to change the address on + * \param address Address to set it to + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_instance_set_local_address(instance, &sin); + * \endcode + * + * This changes the local address that RTP is expected on to the address given in the sin + * structure. + * + * \since 1.6.3 + */ +int ast_rtp_instance_set_local_address(struct ast_rtp_instance *instance, struct sockaddr_in *address); + +/*! + * \brief Get the local address that we are expecting RTP on + * + * \param instance The RTP instance to get the address from + * \param address The variable to store the address in + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * struct sockaddr_in sin; + * ast_rtp_instance_get_local_address(instance, &sin); + * \endcode + * + * This gets the local address that we are expecting RTP on and stores it in the 'sin' structure. + * + * \since 1.6.3 + */ +int ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct sockaddr_in *address); + +/*! + * \brief Get the address of the remote endpoint that we are sending RTP to + * + * \param instance The instance that we want to get the remote address for + * \param address A structure to put the address into + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * struct sockaddr_in sin; + * ast_rtp_instance_get_remote_address(instance, &sin); + * \endcode + * + * This retrieves the current remote address set on the instance pointed to by instance and puts the value + * into the sin structure. + * + * \since 1.6.3 + */ +int ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct sockaddr_in *address); + +/*! + * \brief Set the value of an RTP instance extended property + * + * \param instance The RTP instance to set the extended property on + * \param property The extended property to set + * \param value The value to set the extended property to + * + * \since 1.6.3 + */ +void ast_rtp_instance_set_extended_prop(struct ast_rtp_instance *instance, int property, void *value); + +/*! + * \brief Get the value of an RTP instance extended property + * + * \param instance The RTP instance to get the extended property on + * \param property The extended property to get + * + * \since 1.6.3 + */ +void *ast_rtp_instance_get_extended_prop(struct ast_rtp_instance *instance, int property); + +/*! + * \brief Set the value of an RTP instance property + * + * \param instance The RTP instance to set the property on + * \param property The property to modify + * \param value The value to set the property to + * + * Example usage: + * + * \code + * ast_rtp_instance_set_prop(instance, AST_RTP_PROPERTY_NAT, 1); + * \endcode + * + * This enables the AST_RTP_PROPERTY_NAT property on the instance pointed to by instance. + * + * \since 1.6.3 + */ +void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value); + +/*! + * \brief Get the value of an RTP instance property + * + * \param instance The RTP instance to get the property from + * \param property The property to get + * + * \retval Current value of the property + * + * Example usage: + * + * \code + * ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_NAT); + * \endcode + * + * This returns the current value of the NAT property on the instance pointed to by instance. + * + * \since 1.6.3 + */ +int ast_rtp_instance_get_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property); + +/*! + * \brief Get the codecs structure of an RTP instance + * + * \param instance The RTP instance to get the codecs structure from + * + * Example usage: + * + * \code + * struct ast_rtp_codecs *codecs = ast_rtp_instance_get_codecs(instance); + * \endcode + * + * This gets the codecs structure on the RTP instance pointed to by 'instance'. + * + * \since 1.6.3 + */ +struct ast_rtp_codecs *ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance); + +/*! + * \brief Clear payload information from an RTP instance + * + * \param codecs The codecs structure that payloads will be cleared from + * \param instance Optionally the instance that the codecs structure belongs to + * + * Example usage: + * + * \code + * struct ast_rtp_codecs codecs; + * ast_rtp_codecs_payloads_clear(&codecs, NULL); + * \endcode + * + * This clears the codecs structure and puts it into a pristine state. + * + * \since 1.6.3 + */ +void ast_rtp_codecs_payloads_clear(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance); + +/*! + * \brief Set payload information on an RTP instance to the default + * + * \param codecs The codecs structure to set defaults on + * \param instance Optionally the instance that the codecs structure belongs to + * + * Example usage: + * + * \code + * struct ast_rtp_codecs codecs; + * ast_rtp_codecs_payloads_default(&codecs, NULL); + * \endcode + * + * This sets the default payloads on the codecs structure. + * + * \since 1.6.3 + */ +void ast_rtp_codecs_payloads_default(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance); + +/*! + * \brief Copy payload information from one RTP instance to another + * + * \param src The source codecs structure + * \param dst The destination codecs structure that the values from src will be copied to + * \param instance Optionally the instance that the dst codecs structure belongs to + * + * Example usage: + * + * \code + * ast_rtp_codecs_payloads_copy(&codecs0, &codecs1, NULL); + * \endcode + * + * This copies the payloads from the codecs0 structure to the codecs1 structure, overwriting any current values. + * + * \since 1.6.3 + */ +void ast_rtp_codecs_payloads_copy(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance); + +/*! + * \brief Record payload information that was seen in an m= SDP line + * + * \param codecs The codecs structure to muck with + * \param instance Optionally the instance that the codecs structure belongs to + * \param payload Numerical payload that was seen in the m= SDP line + * + * Example usage: + * + * \code + * ast_rtp_codecs_payloads_set_m_type(&codecs, NULL, 0); + * \endcode + * + * This records that the numerical payload '0' was seen in the codecs structure. + * + * \since 1.6.3 + */ +void ast_rtp_codecs_payloads_set_m_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload); + +/*! + * \brief Record payload information that was seen in an a=rtpmap: SDP line + * + * \param codecs The codecs structure to muck with + * \param instance Optionally the instance that the codecs structure belongs to + * \param payload Numerical payload that was seen in the a=rtpmap: SDP line + * \param mimetype The string mime type that was seen + * \param mimesubtype The strin mime sub type that was seen + * \param options Optional options that may change the behavior of this specific payload + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_codecs_payloads_set_rtpmap_type(&codecs, NULL, 0, "audio", "PCMU", 0); + * \endcode + * + * This records that the numerical payload '0' was seen with mime type 'audio' and sub mime type 'PCMU' in the codecs structure. + * + * \since 1.6.3 + */ +int ast_rtp_codecs_payloads_set_rtpmap_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload, char *mimetype, char *mimesubtype, enum ast_rtp_options options); + +/*! + * \brief Set payload type to a known MIME media type for a codec with a specific sample rate + * + * \param rtp RTP structure to modify + * \param instance Optionally the instance that the codecs structure belongs to + * \param pt Payload type entry to modify + * \param mimetype top-level MIME type of media stream (typically "audio", "video", "text", etc.) + * \param mimesubtype MIME subtype of media stream (typically a codec name) + * \param options Zero or more flags from the ast_rtp_options enum + * \param sample_rate The sample rate of the media stream + * + * This function 'fills in' an entry in the list of possible formats for + * a media stream associated with an RTP structure. + * + * \retval 0 on success + * \retval -1 if the payload type is out of range + * \retval -2 if the mimeType/mimeSubtype combination was not found + * + * \since 1.6.3 + */ +int ast_rtp_codecs_payloads_set_rtpmap_type_rate(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int pt, + char *mimetype, char *mimesubtype, + enum ast_rtp_options options, + unsigned int sample_rate); + +/*! + * \brief Remove payload information + * + * \param codecs The codecs structure to muck with + * \param instance Optionally the instance that the codecs structure belongs to + * \param payload Numerical payload to unset + * + * Example usage: + * + * \code + * ast_rtp_codecs_payloads_unset(&codecs, NULL, 0); + * \endcode + * + * This clears the payload '0' from the codecs structure. It will be as if it was never set. + * + * \since 1.6.3 + */ +void ast_rtp_codecs_payloads_unset(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload); + +/*! + * \brief Retrieve payload information by payload + * + * \param codecs Codecs structure to look in + * \param payload Numerical payload to look up + * + * \retval Payload information + * + * Example usage: + * + * \code + * struct ast_rtp_payload_type payload_type; + * payload_type = ast_rtp_codecs_payload_lookup(&codecs, 0); + * \endcode + * + * This looks up the information for payload '0' from the codecs structure. + * + * \since 1.6.3 + */ +struct ast_rtp_payload_type ast_rtp_codecs_payload_lookup(struct ast_rtp_codecs *codecs, int payload); + +/*! + * \brief Get the sample rate associated with known RTP payload types + * + * \param asterisk_format True if the value in the 'code' parameter is an AST_FORMAT value + * \param code Format code, either from AST_FORMAT list or from AST_RTP list + * + * \return the sample rate if the format was found, zero if it was not found + * + * \since 1.6.3 + */ +unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, int code); + +/*! + * \brief Retrieve all formats that were found + * + * \param codecs Codecs structure to look in + * \param astFormats An integer to put the Asterisk formats in + * \param nonastformats An integer to put the non-Asterisk formats in + * + * Example usage: + * + * \code + * int astformats, nonastformats; + * ast_rtp_codecs_payload_Formats(&codecs, &astformats, &nonastformats); + * \endcode + * + * This retrieves all the formats known about in the codecs structure and puts the Asterisk ones in the integer + * pointed to by astformats and the non-Asterisk ones in the integer pointed to by nonastformats. + * + * \since 1.6.3 + */ +void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, int *astformats, int *nonastformats); + +/*! + * \brief Retrieve a payload based on whether it is an Asterisk format and the code + * + * \param codecs Codecs structure to look in + * \param asterisk_format Non-zero if the given code is an Asterisk format value + * \param code The format to look for + * + * \retval Numerical payload + * + * Example usage: + * + * \code + * int payload = ast_rtp_codecs_payload_code(&codecs, 1, AST_FORMAT_ULAW); + * \endcode + * + * This looks for the numerical payload for ULAW in the codecs structure. + * + * \since 1.6.3 + */ +int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, const int asterisk_format, const int code); + +/*! + * \brief Retrieve mime subtype information on a payload + * + * \param asterisk_format Non-zero if the given code is an Asterisk format value + * \param code Format to look up + * \param options Additional options that may change the result + * + * \retval Mime subtype success + * \retval NULL failure + * + * Example usage: + * + * \code + * const char *subtype = ast_rtp_lookup_mime_subtype2(1, AST_FORMAT_ULAW, 0); + * \endcode + * + * This looks up the mime subtype for the ULAW format. + * + * \since 1.6.3 + */ +const char *ast_rtp_lookup_mime_subtype2(const int asterisk_format, const int code, enum ast_rtp_options options); + +/*! + * \brief Convert formats into a string and put them into a buffer + * + * \param buf Buffer to put the mime output into + * \param capability Formats that we are looking up + * \param asterisk_format Non-zero if the given capability are Asterisk format capabilities + * \param options Additional options that may change the result + * + * \retval non-NULL success + * \retval NULL failure + * + * Example usage: + * + * \code + * char buf[256] = ""; + * char *mime = ast_rtp_lookup_mime_multiple2(&buf, sizeof(buf), AST_FORMAT_ULAW | AST_FORMAT_ALAW, 1, 0); + * \endcode + * + * This returns the mime values for ULAW and ALAW in the buffer pointed to by buf. + * + * \since 1.6.3 + */ +char *ast_rtp_lookup_mime_multiple2(struct ast_str *buf, const int capability, const int asterisk_format, enum ast_rtp_options options); + +/*! + * \brief Set codec packetization preferences + * + * \param codecs Codecs structure to muck with + * \param instance Optionally the instance that the codecs structure belongs to + * \param prefs Codec packetization preferences + * + * Example usage: + * + * \code + * ast_rtp_codecs_packetization_set(&codecs, NULL, &prefs); + * \endcode + * + * This sets the packetization preferences pointed to by prefs on the codecs structure pointed to by codecs. + * + * \since 1.6.3 + */ +void ast_rtp_codecs_packetization_set(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, struct ast_codec_pref *prefs); + +/*! + * \brief Begin sending a DTMF digit + * + * \param instance The RTP instance to send the DTMF on + * \param digit What DTMF digit to send + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_instance_dtmf_begin(instance, '1'); + * \endcode + * + * This starts sending the DTMF '1' on the RTP instance pointed to by instance. It will + * continue being sent until it is ended. + * + * \since 1.6.3 + */ +int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit); + +/*! + * \brief Stop sending a DTMF digit + * + * \param instance The RTP instance to stop the DTMF on + * \param digit What DTMF digit to stop + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_instance_dtmf_end(instance, '1'); + * \endcode + * + * This stops sending the DTMF '1' on the RTP instance pointed to by instance. + * + * \since 1.6.3 + */ +int ast_rtp_instance_dtmf_end(struct ast_rtp_instance *instance, char digit); + +/*! + * \brief Set the DTMF mode that should be used + * + * \param instance the RTP instance to set DTMF mode on + * \param dtmf_mode The DTMF mode that is in use + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_instance_dtmf_mode_set(instance, AST_RTP_DTMF_MODE_RFC2833); + * \endcode + * + * This sets the RTP instance to use RFC2833 for DTMF transmission and receiving. + * + * \since 1.6.3 + */ +int ast_rtp_instance_dtmf_mode_set(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode); + +/*! + * \brief Get the DTMF mode of an RTP instance + * + * \param instance The RTP instance to get the DTMF mode of + * + * \retval DTMF mode + * + * Example usage: + * + * \code + * enum ast_rtp_dtmf_mode dtmf_mode = ast_rtp_instance_dtmf_mode_get(instance); + * \endcode + * + * This gets the DTMF mode set on the RTP instance pointed to by 'instance'. + * + * \since 1.6.3 + */ +enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance); + +/*! + * \brief Indicate a new source of audio has dropped in + * + * \param instance Instance that the new media source is feeding into + * + * Example usage: + * + * \code + * ast_rtp_instance_new_source(instance); + * \endcode + * + * This indicates that a new source of media is feeding the instance pointed to by + * instance. + * + * \since 1.6.3 + */ +void ast_rtp_instance_new_source(struct ast_rtp_instance *instance); + +/*! + * \brief Set QoS parameters on an RTP session + * + * \param instance Instance to set the QoS parameters on + * \param tos Terms of service value + * \param cos Class of service value + * \param desc What is setting the QoS values + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_instance_set_qos(instance, 0, 0, "Example"); + * \endcode + * + * This sets the TOS and COS values to 0 on the instance pointed to by instance. + * + * \since 1.6.3 + */ +int ast_rtp_instance_set_qos(struct ast_rtp_instance *instance, int tos, int cos, const char *desc); + +/*! + * \brief Stop an RTP instance + * + * \param instance Instance that media is no longer going to at this time + * + * Example usage: + * + * \code + * ast_rtp_instance_stop(instance); + * \endcode + * + * This tells the RTP engine being used for the instance pointed to by instance + * that media is no longer going to it at this time, but may in the future. + * + * \since 1.6.3 + */ +void ast_rtp_instance_stop(struct ast_rtp_instance *instance); + +/*! + * \brief Get the file descriptor for an RTP session (or RTCP) + * + * \param instance Instance to get the file descriptor for + * \param rtcp Whether to retrieve the file descriptor for RTCP or not + * + * \retval fd success + * \retval -1 failure + * + * Example usage: + * + * \code + * int rtp_fd = ast_rtp_instance_fd(instance, 0); + * \endcode + * + * This retrieves the file descriptor for the socket carrying media on the instance + * pointed to by instance. + * + * \since 1.6.3 + */ +int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp); + +/*! + * \brief Get the RTP glue that binds a channel to the RTP engine + * + * \param type Name of the glue we want + * + * \retval non-NULL success + * \retval NULL failure + * + * Example usage: + * + * \code + * struct ast_rtp_glue *glue = ast_rtp_instance_get_glue("Example"); + * \endcode + * + * This retrieves the RTP glue that has the name 'Example'. + * + * \since 1.6.3 + */ +struct ast_rtp_glue *ast_rtp_instance_get_glue(const char *type); + +/*! + * \brief Bridge two channels that use RTP instances + * + * \param c0 First channel part of the bridge + * \param c1 Second channel part of the bridge + * \param flags Bridging flags + * \param fo If a frame needs to be passed up it is stored here + * \param rc Channel that passed the above frame up + * \param timeoutms How long the channels should be bridged for + * + * \retval Bridge result + * + * \note This should only be used by channel drivers in their technology declaration. + * + * \since 1.6.3 + */ +enum ast_bridge_result ast_rtp_instance_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms); + +/*! + * \brief Get the other RTP instance that an instance is bridged to + * + * \param instance The RTP instance that we want + * + * \retval non-NULL success + * \retval NULL failure + * + * Example usage: + * + * \code + * struct ast_rtp_instance *bridged = ast_rtp_instance_get_bridged(instance0); + * \endcode + * + * This gets the RTP instance that instance0 is bridged to. + * + * \since 1.6.3 + */ +struct ast_rtp_instance *ast_rtp_instance_get_bridged(struct ast_rtp_instance *instance); + +/*! + * \brief Make two channels compatible for early bridging + * + * \param c0 First channel part of the bridge + * \param c1 Second channel part of the bridge + * + * \since 1.6.3 + */ +void ast_rtp_instance_early_bridge_make_compatible(struct ast_channel *c0, struct ast_channel *c1); + +/*! + * \brief Early bridge two channels that use RTP instances + * + * \param c0 First channel part of the bridge + * \param c1 Second channel part of the bridge + * + * \retval 0 success + * \retval -1 failure + * + * \note This should only be used by channel drivers in their technology declaration. + * + * \since 1.6.3 + */ +int ast_rtp_instance_early_bridge(struct ast_channel *c0, struct ast_channel *c1); + +/*! + * \brief Initialize RED support on an RTP instance + * + * \param instance The instance to initialize RED support on + * \param buffer_time How long to buffer before sending + * \param payloads Payload values + * \param generations Number of generations + * + * \retval 0 success + * \retval -1 failure + * + * \since 1.6.3 + */ +int ast_rtp_red_init(struct ast_rtp_instance *instance, int buffer_time, int *payloads, int generations); + +/*! + * \brief Buffer a frame in an RTP instance for RED + * + * \param instance The instance to buffer the frame on + * \param frame Frame that we want to buffer + * + * \retval 0 success + * \retval -1 failure + * + * \since 1.6.3 + */ +int ast_rtp_red_buffer(struct ast_rtp_instance *instance, struct ast_frame *frame); + +/*! + * \brief Retrieve statistics about an RTP instance + * + * \param instance Instance to get statistics on + * \param stats Structure to put results into + * \param stat What statistic(s) to retrieve + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * struct ast_rtp_instance_stats stats; + * ast_rtp_instance_get_stats(instance, &stats, AST_RTP_INSTANCE_STAT_ALL); + * \endcode + * + * This retrieves all statistics the underlying RTP engine supports and puts the values into the + * stats structure. + * + * \since 1.6.3 + */ +int ast_rtp_instance_get_stats(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat); + +/*! + * \brief Set standard statistics from an RTP instance on a channel + * + * \param chan Channel to set the statistics on + * \param instance The RTP instance that statistics will be retrieved from + * + * Example usage: + * + * \code + * ast_rtp_instance_set_stats_vars(chan, rtp); + * \endcode + * + * This retrieves standard statistics from the RTP instance rtp and sets it on the channel pointed to + * by chan. + * + * \since 1.6.3 + */ +void ast_rtp_instance_set_stats_vars(struct ast_channel *chan, struct ast_rtp_instance *instance); + +/*! + * \brief Retrieve quality statistics about an RTP instance + * + * \param instance Instance to get statistics on + * \param field What quality statistic to retrieve + * \param buf What buffer to put the result into + * \param size Size of the above buffer + * + * \retval non-NULL success + * \retval NULL failure + * + * Example usage: + * + * \code + * char quality[AST_MAX_USER_FIELD]; + * ast_rtp_instance_get_quality(instance, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, &buf, sizeof(buf)); + * \endcode + * + * This retrieves general quality statistics and places a text representation into the buf pointed to by buf. + * + * \since 1.6.3 + */ +char *ast_rtp_instance_get_quality(struct ast_rtp_instance *instance, enum ast_rtp_instance_stat_field field, char *buf, size_t size); + +/*! + * \brief Request that the underlying RTP engine provide audio frames in a specific format + * + * \param instance The RTP instance to change read format on + * \param format Format that frames are wanted in + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_instance_set_read_format(instance, AST_FORMAT_ULAW); + * \endcode + * + * This requests that the RTP engine provide audio frames in the ULAW format. + * + * \since 1.6.3 + */ +int ast_rtp_instance_set_read_format(struct ast_rtp_instance *instance, int format); + +/*! + * \brief Tell underlying RTP engine that audio frames will be provided in a specific format + * + * \param instance The RTP instance to change write format on + * \param format Format that frames will be provided in + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_instance_set_write_format(instance, AST_FORMAT_ULAW); + * \endcode + * + * This tells the underlying RTP engine that audio frames will be provided to it in ULAW format. + * + * \since 1.6.3 + */ +int ast_rtp_instance_set_write_format(struct ast_rtp_instance *instance, int format); + +/*! + * \brief Request that the underlying RTP engine make two RTP instances compatible with eachother + * + * \param chan Our own Asterisk channel + * \param instance The first RTP instance + * \param peer The peer Asterisk channel + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_instance_make_compatible(instance, peer); + * \endcode + * + * This makes the RTP instance for 'peer' compatible with 'instance' and vice versa. + * + * \since 1.6.3 + */ +int ast_rtp_instance_make_compatible(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_channel *peer); + +/*! + * \brief Indicate to the RTP engine that packets are now expected to be sent/received on the RTP instance + * + * \param instance The RTP instance + * + * \retval 0 success + * \retval -1 failure + * + * Example usage: + * + * \code + * ast_rtp_instance_activate(instance); + * \endcode + * + * This tells the underlying RTP engine of instance that packets will now flow. + * + * \since 1.6.3 + */ +int ast_rtp_instance_activate(struct ast_rtp_instance *instance); + +/*! + * \brief Request that the underlying RTP engine send a STUN BIND request + * + * \param instance The RTP instance + * \param suggestion The suggested destination + * \param username Optionally a username for the request + * + * Example usage: + * + * \code + * ast_rtp_instance_stun_request(instance, NULL, NULL); + * \endcode + * + * This requests that the RTP engine send a STUN BIND request on the session pointed to by + * 'instance'. + * + * \since 1.6.3 + */ +void ast_rtp_instance_stun_request(struct ast_rtp_instance *instance, struct sockaddr_in *suggestion, const char *username); + +/*! + * \brief Set the RTP timeout value + * + * \param instance The RTP instance + * \param timeout Value to set the timeout to + * + * Example usage: + * + * \code + * ast_rtp_instance_set_timeout(instance, 5000); + * \endcode + * + * This sets the RTP timeout value on 'instance' to be 5000. + * + * \since 1.6.3 + */ +void ast_rtp_instance_set_timeout(struct ast_rtp_instance *instance, int timeout); + +/*! + * \brief Set the RTP timeout value for when the instance is on hold + * + * \param instance The RTP instance + * \param timeout Value to set the timeout to + * + * Example usage: + * + * \code + * ast_rtp_instance_set_hold_timeout(instance, 5000); + * \endcode + * + * This sets the RTP hold timeout value on 'instance' to be 5000. + * + * \since 1.6.3 + */ +void ast_rtp_instance_set_hold_timeout(struct ast_rtp_instance *instance, int timeout); + +/*! + * \brief Get the RTP timeout value + * + * \param instance The RTP instance + * + * \retval timeout value + * + * Example usage: + * + * \code + * int timeout = ast_rtp_instance_get_timeout(instance); + * \endcode + * + * This gets the RTP timeout value for the RTP instance pointed to by 'instance'. + * + * \since 1.6.3 + */ +int ast_rtp_instance_get_timeout(struct ast_rtp_instance *instance); + +/*! + * \brief Get the RTP timeout value for when an RTP instance is on hold + * + * \param instance The RTP instance + * + * \retval timeout value + * + * Example usage: + * + * \code + * int timeout = ast_rtp_instance_get_hold_timeout(instance); + * \endcode + * + * This gets the RTP hold timeout value for the RTP instance pointed to by 'instance'. + * + * \since 1.6.3 + */ +int ast_rtp_instance_get_hold_timeout(struct ast_rtp_instance *instance); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _ASTERISK_RTP_ENGINE_H */ diff --git a/include/asterisk/stun.h b/include/asterisk/stun.h new file mode 100644 index 000000000..11921f814 --- /dev/null +++ b/include/asterisk/stun.h @@ -0,0 +1,71 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 1999 - 2008, Digium, Inc. + * + * Mark Spencer + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! + * \file stun.h + * \brief STUN support. + * + * STUN is defined in RFC 3489. + */ + +#ifndef _ASTERISK_STUN_H +#define _ASTERISK_STUN_H + +#include "asterisk/network.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +enum ast_stun_result { + AST_STUN_IGNORE = 0, + AST_STUN_ACCEPT, +}; + +struct stun_attr; + +/*! \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 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. + */ +int ast_stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *data, size_t len, stun_cb_f *stun_cb, void *arg); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _ASTERISK_STUN_H */ -- cgit v1.2.3