Mon Oct 8 12:39:28 2012

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/framehook.h"

Go to the source code of this file.

Data Structures

struct  ast_rtp_instance
struct  ast_rtp_mime_type
struct  engines
struct  glues

Functions

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, const int asterisk_format, const format_t 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, format_t *astformats, int *nonastformats)
 Retrieve all formats that were found.
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_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.
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_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.
format_t ast_rtp_instance_available_formats (struct ast_rtp_instance *instance, format_t to_endpoint, format_t to_asterisk)
 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 *c0, struct ast_channel *c1)
 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).
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.
ast_rtp_instanceast_rtp_instance_get_bridged (struct ast_rtp_instance *instance)
 Get the other RTP instance that an instance is bridged to.
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.
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.
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.
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.
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.
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.
ast_rtp_instanceast_rtp_instance_new (const char *engine_name, struct sched_context *sched, const struct ast_sockaddr *sa, void *data)
 Create a new RTP instance.
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, format_t 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, format_t 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, const format_t 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, const format_t code, enum ast_rtp_options options)
 Retrieve mime subtype information on a payload.
unsigned int ast_rtp_lookup_sample_rate2 (int asterisk_format, format_t 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, format_t codec0, format_t codec1, int timeoutms, int flags, struct ast_frame **fo, struct ast_channel **rc, void *pvt0, void *pvt1)
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 []
ast_srtp_resres_srtp = NULL
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.


Detailed Description

Pluggable RTP Architecture.

Author:
Joshua Colp <jcolp@digium.com>

Definition in file rtp_engine.c.


Function Documentation

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:
codecs Codecs structure to muck with
instance Optionally the instance that the codecs structure belongs to
prefs Codec 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 727 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_new(), process_sdp_a_audio(), set_peer_capabilities(), start_rtp(), and transmit_response_with_sdp().

00728 {
00729    codecs->pref = *prefs;
00730 
00731    if (instance && instance->engine->packetization_set) {
00732       instance->engine->packetization_set(instance, &instance->codecs.pref);
00733    }
00734 }

int ast_rtp_codecs_payload_code ( struct ast_rtp_codecs codecs,
const int  asterisk_format,
const format_t  code 
)

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

Parameters:
codecs Codecs structure to look in
asterisk_format Non-zero if the given code is an Asterisk format value
code The format to look for
Return values:
Numerical payload
Example usage:

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

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

Since:
1.8

Definition at line 654 of file rtp_engine.c.

References AST_RTP_MAX_PT, ast_rtp_payload_type::asterisk_format, ast_rtp_payload_type::code, and ast_rtp_codecs::payloads.

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_write(), bridge_p2p_rtp_write(), multicast_rtp_write(), and start_rtp().

00655 {
00656    int i;
00657 
00658    for (i = 0; i < AST_RTP_MAX_PT; i++) {
00659       if (codecs->payloads[i].asterisk_format == asterisk_format && codecs->payloads[i].code == code) {
00660          return i;
00661       }
00662    }
00663 
00664    for (i = 0; i < AST_RTP_MAX_PT; i++) {
00665       if (static_RTP_PT[i].asterisk_format == asterisk_format && static_RTP_PT[i].code == code) {
00666          return i;
00667       }
00668    }
00669 
00670    return -1;
00671 }

void ast_rtp_codecs_payload_formats ( struct ast_rtp_codecs codecs,
format_t astformats,
int *  nonastformats 
)

Retrieve all formats that were found.

Parameters:
codecs Codecs structure to look in
astformats An integer to put the Asterisk formats in
nonastformats An integer to put the non-Asterisk formats in
Example usage:

 int astformats, 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 636 of file rtp_engine.c.

References ast_debug, AST_RTP_MAX_PT, ast_rtp_payload_type::asterisk_format, ast_rtp_payload_type::code, and ast_rtp_codecs::payloads.

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

00637 {
00638    int i;
00639 
00640    *astformats = *nonastformats = 0;
00641 
00642    for (i = 0; i < AST_RTP_MAX_PT; i++) {
00643       if (codecs->payloads[i].code) {
00644          ast_debug(1, "Incorporating payload %d on %p\n", i, codecs);
00645       }
00646       if (codecs->payloads[i].asterisk_format) {
00647          *astformats |= codecs->payloads[i].code;
00648       } else {
00649          *nonastformats |= codecs->payloads[i].code;
00650       }
00651    }
00652 }

struct ast_rtp_payload_type ast_rtp_codecs_payload_lookup ( struct ast_rtp_codecs codecs,
int  payload 
)

Retrieve payload information by payload.

Parameters:
codecs Codecs structure to look in
payload Numerical payload to look up
Return values:
Payload information
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 618 of file rtp_engine.c.

References AST_RTP_MAX_PT, ast_rtp_payload_type::asterisk_format, ast_rtp_payload_type::code, and static_RTP_PT.

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

00619 {
00620    struct ast_rtp_payload_type result = { .asterisk_format = 0, };
00621 
00622    if (payload < 0 || payload >= AST_RTP_MAX_PT) {
00623       return result;
00624    }
00625 
00626    result.asterisk_format = codecs->payloads[payload].asterisk_format;
00627    result.code = codecs->payloads[payload].code;
00628 
00629    if (!result.code) {
00630       result = static_RTP_PT[payload];
00631    }
00632 
00633    return result;
00634 }

void ast_rtp_codecs_payloads_clear ( struct ast_rtp_codecs codecs,
struct ast_rtp_instance instance 
)

Clear payload information from an RTP instance.

Parameters:
codecs The codecs structure that payloads will be cleared from
instance Optionally 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 488 of file rtp_engine.c.

References AST_RTP_MAX_PT, ast_rtp_payload_type::asterisk_format, ast_rtp_payload_type::code, ast_rtp_instance::engine, ast_rtp_engine::payload_set, and ast_rtp_codecs::payloads.

Referenced by gtalk_alloc(), and process_sdp().

00489 {
00490    int i;
00491 
00492    for (i = 0; i < AST_RTP_MAX_PT; i++) {
00493       codecs->payloads[i].asterisk_format = 0;
00494       codecs->payloads[i].code = 0;
00495       if (instance && instance->engine && instance->engine->payload_set) {
00496          instance->engine->payload_set(instance, i, 0, 0);
00497       }
00498    }
00499 }

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:
src The source codecs structure
dest The destination codecs structure that the values from src will be copied to
instance Optionally 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 516 of file rtp_engine.c.

References ast_debug, AST_RTP_MAX_PT, ast_rtp_payload_type::asterisk_format, ast_rtp_payload_type::code, ast_rtp_instance::engine, ast_rtp_engine::payload_set, and ast_rtp_codecs::payloads.

Referenced by ast_rtp_instance_early_bridge_make_compatible(), and process_sdp().

00517 {
00518    int i;
00519 
00520    for (i = 0; i < AST_RTP_MAX_PT; i++) {
00521       if (src->payloads[i].code) {
00522          ast_debug(2, "Copying payload %d from %p to %p\n", i, src, dest);
00523          dest->payloads[i].asterisk_format = src->payloads[i].asterisk_format;
00524          dest->payloads[i].code = src->payloads[i].code;
00525          if (instance && instance->engine && instance->engine->payload_set) {
00526             instance->engine->payload_set(instance, i, dest->payloads[i].asterisk_format, dest->payloads[i].code);
00527          }
00528       }
00529    }
00530 }

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:
codecs The codecs structure to set defaults on
instance Optionally 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 501 of file rtp_engine.c.

References AST_RTP_MAX_PT, ast_rtp_payload_type::asterisk_format, ast_rtp_payload_type::code, ast_rtp_instance::engine, ast_rtp_engine::payload_set, ast_rtp_codecs::payloads, and static_RTP_PT.

00502 {
00503    int i;
00504 
00505    for (i = 0; i < AST_RTP_MAX_PT; i++) {
00506       if (static_RTP_PT[i].code) {
00507          codecs->payloads[i].asterisk_format = static_RTP_PT[i].asterisk_format;
00508          codecs->payloads[i].code = static_RTP_PT[i].code;
00509          if (instance && instance->engine && instance->engine->payload_set) {
00510             instance->engine->payload_set(instance, i, codecs->payloads[i].asterisk_format, codecs->payloads[i].code);
00511          }
00512       }
00513    }
00514 }

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:
codecs The codecs structure to muck with
instance Optionally the instance that the codecs structure belongs to
payload Numerical 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 ast_debug, AST_RTP_MAX_PT, ast_rtp_payload_type::asterisk_format, ast_rtp_payload_type::code, ast_rtp_instance::engine, ast_rtp_engine::payload_set, ast_rtp_codecs::payloads, and static_RTP_PT.

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

00533 {
00534    if (payload < 0 || payload >= AST_RTP_MAX_PT || !static_RTP_PT[payload].code) {
00535       return;
00536    }
00537 
00538    codecs->payloads[payload].asterisk_format = static_RTP_PT[payload].asterisk_format;
00539    codecs->payloads[payload].code = static_RTP_PT[payload].code;
00540 
00541    ast_debug(1, "Setting payload %d based on m type on %p\n", payload, codecs);
00542 
00543    if (instance && instance->engine && instance->engine->payload_set) {
00544       instance->engine->payload_set(instance, payload, codecs->payloads[payload].asterisk_format, codecs->payloads[payload].code);
00545    }
00546 }

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:
codecs The codecs structure to muck with
instance Optionally the instance that the codecs structure belongs to
payload Numerical payload that was seen in the a=rtpmap: SDP line
mimetype The string mime type that was seen
mimesubtype The strin mime sub type that was seen
options Optional options that may change the behavior of this specific payload
Return values:
0 success
-1 failure, invalid payload numbe
-2 failure, 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 597 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_newcall(), process_sdp(), set_dtmf_payload(), and setup_rtp_connection().

00598 {
00599    return ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, instance, payload, mimetype, mimesubtype, options, 0);
00600 }

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:
codecs RTP structure to modify
instance Optionally the instance that the codecs structure belongs to
pt Payload type entry to modify
mimetype top-level MIME type of media stream (typically "audio", "video", "text", etc.)
mimesubtype MIME subtype of media stream (typically a codec name)
options Zero or more flags from the ast_rtp_options enum
sample_rate The sample rate of the media stream
This function 'fills in' an entry in the list of possible formats for a media stream associated with an RTP structure.

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

Definition at line 548 of file rtp_engine.c.

References ARRAY_LEN, AST_FORMAT_G726, AST_FORMAT_G726_AAL2, AST_RTP_MAX_PT, ast_rtp_mime_types, AST_RTP_OPT_G726_NONSTANDARD, ast_rtp_payload_type::asterisk_format, ast_rtp_payload_type::code, ast_rtp_instance::engine, ast_rtp_engine::payload_set, and ast_rtp_codecs::payloads.

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

00552 {
00553    unsigned int i;
00554    int found = 0;
00555 
00556    if (pt < 0 || pt >= AST_RTP_MAX_PT)
00557       return -1; /* bogus payload type */
00558 
00559    for (i = 0; i < ARRAY_LEN(ast_rtp_mime_types); ++i) {
00560       const struct ast_rtp_mime_type *t = &ast_rtp_mime_types[i];
00561 
00562       if (strcasecmp(mimesubtype, t->subtype)) {
00563          continue;
00564       }
00565 
00566       if (strcasecmp(mimetype, t->type)) {
00567          continue;
00568       }
00569 
00570       /* if both sample rates have been supplied, and they don't match,
00571        * then this not a match; if one has not been supplied, then the
00572        * rates are not compared */
00573       if (sample_rate && t->sample_rate &&
00574           (sample_rate != t->sample_rate)) {
00575          continue;
00576       }
00577 
00578       found = 1;
00579       codecs->payloads[pt] = t->payload_type;
00580 
00581       if ((t->payload_type.code == AST_FORMAT_G726) &&
00582                               t->payload_type.asterisk_format &&
00583           (options & AST_RTP_OPT_G726_NONSTANDARD)) {
00584          codecs->payloads[pt].code = AST_FORMAT_G726_AAL2;
00585       }
00586 
00587       if (instance && instance->engine && instance->engine->payload_set) {
00588          instance->engine->payload_set(instance, pt, codecs->payloads[i].asterisk_format, codecs->payloads[i].code);
00589       }
00590 
00591       break;
00592    }
00593 
00594    return (found ? 0 : -2);
00595 }

