Sat Apr 26 2014 22:03:13

Asterisk developer's documentation


rtp_engine.c File Reference

Pluggable RTP Architecture. More...

#include "asterisk.h"
#include <math.h>
#include "asterisk/channel.h"
#include "asterisk/frame.h"
#include "asterisk/module.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/manager.h"
#include "asterisk/options.h"
#include "asterisk/astobj2.h"
#include "asterisk/pbx.h"
#include "asterisk/translate.h"
#include "asterisk/netsock2.h"
#include "asterisk/_private.h"
#include "asterisk/framehook.h"
Include dependency graph for rtp_engine.c:

Go to the source code of this file.

Data Structures

struct  ast_rtp_instance
struct  ast_rtp_mime_type
struct  engines
struct  glues

Functions

static void add_static_payload (int map, const struct ast_format *format, int rtp_code)
int ast_rtp_codecs_find_payload_code (struct ast_rtp_codecs *codecs, int code)
 Search for a payload code in the ast_rtp_codecs structure.
struct ast_formatast_rtp_codecs_get_payload_format (struct ast_rtp_codecs *codecs, int payload)
 Retrieve the actual ast_format stored on the codecs structure for a specific payload.
void ast_rtp_codecs_packetization_set (struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, struct ast_codec_pref *prefs)
 Set codec packetization preferences.
int ast_rtp_codecs_payload_code (struct ast_rtp_codecs *codecs, int asterisk_format, const struct ast_format *format, int code)
 Retrieve a payload based on whether it is an Asterisk format and the code.
void ast_rtp_codecs_payload_formats (struct ast_rtp_codecs *codecs, struct ast_format_cap *astformats, int *nonastformats)
 Retrieve all formats that were found.
struct ast_rtp_payload_type ast_rtp_codecs_payload_lookup (struct ast_rtp_codecs *codecs, int payload)
 Retrieve payload information by payload.
void ast_rtp_codecs_payloads_clear (struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance)
 Clear payload information from an RTP instance.
void ast_rtp_codecs_payloads_copy (struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
 Copy payload information from one RTP instance to another.
void ast_rtp_codecs_payloads_default (struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance)
 Set payload information on an RTP instance to the default.
void ast_rtp_codecs_payloads_destroy (struct ast_rtp_codecs *codecs)
 Destroy the contents of an RTP codecs structure (but not the structure itself)
int ast_rtp_codecs_payloads_initialize (struct ast_rtp_codecs *codecs)
 Initialize an RTP codecs structure.
void ast_rtp_codecs_payloads_set_m_type (struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
 Record payload information that was seen in an m= SDP line.
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)
 Record payload information that was seen in an a=rtpmap: SDP line.
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)
 Set payload type to a known MIME media type for a codec with a specific sample rate.
void ast_rtp_codecs_payloads_unset (struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
 Remove payload information.
void ast_rtp_dtls_cfg_copy (const struct ast_rtp_dtls_cfg *src_cfg, struct ast_rtp_dtls_cfg *dst_cfg)
 Copy contents of a DTLS configuration structure.
void ast_rtp_dtls_cfg_free (struct ast_rtp_dtls_cfg *dtls_cfg)
 Free contents of a DTLS configuration structure.
int ast_rtp_dtls_cfg_parse (struct ast_rtp_dtls_cfg *dtls_cfg, const char *name, const char *value)
 Parse DTLS related configuration options.
int ast_rtp_engine_init ()
 initializes the rtp engine arrays
int ast_rtp_engine_load_format (const struct ast_format *format)
 Custom formats declared in codecs.conf at startup must be communicated to the rtp_engine so their mime type can payload number can be initialized.
int ast_rtp_engine_register2 (struct ast_rtp_engine *engine, struct ast_module *module)
 Register an RTP engine.
int ast_rtp_engine_register_srtp (struct ast_srtp_res *srtp_res, struct ast_srtp_policy_res *policy_res)
int ast_rtp_engine_srtp_is_registered (void)
int ast_rtp_engine_unload_format (const struct ast_format *format)
 Formats requiring the use of a format attribute interface must have that interface registered in order for the rtp engine to handle it correctly. If an attribute interface is unloaded, this function must be called to notify the rtp_engine.
int ast_rtp_engine_unregister (struct ast_rtp_engine *engine)
 Unregister an RTP engine.
void ast_rtp_engine_unregister_srtp (void)
int ast_rtp_glue_register2 (struct ast_rtp_glue *glue, struct ast_module *module)
 Register RTP glue.
int ast_rtp_glue_unregister (struct ast_rtp_glue *glue)
 Unregister RTP glue.
int ast_rtp_instance_activate (struct ast_rtp_instance *instance)
 Indicate to the RTP engine that packets are now expected to be sent/received on the RTP instance.
int ast_rtp_instance_add_srtp_policy (struct ast_rtp_instance *instance, struct ast_srtp_policy *remote_policy, struct ast_srtp_policy *local_policy)
 Add or replace the SRTP policies for the given RTP instance.
void ast_rtp_instance_available_formats (struct ast_rtp_instance *instance, struct ast_format_cap *to_endpoint, struct ast_format_cap *to_asterisk, struct ast_format_cap *result)
 Request the formats that can be transcoded.
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)
 Bridge two channels that use RTP instances.
void ast_rtp_instance_change_source (struct ast_rtp_instance *instance)
 Indicate a new source of audio has dropped in and the ssrc should change.
int ast_rtp_instance_destroy (struct ast_rtp_instance *instance)
 Destroy an RTP instance.
int ast_rtp_instance_dtmf_begin (struct ast_rtp_instance *instance, char digit)
 Begin sending a DTMF digit.
int ast_rtp_instance_dtmf_end (struct ast_rtp_instance *instance, char digit)
 Stop sending a DTMF digit.
int ast_rtp_instance_dtmf_end_with_duration (struct ast_rtp_instance *instance, char digit, unsigned int duration)
enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get (struct ast_rtp_instance *instance)
 Get the DTMF mode of an RTP instance.
int ast_rtp_instance_dtmf_mode_set (struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode)
 Set the DTMF mode that should be used.
int ast_rtp_instance_early_bridge (struct ast_channel *c0, struct ast_channel *c1)
 Early bridge two channels that use RTP instances.
void ast_rtp_instance_early_bridge_make_compatible (struct ast_channel *c_dst, struct ast_channel *c_src)
 Make two channels compatible for early bridging.
int ast_rtp_instance_fd (struct ast_rtp_instance *instance, int rtcp)
 Get the file descriptor for an RTP session (or RTCP)
struct ast_rtp_glueast_rtp_instance_get_active_glue (struct ast_rtp_instance *instance)
 Get the RTP glue in use on an RTP instance.
int ast_rtp_instance_get_and_cmp_local_address (struct ast_rtp_instance *instance, struct ast_sockaddr *address)
 Get the address of the local endpoint that we are sending RTP to, comparing its address to another.
int ast_rtp_instance_get_and_cmp_remote_address (struct ast_rtp_instance *instance, struct ast_sockaddr *address)
 Get the address of the remote endpoint that we are sending RTP to, comparing its address to another.
struct ast_rtp_instanceast_rtp_instance_get_bridged (struct ast_rtp_instance *instance)
 Get the other RTP instance that an instance is bridged to.
struct ast_channelast_rtp_instance_get_chan (struct ast_rtp_instance *instance)
 Get the channel that is associated with an RTP instance while in a bridge.
struct ast_rtp_codecsast_rtp_instance_get_codecs (struct ast_rtp_instance *instance)
 Get the codecs structure of an RTP instance.
void * ast_rtp_instance_get_data (struct ast_rtp_instance *instance)
 Get the data portion of an RTP instance.
struct ast_rtp_engine_dtlsast_rtp_instance_get_dtls (struct ast_rtp_instance *instance)
 Obtain a pointer to the DTLS support present on an RTP instance.
struct ast_rtp_engineast_rtp_instance_get_engine (struct ast_rtp_instance *instance)
 Get the RTP engine in use on an RTP instance.
void * ast_rtp_instance_get_extended_prop (struct ast_rtp_instance *instance, int property)
 Get the value of an RTP instance extended property.
struct ast_rtp_glueast_rtp_instance_get_glue (const char *type)
 Get the RTP glue that binds a channel to the RTP engine.
int ast_rtp_instance_get_hold_timeout (struct ast_rtp_instance *instance)
 Get the RTP timeout value for when an RTP instance is on hold.
struct ast_rtp_engine_iceast_rtp_instance_get_ice (struct ast_rtp_instance *instance)
 Obtain a pointer to the ICE support present on an RTP instance.
int ast_rtp_instance_get_keepalive (struct ast_rtp_instance *instance)
 Get the RTP keepalive interval.
void ast_rtp_instance_get_local_address (struct ast_rtp_instance *instance, struct ast_sockaddr *address)
 Get the local address that we are expecting RTP on.
int ast_rtp_instance_get_prop (struct ast_rtp_instance *instance, enum ast_rtp_property property)
 Get the value of an RTP instance property.
char * ast_rtp_instance_get_quality (struct ast_rtp_instance *instance, enum ast_rtp_instance_stat_field field, char *buf, size_t size)
 Retrieve quality statistics about an RTP instance.
void ast_rtp_instance_get_remote_address (struct ast_rtp_instance *instance, struct ast_sockaddr *address)
 Get the address of the remote endpoint that we are sending RTP to.
struct ast_srtpast_rtp_instance_get_srtp (struct ast_rtp_instance *instance)
 Obtain the SRTP instance associated with an RTP instance.