void ast_rtp_codecs_payloads_unset ( struct ast_rtp_codecs codecs,
struct ast_rtp_instance instance,
int  payload 
)

Remove payload information.

Parameters:
codecs The codecs structure to muck with
instance Optionally the instance that the codecs structure belongs to
payload Numerical 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 602 of file rtp_engine.c.

References ast_debug, AST_RTP_MAX_PT, ast_rtp_payload_type::asterisk_format, ast_rtp_payload_type::code, ast_rtp_instance::engine, ast_rtp_engine::payload_set, and ast_rtp_codecs::payloads.

Referenced by process_sdp_a_audio(), and process_sdp_a_video().

00603 {
00604    if (payload < 0 || payload >= AST_RTP_MAX_PT) {
00605       return;
00606    }
00607 
00608    ast_debug(2, "Unsetting payload %d on %p\n", payload, codecs);
00609 
00610    codecs->payloads[payload].asterisk_format = 0;
00611    codecs->payloads[payload].code = 0;
00612 
00613    if (instance && instance->engine && instance->engine->payload_set) {
00614       instance->engine->payload_set(instance, payload, 0, 0);
00615    }
00616 }

int ast_rtp_engine_register2 ( struct ast_rtp_engine engine,
struct ast_module module 
)

Register an RTP engine.

Parameters:
engine Structure of the RTP engine to register
module Module that the RTP engine is part of
Return values:
0 success
-1 failure
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 188 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, ast_rtp_engine::entry, LOG_WARNING, ast_rtp_engine::mod, ast_rtp_engine::name, ast_rtp_engine::new, ast_rtp_engine::read, and ast_rtp_engine::write.

00189 {
00190    struct ast_rtp_engine *current_engine;
00191 
00192    /* Perform a sanity check on the engine structure to make sure it has the basics */
00193    if (ast_strlen_zero(engine->name) || !engine->new || !engine->destroy || !engine->write || !engine->read) {
00194       ast_log(LOG_WARNING, "RTP Engine '%s' failed sanity check so it was not registered.\n", !ast_strlen_zero(engine->name) ? engine->name : "Unknown");
00195       return -1;
00196    }
00197 
00198    /* Link owner module to the RTP engine for reference counting purposes */
00199    engine->mod = module;
00200 
00201    AST_RWLIST_WRLOCK(&engines);
00202 
00203    /* Ensure that no two modules with the same name are registered at the same time */
00204    AST_RWLIST_TRAVERSE(&engines, current_engine, entry) {
00205       if (!strcmp(current_engine->name, engine->name)) {
00206          ast_log(LOG_WARNING, "An RTP engine with the name '%s' has already been registered.\n", engine->name);
00207          AST_RWLIST_UNLOCK(&engines);
00208          return -1;
00209       }
00210    }
00211 
00212    /* The engine survived our critique. Off to the list it goes to be used */
00213    AST_RWLIST_INSERT_TAIL(&engines, engine, entry);
00214 
00215    AST_RWLIST_UNLOCK(&engines);
00216 
00217    ast_verb(2, "Registered RTP engine '%s'\n", engine->name);
00218 
00219    return 0;
00220 }

int ast_rtp_engine_register_srtp ( struct ast_srtp_res srtp_res,
struct ast_srtp_policy_res policy_res 
)

Definition at line 1767 of file rtp_engine.c.

References policy_res, res_srtp, res_srtp_policy, and srtp_res.

Referenced by res_srtp_init().

01768 {
01769    if (res_srtp || res_srtp_policy) {
01770       return -1;
01771    }
01772    if (!srtp_res || !policy_res) {
01773       return -1;
01774    }
01775 
01776    res_srtp = srtp_res;
01777    res_srtp_policy = policy_res;
01778 
01779    return 0;
01780 }

int ast_rtp_engine_srtp_is_registered ( void   ) 

Definition at line 1788 of file rtp_engine.c.

References res_srtp, and res_srtp_policy.

Referenced by sdp_crypto_activate(), sdp_crypto_process(), sdp_crypto_setup(), set_crypto_policy(), and setup_srtp().

01789 {
01790    return res_srtp && res_srtp_policy;
01791 }

int ast_rtp_engine_unregister ( struct ast_rtp_engine engine  ) 

Unregister an RTP engine.

Parameters:
engine Structure of the RTP engine to unregister
Return values:
0 success
-1 failure
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 222 of file rtp_engine.c.

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

Referenced by load_module(), and unload_module().

00223 {
00224    struct ast_rtp_engine *current_engine = NULL;
00225 
00226    AST_RWLIST_WRLOCK(&engines);
00227 
00228    if ((current_engine = AST_RWLIST_REMOVE(&engines, engine, entry))) {
00229       ast_verb(2, "Unregistered RTP engine '%s'\n", engine->name);
00230    }
00231 
00232    AST_RWLIST_UNLOCK(&engines);
00233 
00234    return current_engine ? 0 : -1;
00235 }

void ast_rtp_engine_unregister_srtp ( void   ) 

Definition at line 1782 of file rtp_engine.c.

References res_srtp, and res_srtp_policy.

Referenced by res_srtp_shutdown().

01783 {
01784    res_srtp = NULL;
01785    res_srtp_policy = NULL;
01786 }

int ast_rtp_glue_register2 ( struct ast_rtp_glue glue,
struct ast_module module 
)

Register RTP glue.

Parameters:
glue The glue to register
module Module that the RTP glue is part of
Return values:
0 success
-1 failure
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 237 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_glue::entry, LOG_WARNING, ast_rtp_glue::mod, and ast_rtp_glue::type.

00238 {
00239    struct ast_rtp_glue *current_glue = NULL;
00240 
00241    if (ast_strlen_zero(glue->type)) {
00242       return -1;
00243    }
00244 
00245    glue->mod = module;
00246 
00247    AST_RWLIST_WRLOCK(&glues);
00248 
00249    AST_RWLIST_TRAVERSE(&glues, current_glue, entry) {
00250       if (!strcasecmp(current_glue->type, glue->type)) {
00251          ast_log(LOG_WARNING, "RTP glue with the name '%s' has already been registered.\n", glue->type);
00252          AST_RWLIST_UNLOCK(&glues);
00253          return -1;
00254       }
00255    }
00256 
00257    AST_RWLIST_INSERT_TAIL(&glues, glue, entry);
00258 
00259    AST_RWLIST_UNLOCK(&glues);
00260 
00261    ast_verb(2, "Registered RTP glue '%s'\n", glue->type);
00262 
00263    return 0;
00264 }

int ast_rtp_glue_unregister ( struct ast_rtp_glue glue  ) 

Unregister RTP glue.

Parameters:
glue The glue to unregister
Return values:
0 success
-1 failure
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 266 of file rtp_engine.c.

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

Referenced by load_module(), and unload_module().

00267 {
00268    struct ast_rtp_glue *current_glue = NULL;
00269 
00270    AST_RWLIST_WRLOCK(&glues);
00271 
00272    if ((current_glue = AST_RWLIST_REMOVE(&glues, glue, entry))) {
00273       ast_verb(2, "Unregistered RTP glue '%s'\n", glue->type);
00274    }
00275 
00276    AST_RWLIST_UNLOCK(&glues);
00277 
00278    return current_glue ? 0 : -1;
00279 }

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:
instance The RTP instance
Return values:
0 success
-1 failure
Example usage:

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

Since:
1.8

Definition at line 1708 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().

01709 {
01710    return instance->engine->activate ? instance->engine->activate(instance) : 0;
01711 }

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:
instance the RTP instance
remote_policy the remote endpoint's policy
local_policy our policy for this RTP instance's remote endpoint
Return values:
0 Success
non-zero Failure

Definition at line 1793 of file rtp_engine.c.

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

Referenced by sdp_crypto_activate().

01794 {
01795    int res = 0;
01796 
01797    if (!res_srtp) {
01798       return -1;
01799    }
01800 
01801    if (!instance->srtp) {
01802       res = res_srtp->create(&instance->srtp, instance, remote_policy);
01803    } else {
01804       res = res_srtp->replace(&instance->srtp, instance, remote_policy);
01805    }
01806    if (!res) {
01807       res = res_srtp->add_stream(instance->srtp, local_policy);
01808    }
01809 
01810    return res;
01811 }

format_t ast_rtp_instance_available_formats ( struct ast_rtp_instance instance,
format_t  to_endpoint,
format_t  to_asterisk 
)

Request the formats that can be transcoded.

Parameters:
instance The RTP instance
to_endpoint Formats being sent/received towards the endpoint
to_asterisk Formats being sent/received towards Asterisk
Return values:
supported formats
Example usage:

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 1697 of file rtp_engine.c.

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

Referenced by sip_call().

01698 {
01699    format_t formats;
01700 
01701    if (instance->engine->available_formats && (formats = instance->engine->available_formats(instance, to_endpoint, to_asterisk))) {
01702       return formats;
01703    }
01704 
01705    return ast_translate_available_formats(to_endpoint, to_asterisk);
01706 }

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:
c0 First channel part of the bridge
c1 Second channel part of the bridge
flags Bridging flags
fo If a frame needs to be passed up it is stored here
rc Channel that passed the above frame up
timeoutms How long the channels should be bridged for
Return values:
Bridge result
Note:
This should only be used by channel drivers in their technology declaration.
Since:
1.8

Definition at line 1255 of file rtp_engine.c.

References AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_debug, ast_getformatname(), 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_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_channel::name, remote_bridge_loop(), ast_sockaddr::ss, ast_channel::tech, ast_channel::tech_pvt, ast_channel_tech::type, and unref_instance_cond().

01256 {
01257    struct ast_rtp_instance *instance0 = NULL, *instance1 = NULL,
01258          *vinstance0 = NULL, *vinstance1 = NULL,
01259          *tinstance0 = NULL, *tinstance1 = NULL;
01260    struct ast_rtp_glue *glue0, *glue1;
01261    struct ast_sockaddr addr1 = { {0, }, }, addr2 = { {0, }, };
01262    enum ast_rtp_glue_result audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID, video_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
01263    enum ast_rtp_glue_result audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID, video_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
01264    enum ast_bridge_result res = AST_BRIDGE_FAILED;
01265    enum ast_rtp_dtmf_mode dmode;
01266    format_t codec0 = 0, codec1 = 0;
01267    int unlock_chans = 1;
01268 
01269    /* Lock both channels so we can look for the glue that binds them together */
01270    ast_channel_lock(c0);
01271    while (ast_channel_trylock(c1)) {
01272       ast_channel_unlock(c0);
01273       usleep(1);
01274       ast_channel_lock(c0);
01275    }
01276 
01277    /* Ensure neither channel got hungup during lock avoidance */
01278    if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
01279       ast_log(LOG_WARNING, "Got hangup while attempting to bridge '%s' and '%s'\n", c0->name, c1->name);
01280       goto done;
01281    }
01282 
01283    /* Grab glue that binds each channel to something using the RTP engine */
01284    if (!(glue0 = ast_rtp_instance_get_glue(c0->tech->type)) || !(glue1 = ast_rtp_instance_get_glue(c1->tech->type))) {
01285       ast_debug(1, "Can't find native functions for channel '%s'\n", glue0 ? c1->name : c0->name);
01286       goto done;
01287    }
01288 
01289    audio_glue0_res = glue0->get_rtp_info(c0, &instance0);
01290    video_glue0_res = glue0->get_vrtp_info ? glue0->get_vrtp_info(c0, &vinstance0) : AST_RTP_GLUE_RESULT_FORBID;
01291 
01292    audio_glue1_res = glue1->get_rtp_info(c1, &instance1);
01293    video_glue1_res = glue1->get_vrtp_info ? glue1->get_vrtp_info(c1, &vinstance1) : AST_RTP_GLUE_RESULT_FORBID;
01294 
01295    /* If we are carrying video, and both sides are not going to remotely bridge... fail the native bridge */
01296    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)) {
01297       audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
01298    }
01299    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)) {
01300       audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
01301    }
01302 
01303    /* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
01304    if (audio_glue0_res == AST_RTP_GLUE_RESULT_FORBID || audio_glue1_res == AST_RTP_GLUE_RESULT_FORBID) {
01305       res = AST_BRIDGE_FAILED_NOWARN;
01306       goto done;
01307    }
01308 
01309 
01310    /* If address families differ, force a local bridge */
01311    ast_rtp_instance_get_remote_address(instance0, &addr1);
01312    ast_rtp_instance_get_remote_address(instance1, &addr2);
01313 
01314    if (addr1.ss.ss_family != addr2.ss.ss_family ||
01315       (ast_sockaddr_is_ipv4_mapped(&addr1) != ast_sockaddr_is_ipv4_mapped(&addr2))) {
01316       audio_glue0_res = AST_RTP_GLUE_RESULT_LOCAL;
01317       audio_glue1_res = AST_RTP_GLUE_RESULT_LOCAL;
01318    }
01319 
01320    /* If we need to get DTMF see if we can do it outside of the RTP stream itself */
01321    dmode = ast_rtp_instance_dtmf_mode_get(instance0);
01322    if ((flags & AST_BRIDGE_DTMF_CHANNEL_0) && dmode) {
01323       res = AST_BRIDGE_FAILED_NOWARN;
01324       goto done;
01325    }
01326    dmode = ast_rtp_instance_dtmf_mode_get(instance1);
01327    if ((flags & AST_BRIDGE_DTMF_CHANNEL_1) && dmode) {
01328       res = AST_BRIDGE_FAILED_NOWARN;
01329       goto done;
01330    }
01331 
01332    /* 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 */
01333    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)))) {
01334       res = AST_BRIDGE_FAILED_NOWARN;
01335       goto done;
01336    }
01337 
01338    /* Make sure that codecs match */
01339    codec0 = glue0->get_codec ? glue0->get_codec(c0) : 0;
01340    codec1 = glue1->get_codec ? glue1->get_codec(c1) : 0;
01341    if (codec0 && codec1 && !(codec0 & codec1)) {
01342       ast_debug(1, "Channel codec0 = %s is not codec1 = %s, cannot native bridge in RTP.\n", ast_getformatname(codec0), ast_getformatname(codec1));
01343       res = AST_BRIDGE_FAILED_NOWARN;
01344       goto done;
01345    }
01346 
01347    instance0->glue = glue0;
01348    instance1->glue = glue1;
01349    instance0->chan = c0;
01350    instance1->chan = c1;
01351 
01352    /* Depending on the end result for bridging either do a local bridge or remote bridge */
01353    if (audio_glue0_res == AST_RTP_GLUE_RESULT_LOCAL || audio_glue1_res == AST_RTP_GLUE_RESULT_LOCAL) {
01354       ast_verb(3, "Locally bridging %s and %s\n", c0->name, c1->name);
01355       res = local_bridge_loop(c0, c1, instance0, instance1, timeoutms, flags, fo, rc, c0->tech_pvt, c1->tech_pvt);
01356    } else {
01357       ast_verb(3, "Remotely bridging %s and %s\n", c0->name, c1->name);
01358       res = remote_bridge_loop(c0, c1, instance0, instance1, vinstance0, vinstance1,
01359             tinstance0, tinstance1, glue0, glue1, codec0, codec1, timeoutms, flags,
01360             fo, rc, c0->tech_pvt, c1->tech_pvt);
01361    }
01362 
01363    instance0->glue = NULL;
01364    instance1->glue = NULL;
01365    instance0->chan = NULL;
01366    instance1->chan = NULL;
01367 
01368    unlock_chans = 0;
01369 
01370 done:
01371    if (unlock_chans) {
01372       ast_channel_unlock(c0);
01373       ast_channel_unlock(c1);
01374    }
01375 
01376    unref_instance_cond(&instance0);
01377    unref_instance_cond(&instance1);
01378    unref_instance_cond(&vinstance0);
01379    unref_instance_cond(&vinstance1);
01380    unref_instance_cond(&tinstance0);
01381    unref_instance_cond(&tinstance1);
01382 
01383    return res;
01384 }

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:
instance Instance 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 767 of file rtp_engine.c.

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

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

00768 {
00769    if (instance->engine->change_source) {
00770       instance->engine->change_source(instance);
00771    }
00772 }

int ast_rtp_instance_destroy ( struct ast_rtp_instance instance  ) 

Destroy an RTP instance.

Parameters:
instance The RTP instance to destroy
Return values:
0 success
-1 failure
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 301 of file rtp_engine.c.

References ao2_ref.

Referenced by __oh323_destroy(), __sip_destroy(), cleanup_connection(), destroy_endpoint(), gtalk_free_pvt(), jingle_free_pvt(), mgcp_hangup(), multicast_rtp_hangup(), multicast_rtp_request(), oh323_alloc(), skinny_hangup(), start_rtp(), unalloc_sub(), and unistim_hangup().

00302 {
00303    ao2_ref(instance, -1);
00304 
00305    return 0;
00306 }

int ast_rtp_instance_dtmf_begin ( struct ast_rtp_instance instance,
char  digit 
)

Begin sending a DTMF digit.

Parameters:
instance The RTP instance to send the DTMF on
digit What DTMF digit to send
Return values:
0 success
-1 failure
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 736 of file rtp_engine.c.

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

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

00737 {
00738    return instance->engine->dtmf_begin ? instance->engine->dtmf_begin(instance, digit) : -1;
00739 }

int ast_rtp_instance_dtmf_end ( struct ast_rtp_instance instance,
char  digit 
)

Stop sending a DTMF digit.

Parameters:
instance The RTP instance to stop the DTMF on
digit What DTMF digit to stop
Return values:
0 success
-1 failure
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 741 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().

00742 {
00743    return instance->engine->dtmf_end ? instance->engine->dtmf_end(instance, digit) : -1;
00744 }

int ast_rtp_instance_dtmf_end_with_duration ( struct ast_rtp_instance instance,
char  digit,
unsigned int  duration 
)

Definition at line 745 of file rtp_engine.c.

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

Referenced by gtalk_digit_end(), and sip_senddigit_end().

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

enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get ( struct ast_rtp_instance instance  ) 

Get the DTMF mode of an RTP instance.

Parameters:
instance The RTP instance to get the DTMF mode of
Return values:
DTMF mode
Example usage:

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

Since:
1.8

Definition at line 755 of file rtp_engine.c.

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

Referenced by ast_rtp_instance_bridge().

00756 {
00757    return instance->engine->dtmf_mode_get ? instance->engine->dtmf_mode_get(instance) : 0;
00758 }

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:
instance the RTP instance to set DTMF mode on
dtmf_mode The DTMF mode that is in use
Return values:
0 success
-1 failure
Example usage:

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

Since:
1.8

Definition at line 750 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().

00751 {
00752    return (!instance->engine->dtmf_mode_set || instance->engine->dtmf_mode_set(instance, dtmf_mode)) ? -1 : 0;
00753 }

int ast_rtp_instance_early_bridge ( struct ast_channel c0,
struct ast_channel c1 
)

Early bridge two channels that use RTP instances.

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

Definition at line 1477 of file rtp_engine.c.

References ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_debug, 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, ast_channel::name, ast_channel::tech, ast_channel_tech::type, unref_instance_cond(), and ast_rtp_glue::update_peer.

01478 {
01479    struct ast_rtp_instance *instance0 = NULL, *instance1 = NULL,
01480          *vinstance0 = NULL, *vinstance1 = NULL,
01481          *tinstance0 = NULL, *tinstance1 = NULL;
01482    struct ast_rtp_glue *glue0, *glue1;
01483    enum ast_rtp_glue_result audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID, video_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
01484    enum ast_rtp_glue_result audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID, video_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
01485    format_t codec0 = 0, codec1 = 0;
01486    int res = 0;
01487 
01488    /* If there is no second channel just immediately bail out, we are of no use in that scenario */
01489    if (!c1) {
01490       return -1;
01491    }
01492 
01493    /* Lock both channels so we can look for the glue that binds them together */
01494    ast_channel_lock(c0);
01495    while (ast_channel_trylock(c1)) {
01496       ast_channel_unlock(c0);
01497       usleep(1);
01498       ast_channel_lock(c0);
01499    }
01500 
01501    /* Grab glue that binds each channel to something using the RTP engine */
01502    if (!(glue0 = ast_rtp_instance_get_glue(c0->tech->type)) || !(glue1 = ast_rtp_instance_get_glue(c1->tech->type))) {
01503       ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", glue0 ? c1->name : c0->name);
01504       goto done;
01505    }
01506 
01507    audio_glue0_res = glue0->get_rtp_info(c0, &instance0);
01508    video_glue0_res = glue0->get_vrtp_info ? glue0->get_vrtp_info(c0, &vinstance0) : AST_RTP_GLUE_RESULT_FORBID;
01509 
01510    audio_glue1_res = glue1->get_rtp_info(c1, &instance1);
01511    video_glue1_res = glue1->get_vrtp_info ? glue1->get_vrtp_info(c1, &vinstance1) : AST_RTP_GLUE_RESULT_FORBID;
01512 
01513    /* If we are carrying video, and both sides are not going to remotely bridge... fail the native bridge */
01514    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)) {
01515       audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
01516    }
01517    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)) {
01518       audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
01519    }
01520    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(c0)) {
01521       codec0 = glue0->get_codec(c0);
01522    }
01523    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(c1)) {
01524       codec1 = glue1->get_codec(c1);
01525    }
01526 
01527    /* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
01528    if (audio_glue0_res != AST_RTP_GLUE_RESULT_REMOTE || audio_glue1_res != AST_RTP_GLUE_RESULT_REMOTE) {
01529       goto done;
01530    }
01531 
01532    /* Make sure we have matching codecs */
01533    if (!(codec0 & codec1)) {
01534       goto done;
01535    }
01536 
01537    /* Bridge media early */
01538    if (glue0->update_peer(c0, instance1, vinstance1, tinstance1, codec1, 0)) {
01539       ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n", c0->name, c1 ? c1->name : "<unspecified>");
01540    }
01541 
01542    res = 0;
01543 
01544 done:
01545    ast_channel_unlock(c0);
01546    ast_channel_unlock(c1);
01547 
01548    unref_instance_cond(&instance0);
01549    unref_instance_cond(&instance1);
01550    unref_instance_cond(&vinstance0);
01551    unref_instance_cond(&vinstance1);
01552    unref_instance_cond(&tinstance0);
01553    unref_instance_cond(&tinstance1);
01554 
01555    if (!res) {
01556       ast_debug(1, "Setting early bridge SDP of '%s' with that of '%s'\n", c0->name, c1 ? c1->name : "<unspecified>");
01557    }
01558 
01559    return res;
01560 }