int ast_rtp_instance_get_stats (struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
 Retrieve statistics about an RTP instance.
int ast_rtp_instance_get_timeout (struct ast_rtp_instance *instance)
 Get the RTP timeout value.
int ast_rtp_instance_make_compatible (struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_channel *peer)
 Request that the underlying RTP engine make two RTP instances compatible with eachother.
struct ast_rtp_instanceast_rtp_instance_new (const char *engine_name, struct ast_sched_context *sched, const struct ast_sockaddr *sa, void *data)
 Create a new RTP instance.
struct ast_frameast_rtp_instance_read (struct ast_rtp_instance *instance, int rtcp)
 Receive a frame over RTP.
int ast_rtp_instance_sendcng (struct ast_rtp_instance *instance, int level)
 Send a comfort noise packet to the RTP instance.
int ast_rtp_instance_set_alt_remote_address (struct ast_rtp_instance *instance, const struct ast_sockaddr *address)
 Set the address of an an alternate RTP address to receive from.
void ast_rtp_instance_set_data (struct ast_rtp_instance *instance, void *data)
 Set the data portion of an RTP instance.
void ast_rtp_instance_set_extended_prop (struct ast_rtp_instance *instance, int property, void *value)
 Set the value of an RTP instance extended property.
void ast_rtp_instance_set_hold_timeout (struct ast_rtp_instance *instance, int timeout)
 Set the RTP timeout value for when the instance is on hold.
void ast_rtp_instance_set_keepalive (struct ast_rtp_instance *instance, int interval)
 Set the RTP keepalive interval.
int ast_rtp_instance_set_local_address (struct ast_rtp_instance *instance, const struct ast_sockaddr *address)
 Set the address that we are expecting to receive RTP on.
void ast_rtp_instance_set_prop (struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
 Set the value of an RTP instance property.
int ast_rtp_instance_set_qos (struct ast_rtp_instance *instance, int tos, int cos, const char *desc)
 Set QoS parameters on an RTP session.
int ast_rtp_instance_set_read_format (struct ast_rtp_instance *instance, struct ast_format *format)
 Request that the underlying RTP engine provide audio frames in a specific format.
int ast_rtp_instance_set_remote_address (struct ast_rtp_instance *instance, const struct ast_sockaddr *address)
 Set the address of the remote endpoint that we are sending RTP to.
void ast_rtp_instance_set_stats_vars (struct ast_channel *chan, struct ast_rtp_instance *instance)
 Set standard statistics from an RTP instance on a channel.
void ast_rtp_instance_set_timeout (struct ast_rtp_instance *instance, int timeout)
 Set the RTP timeout value.
int ast_rtp_instance_set_write_format (struct ast_rtp_instance *instance, struct ast_format *format)
 Tell underlying RTP engine that audio frames will be provided in a specific format.
void ast_rtp_instance_stop (struct ast_rtp_instance *instance)
 Stop an RTP instance.
void ast_rtp_instance_stun_request (struct ast_rtp_instance *instance, struct ast_sockaddr *suggestion, const char *username)
 Request that the underlying RTP engine send a STUN BIND request.
void ast_rtp_instance_update_source (struct ast_rtp_instance *instance)
 Indicate that the RTP marker bit should be set on an RTP stream.
int ast_rtp_instance_write (struct ast_rtp_instance *instance, struct ast_frame *frame)
 Send a frame out over RTP.
char * ast_rtp_lookup_mime_multiple2 (struct ast_str *buf, struct ast_format_cap *ast_format_capability, int rtp_capability, const int asterisk_format, enum ast_rtp_options options)
 Convert formats into a string and put them into a buffer.
const char * ast_rtp_lookup_mime_subtype2 (const int asterisk_format, struct ast_format *format, int code, enum ast_rtp_options options)
 Retrieve mime subtype information on a payload.
unsigned int ast_rtp_lookup_sample_rate2 (int asterisk_format, struct ast_format *format, int code)
 Get the sample rate associated with known RTP payload types.
int ast_rtp_red_buffer (struct ast_rtp_instance *instance, struct ast_frame *frame)
 Buffer a frame in an RTP instance for RED.
int ast_rtp_red_init (struct ast_rtp_instance *instance, int buffer_time, int *payloads, int generations)
 Initialize RED support on an RTP instance.
static void instance_destructor (void *obj)
static enum ast_bridge_result local_bridge_loop (struct ast_channel *c0, struct ast_channel *c1, struct ast_rtp_instance *instance0, struct ast_rtp_instance *instance1, int timeoutms, int flags, struct ast_frame **fo, struct ast_channel **rc, void *pvt0, void *pvt1)
static enum ast_bridge_result remote_bridge_loop (struct ast_channel *c0, struct ast_channel *c1, struct ast_rtp_instance *instance0, struct ast_rtp_instance *instance1, struct ast_rtp_instance *vinstance0, struct ast_rtp_instance *vinstance1, struct ast_rtp_instance *tinstance0, struct ast_rtp_instance *tinstance1, struct ast_rtp_glue *glue0, struct ast_rtp_glue *glue1, struct ast_format_cap *cap0, struct ast_format_cap *cap1, int timeoutms, int flags, struct ast_frame **fo, struct ast_channel **rc, void *pvt0, void *pvt1)
static int rtp_payload_type_add_ast (void *obj, void *arg, int flags)
static int rtp_payload_type_add_nonast (void *obj, void *arg, int flags)
static int rtp_payload_type_cmp (void *obj, void *arg, int flags)
static int rtp_payload_type_find_format (void *obj, void *arg, int flags)
static int rtp_payload_type_find_nonast_format (void *obj, void *arg, int flags)
static int rtp_payload_type_hash (const void *obj, const int flags)
static void set_next_mime_type (const struct ast_format *format, int rtp_code, char *type, char *subtype, unsigned int sample_rate)
static void unref_instance_cond (struct ast_rtp_instance **instance)
 Conditionally unref an rtp instance.

Variables

static struct ast_rtp_mime_type ast_rtp_mime_types [128]
static struct engines engines
static struct glues glues
static int mime_types_len = 0
static ast_rwlock_t mime_types_lock
struct ast_srtp_resres_srtp = NULL
struct ast_srtp_policy_resres_srtp_policy = NULL
static struct ast_rtp_payload_type static_RTP_PT [AST_RTP_MAX_PT]
 Mapping between Asterisk codecs and rtp payload types.
static ast_rwlock_t static_RTP_PT_lock

Detailed Description

Pluggable RTP Architecture.

Author:
Joshua Colp <jcolp@digium.com>

Definition in file rtp_engine.c.


Function Documentation

static void add_static_payload ( int  map,
const struct ast_format format,
int  rtp_code 
) [static]

Definition at line 2191 of file rtp_engine.c.

References ast_format_copy(), ast_getformatname(), ast_log(), ast_rwlock_unlock, ast_rwlock_wrlock, ast_rtp_payload_type::asterisk_format, LOG_WARNING, map, ast_rtp_payload_type::rtp_code, and static_RTP_PT.

Referenced by ast_rtp_engine_init(), and ast_rtp_engine_load_format().

{
   int x;
   ast_rwlock_wrlock(&static_RTP_PT_lock);
   if (map < 0) {
      /* find next available dynamic payload slot */
      for (x = 96; x < 127; x++) {
         if (!static_RTP_PT[x].asterisk_format && !static_RTP_PT[x].rtp_code) {
            map = x;
            break;
         }
      }
   }

   if (map < 0) {
      ast_log(LOG_WARNING, "No Dynamic RTP mapping available for format %s\n" ,ast_getformatname(format));
      ast_rwlock_unlock(&static_RTP_PT_lock);
      return;
   }

   if (format) {
      static_RTP_PT[map].asterisk_format = 1;
      ast_format_copy(&static_RTP_PT[map].format, format);
   } else {
      static_RTP_PT[map].rtp_code = rtp_code;
   }
   ast_rwlock_unlock(&static_RTP_PT_lock);
}
int ast_rtp_codecs_find_payload_code ( struct ast_rtp_codecs codecs,
int  code 
)

Search for a payload code in the ast_rtp_codecs structure.

Parameters:
codecsCodecs structure to look in
codeThe format to look for
Return values:
Numericalpayload or -1 if unable to find payload in codecs

Example usage:

 int payload = ast_rtp_codecs_payload_code(&codecs, 0);

This looks for the numerical payload for ULAW in the codecs structure.

Definition at line 773 of file rtp_engine.c.

References ao2_find, ao2_ref, OBJ_KEY, OBJ_NOLOCK, ast_rtp_payload_type::payload, ast_rtp_codecs::payloads, and type.

Referenced by bridge_p2p_rtp_write().

{
   struct ast_rtp_payload_type *type;
   int res = -1;

   /* Search the payload type in the codecs passed */
   if ((type = ao2_find(codecs->payloads, &code, OBJ_NOLOCK | OBJ_KEY)))
   {
      res = type->payload;
      ao2_ref(type, -1);
      return res;
   }

   return res;
}
struct ast_format* ast_rtp_codecs_get_payload_format ( struct ast_rtp_codecs codecs,
int  payload 
) [read]

Retrieve the actual ast_format stored on the codecs structure for a specific payload.

Parameters:
codecsCodecs structure to look in
payloadNumerical payload to look up
Return values:
pointerto format structure on success
NULLon failure
Since:
10.0

Definition at line 673 of file rtp_engine.c.

References ao2_find, ao2_ref, AST_RTP_MAX_PT, ast_rtp_payload_type::asterisk_format, format, ast_rtp_payload_type::format, OBJ_KEY, OBJ_NOLOCK, ast_rtp_codecs::payloads, and type.

Referenced by process_sdp_a_audio(), and process_sdp_a_video().

{
   struct ast_rtp_payload_type *type;
   struct ast_format *format;

   if (payload < 0 || payload >= AST_RTP_MAX_PT) {
      return NULL;
   }

   if (!(type = ao2_find(codecs->payloads, &payload, OBJ_KEY | OBJ_NOLOCK))) {
      return NULL;
   }

   format = type->asterisk_format ? &type->format : NULL;

   ao2_ref(type, -1);

   return format;
}
void ast_rtp_codecs_packetization_set ( struct ast_rtp_codecs codecs,
struct ast_rtp_instance instance,
struct ast_codec_pref prefs 
)

Set codec packetization preferences.

Parameters:
codecsCodecs structure to muck with
instanceOptionally the instance that the codecs structure belongs to
prefsCodec packetization preferences

Example usage:

This sets the packetization preferences pointed to by prefs on the codecs structure pointed to by codecs.

Since:
1.8

Definition at line 874 of file rtp_engine.c.

References ast_rtp_instance::codecs, ast_rtp_instance::engine, ast_rtp_engine::packetization_set, ast_rtp_codecs::pref, and prefs.

Referenced by __oh323_rtp_create(), check_peer_ok(), create_addr_from_peer(), gtalk_new(), jingle_enable_video(), jingle_new(), process_sdp_a_audio(), set_peer_capabilities(), start_rtp(), and transmit_response_with_sdp().

{
   codecs->pref = *prefs;

   if (instance && instance->engine->packetization_set) {
      instance->engine->packetization_set(instance, &instance->codecs.pref);
   }
}
int ast_rtp_codecs_payload_code ( struct ast_rtp_codecs codecs,
int  asterisk_format,
const struct ast_format format,
int  code 
)

Retrieve a payload based on whether it is an Asterisk format and the code.

Parameters:
codecsCodecs structure to look in
asterisk_formatNon-zero if the given Asterisk format is present
formatAsterisk format to look for
codeThe format to look for
Return values:
Numericalpayload

Example usage:

 int payload = ast_rtp_codecs_payload_code(&codecs, 1, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0), 0);

This looks for the numerical payload for ULAW in the codecs structure.

Since:
1.8

Definition at line 742 of file rtp_engine.c.

References ao2_callback, ao2_ref, ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, AST_RTP_MAX_PT, ast_rwlock_rdlock, ast_rwlock_unlock, OBJ_NOLOCK, ast_rtp_payload_type::payload, ast_rtp_codecs::payloads, ast_rtp_payload_type::rtp_code, rtp_payload_type_find_format(), rtp_payload_type_find_nonast_format(), static_RTP_PT, and type.

Referenced by add_codec_to_sdp(), add_noncodec_to_sdp(), add_sdp(), add_tcodec_to_sdp(), add_vcodec_to_sdp(), ast_rtp_dtmf_begin(), ast_rtp_sendcng(), ast_rtp_write(), bridge_p2p_rtp_write(), jingle_add_payloads_to_description(), multicast_rtp_write(), and send_start_rtp().

{
   struct ast_rtp_payload_type *type;
   int i, res = -1;

   if (asterisk_format && format && (type = ao2_callback(codecs->payloads, OBJ_NOLOCK, rtp_payload_type_find_format, (void*)format))) {
      res = type->payload;
      ao2_ref(type, -1);
      return res;
   } else if (!asterisk_format && (type = ao2_callback(codecs->payloads, OBJ_NOLOCK, rtp_payload_type_find_nonast_format, (void*)&code))) {
      res = type->payload;
      ao2_ref(type, -1);
      return res;
   }

   ast_rwlock_rdlock(&static_RTP_PT_lock);
   for (i = 0; i < AST_RTP_MAX_PT; i++) {
      if (static_RTP_PT[i].asterisk_format && asterisk_format && format &&
         (ast_format_cmp(format, &static_RTP_PT[i].format) != AST_FORMAT_CMP_NOT_EQUAL)) {
         res = i;
         break;
      } else if (!static_RTP_PT[i].asterisk_format && !asterisk_format &&
         (static_RTP_PT[i].rtp_code == code)) {
         res = i;
         break;
      }
   }
   ast_rwlock_unlock(&static_RTP_PT_lock);

   return res;
}
void ast_rtp_codecs_payload_formats ( struct ast_rtp_codecs codecs,
struct ast_format_cap astformats,
int *  nonastformats 
)

Retrieve all formats that were found.

Parameters:
codecsCodecs structure to look in
astformatsA capabilities structure to put the Asterisk formats in.
nonastformatsAn integer to put the non-Asterisk formats in

Example usage:

 struct ast_format_cap *astformats = ast_format_cap_alloc_nolock()
 int nonastformats;
 ast_rtp_codecs_payload_formats(&codecs, &astformats, &nonastformats);

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.8

Definition at line 717 of file rtp_engine.c.

References ao2_callback, ast_format_cap_remove_all(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_NOLOCK, ast_rtp_codecs::payloads, rtp_payload_type_add_ast(), and rtp_payload_type_add_nonast().

Referenced by gtalk_is_answered(), gtalk_newcall(), jingle_interpret_description(), and process_sdp().

struct ast_rtp_payload_type ast_rtp_codecs_payload_lookup ( struct ast_rtp_codecs codecs,
int  payload 
) [read]

Retrieve payload information by payload.

Parameters:
codecsCodecs structure to look in
payloadNumerical payload to look up
Return values:
Payloadinformation

Example usage:

 struct ast_rtp_payload_type payload_type;
 payload_type = ast_rtp_codecs_payload_lookup(&codecs, 0);

This looks up the information for payload '0' from the codecs structure.

Since:
1.8

Definition at line 650 of file rtp_engine.c.

References ao2_find, ao2_ref, AST_RTP_MAX_PT, ast_rwlock_rdlock, ast_rwlock_unlock, ast_rtp_payload_type::asterisk_format, OBJ_KEY, OBJ_NOLOCK, ast_rtp_payload_type::payload, ast_rtp_payload_type::rtp_code, static_RTP_PT, and type.

Referenced by ast_rtp_read(), bridge_p2p_rtp_write(), process_sdp_a_audio(), and setup_rtp_connection().

{
   struct ast_rtp_payload_type result = { .asterisk_format = 0, }, *type;

   if (payload < 0 || payload >= AST_RTP_MAX_PT) {
      return result;
   }

   if ((type = ao2_find(codecs->payloads, &payload, OBJ_KEY | OBJ_NOLOCK))) {
      result = *type;
      ao2_ref(type, -1);
   }

   if (!result.rtp_code && !result.asterisk_format) {
      ast_rwlock_rdlock(&static_RTP_PT_lock);
      result = static_RTP_PT[payload];
      ast_rwlock_unlock(&static_RTP_PT_lock);
   }

   return result;
}
void ast_rtp_codecs_payloads_clear ( struct ast_rtp_codecs codecs,
struct ast_rtp_instance instance 
)

Clear payload information from an RTP instance.

Parameters:
codecsThe codecs structure that payloads will be cleared from
instanceOptionally the instance that the codecs structure belongs to

Example usage:

 struct ast_rtp_codecs codecs;
 ast_rtp_codecs_payloads_clear(&codecs, NULL);

This clears the codecs structure and puts it into a pristine state.

Since:
1.8

Definition at line 451 of file rtp_engine.c.

References ast_rtp_codecs_payloads_destroy(), ast_rtp_codecs_payloads_initialize(), AST_RTP_MAX_PT, ast_rtp_instance::engine, and ast_rtp_engine::payload_set.

Referenced by gtalk_alloc(), and process_sdp().

{
   ast_rtp_codecs_payloads_destroy(codecs);

   if (instance && instance->engine && instance->engine->payload_set) {
      int i;
      for (i = 0; i < AST_RTP_MAX_PT; i++) {
         instance->engine->payload_set(instance, i, 0, NULL, 0);
      }
   }

   ast_rtp_codecs_payloads_initialize(codecs);
}
void ast_rtp_codecs_payloads_copy ( struct ast_rtp_codecs src,
struct ast_rtp_codecs dest,
struct ast_rtp_instance instance 
)

Copy payload information from one RTP instance to another.

Parameters:
srcThe source codecs structure
destThe destination codecs structure that the values from src will be copied to
instanceOptionally the instance that the dst codecs structure belongs to

Example usage:

 ast_rtp_codecs_payloads_copy(&codecs0, &codecs1, NULL);

This copies the payloads from the codecs0 structure to the codecs1 structure, overwriting any current values.

Since:
1.8

Definition at line 499 of file rtp_engine.c.

References ao2_alloc, ao2_find, ao2_link_flags, ao2_ref, ast_debug, AST_RTP_MAX_PT, ast_rtp_payload_type::asterisk_format, ast_rtp_instance::engine, ast_rtp_payload_type::format, OBJ_KEY, OBJ_NOLOCK, ast_rtp_payload_type::payload, ast_rtp_engine::payload_set, ast_rtp_codecs::payloads, ast_rtp_payload_type::rtp_code, and type.

Referenced by ast_rtp_instance_early_bridge_make_compatible(), jingle_interpret_description(), and process_sdp().

{
   int i;
   struct ast_rtp_payload_type *type;

   for (i = 0; i < AST_RTP_MAX_PT; i++) {
      struct ast_rtp_payload_type *new_type;

      if (!(type = ao2_find(src->payloads, &i, OBJ_KEY | OBJ_NOLOCK))) {
         continue;
      }

      if (!(new_type = ao2_alloc(sizeof(*new_type), NULL))) {
         continue;
      }

      ast_debug(2, "Copying payload %d from %p to %p\n", i, src, dest);

      new_type->payload = i;
      *new_type = *type;

      ao2_link_flags(dest->payloads, new_type, OBJ_NOLOCK);

      ao2_ref(new_type, -1);

      if (instance && instance->engine && instance->engine->payload_set) {
         instance->engine->payload_set(instance, i, type->asterisk_format, &type->format, type->rtp_code);
      }

      ao2_ref(type, -1);
   }
}
void ast_rtp_codecs_payloads_default ( struct ast_rtp_codecs codecs,
struct ast_rtp_instance instance 
)

Set payload information on an RTP instance to the default.

Parameters:
codecsThe codecs structure to set defaults on
instanceOptionally the instance that the codecs structure belongs to

Example usage:

 struct ast_rtp_codecs codecs;
 ast_rtp_codecs_payloads_default(&codecs, NULL);

This sets the default payloads on the codecs structure.

Since:
1.8

Definition at line 465 of file rtp_engine.c.

References ao2_alloc, ao2_link_flags, ao2_ref, ast_format_copy(), AST_RTP_MAX_PT, ast_rwlock_rdlock, ast_rwlock_unlock, ast_rtp_payload_type::asterisk_format, ast_rtp_instance::engine, ast_rtp_payload_type::format, OBJ_NOLOCK, ast_rtp_payload_type::payload, ast_rtp_engine::payload_set, ast_rtp_codecs::payloads, ast_rtp_payload_type::rtp_code, static_RTP_PT, and type.

{
   int i;

   ast_rwlock_rdlock(&static_RTP_PT_lock);
   for (i = 0; i < AST_RTP_MAX_PT; i++) {
      if (static_RTP_PT[i].rtp_code || static_RTP_PT[i].asterisk_format) {
         struct ast_rtp_payload_type *type;

         if (!(type = ao2_alloc(sizeof(*type), NULL))) {
            /* Unfortunately if this occurs the payloads container will not contain all possible default payloads
             * but we err on the side of doing what we can in the hopes that the extreme memory conditions which
             * caused this to occur will go away.
             */
            continue;
         }

         type->payload = i;
         type->asterisk_format = static_RTP_PT[i].asterisk_format;
         type->rtp_code = static_RTP_PT[i].rtp_code;
         ast_format_copy(&type->format, &static_RTP_PT[i].format);

         ao2_link_flags(codecs->payloads, type, OBJ_NOLOCK);

         if (instance && instance->engine && instance->engine->payload_set) {
            instance->engine->payload_set(instance, i, type->asterisk_format, &type->format, type->rtp_code);
         }

         ao2_ref(type, -1);
      }
   }
   ast_rwlock_unlock(&static_RTP_PT_lock);
}

Destroy the contents of an RTP codecs structure (but not the structure itself)

Parameters:
codecsThe codecs structure to destroy the contents of

Example usage:

Since:
11

Definition at line 446 of file rtp_engine.c.

References ao2_cleanup, and ast_rtp_codecs::payloads.

Referenced by ast_rtp_codecs_payloads_clear(), instance_destructor(), jingle_interpret_description(), and process_sdp().

{
   ao2_cleanup(codecs->payloads);
}

Initialize an RTP codecs structure.

Parameters:
codecsThe codecs structure to initialize
Return values:
0success
-1failure

Example usage:

Since:
11

Definition at line 437 of file rtp_engine.c.

References ao2_container_alloc, AST_RTP_MAX_PT, ast_rtp_codecs::payloads, rtp_payload_type_cmp(), and rtp_payload_type_hash().

Referenced by ast_rtp_codecs_payloads_clear(), ast_rtp_instance_new(), jingle_interpret_description(), and process_sdp().

{
   if (!(codecs->payloads = ao2_container_alloc(AST_RTP_MAX_PT, rtp_payload_type_hash, rtp_payload_type_cmp))) {
      return -1;
   }

   return 0;
}
void ast_rtp_codecs_payloads_set_m_type ( struct ast_rtp_codecs codecs,
struct ast_rtp_instance instance,
int  payload 
)

Record payload information that was seen in an m= SDP line.

Parameters:
codecsThe codecs structure to muck with
instanceOptionally the instance that the codecs structure belongs to
payloadNumerical payload that was seen in the m= SDP line

Example usage:

This records that the numerical payload '0' was seen in the codecs structure.

Since:
1.8

Definition at line 532 of file rtp_engine.c.

References ao2_alloc, ao2_find, ao2_link_flags, ao2_ref, ast_debug, ast_format_copy(), AST_RTP_MAX_PT, ast_rwlock_rdlock, ast_rwlock_unlock, ast_rtp_payload_type::asterisk_format, ast_rtp_instance::engine, ast_rtp_payload_type::format, OBJ_KEY, OBJ_NOLOCK, ast_rtp_payload_type::payload, ast_rtp_engine::payload_set, ast_rtp_codecs::payloads, ast_rtp_payload_type::rtp_code, static_RTP_PT, and type.

Referenced by gtalk_is_answered(), gtalk_newcall(), jingle_interpret_description(), jingle_newcall(), and process_sdp().

{
   struct ast_rtp_payload_type *type;

   ast_rwlock_rdlock(&static_RTP_PT_lock);

   if (payload < 0 || payload >= AST_RTP_MAX_PT) {
      ast_rwlock_unlock(&static_RTP_PT_lock);
      return;
   }

   if (!(type = ao2_find(codecs->payloads, &payload, OBJ_KEY | OBJ_NOLOCK))) {
      if (!(type = ao2_alloc(sizeof(*type), NULL))) {
         ast_rwlock_unlock(&static_RTP_PT_lock);
         return;
      }
      type->payload = payload;
      ao2_link_flags(codecs->payloads, type, OBJ_NOLOCK);
   }

   type->asterisk_format = static_RTP_PT[payload].asterisk_format;
   type->rtp_code = static_RTP_PT[payload].rtp_code;
   type->payload = payload;
   ast_format_copy(&type->format, &static_RTP_PT[payload].format);

   ast_debug(1, "Setting payload %d based on m type on %p\n", payload, codecs);

   if (instance && instance->engine && instance->engine->payload_set) {
      instance->engine->payload_set(instance, payload, type->asterisk_format, &type->format, type->rtp_code);
   }

   ao2_ref(type, -1);

   ast_rwlock_unlock(&static_RTP_PT_lock);
}
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 
)

Record payload information that was seen in an a=rtpmap: SDP line.

Parameters:
codecsThe codecs structure to muck with
instanceOptionally the instance that the codecs structure belongs to
payloadNumerical payload that was seen in the a=rtpmap: SDP line
mimetypeThe string mime type that was seen
mimesubtypeThe strin mime sub type that was seen
optionsOptional options that may change the behavior of this specific payload
Return values:
0success
-1failure, invalid payload numbe
-2failure, unknown mimetype

Example usage:

 ast_rtp_codecs_payloads_set_rtpmap_type(&codecs, NULL, 0, "audio", "PCMU", 0);

This records that the numerical payload '0' was seen with mime type 'audio' and sub mime type 'PCMU' in the codecs structure.

Since:
1.8

Definition at line 630 of file rtp_engine.c.

References ast_rtp_codecs_payloads_set_rtpmap_type_rate().

Referenced by __oh323_rtp_create(), gtalk_is_answered(), gtalk_newcall(), jingle_interpret_description(), jingle_newcall(), process_sdp(), set_dtmf_payload(), and setup_rtp_connection().

{
   return ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, instance, payload, mimetype, mimesubtype, options, 0);
}
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 
)

Set payload type to a known MIME media type for a codec with a specific sample rate.

Parameters:
codecsRTP structure to modify
instanceOptionally the instance that the codecs structure belongs to
ptPayload type entry to modify
mimetypetop-level MIME type of media stream (typically "audio", "video", "text", etc.)
mimesubtypeMIME subtype of media stream (typically a codec name)
optionsZero or more flags from the ast_rtp_options enum
sample_rateThe 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.

Return values:
0on success
-1if the payload type is out of range
-2if the mimeType/mimeSubtype combination was not found
Since:
1.8

Definition at line 568 of file rtp_engine.c.

References ao2_alloc, ao2_find, ao2_link_flags, ao2_ref, AST_FORMAT_G726, AST_FORMAT_G726_AAL2, ast_format_set(), AST_RTP_MAX_PT, ast_rtp_mime_types, AST_RTP_OPT_G726_NONSTANDARD, ast_rwlock_rdlock, ast_rwlock_unlock, ast_rtp_payload_type::asterisk_format, ast_rtp_instance::engine, ast_rtp_payload_type::format, ast_format::id, mime_types_len, OBJ_KEY, OBJ_NOLOCK, ast_rtp_payload_type::payload, ast_rtp_engine::payload_set, ast_rtp_mime_type::payload_type, ast_rtp_codecs::payloads, ast_rtp_payload_type::rtp_code, ast_rtp_mime_type::sample_rate, ast_rtp_mime_type::subtype, type, and ast_rtp_mime_type::type.

Referenced by ast_rtp_codecs_payloads_set_rtpmap_type(), jingle_interpret_description(), process_sdp_a_audio(), process_sdp_a_text(), and process_sdp_a_video().

{
   unsigned int i;
   int found = 0;

   if (pt < 0 || pt >= AST_RTP_MAX_PT)
      return -1; /* bogus payload type */

   ast_rwlock_rdlock(&mime_types_lock);
   for (i = 0; i < mime_types_len; ++i) {
      const struct ast_rtp_mime_type *t = &ast_rtp_mime_types[i];
      struct ast_rtp_payload_type *type;

      if (strcasecmp(mimesubtype, t->subtype)) {
         continue;
      }

      if (strcasecmp(mimetype, t->type)) {
         continue;
      }

      /* if both sample rates have been supplied, and they don't match,
       * then this not a match; if one has not been supplied, then the
       * rates are not compared */
      if (sample_rate && t->sample_rate &&
          (sample_rate != t->sample_rate)) {
         continue;
      }

      found = 1;

      if (!(type = ao2_find(codecs->payloads, &pt, OBJ_KEY | OBJ_NOLOCK))) {
         if (!(type = ao2_alloc(sizeof(*type), NULL))) {
            continue;
         }
         type->payload = pt;
         ao2_link_flags(codecs->payloads, type, OBJ_NOLOCK);
      }

      *type = t->payload_type;
      type->payload = pt;

      if ((t->payload_type.format.id == AST_FORMAT_G726) && t->payload_type.asterisk_format && (options & AST_RTP_OPT_G726_NONSTANDARD)) {
         ast_format_set(&type->format, AST_FORMAT_G726_AAL2, 0);
      }

      if (instance && instance->engine && instance->engine->payload_set) {
         instance->engine->payload_set(instance, pt, type->asterisk_format, &type->format, type->rtp_code);
      }

      ao2_ref(type, -1);

      break;
   }
   ast_rwlock_unlock(&mime_types_lock);

   return (found ? 0 : -2);
}
void ast_rtp_codecs_payloads_unset ( struct ast_rtp_codecs codecs,
struct ast_rtp_instance instance,
int  payload 
)

Remove payload information.

Parameters:
codecsThe codecs structure to muck with
instanceOptionally the instance that the codecs structure belongs to
payloadNumerical payload to unset

Example usage:

 ast_rtp_codecs_payloads_unset(&codecs, NULL, 0);

This clears the payload '0' from the codecs structure. It will be as if it was never set.

Since:
1.8

Definition at line 635 of file rtp_engine.c.

References ao2_find, ast_debug, AST_RTP_MAX_PT, ast_rtp_instance::engine, OBJ_KEY, OBJ_NODATA, OBJ_NOLOCK, OBJ_UNLINK, ast_rtp_engine::payload_set, and ast_rtp_codecs::payloads.

Referenced by process_sdp_a_audio(), and process_sdp_a_video().

{
   if (payload < 0 || payload >= AST_RTP_MAX_PT) {
      return;
   }

   ast_debug(2, "Unsetting payload %d on %p\n", payload, codecs);

   ao2_find(codecs->payloads, &payload, OBJ_KEY | OBJ_NOLOCK | OBJ_NODATA | OBJ_UNLINK);

   if (instance && instance->engine && instance->engine->payload_set) {
      instance->engine->payload_set(instance, payload, 0, NULL, 0);
   }
}
void ast_rtp_dtls_cfg_copy ( const struct ast_rtp_dtls_cfg src_cfg,
struct ast_rtp_dtls_cfg dst_cfg 
)

Copy contents of a DTLS configuration structure.

Parameters:
src_cfgsource DTLS configuration structure
dst_cfgdestination DTLS configuration structure

Definition at line 2147 of file rtp_engine.c.

References ast_strdup, ast_rtp_dtls_cfg::cafile, ast_rtp_dtls_cfg::capath, ast_rtp_dtls_cfg::certfile, ast_rtp_dtls_cfg::cipher, ast_rtp_dtls_cfg::default_setup, ast_rtp_dtls_cfg::enabled, ast_rtp_dtls_cfg::pvtfile, ast_rtp_dtls_cfg::rekey, ast_rtp_dtls_cfg::suite, and ast_rtp_dtls_cfg::verify.

Referenced by check_peer_ok(), and create_addr_from_peer().

{
   dst_cfg->enabled = src_cfg->enabled;
   dst_cfg->verify = src_cfg->verify;
   dst_cfg->rekey = src_cfg->rekey;
   dst_cfg->suite = src_cfg->suite;
   dst_cfg->certfile = ast_strdup(src_cfg->certfile);
   dst_cfg->pvtfile = ast_strdup(src_cfg->pvtfile);
   dst_cfg->cipher = ast_strdup(src_cfg->cipher);
   dst_cfg->cafile = ast_strdup(src_cfg->cafile);
   dst_cfg->capath = ast_strdup(src_cfg->capath);
   dst_cfg->default_setup = src_cfg->default_setup;
}
void ast_rtp_dtls_cfg_free ( struct ast_rtp_dtls_cfg dtls_cfg)

Free contents of a DTLS configuration structure.

Parameters:
dtls_cfga DTLS configuration structure

Definition at line 2161 of file rtp_engine.c.