void ast_rtp_instance_early_bridge_make_compatible ( struct ast_channel c0,
struct ast_channel c1 
)

Make two channels compatible for early bridging.

Parameters:
c0 First channel part of the bridge
c1 Second channel part of the bridge
Since:
1.8

Definition at line 1391 of file rtp_engine.c.

References ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_debug, 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, ast_channel::name, ast_channel::tech, ast_channel_tech::type, unref_instance_cond(), and ast_rtp_glue::update_peer.

Referenced by dial_exec_full(), and do_forward().

01392 {
01393    struct ast_rtp_instance *instance0 = NULL, *instance1 = NULL,
01394       *vinstance0 = NULL, *vinstance1 = NULL,
01395       *tinstance0 = NULL, *tinstance1 = NULL;
01396    struct ast_rtp_glue *glue0, *glue1;
01397    enum ast_rtp_glue_result audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID, video_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
01398    enum ast_rtp_glue_result audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID, video_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
01399    format_t codec0 = 0, codec1 = 0;
01400    int res = 0;
01401 
01402    /* Lock both channels so we can look for the glue that binds them together */
01403    ast_channel_lock(c0);
01404    while (ast_channel_trylock(c1)) {
01405       ast_channel_unlock(c0);
01406       usleep(1);
01407       ast_channel_lock(c0);
01408    }
01409 
01410    /* Grab glue that binds each channel to something using the RTP engine */
01411    if (!(glue0 = ast_rtp_instance_get_glue(c0->tech->type)) || !(glue1 = ast_rtp_instance_get_glue(c1->tech->type))) {
01412       ast_debug(1, "Can't find native functions for channel '%s'\n", glue0 ? c1->name : c0->name);
01413       goto done;
01414    }
01415 
01416    audio_glue0_res = glue0->get_rtp_info(c0, &instance0);
01417    video_glue0_res = glue0->get_vrtp_info ? glue0->get_vrtp_info(c0, &vinstance0) : AST_RTP_GLUE_RESULT_FORBID;
01418 
01419    audio_glue1_res = glue1->get_rtp_info(c1, &instance1);
01420    video_glue1_res = glue1->get_vrtp_info ? glue1->get_vrtp_info(c1, &vinstance1) : AST_RTP_GLUE_RESULT_FORBID;
01421 
01422    /* If we are carrying video, and both sides are not going to remotely bridge... fail the native bridge */
01423    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)) {
01424       audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
01425    }
01426    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)) {
01427       audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
01428    }
01429    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) {
01430       codec0 = glue0->get_codec(c0);
01431    }
01432    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) {
01433       codec1 = glue1->get_codec(c1);
01434    }
01435 
01436    /* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
01437    if (audio_glue0_res != AST_RTP_GLUE_RESULT_REMOTE || audio_glue1_res != AST_RTP_GLUE_RESULT_REMOTE) {
01438       goto done;
01439    }
01440 
01441    /* Make sure we have matching codecs */
01442    if (!(codec0 & codec1)) {
01443       goto done;
01444    }
01445 
01446    ast_rtp_codecs_payloads_copy(&instance0->codecs, &instance1->codecs, instance1);
01447 
01448    if (vinstance0 && vinstance1) {
01449       ast_rtp_codecs_payloads_copy(&vinstance0->codecs, &vinstance1->codecs, vinstance1);
01450    }
01451    if (tinstance0 && tinstance1) {
01452       ast_rtp_codecs_payloads_copy(&tinstance0->codecs, &tinstance1->codecs, tinstance1);
01453    }
01454 
01455         if (glue0->update_peer(c0, instance1, vinstance1, tinstance1, codec1, 0)) {
01456                 ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n", c0->name, c1 ? c1->name : "<unspecified>");
01457         }
01458 
01459    res = 0;
01460 
01461 done:
01462    ast_channel_unlock(c0);
01463    ast_channel_unlock(c1);
01464 
01465    unref_instance_cond(&instance0);
01466    unref_instance_cond(&instance1);
01467    unref_instance_cond(&vinstance0);
01468    unref_instance_cond(&vinstance1);
01469    unref_instance_cond(&tinstance0);
01470    unref_instance_cond(&tinstance1);
01471 
01472    if (!res) {
01473       ast_debug(1, "Seeded SDP of '%s' with that of '%s'\n", c0->name, c1 ? c1->name : "<unspecified>");
01474    }
01475 }

int ast_rtp_instance_fd ( struct ast_rtp_instance instance,
int  rtcp 
)

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

Parameters:
instance Instance to get the file descriptor for
rtcp Whether to retrieve the file descriptor for RTCP or not
Return values:
fd success
-1 failure
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 786 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_new(), mgcp_new(), process_sdp(), sip_new(), sip_set_rtp_peer(), skinny_new(), start_rtp(), and unistim_new().

00787 {
00788    return instance->engine->fd ? instance->engine->fd(instance, rtcp) : -1;
00789 }

struct ast_rtp_glue* ast_rtp_instance_get_active_glue ( struct ast_rtp_instance instance  ) 

Get the RTP glue in use on an RTP instance.

Parameters:
instance The RTP instance
Return values:
pointer to 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 1757 of file rtp_engine.c.

References ast_rtp_instance::glue.

01758 {
01759    return instance->glue;
01760 }

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:
instance The instance that we want to get the local address for
address An initialized address that may be overwritten if the local address is different
Return values:
0 address was not changed
1 address 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 419 of file rtp_engine.c.

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

00421 {
00422    if (ast_sockaddr_cmp(address, &instance->local_address) != 0) {
00423       ast_sockaddr_copy(address, &instance->local_address);
00424       return 1;
00425    }
00426 
00427    return 0;
00428 }

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:
instance The instance that we want to get the remote address for
address An initialized address that may be overwritten if the remote address is different
Return values:
0 address was not changed
1 address 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 436 of file rtp_engine.c.

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

Referenced by sip_set_rtp_peer().

00438 {
00439    if (ast_sockaddr_cmp(address, &instance->remote_address) != 0) {
00440       ast_sockaddr_copy(address, &instance->remote_address);
00441       return 1;
00442    }
00443 
00444    return 0;
00445 }

struct ast_rtp_instance* ast_rtp_instance_get_bridged ( struct ast_rtp_instance instance  ) 

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

Parameters:
instance The RTP instance that we want
Return values:
non-NULL success
NULL failure
Example usage:

This gets the RTP instance that instance0 is bridged to.

Since:
1.8

Definition at line 1386 of file rtp_engine.c.

References ast_rtp_instance::bridged.

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

01387 {
01388    return instance->bridged;
01389 }

struct ast_channel* ast_rtp_instance_get_chan ( struct ast_rtp_instance instance  ) 

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

Parameters:
instance The RTP instance
Return values:
pointer to 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 1762 of file rtp_engine.c.

References ast_rtp_instance::chan.

01763 {
01764    return instance->chan;
01765 }

struct ast_rtp_codecs* ast_rtp_instance_get_codecs ( struct ast_rtp_instance instance  ) 

Get the codecs structure of an RTP instance.

Parameters:
instance The RTP instance to get the codecs structure from
Example usage:

 struct ast_rtp_codecs *codecs = ast_rtp_instance_get_codecs(instance);

This gets the codecs structure on the RTP instance pointed to by 'instance'.

Since:
1.8

Definition at line 483 of file rtp_engine.c.

References ast_rtp_instance::codecs.

Referenced by __oh323_rtp_create(), add_codec_to_sdp(), add_noncodec_to_sdp(), add_sdp(), add_tcodec_to_sdp(), add_vcodec_to_sdp(), ast_rtp_dtmf_begin(), ast_rtp_read(), ast_rtp_sendcng(), ast_rtp_write(), bridge_p2p_rtp_write(), check_peer_ok(), create_addr_from_peer(), gtalk_alloc(), gtalk_is_answered(), gtalk_new(), gtalk_newcall(), jingle_new(), jingle_newcall(), multicast_rtp_write(), process_sdp(), process_sdp_a_audio(), set_dtmf_payload(), set_peer_capabilities(), setup_rtp_connection(), start_rtp(), and transmit_response_with_sdp().

00484 {
00485    return &instance->codecs;
00486 }

void* ast_rtp_instance_get_data ( struct ast_rtp_instance instance  ) 

Get the data portion of an RTP instance.

Parameters:
instance The 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 369 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_alt_remote_address_set(), ast_rtp_change_source(), ast_rtp_destroy(), 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(), 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().

00370 {
00371    return instance->data;
00372 }

struct ast_rtp_engine* ast_rtp_instance_get_engine ( struct ast_rtp_instance instance  ) 

Get the RTP engine in use on an RTP instance.

Parameters:
instance The RTP instance
Return values:
pointer to 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 1752 of file rtp_engine.c.

References ast_rtp_instance::engine.

01753 {
01754    return instance->engine;
01755 }

void* ast_rtp_instance_get_extended_prop ( struct ast_rtp_instance instance,
int  property 
)

Get the value of an RTP instance extended property.

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

Definition at line 460 of file rtp_engine.c.

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

00461 {
00462    if (instance->engine->extended_prop_get) {
00463       return instance->engine->extended_prop_get(instance, property);
00464    }
00465 
00466    return NULL;
00467 }

struct ast_rtp_glue* ast_rtp_instance_get_glue ( const char *  type  ) 

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

Parameters:
type Name of the glue we want
Return values:
non-NULL success
NULL failure
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 791 of file rtp_engine.c.

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

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

00792 {
00793    struct ast_rtp_glue *glue = NULL;
00794 
00795    AST_RWLIST_RDLOCK(&glues);
00796 
00797    AST_RWLIST_TRAVERSE(&glues, glue, entry) {
00798       if (!strcasecmp(glue->type, type)) {
00799          break;
00800       }
00801    }
00802 
00803    AST_RWLIST_UNLOCK(&glues);
00804 
00805    return glue;
00806 }

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.

Parameters:
instance The RTP instance
Return values:
timeout value
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 1742 of file rtp_engine.c.

References ast_rtp_instance::holdtimeout.

Referenced by check_rtp_timeout().

01743 {
01744    return instance->holdtimeout;
01745 }

int ast_rtp_instance_get_keepalive ( struct ast_rtp_instance instance  ) 

Get the RTP keepalive interval.

Parameters:
instance The RTP instance
Return values:
period Keepalive 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 1747 of file rtp_engine.c.

References ast_rtp_instance::keepalive.

Referenced by check_rtp_timeout().

01748 {
01749    return instance->keepalive;
01750 }

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:
instance The RTP instance to get the address from
address The 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 430 of file rtp_engine.c.

References ast_sockaddr_copy(), and ast_rtp_instance::local_address.

Referenced by add_sdp(), apply_directmedia_ha(), 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(), sip_acf_channel_read(), skinny_set_rtp_peer(), and start_rtp().

00432 {
00433    ast_sockaddr_copy(address, &instance->local_address);
00434 }

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:
instance The RTP instance to get the property from
property The property to get
Return values:
Current value 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 478 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().

00479 {
00480    return instance->properties[property];
00481 }

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:
instance Instance to get statistics on
field What quality statistic to retrieve
buf What buffer to put the result into
size Size of the above buffer
Return values:
non-NULL success
NULL failure
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 1577 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().