References ast_free, ast_rtp_dtls_cfg::cafile, ast_rtp_dtls_cfg::capath, ast_rtp_dtls_cfg::certfile, ast_rtp_dtls_cfg::cipher, and ast_rtp_dtls_cfg::pvtfile.

Referenced by __sip_destroy(), and sip_destroy_peer().

{
   ast_free(dtls_cfg->certfile);
   ast_free(dtls_cfg->pvtfile);
   ast_free(dtls_cfg->cipher);
   ast_free(dtls_cfg->cafile);
   ast_free(dtls_cfg->capath);
}
int ast_rtp_dtls_cfg_parse ( struct ast_rtp_dtls_cfg dtls_cfg,
const char *  name,
const char *  value 
)

Parse DTLS related configuration options.

Parameters:
dtls_cfga DTLS configuration structure
namename of the configuration option
valuevalue of the configuration option
Return values:
0if handled
-1if not handled

Definition at line 2107 of file rtp_engine.c.

References ast_free, AST_RTP_DTLS_SETUP_ACTIVE, AST_RTP_DTLS_SETUP_ACTPASS, AST_RTP_DTLS_SETUP_PASSIVE, ast_strdup, ast_true(), ast_rtp_dtls_cfg::cafile, ast_rtp_dtls_cfg::capath, ast_rtp_dtls_cfg::certfile, ast_rtp_dtls_cfg::cipher, ast_rtp_dtls_cfg::default_setup, ast_rtp_dtls_cfg::enabled, ast_rtp_dtls_cfg::pvtfile, ast_rtp_dtls_cfg::rekey, and ast_rtp_dtls_cfg::verify.

Referenced by build_peer().

{
   if (!strcasecmp(name, "dtlsenable")) {
      dtls_cfg->enabled = ast_true(value) ? 1 : 0;
   } else if (!strcasecmp(name, "dtlsverify")) {
      dtls_cfg->verify = ast_true(value) ? 1 : 0;
   } else if (!strcasecmp(name, "dtlsrekey")) {
      if (sscanf(value, "%30u", &dtls_cfg->rekey) != 1) {
         return -1;
      }
   } else if (!strcasecmp(name, "dtlscertfile")) {
      ast_free(dtls_cfg->certfile);
      dtls_cfg->certfile = ast_strdup(value);
   } else if (!strcasecmp(name, "dtlsprivatekey")) {
      ast_free(dtls_cfg->pvtfile);
      dtls_cfg->pvtfile = ast_strdup(value);
   } else if (!strcasecmp(name, "dtlscipher")) {
      ast_free(dtls_cfg->cipher);
      dtls_cfg->cipher = ast_strdup(value);
   } else if (!strcasecmp(name, "dtlscafile")) {
      ast_free(dtls_cfg->cafile);
      dtls_cfg->cafile = ast_strdup(value);
   } else if (!strcasecmp(name, "dtlscapath") || !strcasecmp(name, "dtlscadir")) {
      ast_free(dtls_cfg->capath);
      dtls_cfg->capath = ast_strdup(value);
   } else if (!strcasecmp(name, "dtlssetup")) {
      if (!strcasecmp(value, "active")) {
         dtls_cfg->default_setup = AST_RTP_DTLS_SETUP_ACTIVE;
      } else if (!strcasecmp(value, "passive")) {
         dtls_cfg->default_setup = AST_RTP_DTLS_SETUP_PASSIVE;
      } else if (!strcasecmp(value, "actpass")) {
         dtls_cfg->default_setup = AST_RTP_DTLS_SETUP_ACTPASS;
      }
   } else {
      return -1;
   }

   return 0;
}
int ast_rtp_engine_init ( void  )

initializes the rtp engine arrays

Definition at line 2267 of file rtp_engine.c.

References add_static_payload(), AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_G719, AST_FORMAT_G722, AST_FORMAT_G723_1, AST_FORMAT_G726, AST_FORMAT_G726_AAL2, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_H261, AST_FORMAT_H263, AST_FORMAT_H263_PLUS, AST_FORMAT_H264, AST_FORMAT_ILBC, AST_FORMAT_JPEG, AST_FORMAT_LPC10, AST_FORMAT_MP4_VIDEO, AST_FORMAT_PNG, ast_format_set(), AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, AST_FORMAT_SLINEAR, AST_FORMAT_SLINEAR16, AST_FORMAT_SPEEX, AST_FORMAT_SPEEX16, AST_FORMAT_SPEEX32, AST_FORMAT_T140, AST_FORMAT_T140RED, AST_FORMAT_ULAW, AST_RTP_CISCO_DTMF, AST_RTP_CN, AST_RTP_DTMF, ast_rwlock_init, and set_next_mime_type().

Referenced by main().

{
   struct ast_format tmpfmt;

   ast_rwlock_init(&mime_types_lock);
   ast_rwlock_init(&static_RTP_PT_lock);

   /* Define all the RTP mime types available */
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_G723_1, 0), 0, "audio", "G723", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_GSM, 0), 0, "audio", "GSM", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0), 0, "audio", "PCMU", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0), 0, "audio", "G711U", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0), 0, "audio", "PCMA", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0), 0, "audio", "G711A", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_G726, 0), 0, "audio", "G726-32", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_ADPCM, 0), 0, "audio", "DVI4", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0), 0, "audio", "L16", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR16, 0), 0, "audio", "L16", 16000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR16, 0), 0, "audio", "L16-256", 16000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_LPC10, 0), 0, "audio", "LPC", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_G729A, 0), 0, "audio", "G729", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_G729A, 0), 0, "audio", "G729A", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_G729A, 0), 0, "audio", "G.729", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_SPEEX, 0), 0, "audio", "speex", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_SPEEX16, 0), 0,  "audio", "speex", 16000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_SPEEX32, 0), 0,  "audio", "speex", 32000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_ILBC, 0), 0, "audio", "iLBC", 8000);
   /* this is the sample rate listed in the RTP profile for the G.722 codec, *NOT* the actual sample rate of the media stream */
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_G722, 0), 0, "audio", "G722", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_G726_AAL2, 0), 0, "audio", "AAL2-G726-32", 8000);
   set_next_mime_type(NULL, AST_RTP_DTMF, "audio", "telephone-event", 8000);
   set_next_mime_type(NULL, AST_RTP_CISCO_DTMF, "audio", "cisco-telephone-event", 8000);
   set_next_mime_type(NULL, AST_RTP_CN, "audio", "CN", 8000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_JPEG, 0), 0, "video", "JPEG", 90000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_PNG, 0), 0, "video", "PNG", 90000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_H261, 0), 0, "video", "H261", 90000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_H263, 0), 0, "video", "H263", 90000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_H263_PLUS, 0), 0, "video", "h263-1998", 90000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_H264, 0), 0, "video", "H264", 90000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_MP4_VIDEO, 0), 0, "video", "MP4V-ES", 90000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_T140RED, 0), 0, "text", "RED", 1000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_T140, 0), 0, "text", "T140", 1000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_SIREN7, 0), 0, "audio", "G7221", 16000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_SIREN14, 0), 0, "audio", "G7221", 32000);
   set_next_mime_type(ast_format_set(&tmpfmt, AST_FORMAT_G719, 0), 0, "audio", "G719", 48000);

   /* Define the static rtp payload mappings */
   add_static_payload(0, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0), 0);
   #ifdef USE_DEPRECATED_G726
   add_static_payload(2, ast_format_set(&tmpfmt, AST_FORMAT_G726, 0), 0);/* Technically this is G.721, but if Cisco can do it, so can we... */
   #endif
   add_static_payload(3, ast_format_set(&tmpfmt, AST_FORMAT_GSM, 0), 0);
   add_static_payload(4, ast_format_set(&tmpfmt, AST_FORMAT_G723_1, 0), 0);
   add_static_payload(5, ast_format_set(&tmpfmt, AST_FORMAT_ADPCM, 0), 0);/* 8 kHz */
   add_static_payload(6, ast_format_set(&tmpfmt, AST_FORMAT_ADPCM, 0), 0); /* 16 kHz */
   add_static_payload(7, ast_format_set(&tmpfmt, AST_FORMAT_LPC10, 0), 0);
   add_static_payload(8, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0), 0);
   add_static_payload(9, ast_format_set(&tmpfmt, AST_FORMAT_G722, 0), 0);
   add_static_payload(10, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0), 0); /* 2 channels */
   add_static_payload(11, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0), 0); /* 1 channel */
   add_static_payload(13, NULL, AST_RTP_CN);
   add_static_payload(16, ast_format_set(&tmpfmt, AST_FORMAT_ADPCM, 0), 0); /* 11.025 kHz */
   add_static_payload(17, ast_format_set(&tmpfmt, AST_FORMAT_ADPCM, 0), 0); /* 22.050 kHz */
   add_static_payload(18, ast_format_set(&tmpfmt, AST_FORMAT_G729A, 0), 0);
   add_static_payload(19, NULL, AST_RTP_CN);         /* Also used for CN */
   add_static_payload(26, ast_format_set(&tmpfmt, AST_FORMAT_JPEG, 0), 0);
   add_static_payload(31, ast_format_set(&tmpfmt, AST_FORMAT_H261, 0), 0);
   add_static_payload(34, ast_format_set(&tmpfmt, AST_FORMAT_H263, 0), 0);
   add_static_payload(97, ast_format_set(&tmpfmt, AST_FORMAT_ILBC, 0), 0);
   add_static_payload(98, ast_format_set(&tmpfmt, AST_FORMAT_H263_PLUS, 0), 0);
   add_static_payload(99, ast_format_set(&tmpfmt, AST_FORMAT_H264, 0), 0);
   add_static_payload(101, NULL, AST_RTP_DTMF);
   add_static_payload(102, ast_format_set(&tmpfmt, AST_FORMAT_SIREN7, 0), 0);
   add_static_payload(103, ast_format_set(&tmpfmt, AST_FORMAT_H263_PLUS, 0), 0);
   add_static_payload(104, ast_format_set(&tmpfmt, AST_FORMAT_MP4_VIDEO, 0), 0);
   add_static_payload(105, ast_format_set(&tmpfmt, AST_FORMAT_T140RED, 0), 0);   /* Real time text chat (with redundancy encoding) */
   add_static_payload(106, ast_format_set(&tmpfmt, AST_FORMAT_T140, 0), 0);     /* Real time text chat */
   add_static_payload(110, ast_format_set(&tmpfmt, AST_FORMAT_SPEEX, 0), 0);
   add_static_payload(111, ast_format_set(&tmpfmt, AST_FORMAT_G726, 0), 0);
   add_static_payload(112, ast_format_set(&tmpfmt, AST_FORMAT_G726_AAL2, 0), 0);
   add_static_payload(115, ast_format_set(&tmpfmt, AST_FORMAT_SIREN14, 0), 0);
   add_static_payload(116, ast_format_set(&tmpfmt, AST_FORMAT_G719, 0), 0);
   add_static_payload(117, ast_format_set(&tmpfmt, AST_FORMAT_SPEEX16, 0), 0);
   add_static_payload(118, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR16, 0), 0); /* 16 Khz signed linear */
   add_static_payload(119, ast_format_set(&tmpfmt, AST_FORMAT_SPEEX32, 0), 0);
   add_static_payload(121, NULL, AST_RTP_CISCO_DTMF);   /* Must be type 121 */

   return 0;
}
int ast_rtp_engine_load_format ( const struct ast_format format)

Custom formats declared in codecs.conf at startup must be communicated to the rtp_engine so their mime type can payload number can be initialized.

Definition at line 2220 of file rtp_engine.c.

References add_static_payload(), AST_FORMAT_CELT, ast_format_rate(), AST_FORMAT_SILK, ast_format::id, and set_next_mime_type().

Referenced by ast_format_attr_reg_interface().

{
   switch (format->id) {
   case AST_FORMAT_SILK:
      set_next_mime_type(format, 0, "audio", "SILK", ast_format_rate(format));
      add_static_payload(-1, format, 0);
      break;
   case AST_FORMAT_CELT:
      set_next_mime_type(format, 0, "audio", "CELT", ast_format_rate(format));
      add_static_payload(-1, format, 0);
      break;
   default:
      break;
   }

   return 0;
}
int ast_rtp_engine_register2 ( struct ast_rtp_engine engine,
struct ast_module module 
)

Register an RTP engine.

Parameters:
engineStructure of the RTP engine to register
moduleModule that the RTP engine is part of
Return values:
0success
-1failure

Example usage:

 ast_rtp_engine_register2(&example_rtp_engine, NULL);

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.8

Definition at line 114 of file rtp_engine.c.

References ast_log(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), ast_verb, ast_rtp_engine::destroy, LOG_WARNING, ast_rtp_engine::mod, ast_rtp_engine::name, ast_rtp_engine::new, ast_rtp_engine::read, and ast_rtp_engine::write.

{
   struct ast_rtp_engine *current_engine;

   /* Perform a sanity check on the engine structure to make sure it has the basics */
   if (ast_strlen_zero(engine->name) || !engine->new || !engine->destroy || !engine->write || !engine->read) {
      ast_log(LOG_WARNING, "RTP Engine '%s' failed sanity check so it was not registered.\n", !ast_strlen_zero(engine->name) ? engine->name : "Unknown");
      return -1;
   }

   /* Link owner module to the RTP engine for reference counting purposes */
   engine->mod = module;

   AST_RWLIST_WRLOCK(&engines);

   /* Ensure that no two modules with the same name are registered at the same time */
   AST_RWLIST_TRAVERSE(&engines, current_engine, entry) {
      if (!strcmp(current_engine->name, engine->name)) {
         ast_log(LOG_WARNING, "An RTP engine with the name '%s' has already been registered.\n", engine->name);
         AST_RWLIST_UNLOCK(&engines);
         return -1;
      }
   }

   /* The engine survived our critique. Off to the list it goes to be used */
   AST_RWLIST_INSERT_TAIL(&engines, engine, entry);

   AST_RWLIST_UNLOCK(&engines);

   ast_verb(2, "Registered RTP engine '%s'\n", engine->name);

   return 0;
}
int ast_rtp_engine_register_srtp ( struct ast_srtp_res srtp_res,
struct ast_srtp_policy_res policy_res 
)

Definition at line 2037 of file rtp_engine.c.

References policy_res, and srtp_res.

Referenced by res_srtp_init().

{
   if (res_srtp || res_srtp_policy) {
      return -1;
   }
   if (!srtp_res || !policy_res) {
      return -1;
   }

   res_srtp = srtp_res;
   res_srtp_policy = policy_res;

   return 0;
}
int ast_rtp_engine_unload_format ( const struct ast_format format)

Formats requiring the use of a format attribute interface must have that interface registered in order for the rtp engine to handle it correctly. If an attribute interface is unloaded, this function must be called to notify the rtp_engine.

Definition at line 2238 of file rtp_engine.c.

References ast_format_cmp(), AST_FORMAT_CMP_EQUAL, AST_RTP_MAX_PT, ast_rtp_mime_types, ast_rwlock_unlock, ast_rwlock_wrlock, mime_types_len, and static_RTP_PT.

Referenced by ast_format_attr_unreg_interface().

{
   int x;
   int y = 0;

   ast_rwlock_wrlock(&static_RTP_PT_lock);
   /* remove everything pertaining to this format id from the lists */
   for (x = 0; x < AST_RTP_MAX_PT; x++) {
      if (ast_format_cmp(&static_RTP_PT[x].format, format) == AST_FORMAT_CMP_EQUAL) {
         memset(&static_RTP_PT[x], 0, sizeof(struct ast_rtp_payload_type));
      }
   }
   ast_rwlock_unlock(&static_RTP_PT_lock);


   ast_rwlock_wrlock(&mime_types_lock);
   /* rebuild the list skipping the items matching this id */
   for (x = 0; x < mime_types_len; x++) {
      if (ast_format_cmp(&ast_rtp_mime_types[x].payload_type.format, format) == AST_FORMAT_CMP_EQUAL) {
         continue;
      }
      ast_rtp_mime_types[y] = ast_rtp_mime_types[x];
      y++;
   }
   mime_types_len = y;
   ast_rwlock_unlock(&mime_types_lock);
   return 0;
}
int ast_rtp_engine_unregister ( struct ast_rtp_engine engine)

Unregister an RTP engine.

Parameters:
engineStructure of the RTP engine to unregister
Return values:
0success
-1failure

Example usage:

 ast_rtp_engine_unregister(&example_rtp_engine);

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.8

Definition at line 148 of file rtp_engine.c.

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, and ast_rtp_engine::name.

Referenced by load_module(), and unload_module().

{
   struct ast_rtp_engine *current_engine = NULL;

   AST_RWLIST_WRLOCK(&engines);

   if ((current_engine = AST_RWLIST_REMOVE(&engines, engine, entry))) {
      ast_verb(2, "Unregistered RTP engine '%s'\n", engine->name);
   }

   AST_RWLIST_UNLOCK(&engines);

   return current_engine ? 0 : -1;
}

Definition at line 2052 of file rtp_engine.c.

Referenced by res_srtp_shutdown().

{
   res_srtp = NULL;
   res_srtp_policy = NULL;
}
int ast_rtp_glue_register2 ( struct ast_rtp_glue glue,
struct ast_module module 
)

Register RTP glue.

Parameters:
glueThe glue to register
moduleModule that the RTP glue is part of
Return values:
0success
-1failure

Example usage:

 ast_rtp_glue_register2(&example_rtp_glue, NULL);

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.8

Definition at line 163 of file rtp_engine.c.

References ast_log(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), ast_verb, LOG_WARNING, ast_rtp_glue::mod, and ast_rtp_glue::type.

{
   struct ast_rtp_glue *current_glue = NULL;

   if (ast_strlen_zero(glue->type)) {
      return -1;
   }

   glue->mod = module;

   AST_RWLIST_WRLOCK(&glues);

   AST_RWLIST_TRAVERSE(&glues, current_glue, entry) {
      if (!strcasecmp(current_glue->type, glue->type)) {
         ast_log(LOG_WARNING, "RTP glue with the name '%s' has already been registered.\n", glue->type);
         AST_RWLIST_UNLOCK(&glues);
         return -1;
      }
   }

   AST_RWLIST_INSERT_TAIL(&glues, glue, entry);

   AST_RWLIST_UNLOCK(&glues);

   ast_verb(2, "Registered RTP glue '%s'\n", glue->type);

   return 0;
}
int ast_rtp_glue_unregister ( struct ast_rtp_glue glue)

Unregister RTP glue.

Parameters:
glueThe glue to unregister
Return values:
0success
-1failure

Example usage:

 ast_rtp_glue_unregister(&example_rtp_glue);

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.8

Definition at line 192 of file rtp_engine.c.

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, and ast_rtp_glue::type.

Referenced by load_module(), and unload_module().

{
   struct ast_rtp_glue *current_glue = NULL;

   AST_RWLIST_WRLOCK(&glues);

   if ((current_glue = AST_RWLIST_REMOVE(&glues, glue, entry))) {
      ast_verb(2, "Unregistered RTP glue '%s'\n", glue->type);
   }

   AST_RWLIST_UNLOCK(&glues);

   return current_glue ? 0 : -1;
}
int ast_rtp_instance_activate ( struct ast_rtp_instance instance)

Indicate to the RTP engine that packets are now expected to be sent/received on the RTP instance.

Parameters:
instanceThe RTP instance
Return values:
0success
-1failure

Example usage:

This tells the underlying RTP engine of instance that packets will now flow.

Since:
1.8

Definition at line 1978 of file rtp_engine.c.

References ast_rtp_engine::activate, and ast_rtp_instance::engine.

Referenced by handle_response_invite(), multicast_rtp_call(), and transmit_response_with_sdp().

{
   return instance->engine->activate ? instance->engine->activate(instance) : 0;
}
int ast_rtp_instance_add_srtp_policy ( struct ast_rtp_instance instance,
struct ast_srtp_policy remote_policy,
struct ast_srtp_policy local_policy 
)

Add or replace the SRTP policies for the given RTP instance.

Parameters:
instancethe RTP instance
remote_policythe remote endpoint's policy
local_policyour policy for this RTP instance's remote endpoint
Return values:
0Success
non-zeroFailure

Definition at line 2063 of file rtp_engine.c.

References ast_srtp_res::add_stream, ast_srtp_res::create, ast_srtp_res::replace, and ast_rtp_instance::srtp.

Referenced by dtls_srtp_setup(), and sdp_crypto_activate().

{
   int res = 0;

   if (!res_srtp) {
      return -1;
   }

   if (!instance->srtp) {
      res = res_srtp->create(&instance->srtp, instance, remote_policy);
   } else {
      res = res_srtp->replace(&instance->srtp, instance, remote_policy);
   }
   if (!res) {
      res = res_srtp->add_stream(instance->srtp, local_policy);
   }

   return res;
}
void ast_rtp_instance_available_formats ( struct ast_rtp_instance instance,
struct ast_format_cap to_endpoint,
struct ast_format_cap to_asterisk,
struct ast_format_cap result 
)

Request the formats that can be transcoded.

Parameters:
instanceThe RTP instance
to_endpointFormats being sent/received towards the endpoint
to_asteriskFormats being sent/received towards Asterisk
resultcapabilities structure to store and return supported formats in.

Example usage:

 ast_rtp_instance_available_formats(instance, to_capabilities, from_capabilities, result_capabilities);