01578 {
01579    struct ast_rtp_instance_stats stats = { 0, };
01580    enum ast_rtp_instance_stat stat;
01581 
01582    /* Determine what statistics we will need to retrieve based on field passed in */
01583    if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY) {
01584       stat = AST_RTP_INSTANCE_STAT_ALL;
01585    } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER) {
01586       stat = AST_RTP_INSTANCE_STAT_COMBINED_JITTER;
01587    } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS) {
01588       stat = AST_RTP_INSTANCE_STAT_COMBINED_LOSS;
01589    } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT) {
01590       stat = AST_RTP_INSTANCE_STAT_COMBINED_RTT;
01591    } else {
01592       return NULL;
01593    }
01594 
01595    /* Attempt to actually retrieve the statistics we need to generate the quality string */
01596    if (ast_rtp_instance_get_stats(instance, &stats, stat)) {
01597       return NULL;
01598    }
01599 
01600    /* Now actually fill the buffer with the good information */
01601    if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY) {
01602       snprintf(buf, size, "ssrc=%i;themssrc=%u;lp=%u;rxjitter=%f;rxcount=%u;txjitter=%f;txcount=%u;rlp=%u;rtt=%f",
01603           stats.local_ssrc, stats.remote_ssrc, stats.rxploss, stats.txjitter, stats.rxcount, stats.rxjitter, stats.txcount, stats.txploss, stats.rtt);
01604    } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER) {
01605       snprintf(buf, size, "minrxjitter=%f;maxrxjitter=%f;avgrxjitter=%f;stdevrxjitter=%f;reported_minjitter=%f;reported_maxjitter=%f;reported_avgjitter=%f;reported_stdevjitter=%f;",
01606           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));
01607    } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS) {
01608       snprintf(buf, size, "minrxlost=%f;maxrxlost=%f;avgrxlost=%f;stdevrxlost=%f;reported_minlost=%f;reported_maxlost=%f;reported_avglost=%f;reported_stdevlost=%f;",
01609           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));
01610    } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT) {
01611       snprintf(buf, size, "minrtt=%f;maxrtt=%f;avgrtt=%f;stdevrtt=%f;", stats.minrtt, stats.maxrtt, stats.normdevrtt, stats.stdevrtt);
01612    }
01613 
01614    return buf;
01615 }

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:
instance The instance that we want to get the remote address for
address A 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 447 of file rtp_engine.c.

References ast_sockaddr_copy(), and ast_rtp_instance::remote_address.

Referenced by add_sdp(), apply_directmedia_ha(), 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(), gtalk_update_stun(), multicast_rtp_write(), multicast_send_control_packet(), oh323_set_rtp_peer(), process_cn_rfc3389(), process_dtmf_rfc2833(), process_sdp(), remote_bridge_loop(), sip_acf_channel_read(), skinny_set_rtp_peer(), and transmit_modify_with_sdp().

00449 {
00450    ast_sockaddr_copy(address, &instance->remote_address);
00451 }

struct ast_srtp* ast_rtp_instance_get_srtp ( struct ast_rtp_instance instance  ) 

Obtain the SRTP instance associated with an RTP instance.

Parameters:
instance the RTP instance
Return values:
the SRTP instance on success
NULL if no SRTP instance exists

Definition at line 1813 of file rtp_engine.c.

References ast_rtp_instance::srtp.

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

01814 {
01815    return instance->srtp;
01816 }

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:
instance Instance to get statistics on
stats Structure to put results into
stat What statistic(s) to retrieve
Return values:
0 success
-1 failure
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 1572 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(), sdp_crypto_activate(), show_chanstats_cb(), and sip_acf_channel_read().

01573 {
01574    return instance->engine->get_stat ? instance->engine->get_stat(instance, stats, stat) : -1;
01575 }

int ast_rtp_instance_get_timeout ( struct ast_rtp_instance instance  ) 

Get the RTP timeout value.

Parameters:
instance The RTP instance
Return values:
timeout value
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 1737 of file rtp_engine.c.

References ast_rtp_instance::timeout.

Referenced by check_rtp_timeout().

01738 {
01739    return instance->timeout;
01740 }

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:
chan Our own Asterisk channel
instance The first RTP instance
peer The peer Asterisk channel
Return values:
0 success
-1 failure
Example usage:

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

Since:
1.8

Definition at line 1661 of file rtp_engine.c.

References ao2_ref, ast_channel_lock, ast_channel_unlock, ast_rtp_instance_get_glue(), ast_rtp_instance::chan, ast_rtp_instance::engine, ast_rtp_glue::get_rtp_info, ast_rtp_instance::glue, ast_rtp_engine::make_compatible, ast_channel::tech, and ast_channel_tech::type.

Referenced by sip_setoption().

01662 {
01663    struct ast_rtp_glue *glue;
01664    struct ast_rtp_instance *peer_instance = NULL;
01665    int res = -1;
01666 
01667    if (!instance->engine->make_compatible) {
01668       return -1;
01669    }
01670 
01671    ast_channel_lock(peer);
01672 
01673    if (!(glue = ast_rtp_instance_get_glue(peer->tech->type))) {
01674       ast_channel_unlock(peer);
01675       return -1;
01676    }
01677 
01678    glue->get_rtp_info(peer, &peer_instance);
01679 
01680    if (!peer_instance || peer_instance->engine != instance->engine) {
01681       ast_channel_unlock(peer);
01682       ao2_ref(peer_instance, -1);
01683       peer_instance = NULL;
01684       return -1;
01685    }
01686 
01687    res = instance->engine->make_compatible(chan, instance, peer, peer_instance);
01688 
01689    ast_channel_unlock(peer);
01690 
01691    ao2_ref(peer_instance, -1);
01692    peer_instance = NULL;
01693 
01694    return res;
01695 }

struct ast_rtp_instance* ast_rtp_instance_new ( const char *  engine_name,
struct sched_context sched,
const struct ast_sockaddr sa,
void *  data 
)

Create a new RTP instance.

Parameters:
engine_name Name of the engine to use for the RTP instance
sched Scheduler context that the RTP engine may want to use
sa Address we want to bind to
data Unique data for the engine
Return values:
non-NULL success
NULL failure
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 308 of file rtp_engine.c.

References ao2_alloc, ao2_ref, ast_debug, ast_log(), ast_module_ref(), ast_module_unref(), AST_RWLIST_FIRST, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_sockaddr_copy(), ast_strlen_zero(), ast_rtp_engine::entry, instance_destructor(), LOG_ERROR, ast_rtp_engine::mod, ast_rtp_engine::name, and sched.

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

00311 {
00312    struct ast_sockaddr address = {{0,}};
00313    struct ast_rtp_instance *instance = NULL;
00314    struct ast_rtp_engine *engine = NULL;
00315 
00316    AST_RWLIST_RDLOCK(&engines);
00317 
00318    /* If an engine name was specified try to use it or otherwise use the first one registered */
00319    if (!ast_strlen_zero(engine_name)) {
00320       AST_RWLIST_TRAVERSE(&engines, engine, entry) {
00321          if (!strcmp(engine->name, engine_name)) {
00322             break;
00323          }
00324       }
00325    } else {
00326       engine = AST_RWLIST_FIRST(&engines);
00327    }
00328 
00329    /* If no engine was actually found bail out now */
00330    if (!engine) {
00331       ast_log(LOG_ERROR, "No RTP engine was found. Do you have one loaded?\n");
00332       AST_RWLIST_UNLOCK(&engines);
00333       return NULL;
00334    }
00335 
00336    /* Bump up the reference count before we return so the module can not be unloaded */
00337    ast_module_ref(engine->mod);
00338 
00339    AST_RWLIST_UNLOCK(&engines);
00340 
00341    /* Allocate a new RTP instance */
00342    if (!(instance = ao2_alloc(sizeof(*instance), instance_destructor))) {
00343       ast_module_unref(engine->mod);
00344       return NULL;
00345    }
00346    instance->engine = engine;
00347    ast_sockaddr_copy(&instance->local_address, sa);
00348    ast_sockaddr_copy(&address, sa);
00349 
00350    ast_debug(1, "Using engine '%s' for RTP instance '%p'\n", engine->name, instance);
00351 
00352    /* And pass it off to the engine to setup */
00353    if (instance->engine->new(instance, sched, &address, data)) {
00354       ast_debug(1, "Engine '%s' failed to setup RTP instance '%p'\n", engine->name, instance);
00355       ao2_ref(instance, -1);
00356       return NULL;
00357    }
00358 
00359    ast_debug(1, "RTP instance '%p' is setup and ready to go\n", instance);
00360 
00361    return instance;
00362 }

struct ast_frame* ast_rtp_instance_read ( struct ast_rtp_instance instance,
int  rtcp 
)

Receive a frame over RTP.

Parameters:
instance The RTP instance to receive frame on
rtcp Whether to read in RTCP or not
Return values:
non-NULL success
NULL failure
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 379 of file rtp_engine.c.

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

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

00380 {
00381    return instance->engine->read(instance, rtcp);
00382 }

int ast_rtp_instance_sendcng ( struct ast_rtp_instance instance,
int  level 
)

Send a comfort noise packet to the RTP instance.

Parameters:
instance The RTP instance
level Magnitude of the noise level
Return values:
0 Success
non-zero Failure

Definition at line 1818 of file rtp_engine.c.

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

Referenced by check_rtp_timeout().

01819 {
01820    if (instance->engine->sendcng) {
01821       return instance->engine->sendcng(instance, level);
01822    }
01823 
01824    return -1;
01825 }

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:
instance The RTP instance to change the address on
address Address to set it to
Return values:
0 success
-1 failure
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 405 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().

00407 {
00408    ast_sockaddr_copy(&instance->alt_remote_address, address);
00409 
00410    /* oink */
00411 
00412    if (instance->engine->alt_remote_address_set) {
00413       instance->engine->alt_remote_address_set(instance, &instance->alt_remote_address);
00414    }
00415 
00416    return 0;
00417 }

void ast_rtp_instance_set_data ( struct ast_rtp_instance instance,
void *  data 
)

Set the data portion of an RTP instance.

Parameters:
instance The RTP instance to manipulate
data Pointer 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 364 of file rtp_engine.c.

References ast_rtp_instance::data.

Referenced by multicast_rtp_new().

00365 {
00366    instance->data = data;
00367 }

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:
instance The RTP instance to set the extended property on
property The extended property to set
value The value to set the extended property to
Since:
1.8

Definition at line 453 of file rtp_engine.c.

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

00454 {
00455    if (instance->engine->extended_prop_set) {
00456       instance->engine->extended_prop_set(instance, property, value);
00457    }
00458 }

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:
instance The RTP instance
timeout Value 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 1727 of file rtp_engine.c.

References ast_rtp_instance::holdtimeout.

Referenced by check_rtp_timeout(), and dialog_initialize_rtp().

01728 {
01729    instance->holdtimeout = timeout;
01730 }

void ast_rtp_instance_set_keepalive ( struct ast_rtp_instance instance,
int  timeout 
)

Set the RTP keepalive interval.

Parameters:
instance The RTP instance
period Value 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 1732 of file rtp_engine.c.

References ast_rtp_instance::keepalive.

Referenced by dialog_initialize_rtp().

01733 {
01734    instance->keepalive = interval;
01735 }

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:
instance The RTP instance to change the address on
address Address to set it to
Return values:
0 success
-1 failure
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 384 of file rtp_engine.c.

References ast_sockaddr_copy(), and ast_rtp_instance::local_address.

Referenced by ast_rtp_new().

00386 {
00387    ast_sockaddr_copy(&instance->local_address, address);
00388    return 0;
00389 }

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:
instance The RTP instance to set the property on
property The property to modify
value The 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 469 of file rtp_engine.c.

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

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

00470 {
00471    instance->properties[property] = value;
00472 
00473    if (instance->engine->prop_set) {
00474       instance->engine->prop_set(instance, property, value);
00475    }
00476 }

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:
instance Instance to set the QoS parameters on
tos Terms of service value
cos Class of service value
desc What is setting the QoS values
Return values:
0 success
-1 failure
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 774 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().

00775 {
00776    return instance->engine->qos ? instance->engine->qos(instance, tos, cos, desc) : -1;
00777 }

int ast_rtp_instance_set_read_format ( struct ast_rtp_instance instance,
format_t  format 
)

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

Parameters:
instance The RTP instance to change read format on
format Format that frames are wanted in
Return values:
0 success
-1 failure
Example usage:

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

Since:
1.8

Definition at line 1651 of file rtp_engine.c.

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

Referenced by sip_new(), and sip_setoption().

01652 {
01653    return instance->engine->set_read_format ? instance->engine->set_read_format(instance, format) : -1;
01654 }

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:
instance The RTP instance to change the address on
address Address to set it to
Return values:
0 success
-1 failure
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 391 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(), multicast_rtp_request(), process_sdp(), setup_rtp_connection(), and start_rtp().

00393 {
00394    ast_sockaddr_copy(&instance->remote_address, address);
00395 
00396    /* moo */
00397 
00398    if (instance->engine->remote_address_set) {
00399       instance->engine->remote_address_set(instance, &instance->remote_address);
00400    }
00401 
00402    return 0;
00403 }

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:
chan Channel to set the statistics on
instance The 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 1617 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().

01618 {
01619    char quality_buf[AST_MAX_USER_FIELD], *quality;
01620    struct ast_channel *bridge = ast_bridged_channel(chan);
01621 
01622    if ((quality = ast_rtp_instance_get_quality(instance, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
01623       pbx_builtin_setvar_helper(chan, "RTPAUDIOQOS", quality);
01624       if (bridge) {
01625          pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSBRIDGED", quality);
01626       }
01627    }
01628 
01629    if ((quality = ast_rtp_instance_get_quality(instance, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, quality_buf, sizeof(quality_buf)))) {
01630       pbx_builtin_setvar_helper(chan, "RTPAUDIOQOSJITTER", quality);
01631       if (bridge) {
01632          pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSJITTERBRIDGED", quality);
01633       }
01634    }
01635 
01636    if ((quality = ast_rtp_instance_get_quality(instance, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, quality_buf, sizeof(quality_buf)))) {
01637       pbx_builtin_setvar_helper(chan, "RTPAUDIOQOSLOSS", quality);
01638       if (bridge) {
01639          pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSLOSSBRIDGED", quality);
01640       }
01641    }
01642 
01643    if ((quality = ast_rtp_instance_get_quality(instance, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, quality_buf, sizeof(quality_buf)))) {
01644       pbx_builtin_setvar_helper(chan, "RTPAUDIOQOSRTT", quality);
01645       if (bridge) {
01646          pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSRTTBRIDGED", quality);
01647       }
01648    }
01649 }

void ast_rtp_instance_set_timeout ( struct ast_rtp_instance instance,
int  timeout 
)

Set the RTP timeout value.

Parameters:
instance The RTP instance
timeout Value 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 1722 of file rtp_engine.c.

References ast_rtp_instance::timeout.

Referenced by check_rtp_timeout(), and dialog_initialize_rtp().

01723 {
01724    instance->timeout = timeout;
01725 }

int ast_rtp_instance_set_write_format ( struct ast_rtp_instance instance,
format_t  format 
)

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

Parameters:
instance The RTP instance to change write format on
format Format that frames will be provided in
Return values:
0 success
-1 failure
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 1656 of file rtp_engine.c.

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

Referenced by sip_new(), and sip_setoption().

01657 {
01658    return instance->engine->set_write_format ? instance->engine->set_write_format(instance, format) : -1;
01659 }

void ast_rtp_instance_stop ( struct ast_rtp_instance instance  ) 

Stop an RTP instance.

Parameters:
instance Instance 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 779 of file rtp_engine.c.

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

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

00780 {
00781    if (instance->engine->stop) {
00782       instance->engine->stop(instance);
00783    }
00784 }

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:
instance The RTP instance
suggestion The suggested destination
username Optionally 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 1713 of file rtp_engine.c.

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

Referenced by gtalk_update_stun(), and jingle_update_stun().

01716 {
01717    if (instance->engine->stun_request) {
01718       instance->engine->stun_request(instance, suggestion, username);
01719    }
01720 }

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:
instance Instance 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 760 of file rtp_engine.c.

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

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

00761 {
00762    if (instance->engine->update_source) {
00763       instance->engine->update_source(instance);
00764    }
00765 }

int ast_rtp_instance_write ( struct ast_rtp_instance instance,
struct ast_frame frame 
)

Send a frame out over RTP.

Parameters:
instance The RTP instance to send frame out on
frame the frame to send out
Return values:
0 success
-1 failure
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 374 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().

00375 {
00376    return instance->engine->write(instance, frame);
00377 }

char* ast_rtp_lookup_mime_multiple2 ( struct ast_str buf,
const format_t  capability,
const int  asterisk_format,
enum ast_rtp_options  options 
)

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

Parameters:
buf Buffer to put the mime output into
capability Formats that we are looking up
asterisk_format Non-zero if the given capability are Asterisk format capabilities
options Additional options that may change the result
Return values:
non-NULL success
NULL failure
Example usage:

 char buf[256] = "";
 char *mime = ast_rtp_lookup_mime_multiple2(&buf, sizeof(buf), AST_FORMAT_ULAW | AST_FORMAT_ALAW, 1, 0);

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

Since:
1.8

Definition at line 703 of file rtp_engine.c.

References ast_rtp_lookup_mime_subtype2(), AST_RTP_MAX, ast_str_append(), ast_str_buffer(), format, and name.

Referenced by process_sdp().

00704 {
00705    format_t format;
00706    int found = 0;
00707 
00708    if (!buf) {
00709       return NULL;
00710    }
00711 
00712    ast_str_append(&buf, 0, "0x%llx (", (unsigned long long) capability);
00713 
00714    for (format = 1; format < AST_RTP_MAX; format <<= 1) {
00715       if (capability & format) {
00716          const char *name = ast_rtp_lookup_mime_subtype2(asterisk_format, format, options);
00717          ast_str_append(&buf, 0, "%s|", name);
00718          found = 1;
00719       }
00720    }
00721 
00722    ast_str_append(&buf, 0, "%s", found ? ")" : "nothing)");
00723 
00724    return ast_str_buffer(buf);
00725 }

const char* ast_rtp_lookup_mime_subtype2 ( const int  asterisk_format,
const format_t  code,
enum ast_rtp_options  options 
)

Retrieve mime subtype information on a payload.

Parameters:
asterisk_format Non-zero if the given code is an Asterisk format value
code Format to look up
options Additional options that may change the result
Return values:
Mime subtype success
NULL failure
Example usage:

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

This looks up the mime subtype for the ULAW format.

Since:
1.8

Definition at line 673 of file rtp_engine.c.

References ARRAY_LEN, AST_FORMAT_G726_AAL2, ast_rtp_mime_types, AST_RTP_OPT_G726_NONSTANDARD, ast_rtp_payload_type::asterisk_format, ast_rtp_mime_type::payload_type, 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(), transmit_connect(), transmit_connect_with_sdp(), transmit_modify_request(), and transmit_modify_with_sdp().

00674 {
00675    int i;
00676 
00677    for (i = 0; i < ARRAY_LEN(ast_rtp_mime_types); i++) {
00678       if (ast_rtp_mime_types[i].payload_type.code == code && ast_rtp_mime_types[i].payload_type.asterisk_format == asterisk_format) {
00679          if (asterisk_format && (code == AST_FORMAT_G726_AAL2) && (options & AST_RTP_OPT_G726_NONSTANDARD)) {
00680             return "G726-32";
00681          } else {
00682             return ast_rtp_mime_types[i].subtype;
00683          }
00684       }
00685    }
00686 
00687    return "";
00688 }

unsigned int ast_rtp_lookup_sample_rate2 ( int  asterisk_format,
format_t  code 
)

Get the sample rate associated with known RTP payload types.

Parameters:
asterisk_format True if the value in the 'code' parameter is an AST_FORMAT value
code Format code, either from AST_FORMAT list or from AST_RTP list
Returns:
the sample rate if the format was found, zero if it was not found
Since:
1.8

Definition at line 690 of file rtp_engine.c.

References ARRAY_LEN, ast_rtp_mime_types, ast_rtp_payload_type::asterisk_format, ast_rtp_mime_type::payload_type, and ast_rtp_mime_type::sample_rate.

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

00691 {
00692    unsigned int i;
00693 
00694    for (i = 0; i < ARRAY_LEN(ast_rtp_mime_types); ++i) {
00695       if ((ast_rtp_mime_types[i].payload_type.code == code) && (ast_rtp_mime_types[i].payload_type.asterisk_format == asterisk_format)) {
00696          return ast_rtp_mime_types[i].sample_rate;
00697       }
00698    }
00699 
00700    return 0;
00701 }

int ast_rtp_red_buffer ( struct ast_rtp_instance instance,
struct ast_frame frame 
)

Buffer a frame in an RTP instance for RED.

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

Definition at line 1567 of file rtp_engine.c.

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

Referenced by sip_write().

01568 {
01569    return instance->engine->red_buffer ? instance->engine->red_buffer(instance, frame) : -1;
01570 }

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:
instance The instance to initialize RED support on
buffer_time How long to buffer before sending
payloads Payload values
generations Number of generations
Return values:
0 success
-1 failure
Since:
1.8

Definition at line 1562 of file rtp_engine.c.

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

Referenced by process_sdp().

01563 {
01564    return instance->engine->red_init ? instance->engine->red_init(instance, buffer_time, payloads, generations) : -1;
01565 }

static void instance_destructor ( void *  obj  )  [static]

Definition at line 281 of file rtp_engine.c.

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

Referenced by ast_rtp_instance_new().

00282 {
00283    struct ast_rtp_instance *instance = obj;
00284 
00285    /* Pass us off to the engine to destroy */
00286    if (instance->data && instance->engine->destroy(instance)) {
00287       ast_debug(1, "Engine '%s' failed to destroy RTP instance '%p'\n", instance->engine->name, instance);
00288       return;
00289    }
00290 
00291    if (instance->srtp) {
00292       res_srtp->destroy(instance->srtp);
00293    }
00294 
00295    /* Drop our engine reference */
00296    ast_module_unref(instance->engine->mod);
00297 
00298    ast_debug(1, "Destroyed RTP instance '%p'\n", instance);
00299 }

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 808 of file rtp_engine.c.

References AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, ast_channel_unlock, ast_debug, ast_framehook_list_is_empty(), ast_frfree, ast_poll_channel_add(), ast_read(), ast_channel::audiohooks, ast_rtp_instance::bridged, ast_rtp_instance::engine, ast_channel::framehooks, ast_rtp_engine::local_bridge, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::rawreadformat, ast_channel::rawwriteformat, and ast_channel::tech_pvt.

Referenced by ast_rtp_instance_bridge().

00809 {
00810    enum ast_bridge_result res = AST_BRIDGE_FAILED;
00811    struct ast_channel *who = NULL, *other = NULL, *cs[3] = { NULL, };
00812    struct ast_frame *fr = NULL;
00813 
00814    /* Start locally bridging both instances */
00815    if (instance0->engine->local_bridge && instance0->engine->local_bridge(instance0, instance1)) {
00816       ast_debug(1, "Failed to locally bridge %s to %s, backing out.\n", c0->name, c1->name);
00817       ast_channel_unlock(c0);
00818       ast_channel_unlock(c1);
00819       return AST_BRIDGE_FAILED_NOWARN;
00820    }
00821    if (instance1->engine->local_bridge && instance1->engine->local_bridge(instance1, instance0)) {
00822       ast_debug(1, "Failed to locally bridge %s to %s, backing out.\n", c1->name, c0->name);
00823       if (instance0->engine->local_bridge) {
00824          instance0->engine->local_bridge(instance0, NULL);
00825       }
00826       ast_channel_unlock(c0);
00827       ast_channel_unlock(c1);
00828       return AST_BRIDGE_FAILED_NOWARN;
00829    }
00830 
00831    ast_channel_unlock(c0);
00832    ast_channel_unlock(c1);
00833 
00834    instance0->bridged = instance1;
00835    instance1->bridged = instance0;
00836 
00837    ast_poll_channel_add(c0, c1);
00838 
00839    /* Hop into a loop waiting for a frame from either channel */
00840    cs[0] = c0;
00841    cs[1] = c1;
00842    cs[2] = NULL;
00843    for (;;) {
00844       /* If the underlying formats have changed force this bridge to break */
00845       if ((c0->rawreadformat != c1->rawwriteformat) || (c1->rawreadformat != c0->rawwriteformat)) {
00846          ast_debug(1, "rtp-engine-local-bridge: Oooh, formats changed, backing out\n");
00847          res = AST_BRIDGE_FAILED_NOWARN;
00848          break;
00849       }
00850       /* Check if anything changed */
00851       if ((c0->tech_pvt != pvt0) ||
00852           (c1->tech_pvt != pvt1) ||
00853           (c0->masq || c0->masqr || c1->masq || c1->masqr) ||
00854           (c0->monitor || c0->audiohooks || c1->monitor || c1->audiohooks) ||
00855           (!ast_framehook_list_is_empty(c0->framehooks) || !ast_framehook_list_is_empty(c1->framehooks))) {
00856          ast_debug(1, "rtp-engine-local-bridge: Oooh, something is weird, backing out\n");
00857          /* 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 */
00858          if ((c0->masq || c0->masqr) && (fr = ast_read(c0))) {
00859             ast_frfree(fr);
00860          }
00861          if ((c1->masq || c1->masqr) && (fr = ast_read(c1))) {
00862             ast_frfree(fr);
00863          }
00864          res = AST_BRIDGE_RETRY;
00865          break;
00866       }
00867       /* Wait on a channel to feed us a frame */
00868       if (!(who = ast_waitfor_n(cs, 2, &timeoutms))) {
00869          if (!timeoutms) {
00870             res = AST_BRIDGE_RETRY;
00871             break;
00872          }
00873          ast_debug(2, "rtp-engine-local-bridge: Ooh, empty read...\n");
00874          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
00875             break;
00876          }
00877          continue;
00878       }
00879       /* Read in frame from channel */
00880       fr = ast_read(who);
00881       other = (who == c0) ? c1 : c0;
00882       /* Depending on the frame we may need to break out of our bridge */
00883       if (!fr || ((fr->frametype == AST_FRAME_DTMF_BEGIN || fr->frametype == AST_FRAME_DTMF_END) &&
00884              ((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) |
00885              ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1)))) {
00886          /* Record received frame and who */
00887          *fo = fr;
00888          *rc = who;
00889          ast_debug(1, "rtp-engine-local-bridge: Ooh, got a %s\n", fr ? "digit" : "hangup");
00890          res = AST_BRIDGE_COMPLETE;
00891          break;
00892       } else if ((fr->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
00893          if ((fr->subclass.integer == AST_CONTROL_HOLD) ||
00894              (fr->subclass.integer == AST_CONTROL_UNHOLD) ||
00895              (fr->subclass.integer == AST_CONTROL_VIDUPDATE) ||
00896              (fr->subclass.integer == AST_CONTROL_SRCUPDATE) ||
00897              (fr->subclass.integer == AST_CONTROL_T38_PARAMETERS) ||
00898              (fr->subclass.integer == AST_CONTROL_UPDATE_RTP_PEER)) {
00899             /* If we are going on hold, then break callback mode and P2P bridging */
00900             if (fr->subclass.integer == AST_CONTROL_HOLD) {
00901                if (instance0->engine->local_bridge) {
00902                   instance0->engine->local_bridge(instance0, NULL);
00903                }
00904                if (instance1->engine->local_bridge) {
00905                   instance1->engine->local_bridge(instance1, NULL);
00906                }
00907                instance0->bridged = NULL;
00908                instance1->bridged = NULL;
00909             } else if (fr->subclass.integer == AST_CONTROL_UNHOLD) {
00910                if (instance0->engine->local_bridge) {
00911                   instance0->engine->local_bridge(instance0, instance1);
00912                }
00913                if (instance1->engine->local_bridge) {
00914                   instance1->engine->local_bridge(instance1, instance0);
00915                }
00916                instance0->bridged = instance1;
00917                instance1->bridged = instance0;
00918             }
00919             /* Since UPDATE_BRIDGE_PEER is only used by the bridging code, don't forward it */
00920             if (fr->subclass.integer != AST_CONTROL_UPDATE_RTP_PEER) {
00921                ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
00922             }
00923             ast_frfree(fr);
00924          } else if (fr->subclass.integer == AST_CONTROL_CONNECTED_LINE) {
00925             if (ast_channel_connected_line_macro(who, other, fr, other == c0, 1)) {
00926                ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
00927             }
00928             ast_frfree(fr);
00929          } else if (fr->subclass.integer == AST_CONTROL_REDIRECTING) {
00930             if (ast_channel_redirecting_macro(who, other, fr, other == c0, 1)) {
00931                ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
00932             }
00933             ast_frfree(fr);
00934          } else {
00935             *fo = fr;
00936             *rc = who;
00937             ast_debug(1, "rtp-engine-local-bridge: Got a FRAME_CONTROL (%d) frame on channel %s\n", fr->subclass.integer, who->name);
00938             res = AST_BRIDGE_COMPLETE;
00939             break;
00940          }
00941       } else {
00942          if ((fr->frametype == AST_FRAME_DTMF_BEGIN) ||
00943              (fr->frametype == AST_FRAME_DTMF_END) ||
00944              (fr->frametype == AST_FRAME_VOICE) ||
00945              (fr->frametype == AST_FRAME_VIDEO) ||
00946              (fr->frametype == AST_FRAME_IMAGE) ||
00947              (fr->frametype == AST_FRAME_HTML) ||
00948              (fr->frametype == AST_FRAME_MODEM) ||
00949              (fr->frametype == AST_FRAME_TEXT)) {
00950             ast_write(other, fr);
00951          }
00952 
00953          ast_frfree(fr);
00954       }
00955       /* Swap priority */
00956       cs[2] = cs[0];
00957       cs[0] = cs[1];
00958       cs[1] = cs[2];
00959    }
00960 
00961    /* Stop locally bridging both instances */
00962    if (instance0->engine->local_bridge) {
00963       instance0->engine->local_bridge(instance0, NULL);
00964    }
00965    if (instance1->engine->local_bridge) {
00966       instance1->engine->local_bridge(instance1, NULL);
00967    }
00968 
00969    instance0->bridged = NULL;
00970    instance1->bridged = NULL;
00971 
00972    ast_poll_channel_del(c0, c1);
00973 
00974    return res;
00975 }

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,
format_t  codec0,
format_t  codec1,
int  timeoutms,
int  flags,
struct ast_frame **  fo,
struct ast_channel **  rc,
void *  pvt0,
void *  pvt1 
) [static]