This sees if it is possible to have ulaw communicated to the endpoint but signed linear received into Asterisk.

Since:
1.8

Definition at line 1966 of file rtp_engine.c.

References ast_format_cap_is_empty(), ast_translate_available_formats(), ast_rtp_engine::available_formats, and ast_rtp_instance::engine.

Referenced by sip_call().

{
   if (instance->engine->available_formats) {
      instance->engine->available_formats(instance, to_endpoint, to_asterisk, result);
      if (!ast_format_cap_is_empty(result)) {
         return;
      }
   }

   ast_translate_available_formats(to_endpoint, to_asterisk, result);
}
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 
)

Bridge two channels that use RTP instances.

Parameters:
c0First channel part of the bridge
c1Second channel part of the bridge
flagsBridging flags
foIf a frame needs to be passed up it is stored here
rcChannel that passed the above frame up
timeoutmsHow long the channels should be bridged for
Return values:
Bridgeresult
Note:
This should only be used by channel drivers in their technology declaration.
Since:
1.8

Definition at line 1465 of file rtp_engine.c.

References ast_rtp_glue::allow_rtp_remote, ast_rtp_glue::allow_vrtp_remote, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, ast_channel_lock, ast_channel_name(), ast_channel_rawreadformat(), ast_channel_rawwriteformat(), ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_codec_pref_getsize(), ast_debug, ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_cap_has_joint(), ast_format_cap_is_empty(), ast_getformatname_multiple(), ast_log(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_rtp_instance_dtmf_mode_get(), ast_rtp_instance_get_glue(), ast_rtp_instance_get_remote_address(), ast_sockaddr_is_ipv4_mapped(), ast_verb, ast_rtp_instance::chan, ast_rtp_instance::codecs, ast_rtp_engine::dtmf_compatible, ast_rtp_instance::engine, ast_rtp_glue::get_codec, ast_rtp_glue::get_rtp_info, ast_rtp_glue::get_vrtp_info, ast_rtp_instance::glue, ast_rtp_engine::local_bridge, local_bridge_loop(), LOG_WARNING, ast_rtp_codecs::pref, remote_bridge_loop(), ast_sockaddr::ss, type, and unref_instance_cond().

{
   struct ast_rtp_instance *instance0 = NULL, *instance1 = NULL,
         *vinstance0 = NULL, *vinstance1 = NULL,
         *tinstance0 = NULL, *tinstance1 = NULL;
   struct ast_rtp_glue *glue0, *glue1;
   struct ast_sockaddr addr1 = { {0, }, }, addr2 = { {0, }, };
   enum ast_rtp_glue_result audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID, video_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
   enum ast_rtp_glue_result audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID, video_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
   enum ast_bridge_result res = AST_BRIDGE_FAILED;
   enum ast_rtp_dtmf_mode dmode;
   struct ast_format_cap *cap0 = ast_format_cap_alloc_nolock();
   struct ast_format_cap *cap1 = ast_format_cap_alloc_nolock();
   int unlock_chans = 1;
   int read_ptime0, read_ptime1, write_ptime0, write_ptime1;

   if (!cap0 || !cap1) {
      unlock_chans = 0;
      goto done;
   }

   /* Lock both channels so we can look for the glue that binds them together */
   ast_channel_lock(c0);
   while (ast_channel_trylock(c1)) {
      ast_channel_unlock(c0);
      usleep(1);
      ast_channel_lock(c0);
   }

   /* Ensure neither channel got hungup during lock avoidance */
   if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
      ast_log(LOG_WARNING, "Got hangup while attempting to bridge '%s' and '%s'\n", ast_channel_name(c0), ast_channel_name(c1));
      goto done;
   }

   /* Grab glue that binds each channel to something using the RTP engine */
   if (!(glue0 = ast_rtp_instance_get_glue(ast_channel_tech(c0)->type)) || !(glue1 = ast_rtp_instance_get_glue(ast_channel_tech(c1)->type))) {
      ast_debug(1, "Can't find native functions for channel '%s'\n", glue0 ? ast_channel_name(c1) : ast_channel_name(c0));
      goto done;
   }

   audio_glue0_res = glue0->get_rtp_info(c0, &instance0);
   video_glue0_res = glue0->get_vrtp_info ? glue0->get_vrtp_info(c0, &vinstance0) : AST_RTP_GLUE_RESULT_FORBID;

   audio_glue1_res = glue1->get_rtp_info(c1, &instance1);
   video_glue1_res = glue1->get_vrtp_info ? glue1->get_vrtp_info(c1, &vinstance1) : AST_RTP_GLUE_RESULT_FORBID;

   /* If the channels are of the same technology, they might have limitations on remote bridging */
   if (ast_channel_tech(c0) == ast_channel_tech(c1)) {
      if (audio_glue0_res == audio_glue1_res && audio_glue1_res == AST_RTP_GLUE_RESULT_REMOTE) {
         if (glue0->allow_rtp_remote && !(glue0->allow_rtp_remote(c0, c1))) {
            /* If the allow_rtp_remote indicates that remote isn't allowed, revert to local bridge */
            audio_glue0_res = audio_glue1_res = AST_RTP_GLUE_RESULT_LOCAL;
         }
      }
      if (video_glue0_res == video_glue1_res && video_glue1_res == AST_RTP_GLUE_RESULT_REMOTE) {
         if (glue0->allow_vrtp_remote && !(glue0->allow_vrtp_remote(c0, c1))) {
            /* if the allow_vrtp_remote indicates that remote isn't allowed, revert to local bridge */
            video_glue0_res = video_glue1_res = AST_RTP_GLUE_RESULT_LOCAL;
         }
      }
   }

   /* If we are carrying video, and both sides are not going to remotely bridge... fail the native bridge */
   if (video_glue0_res != AST_RTP_GLUE_RESULT_FORBID && (audio_glue0_res != AST_RTP_GLUE_RESULT_REMOTE || video_glue0_res != AST_RTP_GLUE_RESULT_REMOTE)) {
      audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
   }
   if (video_glue1_res != AST_RTP_GLUE_RESULT_FORBID && (audio_glue1_res != AST_RTP_GLUE_RESULT_REMOTE || video_glue1_res != AST_RTP_GLUE_RESULT_REMOTE)) {
      audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
   }

   /* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
   if (audio_glue0_res == AST_RTP_GLUE_RESULT_FORBID || audio_glue1_res == AST_RTP_GLUE_RESULT_FORBID) {
      res = AST_BRIDGE_FAILED_NOWARN;
      goto done;
   }


   /* If address families differ, force a local bridge */
   ast_rtp_instance_get_remote_address(instance0, &addr1);
   ast_rtp_instance_get_remote_address(instance1, &addr2);

   if (addr1.ss.ss_family != addr2.ss.ss_family ||
      (ast_sockaddr_is_ipv4_mapped(&addr1) != ast_sockaddr_is_ipv4_mapped(&addr2))) {
      audio_glue0_res = AST_RTP_GLUE_RESULT_LOCAL;
      audio_glue1_res = AST_RTP_GLUE_RESULT_LOCAL;
   }

   /* If we need to get DTMF see if we can do it outside of the RTP stream itself */
   dmode = ast_rtp_instance_dtmf_mode_get(instance0);
   if ((flags & AST_BRIDGE_DTMF_CHANNEL_0) && dmode) {
      res = AST_BRIDGE_FAILED_NOWARN;
      goto done;
   }
   dmode = ast_rtp_instance_dtmf_mode_get(instance1);
   if ((flags & AST_BRIDGE_DTMF_CHANNEL_1) && dmode) {
      res = AST_BRIDGE_FAILED_NOWARN;
      goto done;
   }

   /* If we have gotten to a local bridge make sure that both sides have the same local bridge callback and that they are DTMF compatible */
   if ((audio_glue0_res == AST_RTP_GLUE_RESULT_LOCAL || audio_glue1_res == AST_RTP_GLUE_RESULT_LOCAL) && ((instance0->engine->local_bridge != instance1->engine->local_bridge) || (instance0->engine->dtmf_compatible && !instance0->engine->dtmf_compatible(c0, instance0, c1, instance1)))) {
      res = AST_BRIDGE_FAILED_NOWARN;
      goto done;
   }

   /* Make sure that codecs match */
   if (glue0->get_codec){
      glue0->get_codec(c0, cap0);
   }
   if (glue1->get_codec) {
      glue1->get_codec(c1, cap1);
   }
   if (!ast_format_cap_is_empty(cap0) && !ast_format_cap_is_empty(cap1) && !ast_format_cap_has_joint(cap0, cap1)) {
      char tmp0[256] = { 0, };
      char tmp1[256] = { 0, };
      ast_debug(1, "Channel codec0 = %s is not codec1 = %s, cannot native bridge in RTP.\n",
         ast_getformatname_multiple(tmp0, sizeof(tmp0), cap0),
         ast_getformatname_multiple(tmp1, sizeof(tmp1), cap1));
      res = AST_BRIDGE_FAILED_NOWARN;
      goto done;
   }

   read_ptime0 = (ast_codec_pref_getsize(&instance0->codecs.pref, ast_channel_rawreadformat(c0))).cur_ms;
   read_ptime1 = (ast_codec_pref_getsize(&instance1->codecs.pref, ast_channel_rawreadformat(c1))).cur_ms;
   write_ptime0 = (ast_codec_pref_getsize(&instance0->codecs.pref, ast_channel_rawwriteformat(c0))).cur_ms;
   write_ptime1 = (ast_codec_pref_getsize(&instance1->codecs.pref, ast_channel_rawwriteformat(c1))).cur_ms;

   if (read_ptime0 != write_ptime1 || read_ptime1 != write_ptime0) {
      ast_debug(1, "Packetization differs between RTP streams (%d != %d or %d != %d). Cannot native bridge in RTP\n",
            read_ptime0, write_ptime1, read_ptime1, write_ptime0);
      res = AST_BRIDGE_FAILED_NOWARN;
      goto done;
   }

   instance0->glue = glue0;
   instance1->glue = glue1;
   instance0->chan = c0;
   instance1->chan = c1;

   /* Depending on the end result for bridging either do a local bridge or remote bridge */
   if (audio_glue0_res == AST_RTP_GLUE_RESULT_LOCAL || audio_glue1_res == AST_RTP_GLUE_RESULT_LOCAL) {
      ast_verb(3, "Locally bridging %s and %s\n", ast_channel_name(c0), ast_channel_name(c1));
      res = local_bridge_loop(c0, c1, instance0, instance1, timeoutms, flags, fo, rc, ast_channel_tech_pvt(c0), ast_channel_tech_pvt(c1));
   } else {
      ast_verb(3, "Remotely bridging %s and %s\n", ast_channel_name(c0), ast_channel_name(c1));
      res = remote_bridge_loop(c0, c1, instance0, instance1, vinstance0, vinstance1,
            tinstance0, tinstance1, glue0, glue1, cap0, cap1, timeoutms, flags,
            fo, rc, ast_channel_tech_pvt(c0), ast_channel_tech_pvt(c1));
   }

   instance0->glue = NULL;
   instance1->glue = NULL;
   instance0->chan = NULL;
   instance1->chan = NULL;

   unlock_chans = 0;

done:
   if (unlock_chans) {
      ast_channel_unlock(c0);
      ast_channel_unlock(c1);
   }
   ast_format_cap_destroy(cap1);
   ast_format_cap_destroy(cap0);

   unref_instance_cond(&instance0);
   unref_instance_cond(&instance1);
   unref_instance_cond(&vinstance0);
   unref_instance_cond(&vinstance1);
   unref_instance_cond(&tinstance0);
   unref_instance_cond(&tinstance1);

   return res;
}
void ast_rtp_instance_change_source ( struct ast_rtp_instance instance)

Indicate a new source of audio has dropped in and the ssrc should change.

Parameters:
instanceInstance that the new media source is feeding into

Example usage:

This indicates that the source of media that is feeding the instance pointed to by instance has changed and that the marker bit should be set and the SSRC updated.

Since:
1.8

Definition at line 914 of file rtp_engine.c.

References ast_rtp_engine::change_source, and ast_rtp_instance::engine.

Referenced by jingle_indicate(), mgcp_indicate(), oh323_indicate(), sip_indicate(), skinny_indicate(), and unistim_indicate().

{
   if (instance->engine->change_source) {
      instance->engine->change_source(instance);
   }
}
int ast_rtp_instance_destroy ( struct ast_rtp_instance instance)

Destroy an RTP instance.

Parameters:
instanceThe RTP instance to destroy
Return values:
0success
-1failure

Example usage:

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.8

Definition at line 229 of file rtp_engine.c.

References ao2_ref.

Referenced by __oh323_destroy(), __sip_destroy(), cleanup_connection(), destroy_endpoint(), destroy_rtp(), gtalk_free_pvt(), jingle_free_pvt(), jingle_session_destructor(), mgcp_hangup(), multicast_rtp_hangup(), multicast_rtp_request(), oh323_alloc(), start_rtp(), unalloc_sub(), and unistim_hangup_clean().

{
   ao2_ref(instance, -1);

   return 0;
}
int ast_rtp_instance_dtmf_begin ( struct ast_rtp_instance instance,
char  digit 
)

Begin sending a DTMF digit.

Parameters:
instanceThe RTP instance to send the DTMF on
digitWhat DTMF digit to send
Return values:
0success
-1failure

Example usage:

 ast_rtp_instance_dtmf_begin(instance, '1');

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.8

Definition at line 883 of file rtp_engine.c.

References ast_rtp_engine::dtmf_begin, and ast_rtp_instance::engine.

Referenced by gtalk_digit_begin(), jingle_digit_begin(), mgcp_senddigit_begin(), oh323_digit_begin(), and sip_senddigit_begin().

{
   return instance->engine->dtmf_begin ? instance->engine->dtmf_begin(instance, digit) : -1;
}
int ast_rtp_instance_dtmf_end ( struct ast_rtp_instance instance,
char  digit 
)

Stop sending a DTMF digit.

Parameters:
instanceThe RTP instance to stop the DTMF on
digitWhat DTMF digit to stop
Return values:
0success
-1failure

Example usage:

 ast_rtp_instance_dtmf_end(instance, '1');

This stops sending the DTMF '1' on the RTP instance pointed to by instance.

Since:
1.8

Definition at line 888 of file rtp_engine.c.

References ast_rtp_engine::dtmf_end, and ast_rtp_instance::engine.

Referenced by mgcp_senddigit_end(), and oh323_digit_end().

{
   return instance->engine->dtmf_end ? instance->engine->dtmf_end(instance, digit) : -1;
}
int ast_rtp_instance_dtmf_end_with_duration ( struct ast_rtp_instance instance,
char  digit,
unsigned int  duration 
)

Definition at line 892 of file rtp_engine.c.

References ast_rtp_engine::dtmf_end_with_duration, and ast_rtp_instance::engine.

Referenced by gtalk_digit_end(), jingle_digit_end(), and sip_senddigit_end().

{
   return instance->engine->dtmf_end_with_duration ? instance->engine->dtmf_end_with_duration(instance, digit, duration) : -1;
}

Get the DTMF mode of an RTP instance.

Parameters:
instanceThe RTP instance to get the DTMF mode of
Return values:
DTMFmode

Example usage:

This gets the DTMF mode set on the RTP instance pointed to by 'instance'.

Since:
1.8

Definition at line 902 of file rtp_engine.c.

References ast_rtp_engine::dtmf_mode_get, and ast_rtp_instance::engine.

Referenced by ast_rtp_instance_bridge().

{
   return instance->engine->dtmf_mode_get ? instance->engine->dtmf_mode_get(instance) : 0;
}
int ast_rtp_instance_dtmf_mode_set ( struct ast_rtp_instance instance,
enum ast_rtp_dtmf_mode  dtmf_mode 
)

Set the DTMF mode that should be used.

Parameters:
instancethe RTP instance to set DTMF mode on
dtmf_modeThe DTMF mode that is in use
Return values:
0success
-1failure

Example usage:

This sets the RTP instance to use RFC2833 for DTMF transmission and receiving.

Since:
1.8

Definition at line 897 of file rtp_engine.c.

References ast_rtp_engine::dtmf_mode_set, and ast_rtp_instance::engine.

Referenced by enable_dsp_detect(), gtalk_alloc(), and sip_new().

{
   return (!instance->engine->dtmf_mode_set || instance->engine->dtmf_mode_set(instance, dtmf_mode)) ? -1 : 0;
}
int ast_rtp_instance_early_bridge ( struct ast_channel c0,
struct ast_channel c1 
)

Early bridge two channels that use RTP instances.

Parameters:
c0First channel part of the bridge
c1Second channel part of the bridge
Return values:
0success
-1failure
Note:
This should only be used by channel drivers in their technology declaration.
Since:
1.8

Definition at line 1732 of file rtp_engine.c.