Definition at line 977 of file rtp_engine.c.

References AST_BRIDGE_COMPLETE, AST_BRIDGE_FAILED, AST_BRIDGE_RETRY, ast_channel_connected_line_macro(), ast_channel_redirecting_macro(), ast_channel_unlock, ast_check_hangup(), AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_REDIRECTING, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, ast_debug, 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(), ast_indicate_data(), ast_log(), ast_poll_channel_add(), ast_read(), ast_rtp_instance_get_remote_address(), ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_waitfor_n(), ast_write(), ast_channel::audiohooks, ast_rtp_instance::bridged, ast_frame::data, ast_frame::datalen, ast_channel::framehooks, ast_frame::frametype, ast_rtp_glue::get_codec, ast_frame_subclass::integer, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_frame::ptr, ast_frame::subclass, t1, ast_channel::tech_pvt, and ast_rtp_glue::update_peer.

Referenced by ast_rtp_instance_bridge().

00981 {
00982    enum ast_bridge_result res = AST_BRIDGE_FAILED;
00983    struct ast_channel *who = NULL, *other = NULL, *cs[3] = { NULL, };
00984    format_t oldcodec0 = codec0, oldcodec1 = codec1;
00985    struct ast_sockaddr ac1 = {{0,}}, vac1 = {{0,}}, tac1 = {{0,}}, ac0 = {{0,}}, vac0 = {{0,}}, tac0 = {{0,}};
00986    struct ast_sockaddr t1 = {{0,}}, vt1 = {{0,}}, tt1 = {{0,}}, t0 = {{0,}}, vt0 = {{0,}}, tt0 = {{0,}};
00987    struct ast_frame *fr = NULL;
00988 
00989    /* Test the first channel */
00990    if (!(glue0->update_peer(c0, instance1, vinstance1, tinstance1, codec1, 0))) {
00991       ast_rtp_instance_get_remote_address(instance1, &ac1);
00992       if (vinstance1) {
00993          ast_rtp_instance_get_remote_address(vinstance1, &vac1);
00994       }
00995       if (tinstance1) {
00996          ast_rtp_instance_get_remote_address(tinstance1, &tac1);
00997       }
00998    } else {
00999       ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name);
01000    }
01001 
01002    /* Test the second channel */
01003    if (!(glue1->update_peer(c1, instance0, vinstance0, tinstance0, codec0, 0))) {
01004       ast_rtp_instance_get_remote_address(instance0, &ac0);
01005       if (vinstance0) {
01006          ast_rtp_instance_get_remote_address(instance0, &vac0);
01007       }
01008       if (tinstance0) {
01009          ast_rtp_instance_get_remote_address(instance0, &tac0);
01010       }
01011    } else {
01012       ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c1->name, c0->name);
01013    }
01014 
01015    ast_channel_unlock(c0);
01016    ast_channel_unlock(c1);
01017 
01018    instance0->bridged = instance1;
01019    instance1->bridged = instance0;
01020 
01021    ast_poll_channel_add(c0, c1);
01022 
01023    /* Go into a loop handling any stray frames that may come in */
01024    cs[0] = c0;
01025    cs[1] = c1;
01026    cs[2] = NULL;
01027    for (;;) {
01028       /* Check if anything changed */
01029       if ((c0->tech_pvt != pvt0) ||
01030           (c1->tech_pvt != pvt1) ||
01031           (c0->masq || c0->masqr || c1->masq || c1->masqr) ||
01032           (c0->monitor || c0->audiohooks || c1->monitor || c1->audiohooks) ||
01033           (!ast_framehook_list_is_empty(c0->framehooks) || !ast_framehook_list_is_empty(c1->framehooks))) {
01034          ast_debug(1, "Oooh, something is weird, backing out\n");
01035          res = AST_BRIDGE_RETRY;
01036          break;
01037       }
01038 
01039       /* Check if they have changed their address */
01040       ast_rtp_instance_get_remote_address(instance1, &t1);
01041       if (vinstance1) {
01042          ast_rtp_instance_get_remote_address(vinstance1, &vt1);
01043       }
01044       if (tinstance1) {
01045          ast_rtp_instance_get_remote_address(tinstance1, &tt1);
01046       }
01047       if (glue1->get_codec) {
01048          codec1 = glue1->get_codec(c1);
01049       }
01050 
01051       ast_rtp_instance_get_remote_address(instance0, &t0);
01052       if (vinstance0) {
01053          ast_rtp_instance_get_remote_address(vinstance0, &vt0);
01054       }
01055       if (tinstance0) {
01056          ast_rtp_instance_get_remote_address(tinstance0, &tt0);
01057       }
01058       if (glue0->get_codec) {
01059          codec0 = glue0->get_codec(c0);
01060       }
01061 
01062       if ((ast_sockaddr_cmp(&t1, &ac1)) ||
01063           (vinstance1 && ast_sockaddr_cmp(&vt1, &vac1)) ||
01064           (tinstance1 && ast_sockaddr_cmp(&tt1, &tac1)) ||
01065           (codec1 != oldcodec1)) {
01066          ast_debug(1, "Oooh, '%s' changed end address to %s (format %s)\n",
01067               c1->name, ast_sockaddr_stringify(&t1),
01068               ast_getformatname(codec1));
01069          ast_debug(1, "Oooh, '%s' changed end vaddress to %s (format %s)\n",
01070               c1->name, ast_sockaddr_stringify(&vt1),
01071               ast_getformatname(codec1));
01072          ast_debug(1, "Oooh, '%s' changed end taddress to %s (format %s)\n",
01073               c1->name, ast_sockaddr_stringify(&tt1),
01074               ast_getformatname(codec1));
01075          ast_debug(1, "Oooh, '%s' was %s/(format %s)\n",
01076               c1->name, ast_sockaddr_stringify(&ac1),
01077               ast_getformatname(oldcodec1));
01078          ast_debug(1, "Oooh, '%s' was %s/(format %s)\n",
01079               c1->name, ast_sockaddr_stringify(&vac1),
01080               ast_getformatname(oldcodec1));
01081          ast_debug(1, "Oooh, '%s' was %s/(format %s)\n",
01082               c1->name, ast_sockaddr_stringify(&tac1),
01083               ast_getformatname(oldcodec1));
01084          if (glue0->update_peer(c0,
01085                       ast_sockaddr_isnull(&t1)  ? NULL : instance1,
01086                       ast_sockaddr_isnull(&vt1) ? NULL : vinstance1,
01087                       ast_sockaddr_isnull(&tt1) ? NULL : tinstance1,
01088                       codec1, 0)) {
01089             ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c0->name, c1->name);
01090          }
01091          ast_sockaddr_copy(&ac1, &t1);
01092          ast_sockaddr_copy(&vac1, &vt1);
01093          ast_sockaddr_copy(&tac1, &tt1);
01094          oldcodec1 = codec1;
01095       }
01096       if ((ast_sockaddr_cmp(&t0, &ac0)) ||
01097           (vinstance0 && ast_sockaddr_cmp(&vt0, &vac0)) ||
01098           (tinstance0 && ast_sockaddr_cmp(&tt0, &tac0)) ||
01099           (codec0 != oldcodec0)) {
01100          ast_debug(1, "Oooh, '%s' changed end address to %s (format %s)\n",
01101               c0->name, ast_sockaddr_stringify(&t0),
01102               ast_getformatname(codec0));
01103          ast_debug(1, "Oooh, '%s' was %s/(format %s)\n",
01104               c0->name, ast_sockaddr_stringify(&ac0),
01105               ast_getformatname(oldcodec0));
01106          if (glue1->update_peer(c1, t0.len ? instance0 : NULL,
01107                   vt0.len ? vinstance0 : NULL,
01108                   tt0.len ? tinstance0 : NULL,
01109                   codec0, 0)) {
01110             ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c1->name, c0->name);
01111          }
01112          ast_sockaddr_copy(&ac0, &t0);
01113          ast_sockaddr_copy(&vac0, &vt0);
01114          ast_sockaddr_copy(&tac0, &tt0);
01115          oldcodec0 = codec0;
01116       }
01117 
01118       /* Wait for frame to come in on the channels */
01119       if (!(who = ast_waitfor_n(cs, 2, &timeoutms))) {
01120          if (!timeoutms) {
01121             res = AST_BRIDGE_RETRY;
01122             break;
01123          }
01124          ast_debug(1, "Ooh, empty read...\n");
01125          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
01126             break;
01127          }
01128          continue;
01129       }
01130       fr = ast_read(who);
01131       other = (who == c0) ? c1 : c0;
01132       if (!fr || ((fr->frametype == AST_FRAME_DTMF_BEGIN || fr->frametype == AST_FRAME_DTMF_END) &&
01133              (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) ||
01134               ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) {
01135          /* Break out of bridge */
01136          *fo = fr;
01137          *rc = who;
01138          ast_debug(1, "Oooh, got a %s\n", fr ? "digit" : "hangup");
01139          res = AST_BRIDGE_COMPLETE;
01140          break;
01141       } else if ((fr->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
01142          if ((fr->subclass.integer == AST_CONTROL_HOLD) ||
01143              (fr->subclass.integer == AST_CONTROL_UNHOLD) ||
01144              (fr->subclass.integer == AST_CONTROL_VIDUPDATE) ||
01145              (fr->subclass.integer == AST_CONTROL_SRCUPDATE) ||
01146              (fr->subclass.integer == AST_CONTROL_T38_PARAMETERS) ||
01147             (fr->subclass.integer == AST_CONTROL_UPDATE_RTP_PEER)) {
01148             if (fr->subclass.integer == AST_CONTROL_HOLD) {
01149                /* If we someone went on hold we want the other side to reinvite back to us */
01150                if (who == c0) {
01151                   glue1->update_peer(c1, NULL, NULL, NULL, 0, 0);
01152                } else {
01153                   glue0->update_peer(c0, NULL, NULL, NULL, 0, 0);
01154                }
01155             } else if (fr->subclass.integer == AST_CONTROL_UNHOLD ||
01156                fr->subclass.integer == AST_CONTROL_UPDATE_RTP_PEER) {
01157                /* If they went off hold they should go back to being direct, or if we have
01158                 * been told to force a peer update, go ahead and do it. */
01159                if (who == c0) {
01160                   glue1->update_peer(c1, instance0, vinstance0, tinstance0, codec0, 0);
01161                } else {
01162                   glue0->update_peer(c0, instance1, vinstance1, tinstance1, codec1, 0);
01163                }
01164             }
01165             /* Update local address information */
01166             ast_rtp_instance_get_remote_address(instance0, &t0);
01167             ast_sockaddr_copy(&ac0, &t0);
01168             ast_rtp_instance_get_remote_address(instance1, &t1);
01169             ast_sockaddr_copy(&ac1, &t1);
01170             /* Update codec information */
01171             if (glue0->get_codec && c0->tech_pvt) {
01172                oldcodec0 = codec0 = glue0->get_codec(c0);
01173             }
01174             if (glue1->get_codec && c1->tech_pvt) {
01175                oldcodec1 = codec1 = glue1->get_codec(c1);
01176             }
01177             /* Since UPDATE_BRIDGE_PEER is only used by the bridging code, don't forward it */
01178             if (fr->subclass.integer != AST_CONTROL_UPDATE_RTP_PEER) {
01179                ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
01180             }
01181             ast_frfree(fr);
01182          } else if (fr->subclass.integer == AST_CONTROL_CONNECTED_LINE) {
01183             if (ast_channel_connected_line_macro(who, other, fr, other == c0, 1)) {
01184                ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
01185             }
01186             ast_frfree(fr);
01187          } else if (fr->subclass.integer == AST_CONTROL_REDIRECTING) {
01188             if (ast_channel_redirecting_macro(who, other, fr, other == c0, 1)) {
01189                ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
01190             }
01191             ast_frfree(fr);
01192          } else {
01193             *fo = fr;
01194             *rc = who;
01195             ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", fr->subclass.integer, who->name);
01196             return AST_BRIDGE_COMPLETE;
01197          }
01198       } else {
01199          if ((fr->frametype == AST_FRAME_DTMF_BEGIN) ||
01200              (fr->frametype == AST_FRAME_DTMF_END) ||
01201              (fr->frametype == AST_FRAME_VOICE) ||
01202              (fr->frametype == AST_FRAME_VIDEO) ||
01203              (fr->frametype == AST_FRAME_IMAGE) ||
01204              (fr->frametype == AST_FRAME_HTML) ||
01205              (fr->frametype == AST_FRAME_MODEM) ||
01206              (fr->frametype == AST_FRAME_TEXT)) {
01207             ast_write(other, fr);
01208          }
01209          ast_frfree(fr);
01210       }
01211       /* Swap priority */
01212       cs[2] = cs[0];
01213       cs[0] = cs[1];
01214       cs[1] = cs[2];
01215    }
01216 
01217    if (ast_test_flag(c0, AST_FLAG_ZOMBIE)) {
01218       ast_debug(1, "Channel '%s' Zombie cleardown from bridge\n", c0->name);
01219    } else if (c0->tech_pvt != pvt0) {
01220       ast_debug(1, "Channel c0->'%s' pvt changed, in bridge with c1->'%s'\n", c0->name, c1->name);
01221    } else if (glue0 != ast_rtp_instance_get_glue(c0->tech->type)) {
01222       ast_debug(1, "Channel c0->'%s' technology changed, in bridge with c1->'%s'\n", c0->name, c1->name);
01223    } else if (glue0->update_peer(c0, NULL, NULL, NULL, 0, 0)) {
01224       ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name);
01225    }
01226    if (ast_test_flag(c1, AST_FLAG_ZOMBIE)) {
01227       ast_debug(1, "Channel '%s' Zombie cleardown from bridge\n", c1->name);
01228    } else if (c1->tech_pvt != pvt1) {
01229       ast_debug(1, "Channel c1->'%s' pvt changed, in bridge with c0->'%s'\n", c1->name, c0->name);
01230    } else if (glue1 != ast_rtp_instance_get_glue(c1->tech->type)) {
01231       ast_debug(1, "Channel c1->'%s' technology changed, in bridge with c0->'%s'\n", c1->name, c0->name);
01232    } else if (glue1->update_peer(c1, NULL, NULL, NULL, 0, 0)) {
01233       ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name);
01234    }
01235 
01236    instance0->bridged = NULL;
01237    instance1->bridged = NULL;
01238 
01239    ast_poll_channel_del(c0, c1);
01240 
01241    return res;
01242 }