References ast_channel_lock, ast_channel_name(), ast_channel_tech(), ast_channel_trylock, ast_channel_unlock, ast_debug, ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_cap_has_joint(), ast_log(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, ast_rtp_instance_get_glue(), ast_rtp_glue::get_codec, ast_rtp_glue::get_rtp_info, ast_rtp_glue::get_vrtp_info, LOG_WARNING, type, unref_instance_cond(), and ast_rtp_glue::update_peer.

{
   struct ast_rtp_instance *instance0 = NULL, *instance1 = NULL,
         *vinstance0 = NULL, *vinstance1 = NULL,
         *tinstance0 = NULL, *tinstance1 = NULL;
   struct ast_rtp_glue *glue0, *glue1;
   enum ast_rtp_glue_result audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID, video_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
   enum ast_rtp_glue_result audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID, video_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
   struct ast_format_cap *cap0 = ast_format_cap_alloc_nolock();
   struct ast_format_cap *cap1 = ast_format_cap_alloc_nolock();
   int res = 0;

   /* If there is no second channel just immediately bail out, we are of no use in that scenario */
   if (!c1) {
      ast_format_cap_destroy(cap0);
      ast_format_cap_destroy(cap1);
      return -1;
   }

   /* Lock both channels so we can look for the glue that binds them together */
   ast_channel_lock(c0);
   while (ast_channel_trylock(c1)) {
      ast_channel_unlock(c0);
      usleep(1);
      ast_channel_lock(c0);
   }

   if (!cap1 || !cap0) {
      goto done;
   }

   /* Grab glue that binds each channel to something using the RTP engine */
   if (!(glue0 = ast_rtp_instance_get_glue(ast_channel_tech(c0)->type)) || !(glue1 = ast_rtp_instance_get_glue(ast_channel_tech(c1)->type))) {
      ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", glue0 ? ast_channel_name(c1) : ast_channel_name(c0));
      goto done;
   }

   audio_glue0_res = glue0->get_rtp_info(c0, &instance0);
   video_glue0_res = glue0->get_vrtp_info ? glue0->get_vrtp_info(c0, &vinstance0) : AST_RTP_GLUE_RESULT_FORBID;

   audio_glue1_res = glue1->get_rtp_info(c1, &instance1);
   video_glue1_res = glue1->get_vrtp_info ? glue1->get_vrtp_info(c1, &vinstance1) : AST_RTP_GLUE_RESULT_FORBID;

   /* If we are carrying video, and both sides are not going to remotely bridge... fail the native bridge */
   if (video_glue0_res != AST_RTP_GLUE_RESULT_FORBID && (audio_glue0_res != AST_RTP_GLUE_RESULT_REMOTE || video_glue0_res != AST_RTP_GLUE_RESULT_REMOTE)) {
      audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
   }
   if (video_glue1_res != AST_RTP_GLUE_RESULT_FORBID && (audio_glue1_res != AST_RTP_GLUE_RESULT_REMOTE || video_glue1_res != AST_RTP_GLUE_RESULT_REMOTE)) {
      audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
   }
   if (audio_glue0_res == AST_RTP_GLUE_RESULT_REMOTE && (video_glue0_res == AST_RTP_GLUE_RESULT_FORBID || video_glue0_res == AST_RTP_GLUE_RESULT_REMOTE) && glue0->get_codec) {
      glue0->get_codec(c0, cap0);
   }
   if (audio_glue1_res == AST_RTP_GLUE_RESULT_REMOTE && (video_glue1_res == AST_RTP_GLUE_RESULT_FORBID || video_glue1_res == AST_RTP_GLUE_RESULT_REMOTE) && glue1->get_codec) {
      glue1->get_codec(c1, cap1);
   }

   /* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
   if (audio_glue0_res != AST_RTP_GLUE_RESULT_REMOTE || audio_glue1_res != AST_RTP_GLUE_RESULT_REMOTE) {
      goto done;
   }

   /* Make sure we have matching codecs */
   if (!ast_format_cap_has_joint(cap0, cap1)) {
      goto done;
   }

   /* Bridge media early */
   if (glue0->update_peer(c0, instance1, vinstance1, tinstance1, cap1, 0)) {
      ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n", ast_channel_name(c0), c1 ? ast_channel_name(c1) : "<unspecified>");
   }

   res = 0;

done:
   ast_channel_unlock(c0);
   ast_channel_unlock(c1);

   ast_format_cap_destroy(cap0);
   ast_format_cap_destroy(cap1);

   unref_instance_cond(&instance0);
   unref_instance_cond(&instance1);
   unref_instance_cond(&vinstance0);
   unref_instance_cond(&vinstance1);
   unref_instance_cond(&tinstance0);
   unref_instance_cond(&tinstance1);

   if (!res) {
      ast_debug(1, "Setting early bridge SDP of '%s' with that of '%s'\n", ast_channel_name(c0), c1 ? ast_channel_name(c1) : "<unspecified>");
   }

   return res;
}
void ast_rtp_instance_early_bridge_make_compatible ( struct ast_channel c_dst,
struct ast_channel c_src 
)

Make two channels compatible for early bridging.

Parameters:
c_dstDestination channel to copy to
c_srcSource channel to copy from
Since:
1.8

Definition at line 1646 of file rtp_engine.c.

References ast_channel_lock_both, ast_channel_name(), ast_channel_tech(), ast_channel_unlock, ast_debug, ast_format_cap_alloc_nolock(), ast_format_cap_destroy(), ast_format_cap_has_joint(), ast_log(), ast_rtp_codecs_payloads_copy(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_REMOTE, ast_rtp_instance_get_glue(), ast_rtp_instance::codecs, ast_rtp_glue::get_codec, ast_rtp_glue::get_rtp_info, ast_rtp_glue::get_vrtp_info, LOG_WARNING, type, unref_instance_cond(), and ast_rtp_glue::update_peer.

Referenced by dial_exec_full(), and do_forward().

{
   struct ast_rtp_instance *instance_dst = NULL, *instance_src = NULL,
      *vinstance_dst = NULL, *vinstance_src = NULL,
      *tinstance_dst = NULL, *tinstance_src = NULL;
   struct ast_rtp_glue *glue_dst, *glue_src;
   enum ast_rtp_glue_result audio_glue_dst_res = AST_RTP_GLUE_RESULT_FORBID, video_glue_dst_res = AST_RTP_GLUE_RESULT_FORBID;
   enum ast_rtp_glue_result audio_glue_src_res = AST_RTP_GLUE_RESULT_FORBID, video_glue_src_res = AST_RTP_GLUE_RESULT_FORBID;
   struct ast_format_cap *cap_dst = ast_format_cap_alloc_nolock();
   struct ast_format_cap *cap_src = ast_format_cap_alloc_nolock();

   /* Lock both channels so we can look for the glue that binds them together */
   ast_channel_lock_both(c_dst, c_src);

   if (!cap_src || !cap_dst) {
      goto done;
   }

   /* Grab glue that binds each channel to something using the RTP engine */
   if (!(glue_dst = ast_rtp_instance_get_glue(ast_channel_tech(c_dst)->type)) || !(glue_src = ast_rtp_instance_get_glue(ast_channel_tech(c_src)->type))) {
      ast_debug(1, "Can't find native functions for channel '%s'\n", glue_dst ? ast_channel_name(c_src) : ast_channel_name(c_dst));
      goto done;
   }

   audio_glue_dst_res = glue_dst->get_rtp_info(c_dst, &instance_dst);
   video_glue_dst_res = glue_dst->get_vrtp_info ? glue_dst->get_vrtp_info(c_dst, &vinstance_dst) : AST_RTP_GLUE_RESULT_FORBID;

   audio_glue_src_res = glue_src->get_rtp_info(c_src, &instance_src);
   video_glue_src_res = glue_src->get_vrtp_info ? glue_src->get_vrtp_info(c_src, &vinstance_src) : AST_RTP_GLUE_RESULT_FORBID;

   /* If we are carrying video, and both sides are not going to remotely bridge... fail the native bridge */
   if (video_glue_dst_res != AST_RTP_GLUE_RESULT_FORBID && (audio_glue_dst_res != AST_RTP_GLUE_RESULT_REMOTE || video_glue_dst_res != AST_RTP_GLUE_RESULT_REMOTE)) {
      audio_glue_dst_res = AST_RTP_GLUE_RESULT_FORBID;
   }
   if (video_glue_src_res != AST_RTP_GLUE_RESULT_FORBID && (audio_glue_src_res != AST_RTP_GLUE_RESULT_REMOTE || video_glue_src_res != AST_RTP_GLUE_RESULT_REMOTE)) {
      audio_glue_src_res = AST_RTP_GLUE_RESULT_FORBID;
   }
   if (audio_glue_dst_res == AST_RTP_GLUE_RESULT_REMOTE && (video_glue_dst_res == AST_RTP_GLUE_RESULT_FORBID || video_glue_dst_res == AST_RTP_GLUE_RESULT_REMOTE) && glue_dst->get_codec) {
      glue_dst->get_codec(c_dst, cap_dst);
   }
   if (audio_glue_src_res == AST_RTP_GLUE_RESULT_REMOTE && (video_glue_src_res == AST_RTP_GLUE_RESULT_FORBID || video_glue_src_res == AST_RTP_GLUE_RESULT_REMOTE) && glue_src->get_codec) {
      glue_src->get_codec(c_src, cap_src);
   }

   /* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
   if (audio_glue_dst_res != AST_RTP_GLUE_RESULT_REMOTE || audio_glue_src_res != AST_RTP_GLUE_RESULT_REMOTE) {
      goto done;
   }

   /* Make sure we have matching codecs */
   if (!ast_format_cap_has_joint(cap_dst, cap_src)) {
      goto done;
   }

   ast_rtp_codecs_payloads_copy(&instance_src->codecs, &instance_dst->codecs, instance_dst);

   if (vinstance_dst && vinstance_src) {
      ast_rtp_codecs_payloads_copy(&vinstance_src->codecs, &vinstance_dst->codecs, vinstance_dst);
   }
   if (tinstance_dst && tinstance_src) {
      ast_rtp_codecs_payloads_copy(&tinstance_src->codecs, &tinstance_dst->codecs, tinstance_dst);
   }

   if (glue_dst->update_peer(c_dst, instance_src, vinstance_src, tinstance_src, cap_src, 0)) {
      ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n",
         ast_channel_name(c_dst), ast_channel_name(c_src));
   } else {
      ast_debug(1, "Seeded SDP of '%s' with that of '%s'\n",
         ast_channel_name(c_dst), ast_channel_name(c_src));
   }

done:
   ast_channel_unlock(c_dst);
   ast_channel_unlock(c_src);

   ast_format_cap_destroy(cap_dst);
   ast_format_cap_destroy(cap_src);

   unref_instance_cond(&instance_dst);
   unref_instance_cond(&instance_src);
   unref_instance_cond(&vinstance_dst);
   unref_instance_cond(&vinstance_src);
   unref_instance_cond(&tinstance_dst);
   unref_instance_cond(&tinstance_src);
}
int ast_rtp_instance_fd ( struct ast_rtp_instance instance,
int  rtcp 
)

Get the file descriptor for an RTP session (or RTCP)

Parameters:
instanceInstance to get the file descriptor for
rtcpWhether to retrieve the file descriptor for RTCP or not
Return values:
fdsuccess
-1failure

Example usage:

 int rtp_fd = ast_rtp_instance_fd(instance, 0);

This retrieves the file descriptor for the socket carrying media on the instance pointed to by instance.

Since:
1.8

Definition at line 933 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::fd.

Referenced by __oh323_new(), __oh323_rtp_create(), __oh323_update_info(), gtalk_new(), jingle_enable_video(), jingle_new(), mgcp_new(), process_sdp(), sip_new(), sip_set_rtp_peer(), skinny_new(), start_rtp(), and unistim_new().

{
   return instance->engine->fd ? instance->engine->fd(instance, rtcp) : -1;
}
struct ast_rtp_glue* ast_rtp_instance_get_active_glue ( struct ast_rtp_instance instance) [read]

Get the RTP glue in use on an RTP instance.

Parameters:
instanceThe RTP instance
Return values:
pointerto the glue

Example:

This gets the RTP glue currently in use on the RTP instance pointed to by 'instance'.

Since:
1.8

Definition at line 2027 of file rtp_engine.c.

References ast_rtp_instance::glue.

{
   return instance->glue;
}
int ast_rtp_instance_get_and_cmp_local_address ( struct ast_rtp_instance instance,
struct ast_sockaddr address 
)

Get the address of the local endpoint that we are sending RTP to, comparing its address to another.

Parameters:
instanceThe instance that we want to get the local address for
addressAn initialized address that may be overwritten if the local address is different
Return values:
0address was not changed
1address was changed Example usage:
 struct ast_sockaddr address;
 int ret;
 ret = ast_rtp_instance_get_and_cmp_local_address(instance, &address);

This retrieves the current local address set on the instance pointed to by instance and puts the value into the address structure.

Since:
1.8

Definition at line 352 of file rtp_engine.c.

References ast_sockaddr_cmp(), ast_sockaddr_copy(), and ast_rtp_instance::local_address.

{
   if (ast_sockaddr_cmp(address, &instance->local_address) != 0) {
      ast_sockaddr_copy(address, &instance->local_address);
      return 1;
   }

   return 0;
}
int ast_rtp_instance_get_and_cmp_remote_address ( struct ast_rtp_instance instance,
struct ast_sockaddr address 
)

Get the address of the remote endpoint that we are sending RTP to, comparing its address to another.

Parameters:
instanceThe instance that we want to get the remote address for
addressAn initialized address that may be overwritten if the remote address is different
Return values:
0address was not changed
1address was changed Example usage:
 struct ast_sockaddr address;
 int ret;
 ret = ast_rtp_instance_get_and_cmp_remote_address(instance, &address);

This retrieves the current remote address set on the instance pointed to by instance and puts the value into the address structure.

Since:
1.8

Definition at line 369 of file rtp_engine.c.

References ast_sockaddr_cmp(), ast_sockaddr_copy(), and ast_rtp_instance::remote_address.

Referenced by sip_set_rtp_peer().

{
   if (ast_sockaddr_cmp(address, &instance->remote_address) != 0) {
      ast_sockaddr_copy(address, &instance->remote_address);
      return 1;
   }

   return 0;
}
struct ast_rtp_instance* ast_rtp_instance_get_bridged ( struct ast_rtp_instance instance) [read]

Get the other RTP instance that an instance is bridged to.

Parameters:
instanceThe RTP instance that we want
Return values:
non-NULLsuccess
NULLfailure

Example usage:

This gets the RTP instance that instance0 is bridged to.

Since:
1.8

Definition at line 1641 of file rtp_engine.c.

References ast_rtp_instance::bridged.

Referenced by ast_rtp_read(), bridge_p2p_rtp_write(), and dialog_needdestroy().

{
   return instance->bridged;
}
struct ast_channel* ast_rtp_instance_get_chan ( struct ast_rtp_instance instance) [read]

Get the channel that is associated with an RTP instance while in a bridge.

Parameters:
instanceThe RTP instance
Return values:
pointerto the channel

Example:

 struct ast_channel *chan = ast_rtp_instance_get_chan(instance);

This gets the channel associated with the RTP instance pointed to by 'instance'.

Note:
This will only return a channel while in a local or remote bridge.
Since:
1.8

Definition at line 2032 of file rtp_engine.c.

References ast_rtp_instance::chan.

{
   return instance->chan;
}
void* ast_rtp_instance_get_data ( struct ast_rtp_instance instance)

Get the data portion of an RTP instance.

Parameters:
instanceThe RTP instance we want the data portion from

Example usage:

 struct *blob = ast_rtp_instance_get_data(instance);
 ( 

This gets the data pointer on the RTP instance pointed to by 'instance'.

Since:
1.8

Definition at line 302 of file rtp_engine.c.

References ast_rtp_instance::data.

Referenced by __rtp_recvfrom(), __rtp_sendto(), ast_rtcp_read(), ast_rtcp_write(), ast_rtcp_write_rr(), ast_rtcp_write_sr(), ast_rtp_activate(), ast_rtp_alt_remote_address_set(), ast_rtp_change_source(), ast_rtp_destroy(), ast_rtp_dtls_active(), ast_rtp_dtls_get_connection(), ast_rtp_dtls_get_fingerprint(), ast_rtp_dtls_get_setup(), ast_rtp_dtls_reset(), ast_rtp_dtls_set_configuration(), ast_rtp_dtls_set_fingerprint(), ast_rtp_dtls_set_setup(), ast_rtp_dtls_stop(), ast_rtp_dtmf_begin(), ast_rtp_dtmf_continuation(), ast_rtp_dtmf_end_with_duration(), ast_rtp_dtmf_mode_get(), ast_rtp_dtmf_mode_set(), ast_rtp_fd(), ast_rtp_get_stat(), ast_rtp_local_bridge(), ast_rtp_prop_set(), ast_rtp_qos_set(), ast_rtp_raw_write(), ast_rtp_read(), ast_rtp_remote_address_set(), ast_rtp_sendcng(), ast_rtp_stop(), ast_rtp_stun_request(), ast_rtp_update_source(), ast_rtp_write(), bridge_p2p_rtp_write(), create_dtmf_frame(), dtls_srtp_renegotiate(), multicast_rtp_activate(), multicast_rtp_destroy(), multicast_rtp_write(), process_cn_rfc3389(), process_dtmf_cisco(), process_dtmf_rfc2833(), red_write(), rtp_red_buffer(), and rtp_red_init().

{
   return instance->data;
}
struct ast_rtp_engine_dtls* ast_rtp_instance_get_dtls ( struct ast_rtp_instance instance) [read]

Obtain a pointer to the DTLS support present on an RTP instance.

Parameters:
instancethe RTP instance
Return values:
DTLSsupport if present
NULLif no DTLS support available

Definition at line 2102 of file rtp_engine.c.

References ast_rtp_engine::dtls, and ast_rtp_instance::engine.

Referenced by add_dtls_to_sdp(), dialog_initialize_dtls_srtp(), get_sdp_rtp_profile(), process_crypto(), process_sdp(), and process_sdp_a_dtls().

{
   return instance->engine->dtls;
}
struct ast_rtp_engine* ast_rtp_instance_get_engine ( struct ast_rtp_instance instance) [read]

Get the RTP engine in use on an RTP instance.

Parameters:
instanceThe RTP instance
Return values:
pointerto the engine

Example usage:

 struct ast_rtp_engine *engine = ast_rtp_instance_get_engine(instance);

This gets the RTP engine currently in use on the RTP instance pointed to by 'instance'.

Since:
1.8

Definition at line 2022 of file rtp_engine.c.

References ast_rtp_instance::engine.

{
   return instance->engine;
}
void* ast_rtp_instance_get_extended_prop ( struct ast_rtp_instance instance,
int  property 
)

Get the value of an RTP instance extended property.

Parameters:
instanceThe RTP instance to get the extended property on
propertyThe extended property to get
Since:
1.8

Definition at line 393 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::extended_prop_get.

{
   if (instance->engine->extended_prop_get) {
      return instance->engine->extended_prop_get(instance, property);
   }

   return NULL;
}
struct ast_rtp_glue* ast_rtp_instance_get_glue ( const char *  type) [read]

Get the RTP glue that binds a channel to the RTP engine.

Parameters:
typeName of the glue we want
Return values:
non-NULLsuccess
NULLfailure

Example usage:

 struct ast_rtp_glue *glue = ast_rtp_instance_get_glue("Example");

This retrieves the RTP glue that has the name 'Example'.

Since:
1.8

Definition at line 938 of file rtp_engine.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, and ast_rtp_glue::type.

Referenced by ast_rtp_instance_bridge(), ast_rtp_instance_early_bridge(), ast_rtp_instance_early_bridge_make_compatible(), ast_rtp_instance_make_compatible(), and remote_bridge_loop().

{
   struct ast_rtp_glue *glue = NULL;

   AST_RWLIST_RDLOCK(&glues);

   AST_RWLIST_TRAVERSE(&glues, glue, entry) {
      if (!strcasecmp(glue->type, type)) {
         break;
      }
   }

   AST_RWLIST_UNLOCK(&glues);

   return glue;
}

Get the RTP timeout value for when an RTP instance is on hold.

Parameters:
instanceThe RTP instance
Return values:
timeoutvalue

Example usage:

 int timeout = ast_rtp_instance_get_hold_timeout(instance);

This gets the RTP hold timeout value for the RTP instance pointed to by 'instance'.

Since:
1.8

Definition at line 2012 of file rtp_engine.c.

References ast_rtp_instance::holdtimeout.

Referenced by check_rtp_timeout().

{
   return instance->holdtimeout;
}
struct ast_rtp_engine_ice* ast_rtp_instance_get_ice ( struct ast_rtp_instance instance) [read]

Obtain a pointer to the ICE support present on an RTP instance.

Parameters:
instancethe RTP instance
Return values:
ICEsupport if present
NULLif no ICE support available

Definition at line 2097 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::ice.

Referenced by add_ice_to_sdp(), dialog_initialize_rtp(), jingle_add_google_candidates_to_transport(), jingle_add_ice_udp_candidates_to_transport(), jingle_enable_video(), jingle_interpret_google_transport(), jingle_interpret_ice_udp_transport(), jingle_new(), jingle_outgoing_hook(), jingle_request(), process_sdp_a_ice(), and start_ice().

{
   return instance->engine->ice;
}

Get the RTP keepalive interval.

Parameters:
instanceThe RTP instance
Return values:
periodKeepalive interval value

Example usage:

 int interval = ast_rtp_instance_get_keepalive(instance);

This gets the RTP keepalive interval value for the RTP instance pointed to by 'instance'.

Since:
1.8

Definition at line 2017 of file rtp_engine.c.

References ast_rtp_instance::keepalive.

Referenced by check_rtp_timeout().

{
   return instance->keepalive;
}
void ast_rtp_instance_get_local_address ( struct ast_rtp_instance instance,
struct ast_sockaddr address 
)

Get the local address that we are expecting RTP on.

Parameters:
instanceThe RTP instance to get the address from
addressThe variable to store the address in

Example usage:

 struct ast_sockaddr address;
 ast_rtp_instance_get_local_address(instance, &address);

This gets the local address that we are expecting RTP on and stores it in the 'address' structure.

Since:
1.8

Definition at line 363 of file rtp_engine.c.

References ast_sockaddr_copy(), and ast_rtp_instance::local_address.

Referenced by add_sdp(), apply_directmedia_acl(), ast_rtp_prop_set(), external_rtp_create(), get_our_media_address(), gtalk_create_candidates(), handle_open_receive_channel_ack_message(), jingle_create_candidates(), multicast_send_control_packet(), oh323_set_rtp_peer(), send_start_rtp(), sip_acf_channel_read(), skinny_set_rtp_peer(), and unistim_set_rtp_peer().

{
   ast_sockaddr_copy(address, &instance->local_address);
}
int ast_rtp_instance_get_prop ( struct ast_rtp_instance instance,
enum ast_rtp_property  property 
)

Get the value of an RTP instance property.

Parameters:
instanceThe RTP instance to get the property from
propertyThe property to get
Return values:
Currentvalue of the property

Example usage:

This returns the current value of the NAT property on the instance pointed to by instance.

Since:
1.8

Definition at line 411 of file rtp_engine.c.

References ast_rtp_instance::properties.

Referenced by ast_rtcp_read(), ast_rtp_dtmf_compatible(), ast_rtp_raw_write(), ast_rtp_read(), bridge_p2p_rtp_write(), process_dtmf_cisco(), and process_dtmf_rfc2833().

{
   return instance->properties[property];
}
char* ast_rtp_instance_get_quality ( struct ast_rtp_instance instance,
enum ast_rtp_instance_stat_field  field,
char *  buf,
size_t  size 
)

Retrieve quality statistics about an RTP instance.

Parameters:
instanceInstance to get statistics on
fieldWhat quality statistic to retrieve
bufWhat buffer to put the result into
sizeSize of the above buffer
Return values:
non-NULLsuccess
NULLfailure

Example usage:

This retrieves general quality statistics and places a text representation into the buf pointed to by buf.

Since:
1.8

Definition at line 1842 of file rtp_engine.c.

References ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_ALL, AST_RTP_INSTANCE_STAT_COMBINED_JITTER, AST_RTP_INSTANCE_STAT_COMBINED_LOSS, AST_RTP_INSTANCE_STAT_COMBINED_RTT, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, ast_rtp_instance_stats::local_maxjitter, ast_rtp_instance_stats::local_maxrxploss, ast_rtp_instance_stats::local_minjitter, ast_rtp_instance_stats::local_minrxploss, ast_rtp_instance_stats::local_normdevjitter, ast_rtp_instance_stats::local_normdevrxploss, ast_rtp_instance_stats::local_ssrc, ast_rtp_instance_stats::local_stdevjitter, ast_rtp_instance_stats::local_stdevrxploss, ast_rtp_instance_stats::maxrtt, ast_rtp_instance_stats::minrtt, ast_rtp_instance_stats::normdevrtt, ast_rtp_instance_stats::remote_maxjitter, ast_rtp_instance_stats::remote_maxrxploss, ast_rtp_instance_stats::remote_minjitter, ast_rtp_instance_stats::remote_minrxploss, ast_rtp_instance_stats::remote_normdevjitter, ast_rtp_instance_stats::remote_normdevrxploss, ast_rtp_instance_stats::remote_ssrc, ast_rtp_instance_stats::remote_stdevjitter, ast_rtp_instance_stats::remote_stdevrxploss, ast_rtp_instance_stats::rtt, ast_rtp_instance_stats::rxcount, ast_rtp_instance_stats::rxjitter, ast_rtp_instance_stats::rxploss, ast_rtp_instance_stats::stdevrtt, ast_rtp_instance_stats::txcount, ast_rtp_instance_stats::txjitter, and ast_rtp_instance_stats::txploss.

Referenced by ast_rtp_instance_set_stats_vars(), handle_request_bye(), sip_acf_channel_read(), and sip_hangup().

{
   struct ast_rtp_instance_stats stats = { 0, };
   enum ast_rtp_instance_stat stat;

   /* Determine what statistics we will need to retrieve based on field passed in */
   if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY) {
      stat = AST_RTP_INSTANCE_STAT_ALL;
   } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER) {
      stat = AST_RTP_INSTANCE_STAT_COMBINED_JITTER;
   } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS) {
      stat = AST_RTP_INSTANCE_STAT_COMBINED_LOSS;
   } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT) {
      stat = AST_RTP_INSTANCE_STAT_COMBINED_RTT;
   } else {
      return NULL;
   }

   /* Attempt to actually retrieve the statistics we need to generate the quality string */
   if (ast_rtp_instance_get_stats(instance, &stats, stat)) {
      return NULL;
   }

   /* Now actually fill the buffer with the good information */
   if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY) {
      snprintf(buf, size, "ssrc=%i;themssrc=%u;lp=%u;rxjitter=%f;rxcount=%u;txjitter=%f;txcount=%u;rlp=%u;rtt=%f",
          stats.local_ssrc, stats.remote_ssrc, stats.rxploss, stats.rxjitter, stats.rxcount, stats.txjitter, stats.txcount, stats.txploss, stats.rtt);
   } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER) {
      snprintf(buf, size, "minrxjitter=%f;maxrxjitter=%f;avgrxjitter=%f;stdevrxjitter=%f;reported_minjitter=%f;reported_maxjitter=%f;reported_avgjitter=%f;reported_stdevjitter=%f;",
          stats.local_minjitter, stats.local_maxjitter, stats.local_normdevjitter, sqrt(stats.local_stdevjitter), stats.remote_minjitter, stats.remote_maxjitter, stats.remote_normdevjitter, sqrt(stats.remote_stdevjitter));
   } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS) {
      snprintf(buf, size, "minrxlost=%f;maxrxlost=%f;avgrxlost=%f;stdevrxlost=%f;reported_minlost=%f;reported_maxlost=%f;reported_avglost=%f;reported_stdevlost=%f;",
          stats.local_minrxploss, stats.local_maxrxploss, stats.local_normdevrxploss, sqrt(stats.local_stdevrxploss), stats.remote_minrxploss, stats.remote_maxrxploss, stats.remote_normdevrxploss, sqrt(stats.remote_stdevrxploss));
   } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT) {
      snprintf(buf, size, "minrtt=%f;maxrtt=%f;avgrtt=%f;stdevrtt=%f;", stats.minrtt, stats.maxrtt, stats.normdevrtt, stats.stdevrtt);
   }

   return buf;
}
void ast_rtp_instance_get_remote_address ( struct ast_rtp_instance instance,
struct ast_sockaddr address 
)

Get the address of the remote endpoint that we are sending RTP to.

Parameters:
instanceThe instance that we want to get the remote address for
addressA structure to put the address into

Example usage:

 struct ast_sockaddr address;
 ast_rtp_instance_get_remote_address(instance, &address);

This retrieves the current remote address set on the instance pointed to by instance and puts the value into the address structure.

Since:
1.8

Definition at line 380 of file rtp_engine.c.

References ast_sockaddr_copy(), and ast_rtp_instance::remote_address.

Referenced by add_sdp(), apply_directmedia_acl(), ast_rtp_dtmf_begin(), ast_rtp_dtmf_continuation(), ast_rtp_dtmf_end_with_duration(), ast_rtp_instance_bridge(), ast_rtp_raw_write(), ast_rtp_read(), ast_rtp_sendcng(), ast_rtp_write(), bridge_p2p_rtp_write(), create_dtmf_frame(), dtls_srtp_check_pending(), find_rtp_port(), gtalk_update_stun(), handle_response_invite(), jingle_interpret_ice_udp_transport(), multicast_rtp_write(), multicast_send_control_packet(), oh323_set_rtp_peer(), process_cn_rfc3389(), process_dtmf_rfc2833(), process_sdp(), remote_bridge_loop(), send_start_rtp(), sip_acf_channel_read(), skinny_set_rtp_peer(), transmit_modify_with_sdp(), and unistim_set_rtp_peer().

{
   ast_sockaddr_copy(address, &instance->remote_address);
}
struct ast_srtp* ast_rtp_instance_get_srtp ( struct ast_rtp_instance instance) [read]

Obtain the SRTP instance associated with an RTP instance.

Parameters:
instancethe RTP instance
Return values:
theSRTP instance on success
NULLif no SRTP instance exists

Definition at line 2083 of file rtp_engine.c.

References ast_rtp_instance::srtp.

Referenced by __rtp_recvfrom(), __rtp_sendto(), and ast_rtp_change_source().

{
   return instance->srtp;
}
int ast_rtp_instance_get_stats ( struct ast_rtp_instance instance,
struct ast_rtp_instance_stats stats,
enum ast_rtp_instance_stat  stat 
)

Retrieve statistics about an RTP instance.

Parameters:
instanceInstance to get statistics on
statsStructure to put results into
statWhat statistic(s) to retrieve
Return values:
0success
-1failure

Example usage:

This retrieves all statistics the underlying RTP engine supports and puts the values into the stats structure.

Since:
1.8

Definition at line 1837 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::get_stat.

Referenced by ast_rtp_instance_get_quality(), ast_srtp_unprotect(), dtls_srtp_setup(), sdp_crypto_activate(), show_chanstats_cb(), and sip_acf_channel_read().

{
   return instance->engine->get_stat ? instance->engine->get_stat(instance, stats, stat) : -1;
}
int ast_rtp_instance_get_timeout ( struct ast_rtp_instance instance)

Get the RTP timeout value.

Parameters:
instanceThe RTP instance
Return values:
timeoutvalue

Example usage:

 int timeout = ast_rtp_instance_get_timeout(instance);

This gets the RTP timeout value for the RTP instance pointed to by 'instance'.

Since:
1.8

Definition at line 2007 of file rtp_engine.c.

References ast_rtp_instance::timeout.

Referenced by check_rtp_timeout().

{
   return instance->timeout;
}
int ast_rtp_instance_make_compatible ( struct ast_channel chan,
struct ast_rtp_instance instance,
struct ast_channel peer 
)

Request that the underlying RTP engine make two RTP instances compatible with eachother.

Parameters:
chanOur own Asterisk channel
instanceThe first RTP instance
peerThe peer Asterisk channel
Return values:
0success
-1failure

Example usage:

This makes the RTP instance for 'peer' compatible with 'instance' and vice versa.

Since:
1.8

Definition at line 1926 of file rtp_engine.c.

References ao2_ref, ast_channel_lock, ast_channel_tech(), ast_channel_unlock, ast_log(), ast_rtp_instance_get_glue(), ast_rtp_instance::engine, ast_rtp_glue::get_rtp_info, LOG_ERROR, ast_rtp_engine::make_compatible, type, and ast_rtp_glue::type.

Referenced by sip_setoption().

{
   struct ast_rtp_glue *glue;
   struct ast_rtp_instance *peer_instance = NULL;
   int res = -1;

   if (!instance->engine->make_compatible) {
      return -1;
   }

   ast_channel_lock(peer);

   if (!(glue = ast_rtp_instance_get_glue(ast_channel_tech(peer)->type))) {
      ast_channel_unlock(peer);
      return -1;
   }

   glue->get_rtp_info(peer, &peer_instance);
   if (!peer_instance) {
      ast_log(LOG_ERROR, "Unable to get_rtp_info for peer type %s\n", glue->type);
      ast_channel_unlock(peer);
      return -1;
   }
   if (peer_instance->engine != instance->engine) {
      ast_log(LOG_ERROR, "Peer engine mismatch for type %s\n", glue->type);
      ast_channel_unlock(peer);
      ao2_ref(peer_instance, -1);
      return -1;
   }

   res = instance->engine->make_compatible(chan, instance, peer, peer_instance);

   ast_channel_unlock(peer);

   ao2_ref(peer_instance, -1);
   peer_instance = NULL;

   return res;
}
struct ast_rtp_instance* ast_rtp_instance_new ( const char *  engine_name,
struct ast_sched_context sched,
const struct ast_sockaddr sa,
void *  data 
) [read]

Create a new RTP instance.

Parameters:
engine_nameName of the engine to use for the RTP instance
schedScheduler context that the RTP engine may want to use
saAddress we want to bind to
dataUnique data for the engine
Return values:
non-NULLsuccess
NULLfailure

Example usage:

 struct ast_rtp_instance *instance = NULL;
 instance = ast_rtp_instance_new(NULL, sched, &sin, NULL);

This creates a new RTP instance using the default engine and asks the RTP engine to bind to the address given in the address 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.8

Definition at line 236 of file rtp_engine.c.

References ao2_alloc, ao2_ref, ast_debug, ast_log(), ast_module_ref(), ast_module_unref(), ast_rtp_codecs_payloads_initialize(), AST_RWLIST_FIRST, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_sockaddr_copy(), ast_strlen_zero(), ast_rtp_instance::codecs, ast_rtp_instance::engine, instance_destructor(), ast_rtp_instance::local_address, LOG_ERROR, ast_rtp_engine::mod, ast_rtp_engine::name, and ast_rtp_engine::new.

Referenced by __oh323_rtp_create(), dialog_initialize_rtp(), gtalk_alloc(), jingle_alloc(), jingle_enable_video(), multicast_rtp_request(), and start_rtp().

{
   struct ast_sockaddr address = {{0,}};
   struct ast_rtp_instance *instance = NULL;
   struct ast_rtp_engine *engine = NULL;

   AST_RWLIST_RDLOCK(&engines);

   /* If an engine name was specified try to use it or otherwise use the first one registered */
   if (!ast_strlen_zero(engine_name)) {
      AST_RWLIST_TRAVERSE(&engines, engine, entry) {
         if (!strcmp(engine->name, engine_name)) {
            break;
         }
      }
   } else {
      engine = AST_RWLIST_FIRST(&engines);
   }

   /* If no engine was actually found bail out now */
   if (!engine) {
      ast_log(LOG_ERROR, "No RTP engine was found. Do you have one loaded?\n");
      AST_RWLIST_UNLOCK(&engines);
      return NULL;
   }

   /* Bump up the reference count before we return so the module can not be unloaded */
   ast_module_ref(engine->mod);

   AST_RWLIST_UNLOCK(&engines);

   /* Allocate a new RTP instance */
   if (!(instance = ao2_alloc(sizeof(*instance), instance_destructor))) {
      ast_module_unref(engine->mod);
      return NULL;
   }
   instance->engine = engine;
   ast_sockaddr_copy(&instance->local_address, sa);
   ast_sockaddr_copy(&address, sa);

   if (ast_rtp_codecs_payloads_initialize(&instance->codecs)) {
      ao2_ref(instance, -1);
      return NULL;
   }

   ast_debug(1, "Using engine '%s' for RTP instance '%p'\n", engine->name, instance);

   /* And pass it off to the engine to setup */
   if (instance->engine->new(instance, sched, &address, data)) {
      ast_debug(1, "Engine '%s' failed to setup RTP instance '%p'\n", engine->name, instance);
      ao2_ref(instance, -1);
      return NULL;
   }

   ast_debug(1, "RTP instance '%p' is setup and ready to go\n", instance);

   return instance;
}
struct ast_frame* ast_rtp_instance_read ( struct ast_rtp_instance instance,
int  rtcp 
) [read]

Receive a frame over RTP.

Parameters:
instanceThe RTP instance to receive frame on
rtcpWhether to read in RTCP or not
Return values:
non-NULLsuccess
NULLfailure

Example usage:

 struct ast_frame *frame;
 frame = ast_rtp_instance_read(instance, 0);

This asks the RTP engine to read in RTP from the instance and return it as an Asterisk frame.

Since:
1.8

Definition at line 312 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::read.

Referenced by gtalk_rtp_read(), jingle_read(), jingle_rtp_read(), mgcp_rtp_read(), oh323_read(), oh323_rtp_read(), sip_rtp_read(), skinny_rtp_read(), and unistim_rtp_read().

{
   return instance->engine->read(instance, rtcp);
}
int ast_rtp_instance_sendcng ( struct ast_rtp_instance instance,
int  level 
)

Send a comfort noise packet to the RTP instance.

Parameters:
instanceThe RTP instance
levelMagnitude of the noise level
Return values:
0Success
non-zeroFailure

Definition at line 2088 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::sendcng.

Referenced by check_rtp_timeout().

{
   if (instance->engine->sendcng) {
      return instance->engine->sendcng(instance, level);
   }

   return -1;
}
int ast_rtp_instance_set_alt_remote_address ( struct ast_rtp_instance instance,
const struct ast_sockaddr address 
)

Set the address of an an alternate RTP address to receive from.

Parameters:
instanceThe RTP instance to change the address on
addressAddress to set it to
Return values:
0success
-1failure

Example usage:

This changes the alternate remote address that RTP will be sent to on instance to the address given in the sin structure.

Since:
1.8

Definition at line 338 of file rtp_engine.c.

References ast_rtp_instance::alt_remote_address, ast_rtp_engine::alt_remote_address_set, ast_sockaddr_copy(), and ast_rtp_instance::engine.

Referenced by handle_request_invite().

{
   ast_sockaddr_copy(&instance->alt_remote_address, address);

   /* oink */

   if (instance->engine->alt_remote_address_set) {
      instance->engine->alt_remote_address_set(instance, &instance->alt_remote_address);
   }

   return 0;
}
void ast_rtp_instance_set_data ( struct ast_rtp_instance instance,
void *  data 
)

Set the data portion of an RTP instance.

Parameters:
instanceThe RTP instance to manipulate
dataPointer to data

Example usage:

 ast_rtp_instance_set_data(instance, blob);

This sets the data pointer on the RTP instance pointed to by 'instance' to blob.

Since:
1.8

Definition at line 297 of file rtp_engine.c.

References ast_rtp_instance::data.

Referenced by ast_rtp_new(), and multicast_rtp_new().

{
   instance->data = data;
}
void ast_rtp_instance_set_extended_prop ( struct ast_rtp_instance instance,
int  property,
void *  value 
)

Set the value of an RTP instance extended property.

Parameters:
instanceThe RTP instance to set the extended property on
propertyThe extended property to set
valueThe value to set the extended property to
Since:
1.8

Definition at line 386 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::extended_prop_set.

{
   if (instance->engine->extended_prop_set) {
      instance->engine->extended_prop_set(instance, property, value);
   }
}
void ast_rtp_instance_set_hold_timeout ( struct ast_rtp_instance instance,
int  timeout 
)

Set the RTP timeout value for when the instance is on hold.

Parameters:
instanceThe RTP instance
timeoutValue to set the timeout to

Example usage:

This sets the RTP hold timeout value on 'instance' to be 5000.

Since:
1.8

Definition at line 1997 of file rtp_engine.c.

References ast_rtp_instance::holdtimeout, and ast_rtp_instance::timeout.

Referenced by check_rtp_timeout(), and dialog_initialize_rtp().

{
   instance->holdtimeout = timeout;
}
void ast_rtp_instance_set_keepalive ( struct ast_rtp_instance instance,
int  timeout 
)

Set the RTP keepalive interval.

Parameters:
instanceThe RTP instance
periodValue to set the keepalive interval to

Example usage:

This sets the RTP keepalive interval on 'instance' to be 5000.

Since:
1.8

Definition at line 2002 of file rtp_engine.c.

References ast_rtp_instance::keepalive.

Referenced by dialog_initialize_rtp().

{
   instance->keepalive = interval;
}
int ast_rtp_instance_set_local_address ( struct ast_rtp_instance instance,
const struct ast_sockaddr address 
)

Set the address that we are expecting to receive RTP on.

Parameters:
instanceThe RTP instance to change the address on
addressAddress to set it to
Return values:
0success
-1failure

Example usage:

This changes the local address that RTP is expected on to the address given in the sin structure.

Since:
1.8

Definition at line 317 of file rtp_engine.c.

References ast_sockaddr_copy(), and ast_rtp_instance::local_address.

Referenced by ast_rtp_new().

{
   ast_sockaddr_copy(&instance->local_address, address);
   return 0;
}
void ast_rtp_instance_set_prop ( struct ast_rtp_instance instance,
enum ast_rtp_property  property,
int  value 
)

Set the value of an RTP instance property.

Parameters:
instanceThe RTP instance to set the property on
propertyThe property to modify
valueThe value to set the property to

Example usage:

This enables the AST_RTP_PROPERTY_NAT property on the instance pointed to by instance.

Since:
1.8

Definition at line 402 of file rtp_engine.c.

References ast_rtp_instance::engine, ast_rtp_engine::prop_set, ast_rtp_instance::properties, and value.

Referenced by __oh323_rtp_create(), create_addr_from_peer(), dialog_initialize_rtp(), do_setnat(), gtalk_alloc(), handle_request_invite(), jingle_alloc(), jingle_enable_video(), oh323_rtp_read(), process_sdp(), sip_dtmfmode(), sip_set_rtp_peer(), and start_rtp().

{
   instance->properties[property] = value;

   if (instance->engine->prop_set) {
      instance->engine->prop_set(instance, property, value);
   }
}
int ast_rtp_instance_set_qos ( struct ast_rtp_instance instance,
int  tos,
int  cos,
const char *  desc 
)

Set QoS parameters on an RTP session.

Parameters:
instanceInstance to set the QoS parameters on
tosTerms of service value
cosClass of service value
descWhat is setting the QoS values
Return values:
0success
-1failure

Example usage:

 ast_rtp_instance_set_qos(instance, 0, 0, "Example");

This sets the TOS and COS values to 0 on the instance pointed to by instance.

Since:
1.8

Definition at line 921 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::qos.

Referenced by __oh323_rtp_create(), dialog_initialize_rtp(), and start_rtp().

{
   return instance->engine->qos ? instance->engine->qos(instance, tos, cos, desc) : -1;
}
int ast_rtp_instance_set_read_format ( struct ast_rtp_instance instance,
struct ast_format format 
)

Request that the underlying RTP engine provide audio frames in a specific format.

Parameters:
instanceThe RTP instance to change read format on
formatFormat that frames are wanted in
Return values:
0success
-1failure

Example usage:

This requests that the RTP engine provide audio frames in the ULAW format.

Since:
1.8

Definition at line 1916 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::set_read_format.

Referenced by sip_new(), and sip_setoption().

{
   return instance->engine->set_read_format ? instance->engine->set_read_format(instance, format) : -1;
}
int ast_rtp_instance_set_remote_address ( struct ast_rtp_instance instance,
const struct ast_sockaddr address 
)

Set the address of the remote endpoint that we are sending RTP to.

Parameters:
instanceThe RTP instance to change the address on
addressAddress to set it to
Return values:
0success
-1failure

Example usage:

This changes the remote address that RTP will be sent to on instance to the address given in the sin structure.

Since:
1.8

Definition at line 324 of file rtp_engine.c.

References ast_sockaddr_copy(), ast_rtp_instance::engine, ast_rtp_instance::remote_address, and ast_rtp_engine::remote_address_set.

Referenced by ast_rtp_read(), ast_rtp_stop(), handle_open_receive_channel_ack_message(), jingle_interpret_ice_udp_transport(), multicast_rtp_request(), process_sdp(), setup_rtp_connection(), and start_rtp().

{
   ast_sockaddr_copy(&instance->remote_address, address);

   /* moo */

   if (instance->engine->remote_address_set) {
      instance->engine->remote_address_set(instance, &instance->remote_address);
   }

   return 0;
}
void ast_rtp_instance_set_stats_vars ( struct ast_channel chan,
struct ast_rtp_instance instance 
)

Set standard statistics from an RTP instance on a channel.

Parameters:
chanChannel to set the statistics on
instanceThe RTP instance that statistics will be retrieved from

Example usage:

This retrieves standard statistics from the RTP instance rtp and sets it on the channel pointed to by chan.

Since:
1.8

Definition at line 1882 of file rtp_engine.c.

References ast_bridged_channel(), AST_MAX_USER_FIELD, ast_rtp_instance_get_quality(), AST_RTP_INSTANCE_STAT_FIELD_QUALITY, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, ast_channel::bridge, pbx_builtin_setvar_helper(), and quality.

Referenced by handle_request_bye(), and sip_hangup().