static void unref_instance_cond ( struct ast_rtp_instance **  instance  )  [static]

Conditionally unref an rtp instance.

Definition at line 1247 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().

01248 {
01249    if (*instance) {
01250       ao2_ref(*instance, -1);
01251       *instance = NULL;
01252    }
01253 }


Variable Documentation

struct ast_rtp_mime_type ast_rtp_mime_types[] [static]

The following array defines the MIME Media type (and subtype) for each of our codecs, or RTP-specific data type.

Referenced by ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_lookup_mime_subtype2(), and ast_rtp_lookup_sample_rate2().

struct ast_srtp_res* res_srtp = NULL

Definition at line 48 of file rtp_engine.c.

struct ast_srtp_policy_res* res_srtp_policy = NULL

Definition at line 49 of file rtp_engine.c.

Referenced by ast_rtp_engine_register_srtp(), ast_rtp_engine_srtp_is_registered(), ast_rtp_engine_unregister_srtp(), sdp_crypto_activate(), and set_crypto_policy().

struct ast_rtp_payload_type static_RTP_PT[AST_RTP_MAX_PT] [static]

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 147 of file rtp_engine.c.

Referenced by ast_rtp_codecs_payload_lookup(), ast_rtp_codecs_payloads_default(), and ast_rtp_codecs_payloads_set_m_type().


Generated on Mon Oct 8 12:39:28 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7