{
   char quality_buf[AST_MAX_USER_FIELD], *quality;
   struct ast_channel *bridge = ast_bridged_channel(chan);

   if ((quality = ast_rtp_instance_get_quality(instance, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
      pbx_builtin_setvar_helper(chan, "RTPAUDIOQOS", quality);
      if (bridge) {
         pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSBRIDGED", quality);
      }
   }

   if ((quality = ast_rtp_instance_get_quality(instance, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, quality_buf, sizeof(quality_buf)))) {
      pbx_builtin_setvar_helper(chan, "RTPAUDIOQOSJITTER", quality);
      if (bridge) {
         pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSJITTERBRIDGED", quality);
      }
   }

   if ((quality = ast_rtp_instance_get_quality(instance, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, quality_buf, sizeof(quality_buf)))) {
      pbx_builtin_setvar_helper(chan, "RTPAUDIOQOSLOSS", quality);
      if (bridge) {
         pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSLOSSBRIDGED", quality);
      }
   }

   if ((quality = ast_rtp_instance_get_quality(instance, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, quality_buf, sizeof(quality_buf)))) {
      pbx_builtin_setvar_helper(chan, "RTPAUDIOQOSRTT", quality);
      if (bridge) {
         pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSRTTBRIDGED", quality);
      }
   }
}
void ast_rtp_instance_set_timeout ( struct ast_rtp_instance instance,
int  timeout 
)

Set the RTP timeout value.

Parameters:
instanceThe RTP instance
timeoutValue to set the timeout to

Example usage:

 ast_rtp_instance_set_timeout(instance, 5000);

This sets the RTP timeout value on 'instance' to be 5000.

Since:
1.8

Definition at line 1992 of file rtp_engine.c.

References ast_rtp_instance::timeout.

Referenced by check_rtp_timeout(), and dialog_initialize_rtp().

{
   instance->timeout = timeout;
}
int ast_rtp_instance_set_write_format ( struct ast_rtp_instance instance,
struct ast_format format 
)

Tell underlying RTP engine that audio frames will be provided in a specific format.

Parameters:
instanceThe RTP instance to change write format on
formatFormat that frames will be provided in
Return values:
0success
-1failure

Example usage:

This tells the underlying RTP engine that audio frames will be provided to it in ULAW format.

Since:
1.8

Definition at line 1921 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::set_write_format.

Referenced by sip_new(), and sip_setoption().

{
   return instance->engine->set_write_format ? instance->engine->set_write_format(instance, format) : -1;
}
void ast_rtp_instance_stop ( struct ast_rtp_instance instance)

Stop an RTP instance.

Parameters:
instanceInstance that media is no longer going to at this time

Example usage:

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.8

Definition at line 926 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::stop.

Referenced by destroy_rtp(), jingle_session_destructor(), process_sdp(), setup_rtp_connection(), and stop_media_flows().

{
   if (instance->engine->stop) {
      instance->engine->stop(instance);
   }
}
void ast_rtp_instance_stun_request ( struct ast_rtp_instance instance,
struct ast_sockaddr suggestion,
const char *  username 
)

Request that the underlying RTP engine send a STUN BIND request.

Parameters:
instanceThe RTP instance
suggestionThe suggested destination
usernameOptionally a username for the request

Example usage:

 ast_rtp_instance_stun_request(instance, NULL, NULL);

This requests that the RTP engine send a STUN BIND request on the session pointed to by 'instance'.

Since:
1.8

Definition at line 1983 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::stun_request.

Referenced by gtalk_update_stun(), jingle_interpret_google_transport(), and jingle_update_stun().

{
   if (instance->engine->stun_request) {
      instance->engine->stun_request(instance, suggestion, username);
   }
}
void ast_rtp_instance_update_source ( struct ast_rtp_instance instance)

Indicate that the RTP marker bit should be set on an RTP stream.

Parameters:
instanceInstance that the new media source is feeding into

Example usage:

This indicates that the source of media that is feeding the instance pointed to by instance has been updated and that the marker bit should be set.

Since:
1.8

Definition at line 907 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::update_source.

Referenced by jingle_indicate(), mgcp_indicate(), oh323_indicate(), sip_answer(), sip_indicate(), sip_write(), and skinny_indicate().

{
   if (instance->engine->update_source) {
      instance->engine->update_source(instance);
   }
}
int ast_rtp_instance_write ( struct ast_rtp_instance instance,
struct ast_frame frame 
)

Send a frame out over RTP.

Parameters:
instanceThe RTP instance to send frame out on
framethe frame to send out
Return values:
0success
-1failure

Example usage:

 ast_rtp_instance_write(instance, frame);

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.8

Definition at line 307 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::write.

Referenced by gtalk_write(), jingle_write(), mgcp_write(), multicast_rtp_write(), oh323_write(), sip_write(), skinny_write(), and unistim_write().

{
   return instance->engine->write(instance, frame);
}
char* ast_rtp_lookup_mime_multiple2 ( struct ast_str buf,
struct ast_format_cap ast_format_capability,
int  rtp_capability,
const int  asterisk_format,
enum ast_rtp_options  options 
)

Convert formats into a string and put them into a buffer.

Parameters:
bufBuffer to put the mime output into
ast_format_capabilityAsterisk Formats we are looking up.
rtp_capabilityRTP codes that we are looking up
asterisk_formatNon-zero if the ast_format_capability structure is to be used, 0 if rtp_capability is to be used
optionsAdditional options that may change the result
Return values:
non-NULLsuccess
NULLfailure

Example usage:

 char buf[256] = "";
 struct ast_format tmp_fmt;
 struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
 ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0));
 ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_GSM, 0));
 char *mime = ast_rtp_lookup_mime_multiple2(&buf, sizeof(buf), cap, 0, 1, 0);
 ast_format_cap_destroy(cap);

This returns the mime values for ULAW and ALAW in the buffer pointed to by buf.

Since:
1.8

Definition at line 838 of file rtp_engine.c.

References ast_format_cap_iter_end(), ast_format_cap_iter_next(), ast_format_cap_iter_start(), ast_rtp_lookup_mime_subtype2(), AST_RTP_MAX, ast_str_append(), ast_str_buffer(), and name.

Referenced by process_sdp().

{
   int found = 0;
   const char *name;
   if (!buf) {
      return NULL;
   }


   if (asterisk_format) {
      struct ast_format tmp_fmt;
      ast_format_cap_iter_start(ast_format_capability);
      while (!ast_format_cap_iter_next(ast_format_capability, &tmp_fmt)) {
         name = ast_rtp_lookup_mime_subtype2(asterisk_format, &tmp_fmt, 0, options);
         ast_str_append(&buf, 0, "%s|", name);
         found = 1;
      }
      ast_format_cap_iter_end(ast_format_capability);

   } else {
      int x;
      ast_str_append(&buf, 0, "0x%x (", (unsigned int) rtp_capability);
      for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
         if (rtp_capability & x) {
            name = ast_rtp_lookup_mime_subtype2(asterisk_format, NULL, x, options);
            ast_str_append(&buf, 0, "%s|", name);
            found = 1;
         }
      }
   }

   ast_str_append(&buf, 0, "%s", found ? ")" : "nothing)");

   return ast_str_buffer(buf);
}
const char* ast_rtp_lookup_mime_subtype2 ( const int  asterisk_format,
struct ast_format format,
int  code,
enum ast_rtp_options  options 
)

Retrieve mime subtype information on a payload.

Parameters:
asterisk_formatNon-zero to look up using Asterisk format
formatAsterisk format to look up
codeRTP code to look up
optionsAdditional options that may change the result
Return values:
Mimesubtype success
NULLfailure

Example usage:

 const char *subtype = ast_rtp_lookup_mime_subtype2(1, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0), 0, 0);

This looks up the mime subtype for the ULAW format.

Since:
1.8

Definition at line 788 of file rtp_engine.c.

References ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, AST_FORMAT_G726_AAL2, ast_rtp_mime_types, AST_RTP_OPT_G726_NONSTANDARD, ast_rwlock_rdlock, ast_rwlock_unlock, ast_format::id, mime_types_len, ast_rtp_mime_type::payload_type, ast_rtp_payload_type::rtp_code, and ast_rtp_mime_type::subtype.

Referenced by add_codec_to_sdp(), add_noncodec_to_sdp(), add_sdp(), add_tcodec_to_sdp(), add_vcodec_to_sdp(), ast_rtp_lookup_mime_multiple2(), jingle_add_payloads_to_description(), transmit_connect(), transmit_connect_with_sdp(), transmit_modify_request(), and transmit_modify_with_sdp().

{
   int i;
   const char *res = "";

   ast_rwlock_rdlock(&mime_types_lock);
   for (i = 0; i < mime_types_len; i++) {
      if (ast_rtp_mime_types[i].payload_type.asterisk_format && asterisk_format && format &&
         (ast_format_cmp(format, &ast_rtp_mime_types[i].payload_type.format) != AST_FORMAT_CMP_NOT_EQUAL)) {
         if ((format->id == AST_FORMAT_G726_AAL2) && (options & AST_RTP_OPT_G726_NONSTANDARD)) {
            res = "G726-32";
            break;
         } else {
            res = ast_rtp_mime_types[i].subtype;
            break;
         }
      } else if (!ast_rtp_mime_types[i].payload_type.asterisk_format && !asterisk_format &&
         ast_rtp_mime_types[i].payload_type.rtp_code == code) {

         res = ast_rtp_mime_types[i].subtype;
         break;
      }
   }
   ast_rwlock_unlock(&mime_types_lock);

   return res;
}
unsigned int ast_rtp_lookup_sample_rate2 ( int  asterisk_format,
struct ast_format format,
int  code 
)

Get the sample rate associated with known RTP payload types.

Parameters:
asterisk_formatTrue if the value in format is to be used.
Anasterisk format
codefrom AST_RTP list
Returns:
the sample rate if the format was found, zero if it was not found
Since:
1.8

Definition at line 816 of file rtp_engine.c.

References ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_rtp_mime_types, ast_rwlock_rdlock, ast_rwlock_unlock, mime_types_len, ast_rtp_mime_type::payload_type, ast_rtp_payload_type::rtp_code, and ast_rtp_mime_type::sample_rate.

Referenced by add_codec_to_sdp(), add_noncodec_to_sdp(), add_tcodec_to_sdp(), add_vcodec_to_sdp(), and jingle_add_payloads_to_description().

{
   unsigned int i;
   unsigned int res = 0;

   ast_rwlock_rdlock(&mime_types_lock);
   for (i = 0; i < mime_types_len; ++i) {
      if (ast_rtp_mime_types[i].payload_type.asterisk_format && asterisk_format && format &&
         (ast_format_cmp(format, &ast_rtp_mime_types[i].payload_type.format) != AST_FORMAT_CMP_NOT_EQUAL)) {
         res = ast_rtp_mime_types[i].sample_rate;
         break;
      } else if (!ast_rtp_mime_types[i].payload_type.asterisk_format && !asterisk_format &&
         ast_rtp_mime_types[i].payload_type.rtp_code == code) {
         res = ast_rtp_mime_types[i].sample_rate;
         break;
      }
   }
   ast_rwlock_unlock(&mime_types_lock);

   return res;
}
int ast_rtp_red_buffer ( struct ast_rtp_instance instance,
struct ast_frame frame 
)

Buffer a frame in an RTP instance for RED.

Parameters:
instanceThe instance to buffer the frame on
frameFrame that we want to buffer
Return values:
0success
-1failure
Since:
1.8

Definition at line 1832 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::red_buffer.

Referenced by sip_write().

{
   return instance->engine->red_buffer ? instance->engine->red_buffer(instance, frame) : -1;
}
int ast_rtp_red_init ( struct ast_rtp_instance instance,
int  buffer_time,
int *  payloads,
int  generations 
)

Initialize RED support on an RTP instance.

Parameters:
instanceThe instance to initialize RED support on
buffer_timeHow long to buffer before sending
payloadsPayload values
generationsNumber of generations
Return values:
0success
-1failure
Since:
1.8

Definition at line 1827 of file rtp_engine.c.

References ast_rtp_instance::engine, and ast_rtp_engine::red_init.

Referenced by process_sdp().

{
   return instance->engine->red_init ? instance->engine->red_init(instance, buffer_time, payloads, generations) : -1;
}
static void instance_destructor ( void *  obj) [static]

Definition at line 207 of file rtp_engine.c.

References ast_debug, ast_module_unref(), ast_rtp_codecs_payloads_destroy(), ast_rtp_instance::codecs, ast_rtp_instance::data, ast_srtp_res::destroy, ast_rtp_engine::destroy, ast_rtp_instance::engine, ast_rtp_engine::mod, ast_rtp_engine::name, and ast_rtp_instance::srtp.

Referenced by ast_rtp_instance_new().

{
   struct ast_rtp_instance *instance = obj;

   /* Pass us off to the engine to destroy */
   if (instance->data && instance->engine->destroy(instance)) {
      ast_debug(1, "Engine '%s' failed to destroy RTP instance '%p'\n", instance->engine->name, instance);
      return;
   }

   if (instance->srtp) {
      res_srtp->destroy(instance->srtp);
   }

   ast_rtp_codecs_payloads_destroy(&instance->codecs);

   /* Drop our engine reference */
   ast_module_unref(instance->engine->mod);

   ast_debug(1, "Destroyed RTP instance '%p'\n", instance);
}
static enum ast_bridge_result local_bridge_loop ( struct ast_channel c0,
struct ast_channel c1,
struct ast_rtp_instance instance0,
struct ast_rtp_instance instance1,
int  timeoutms,
int  flags,
struct ast_frame **  fo,
struct ast_channel **  rc,
void *  pvt0,
void *  pvt1 
) [static]

Definition at line 955 of file rtp_engine.c.

References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_channel_audiohooks(), ast_channel_connected_line_macro(), ast_channel_connected_line_sub(), ast_channel_framehooks(), ast_channel_hangupcause_hash_set(), ast_channel_masq(), ast_channel_masqr(), ast_channel_monitor(), ast_channel_name(), ast_channel_rawreadformat(), ast_channel_rawwriteformat(), ast_channel_redirecting_macro(), ast_channel_redirecting_sub(), ast_channel_tech_pvt(), ast_channel_unlock, ast_check_hangup(), AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_REDIRECTING, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, ast_debug, ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_framehook_list_is_empty(), ast_frfree, ast_indicate_data(), ast_poll_channel_add(), ast_poll_channel_del(), ast_read(), ast_remaining_ms(), ast_tvnow(), ast_waitfor_n(), ast_write(), ast_rtp_instance::bridged, ast_frame::data, ast_frame::datalen, ast_rtp_instance::engine, ast_frame::frametype, ast_frame_subclass::integer, ast_rtp_engine::local_bridge, ast_frame::ptr, and ast_frame::subclass.

Referenced by ast_rtp_instance_bridge().

{
   enum ast_bridge_result res = AST_BRIDGE_FAILED;
   struct ast_channel *who = NULL, *other = NULL, *cs[3] = { NULL, };
   struct ast_frame *fr = NULL;
   struct timeval start;

   /* Start locally bridging both instances */
   if (instance0->engine->local_bridge && instance0->engine->local_bridge(instance0, instance1)) {
      ast_debug(1, "Failed to locally bridge %s to %s, backing out.\n", ast_channel_name(c0), ast_channel_name(c1));
      ast_channel_unlock(c0);
      ast_channel_unlock(c1);
      return AST_BRIDGE_FAILED_NOWARN;
   }
   if (instance1->engine->local_bridge && instance1->engine->local_bridge(instance1, instance0)) {
      ast_debug(1, "Failed to locally bridge %s to %s, backing out.\n", ast_channel_name(c1), ast_channel_name(c0));
      if (instance0->engine->local_bridge) {
         instance0->engine->local_bridge(instance0, NULL);
      }
      ast_channel_unlock(c0);
      ast_channel_unlock(c1);
      return AST_BRIDGE_FAILED_NOWARN;
   }

   ast_channel_unlock(c0);
   ast_channel_unlock(c1);

   instance0->bridged = instance1;
   instance1->bridged = instance0;

   ast_poll_channel_add(c0, c1);

   /* Hop into a loop waiting for a frame from either channel */
   cs[0] = c0;
   cs[1] = c1;
   cs[2] = NULL;
   start = ast_tvnow();
   for (;;) {
      int ms;
      /* If the underlying formats have changed force this bridge to break */
      if ((ast_format_cmp(ast_channel_rawreadformat(c0), ast_channel_rawwriteformat(c1)) == AST_FORMAT_CMP_NOT_EQUAL) ||
         (ast_format_cmp(ast_channel_rawreadformat(c1), ast_channel_rawwriteformat(c0)) == AST_FORMAT_CMP_NOT_EQUAL)) {
         ast_debug(1, "rtp-engine-local-bridge: Oooh, formats changed, backing out\n");
         res = AST_BRIDGE_FAILED_NOWARN;
         break;
      }
      /* Check if anything changed */
      if ((ast_channel_tech_pvt(c0) != pvt0) ||
          (ast_channel_tech_pvt(c1) != pvt1) ||
          (ast_channel_masq(c0) || ast_channel_masqr(c0) || ast_channel_masq(c1) || ast_channel_masqr(c1)) ||
          (ast_channel_monitor(c0) || ast_channel_audiohooks(c0) || ast_channel_monitor(c1) || ast_channel_audiohooks(c1)) ||
          (!ast_framehook_list_is_empty(ast_channel_framehooks(c0)) || !ast_framehook_list_is_empty(ast_channel_framehooks(c1)))) {
         ast_debug(1, "rtp-engine-local-bridge: Oooh, something is weird, backing out\n");
         /* If a masquerade needs to happen we have to try to read in a frame so that it actually happens. Without this we risk being called again and going into a loop */
         if ((ast_channel_masq(c0) || ast_channel_masqr(c0)) && (fr = ast_read(c0))) {
            ast_frfree(fr);
         }
         if ((ast_channel_masq(c1) || ast_channel_masqr(c1)) && (fr = ast_read(c1))) {
            ast_frfree(fr);
         }
         res = AST_BRIDGE_RETRY;
         break;
      }
      /* Wait on a channel to feed us a frame */
      ms = ast_remaining_ms(start, timeoutms);
      if (!(who = ast_waitfor_n(cs, 2, &ms))) {
         if (!ms) {
            res = AST_BRIDGE_RETRY;
            break;
         }
         ast_debug(2, "rtp-engine-local-bridge: Ooh, empty read...\n");
         if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
            break;
         }
         continue;
      }
      /* Read in frame from channel */
      fr = ast_read(who);
      other = (who == c0) ? c1 : c0;
      /* Depending on the frame we may need to break out of our bridge */
      if (!fr || ((fr->frametype == AST_FRAME_DTMF_BEGIN || fr->frametype == AST_FRAME_DTMF_END) &&
             ((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) |
             ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1)))) {
         /* Record received frame and who */
         *fo = fr;
         *rc = who;
         ast_debug(1, "rtp-engine-local-bridge: Ooh, got a %s\n", fr ? "digit" : "hangup");
         res = AST_BRIDGE_COMPLETE;
         break;
      } else if ((fr->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
         if ((fr->subclass.integer == AST_CONTROL_HOLD) ||
             (fr->subclass.integer == AST_CONTROL_UNHOLD) ||
             (fr->subclass.integer == AST_CONTROL_VIDUPDATE) ||
             (fr->subclass.integer == AST_CONTROL_SRCUPDATE) ||
             (fr->subclass.integer == AST_CONTROL_T38_PARAMETERS) ||
             (fr->subclass.integer == AST_CONTROL_UPDATE_RTP_PEER)) {
            /* If we are going on hold, then break callback mode and P2P bridging */
            if (fr->subclass.integer == AST_CONTROL_HOLD) {
               if (instance0->engine->local_bridge) {
                  instance0->engine->local_bridge(instance0, NULL);
               }
               if (instance1->engine->local_bridge) {
                  instance1->engine->local_bridge(instance1, NULL);
               }
               instance0->bridged = NULL;
               instance1->bridged = NULL;
            } else if (fr->subclass.integer == AST_CONTROL_UNHOLD) {
               if (instance0->engine->local_bridge) {
                  instance0->engine->local_bridge(instance0, instance1);
               }
               if (instance1->engine->local_bridge) {
                  instance1->engine->local_bridge(instance1, instance0);
               }
               instance0->bridged = instance1;
               instance1->bridged = instance0;
            }
            /* Since UPDATE_BRIDGE_PEER is only used by the bridging code, don't forward it */
            if (fr->subclass.integer != AST_CONTROL_UPDATE_RTP_PEER) {
               ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
            }
            ast_frfree(fr);
         } else if (fr->subclass.integer == AST_CONTROL_CONNECTED_LINE) {
            if (ast_channel_connected_line_sub(who, other, fr, 1) &&
               ast_channel_connected_line_macro(who, other, fr, other == c0, 1)) {
               ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
            }
            ast_frfree(fr);
         } else if (fr->subclass.integer == AST_CONTROL_REDIRECTING) {
            if (ast_channel_redirecting_sub(who, other, fr, 1) &&
               ast_channel_redirecting_macro(who, other, fr, other == c0, 1)) {
               ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
            }
            ast_frfree(fr);
         } else if (fr->subclass.integer == AST_CONTROL_PVT_CAUSE_CODE) {
            ast_channel_hangupcause_hash_set(other, fr->data.ptr, fr->datalen);
            ast_frfree(fr);
         } else {
            *fo = fr;
            *rc = who;
            ast_debug(1, "rtp-engine-local-bridge: Got a FRAME_CONTROL (%d) frame on channel %s\n", fr->subclass.integer, ast_channel_name(who));
            res = AST_BRIDGE_COMPLETE;
            break;
         }
      } else {
         if ((fr->frametype == AST_FRAME_DTMF_BEGIN) ||
             (fr->frametype == AST_FRAME_DTMF_END) ||
             (fr->frametype == AST_FRAME_VOICE) ||
             (fr->frametype == AST_FRAME_VIDEO) ||
             (fr->frametype == AST_FRAME_IMAGE) ||
             (fr->frametype == AST_FRAME_HTML) ||
             (fr->frametype == AST_FRAME_MODEM) ||
             (fr->frametype == AST_FRAME_TEXT)) {
            ast_write(other, fr);
         }

         ast_frfree(fr);
      }
      /* Swap priority */
      cs[2] = cs[0];
      cs[0] = cs[1];
      cs[1] = cs[2];
   }

   /* Stop locally bridging both instances */
   if (instance0->engine->local_bridge) {
      instance0->engine->local_bridge(instance0, NULL);
   }
   if (instance1->engine->local_bridge) {
      instance1->engine->local_bridge(instance1, NULL);
   }

   instance0->bridged = NULL;
   instance1->bridged = NULL;

   ast_poll_channel_del(c0, c1);

   return res;
}
static enum ast_bridge_result remote_bridge_loop ( struct ast_channel c0,
struct ast_channel c1,
struct ast_rtp_instance instance0,
struct ast_rtp_instance instance1,
struct ast_rtp_instance vinstance0,
struct ast_rtp_instance vinstance1,
struct ast_rtp_instance tinstance0,
struct ast_rtp_instance tinstance1,
struct ast_rtp_glue glue0,
struct ast_rtp_glue glue1,
struct ast_format_cap cap0,
struct ast_format_cap cap1,
int  timeoutms,
int  flags,
struct ast_frame **  fo,
struct ast_channel **  rc,
void *  pvt0,
void *  pvt1 
) [static]

Definition at line 1134 of file rtp_engine.c.

References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_channel_audiohooks(), ast_channel_connected_line_macro(), ast_channel_connected_line_sub(), ast_channel_flags(), ast_channel_framehooks(), ast_channel_hangupcause_hash_set(), ast_channel_lock, ast_channel_masq(), ast_channel_masqr(), ast_channel_monitor(), ast_channel_name(), ast_channel_redirecting_macro(), ast_channel_redirecting_sub(), ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_unlock, ast_check_hangup(), AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_REDIRECTING, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, ast_debug, AST_FLAG_ZOMBIE, ast_format_cap_append(), ast_format_cap_copy(), ast_format_cap_destroy(), ast_format_cap_dup(), ast_format_cap_identical(), ast_format_cap_remove_all(), AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_framehook_list_is_empty(), ast_frfree, ast_getformatname_multiple(), ast_indicate_data(), ast_log(), ast_poll_channel_add(), ast_poll_channel_del(), ast_read(), ast_remaining_ms(), ast_rtp_instance_get_glue(), ast_rtp_instance_get_remote_address(), ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_test_flag, ast_tvnow(), ast_waitfor_n(), ast_write(), ast_rtp_instance::bridged, ast_frame::data, ast_frame::datalen, ast_frame::frametype, ast_rtp_glue::get_codec, ast_frame_subclass::integer, LOG_WARNING, ast_frame::ptr, ast_frame::subclass, tmp_buf, type, and ast_rtp_glue::update_peer.

Referenced by ast_rtp_instance_bridge().

{
   enum ast_bridge_result res = AST_BRIDGE_FAILED;
   struct ast_channel *who = NULL, *other = NULL, *cs[3] = { NULL, };
   struct ast_format_cap *oldcap0 = ast_format_cap_dup(cap0);
   struct ast_format_cap *oldcap1 = ast_format_cap_dup(cap1);
   struct ast_sockaddr ac1 = {{0,}}, vac1 = {{0,}}, tac1 = {{0,}}, ac0 = {{0,}}, vac0 = {{0,}}, tac0 = {{0,}};
   struct ast_sockaddr t1 = {{0,}}, vt1 = {{0,}}, tt1 = {{0,}}, t0 = {{0,}}, vt0 = {{0,}}, tt0 = {{0,}};
   struct ast_frame *fr = NULL;
   struct timeval start;

   if (!oldcap0 || !oldcap1) {
      ast_channel_unlock(c0);
      ast_channel_unlock(c1);
      goto remote_bridge_cleanup;
   }
   /* Test the first channel */
   if (!(glue0->update_peer(c0, instance1, vinstance1, tinstance1, cap1, 0))) {
      ast_rtp_instance_get_remote_address(instance1, &ac1);
      if (vinstance1) {
         ast_rtp_instance_get_remote_address(vinstance1, &vac1);
      }
      if (tinstance1) {
         ast_rtp_instance_get_remote_address(tinstance1, &tac1);
      }
   } else {
      ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", ast_channel_name(c0), ast_channel_name(c1));
   }

   /* Test the second channel */
   if (!(glue1->update_peer(c1, instance0, vinstance0, tinstance0, cap0, 0))) {
      ast_rtp_instance_get_remote_address(instance0, &ac0);
      if (vinstance0) {
         ast_rtp_instance_get_remote_address(instance0, &vac0);
      }
      if (tinstance0) {
         ast_rtp_instance_get_remote_address(instance0, &tac0);
      }
   } else {
      ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", ast_channel_name(c1), ast_channel_name(c0));
   }

   ast_channel_unlock(c0);
   ast_channel_unlock(c1);

   instance0->bridged = instance1;
   instance1->bridged = instance0;

   ast_poll_channel_add(c0, c1);

   /* Go into a loop handling any stray frames that may come in */
   cs[0] = c0;
   cs[1] = c1;
   cs[2] = NULL;
   start = ast_tvnow();
   for (;;) {
      int ms;
      /* Check if anything changed */
      if ((ast_channel_tech_pvt(c0) != pvt0) ||
          (ast_channel_tech_pvt(c1) != pvt1) ||
          (ast_channel_masq(c0) || ast_channel_masqr(c0) || ast_channel_masq(c1) || ast_channel_masqr(c1)) ||
          (ast_channel_monitor(c0) || ast_channel_audiohooks(c0) || ast_channel_monitor(c1) || ast_channel_audiohooks(c1)) ||
          (!ast_framehook_list_is_empty(ast_channel_framehooks(c0)) || !ast_framehook_list_is_empty(ast_channel_framehooks(c1)))) {
         ast_debug(1, "Oooh, something is weird, backing out\n");
         res = AST_BRIDGE_RETRY;
         break;
      }

      /* Check if they have changed their address */
      ast_rtp_instance_get_remote_address(instance1, &t1);
      if (vinstance1) {
         ast_rtp_instance_get_remote_address(vinstance1, &vt1);
      }
      if (tinstance1) {
         ast_rtp_instance_get_remote_address(tinstance1, &tt1);
      }
      ast_channel_lock(c1);
      if (glue1->get_codec && ast_channel_tech_pvt(c1)) {
         ast_format_cap_remove_all(cap1);
         glue1->get_codec(c1, cap1);
      }
      ast_channel_unlock(c1);

      ast_rtp_instance_get_remote_address(instance0, &t0);
      if (vinstance0) {
         ast_rtp_instance_get_remote_address(vinstance0, &vt0);
      }
      if (tinstance0) {
         ast_rtp_instance_get_remote_address(tinstance0, &tt0);
      }
      ast_channel_lock(c0);
      if (glue0->get_codec && ast_channel_tech_pvt(c0)) {
         ast_format_cap_remove_all(cap0);
         glue0->get_codec(c0, cap0);
      }
      ast_channel_unlock(c0);

      if ((ast_sockaddr_cmp(&t1, &ac1)) ||
          (vinstance1 && ast_sockaddr_cmp(&vt1, &vac1)) ||
          (tinstance1 && ast_sockaddr_cmp(&tt1, &tac1)) ||
          (!ast_format_cap_identical(cap1, oldcap1))) {
         char tmp_buf[512] = { 0, };
         ast_debug(1, "Oooh, '%s' changed end address to %s (format %s)\n",
              ast_channel_name(c1), ast_sockaddr_stringify(&t1),
              ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), cap1));
         ast_debug(1, "Oooh, '%s' changed end vaddress to %s (format %s)\n",
              ast_channel_name(c1), ast_sockaddr_stringify(&vt1),
              ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), cap1));
         ast_debug(1, "Oooh, '%s' changed end taddress to %s (format %s)\n",
              ast_channel_name(c1), ast_sockaddr_stringify(&tt1),
              ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), cap1));
         ast_debug(1, "Oooh, '%s' was %s/(format %s)\n",
              ast_channel_name(c1), ast_sockaddr_stringify(&ac1),
              ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), oldcap1));
         ast_debug(1, "Oooh, '%s' was %s/(format %s)\n",
              ast_channel_name(c1), ast_sockaddr_stringify(&vac1),
              ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), oldcap1));
         ast_debug(1, "Oooh, '%s' was %s/(format %s)\n",
              ast_channel_name(c1), ast_sockaddr_stringify(&tac1),
              ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), oldcap1));
         if (glue0->update_peer(c0,
                      ast_sockaddr_isnull(&t1)  ? NULL : instance1,
                      ast_sockaddr_isnull(&vt1) ? NULL : vinstance1,
                      ast_sockaddr_isnull(&tt1) ? NULL : tinstance1,
                      cap1, 0)) {
            ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", ast_channel_name(c0), ast_channel_name(c1));
         }
         ast_sockaddr_copy(&ac1, &t1);
         ast_sockaddr_copy(&vac1, &vt1);
         ast_sockaddr_copy(&tac1, &tt1);
         ast_format_cap_copy(oldcap1, cap1);
      }
      if ((ast_sockaddr_cmp(&t0, &ac0)) ||
          (vinstance0 && ast_sockaddr_cmp(&vt0, &vac0)) ||
          (tinstance0 && ast_sockaddr_cmp(&tt0, &tac0)) ||
          (!ast_format_cap_identical(cap0, oldcap0))) {
         char tmp_buf[512] = { 0, };
         ast_debug(1, "Oooh, '%s' changed end address to %s (format %s)\n",
              ast_channel_name(c0), ast_sockaddr_stringify(&t0),
              ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), cap0));
         ast_debug(1, "Oooh, '%s' was %s/(format %s)\n",
              ast_channel_name(c0), ast_sockaddr_stringify(&ac0),
              ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), oldcap0));
         if (glue1->update_peer(c1, t0.len ? instance0 : NULL,
                  vt0.len ? vinstance0 : NULL,
                  tt0.len ? tinstance0 : NULL,
                  cap0, 0)) {
            ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", ast_channel_name(c1), ast_channel_name(c0));
         }
         ast_sockaddr_copy(&ac0, &t0);
         ast_sockaddr_copy(&vac0, &vt0);
         ast_sockaddr_copy(&tac0, &tt0);
         ast_format_cap_copy(oldcap0, cap0);
      }

      ms = ast_remaining_ms(start, timeoutms);
      /* Wait for frame to come in on the channels */
      if (!(who = ast_waitfor_n(cs, 2, &ms))) {
         if (!ms) {
            res = AST_BRIDGE_RETRY;
            break;
         }
         ast_debug(1, "Ooh, empty read...\n");
         if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
            break;
         }
         continue;
      }
      fr = ast_read(who);
      other = (who == c0) ? c1 : c0;
      if (!fr || ((fr->frametype == AST_FRAME_DTMF_BEGIN || fr->frametype == AST_FRAME_DTMF_END) &&
             (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) ||
              ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) {
         /* Break out of bridge */
         *fo = fr;
         *rc = who;
         ast_debug(1, "Oooh, got a %s\n", fr ? "digit" : "hangup");
         res = AST_BRIDGE_COMPLETE;
         break;
      } else if ((fr->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
         if ((fr->subclass.integer == AST_CONTROL_HOLD) ||
             (fr->subclass.integer == AST_CONTROL_UNHOLD) ||
             (fr->subclass.integer == AST_CONTROL_VIDUPDATE) ||
             (fr->subclass.integer == AST_CONTROL_SRCUPDATE) ||
             (fr->subclass.integer == AST_CONTROL_T38_PARAMETERS) ||
            (fr->subclass.integer == AST_CONTROL_UPDATE_RTP_PEER)) {
            if (fr->subclass.integer == AST_CONTROL_HOLD) {
               /* If we someone went on hold we want the other side to reinvite back to us */
               if (who == c0) {
                  glue1->update_peer(c1, NULL, NULL, NULL, 0, 0);
               } else {
                  glue0->update_peer(c0, NULL, NULL, NULL, 0, 0);
               }
            } else if (fr->subclass.integer == AST_CONTROL_UNHOLD ||
               fr->subclass.integer == AST_CONTROL_UPDATE_RTP_PEER) {
               /* If they went off hold they should go back to being direct, or if we have
                * been told to force a peer update, go ahead and do it. */
               if (who == c0) {
                  glue1->update_peer(c1, instance0, vinstance0, tinstance0, cap0, 0);
               } else {
                  glue0->update_peer(c0, instance1, vinstance1, tinstance1, cap1, 0);
               }
            }
            /* Update local address information */
            ast_rtp_instance_get_remote_address(instance0, &t0);
            ast_sockaddr_copy(&ac0, &t0);
            ast_rtp_instance_get_remote_address(instance1, &t1);
            ast_sockaddr_copy(&ac1, &t1);
            /* Update codec information */
            ast_channel_lock(c0);
            if (glue0->get_codec && ast_channel_tech_pvt(c0)) {
               ast_format_cap_remove_all(cap0);
               ast_format_cap_remove_all(oldcap0);
               glue0->get_codec(c0, cap0);
               ast_format_cap_append(oldcap0, cap0);

            }
            ast_channel_unlock(c0);
            ast_channel_lock(c1);
            if (glue1->get_codec && ast_channel_tech_pvt(c1)) {
               ast_format_cap_remove_all(cap1);
               ast_format_cap_remove_all(oldcap1);
               glue1->get_codec(c1, cap1);
               ast_format_cap_append(oldcap1, cap1);
            }
            ast_channel_unlock(c1);
            /* Since UPDATE_BRIDGE_PEER is only used by the bridging code, don't forward it */
            if (fr->subclass.integer != AST_CONTROL_UPDATE_RTP_PEER) {
               ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
            }
            ast_frfree(fr);
         } else if (fr->subclass.integer == AST_CONTROL_CONNECTED_LINE) {
            if (ast_channel_connected_line_sub(who, other, fr, 1) &&
               ast_channel_connected_line_macro(who, other, fr, other == c0, 1)) {
               ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
            }
            ast_frfree(fr);
         } else if (fr->subclass.integer == AST_CONTROL_REDIRECTING) {
            if (ast_channel_redirecting_sub(who, other, fr, 1) &&
               ast_channel_redirecting_macro(who, other, fr, other == c0, 1)) {
               ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
            }
            ast_frfree(fr);
         } else if (fr->subclass.integer == AST_CONTROL_PVT_CAUSE_CODE) {
            ast_channel_hangupcause_hash_set(other, fr->data.ptr, fr->datalen);
            ast_frfree(fr);
         } else {
            *fo = fr;
            *rc = who;
            ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", fr->subclass.integer, ast_channel_name(who));
            res = AST_BRIDGE_COMPLETE;
            break;
         }
      } else {
         if ((fr->frametype == AST_FRAME_DTMF_BEGIN) ||
             (fr->frametype == AST_FRAME_DTMF_END) ||
             (fr->frametype == AST_FRAME_VOICE) ||
             (fr->frametype == AST_FRAME_VIDEO) ||
             (fr->frametype == AST_FRAME_IMAGE) ||
             (fr->frametype == AST_FRAME_HTML) ||
             (fr->frametype == AST_FRAME_MODEM) ||
             (fr->frametype == AST_FRAME_TEXT)) {
            ast_write(other, fr);
         }
         ast_frfree(fr);
      }
      /* Swap priority */
      cs[2] = cs[0];
      cs[0] = cs[1];
      cs[1] = cs[2];
   }

   if (ast_test_flag(ast_channel_flags(c0), AST_FLAG_ZOMBIE)) {
      ast_debug(1, "Channel '%s' Zombie cleardown from bridge\n", ast_channel_name(c0));
   } else if (ast_channel_tech_pvt(c0) != pvt0) {
      ast_debug(1, "Channel c0->'%s' pvt changed, in bridge with c1->'%s'\n", ast_channel_name(c0), ast_channel_name(c1));
   } else if (glue0 != ast_rtp_instance_get_glue(ast_channel_tech(c0)->type)) {
      ast_debug(1, "Channel c0->'%s' technology changed, in bridge with c1->'%s'\n", ast_channel_name(c0), ast_channel_name(c1));
   } else if (glue0->update_peer(c0, NULL, NULL, NULL, 0, 0)) {
      ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", ast_channel_name(c0));
   }
   if (ast_test_flag(ast_channel_flags(c1), AST_FLAG_ZOMBIE)) {
      ast_debug(1, "Channel '%s' Zombie cleardown from bridge\n", ast_channel_name(c1));
   } else if (ast_channel_tech_pvt(c1) != pvt1) {
      ast_debug(1, "Channel c1->'%s' pvt changed, in bridge with c0->'%s'\n", ast_channel_name(c1), ast_channel_name(c0));
   } else if (glue1 != ast_rtp_instance_get_glue(ast_channel_tech(c1)->type)) {
      ast_debug(1, "Channel c1->'%s' technology changed, in bridge with c0->'%s'\n", ast_channel_name(c1), ast_channel_name(c0));
   } else if (glue1->update_peer(c1, NULL, NULL, NULL, 0, 0)) {
      ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", ast_channel_name(c1));
   }

   instance0->bridged = NULL;
   instance1->bridged = NULL;

   ast_poll_channel_del(c0, c1);

remote_bridge_cleanup:
   ast_format_cap_destroy(oldcap0);
   ast_format_cap_destroy(oldcap1);

   return res;
}
static int rtp_payload_type_add_ast ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 693 of file rtp_engine.c.

References ast_format_cap_add(), ast_rtp_payload_type::asterisk_format, ast_rtp_payload_type::format, and type.

Referenced by ast_rtp_codecs_payload_formats().

{
   struct ast_rtp_payload_type *type = obj;
   struct ast_format_cap *astformats = arg;

   if (type->asterisk_format) {
      ast_format_cap_add(astformats, &type->format);
   }

   return 0;
}
static int rtp_payload_type_add_nonast ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 705 of file rtp_engine.c.

References ast_rtp_payload_type::asterisk_format, ast_rtp_payload_type::rtp_code, and type.

Referenced by ast_rtp_codecs_payload_formats().

{
   struct ast_rtp_payload_type *type = obj;
   int *nonastformats = arg;

   if (!type->asterisk_format) {
      *nonastformats |= type->rtp_code;
   }

   return 0;
}
static int rtp_payload_type_cmp ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 429 of file rtp_engine.c.

References CMP_MATCH, CMP_STOP, OBJ_KEY, and ast_rtp_payload_type::payload.

Referenced by ast_rtp_codecs_payloads_initialize().

{
   struct ast_rtp_payload_type *type1 = obj, *type2 = arg;
   const int *payload = arg;

   return (type1->payload == (OBJ_KEY ? *payload : type2->payload)) ? CMP_MATCH | CMP_STOP : 0;
}
static int rtp_payload_type_find_format ( void *  obj,
void *  arg,
int  flags 
) [static]
static int rtp_payload_type_find_nonast_format ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 734 of file rtp_engine.c.

References ast_rtp_payload_type::asterisk_format, CMP_MATCH, CMP_STOP, ast_rtp_payload_type::rtp_code, and type.

Referenced by ast_rtp_codecs_payload_code().

{
   struct ast_rtp_payload_type *type = obj;
   int *rtp_code = arg;

   return ((!type->asterisk_format && (type->rtp_code == *rtp_code)) ? CMP_MATCH | CMP_STOP : 0);
}
static int rtp_payload_type_hash ( const void *  obj,
const int  flags 
) [static]

Definition at line 421 of file rtp_engine.c.

References OBJ_KEY, ast_rtp_payload_type::payload, and type.

Referenced by ast_rtp_codecs_payloads_initialize().

{
   const struct ast_rtp_payload_type *type = obj;
   const int *payload = obj;

   return (flags & OBJ_KEY) ? *payload : type->payload;
}
static void unref_instance_cond ( struct ast_rtp_instance **  instance) [static]

Conditionally unref an rtp instance.

Definition at line 1457 of file rtp_engine.c.

References ao2_ref.

Referenced by ast_rtp_instance_bridge(), ast_rtp_instance_early_bridge(), and ast_rtp_instance_early_bridge_make_compatible().

{
   if (*instance) {
      ao2_ref(*instance, -1);
      *instance = NULL;
   }
}

Variable Documentation

struct engines engines [static]
struct glues glues [static]

Definition at line 98 of file rtp_engine.c.

struct ast_srtp_res* res_srtp = NULL

Definition at line 49 of file rtp_engine.c.

Definition at line 50 of file rtp_engine.c.

Referenced by ast_rtp_engine_srtp_is_registered().

Mapping between Asterisk codecs and rtp payload types.

Static (i.e., well-known) RTP payload types for our "AST_FORMAT..."s: also, our own choices for dynamic payload types. This is our master table for transmission

See http://www.iana.org/assignments/rtp-parameters for a list of assigned values

Definition at line 111 of file rtp_engine.c.

Referenced by add_static_payload(), ast_rtp_codecs_payload_code(), ast_rtp_codecs_payload_lookup(), ast_rtp_codecs_payloads_default(), ast_rtp_codecs_payloads_set_m_type(), and ast_rtp_engine_unload_format().

Definition at line 112 of file rtp_engine.c.