Mon Mar 19 11:30:54 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 *policy)
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)
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 723 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().

00724 {
00725    codecs->pref = *prefs;
00726 
00727    if (instance && instance->engine->packetization_set) {
00728       instance->engine->packetization_set(instance, &instance->codecs.pref);
00729    }
00730 }

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 650 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().

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

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 632 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().

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

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 614 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().

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

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 484 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().

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

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 512 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().

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

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

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

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 528 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().

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

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 593 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().

00594 {
00595    return ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, instance, payload, mimetype, mimesubtype, options, 0);
00596 }

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 544 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().

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

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 598 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().

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

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

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

int ast_rtp_engine_register_srtp ( struct ast_srtp_res srtp_res,
struct ast_srtp_policy_res policy_res 
)

Definition at line 1763 of file rtp_engine.c.

References policy_res, res_srtp, res_srtp_policy, and srtp_res.

Referenced by res_srtp_init().

01764 {
01765    if (res_srtp || res_srtp_policy) {
01766       return -1;
01767    }
01768    if (!srtp_res || !policy_res) {
01769       return -1;
01770    }
01771 
01772    res_srtp = srtp_res;
01773    res_srtp_policy = policy_res;
01774 
01775    return 0;
01776 }

int ast_rtp_engine_srtp_is_registered ( void   ) 

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

01785 {
01786    return res_srtp && res_srtp_policy;
01787 }

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 218 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().

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

void ast_rtp_engine_unregister_srtp ( void   ) 

Definition at line 1778 of file rtp_engine.c.

References res_srtp, and res_srtp_policy.

Referenced by unload_module().

01779 {
01780    res_srtp = NULL;
01781    res_srtp_policy = NULL;
01782 }

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

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

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 262 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().

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

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 1704 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().

01705 {
01706    return instance->engine->activate ? instance->engine->activate(instance) : 0;
01707 }

int ast_rtp_instance_add_srtp_policy ( struct ast_rtp_instance instance,
struct ast_srtp_policy policy 
)

Definition at line 1789 of file rtp_engine.c.

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

Referenced by sdp_crypto_activate().

01790 {
01791    if (!res_srtp) {
01792       return -1;
01793    }
01794 
01795    if (!instance->srtp) {
01796       return res_srtp->create(&instance->srtp, instance, policy);
01797    } else {
01798       return res_srtp->add_stream(instance->srtp, policy);
01799    }
01800 }

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

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

Referenced by sip_call().

01694 {
01695    format_t formats;
01696 
01697    if (instance->engine->available_formats && (formats = instance->engine->available_formats(instance, to_endpoint, to_asterisk))) {
01698       return formats;
01699    }
01700 
01701    return ast_translate_available_formats(to_endpoint, to_asterisk);
01702 }

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 1251 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().

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

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 763 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().

00764 {
00765    if (instance->engine->change_source) {
00766       instance->engine->change_source(instance);
00767    }
00768 }

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 297 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().

00298 {
00299    ao2_ref(instance, -1);
00300 
00301    return 0;
00302 }

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 732 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().

00733 {
00734    return instance->engine->dtmf_begin ? instance->engine->dtmf_begin(instance, digit) : -1;
00735 }

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 737 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().

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

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

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

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

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

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

Referenced by ast_rtp_instance_bridge().

00752 {
00753    return instance->engine->dtmf_mode_get ? instance->engine->dtmf_mode_get(instance) : 0;
00754 }

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 746 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().

00747 {
00748    return (!instance->engine->dtmf_mode_set || instance->engine->dtmf_mode_set(instance, dtmf_mode)) ? -1 : 0;
00749 }

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

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

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 1387 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().

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

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 782 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(), skinny_new(), start_rtp(), and unistim_new().

00783 {
00784    return instance->engine->fd ? instance->engine->fd(instance, rtcp) : -1;
00785 }

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

References ast_rtp_instance::glue.

01754 {
01755    return instance->glue;
01756 }

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

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

00417 {
00418    if (ast_sockaddr_cmp(address, &instance->local_address) != 0) {
00419       ast_sockaddr_copy(address, &instance->local_address);
00420       return 1;
00421    }
00422 
00423    return 0;
00424 }

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

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

Referenced by sip_set_rtp_peer().

00434 {
00435    if (ast_sockaddr_cmp(address, &instance->remote_address) != 0) {
00436       ast_sockaddr_copy(address, &instance->remote_address);
00437       return 1;
00438    }
00439 
00440    return 0;
00441 }

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

References ast_rtp_instance::bridged.

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

01383 {
01384    return instance->bridged;
01385 }

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

References ast_rtp_instance::chan.

01759 {
01760    return instance->chan;
01761 }

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 479 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().

00480 {
00481    return &instance->codecs;
00482 }

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 365 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().

00366 {
00367    return instance->data;
00368 }

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

References ast_rtp_instance::engine.

01749 {
01750    return instance->engine;
01751 }

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

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

00457 {
00458    if (instance->engine->extended_prop_get) {
00459       return instance->engine->extended_prop_get(instance, property);
00460    }
00461 
00462    return NULL;
00463 }

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 787 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().

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

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

References ast_rtp_instance::holdtimeout.

Referenced by check_rtp_timeout().

01739 {
01740    return instance->holdtimeout;
01741 }

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

References ast_rtp_instance::keepalive.

Referenced by check_rtp_timeout().

01744 {
01745    return instance->keepalive;
01746 }

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 426 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().

00428 {
00429    ast_sockaddr_copy(address, &instance->local_address);
00430 }

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 474 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().

00475 {
00476    return instance->properties[property];
00477 }

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 1573 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().

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

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 443 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().

00445 {
00446    ast_sockaddr_copy(address, &instance->remote_address);
00447 }

struct ast_srtp* ast_rtp_instance_get_srtp ( struct ast_rtp_instance instance  ) 

Definition at line 1802 of file rtp_engine.c.

References ast_rtp_instance::srtp.

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

01803 {
01804    return instance->srtp;
01805 }

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 1568 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().

01569 {
01570    return instance->engine->get_stat ? instance->engine->get_stat(instance, stats, stat) : -1;
01571 }

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

References ast_rtp_instance::timeout.

Referenced by check_rtp_timeout().

01734 {
01735    return instance->timeout;
01736 }

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 1657 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().

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

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 304 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().

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

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 375 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().

00376 {
00377    return instance->engine->read(instance, rtcp);
00378 }

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

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

Referenced by check_rtp_timeout().

01808 {
01809    if (instance->engine->sendcng) {
01810       return instance->engine->sendcng(instance, level);
01811    }
01812 
01813    return -1;
01814 }

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 401 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().

00403 {
00404    ast_sockaddr_copy(&instance->alt_remote_address, address);
00405 
00406    /* oink */
00407 
00408    if (instance->engine->alt_remote_address_set) {
00409       instance->engine->alt_remote_address_set(instance, &instance->alt_remote_address);
00410    }
00411 
00412    return 0;
00413 }

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

References ast_rtp_instance::data.

Referenced by multicast_rtp_new().

00361 {
00362    instance->data = data;
00363 }

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

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

00450 {
00451    if (instance->engine->extended_prop_set) {
00452       instance->engine->extended_prop_set(instance, property, value);
00453    }
00454 }

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

References ast_rtp_instance::holdtimeout.

Referenced by check_rtp_timeout(), and dialog_initialize_rtp().

01724 {
01725    instance->holdtimeout = timeout;
01726 }

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

References ast_rtp_instance::keepalive.

Referenced by dialog_initialize_rtp().

01729 {
01730    instance->keepalive = interval;
01731 }

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

References ast_sockaddr_copy(), and ast_rtp_instance::local_address.

Referenced by ast_rtp_new().

00382 {
00383    ast_sockaddr_copy(&instance->local_address, address);
00384    return 0;
00385 }

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 465 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(), and start_rtp().

00466 {
00467    instance->properties[property] = value;
00468 
00469    if (instance->engine->prop_set) {
00470       instance->engine->prop_set(instance, property, value);
00471    }
00472 }

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 770 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().

00771 {
00772    return instance->engine->qos ? instance->engine->qos(instance, tos, cos, desc) : -1;
00773 }

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

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

Referenced by sip_new(), and sip_setoption().

01648 {
01649    return instance->engine->set_read_format ? instance->engine->set_read_format(instance, format) : -1;
01650 }

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 387 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().

00389 {
00390    ast_sockaddr_copy(&instance->remote_address, address);
00391 
00392    /* moo */
00393 
00394    if (instance->engine->remote_address_set) {
00395       instance->engine->remote_address_set(instance, &instance->remote_address);
00396    }
00397 
00398    return 0;
00399 }

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 1613 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().

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

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

References ast_rtp_instance::timeout.

Referenced by check_rtp_timeout(), and dialog_initialize_rtp().

01719 {
01720    instance->timeout = timeout;
01721 }

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

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

Referenced by sip_new(), and sip_setoption().

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

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 775 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().

00776 {
00777    if (instance->engine->stop) {
00778       instance->engine->stop(instance);
00779    }
00780 }

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 1709 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().

01712 {
01713    if (instance->engine->stun_request) {
01714       instance->engine->stun_request(instance, suggestion, username);
01715    }
01716 }

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 756 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().

00757 {
00758    if (instance->engine->update_source) {
00759       instance->engine->update_source(instance);
00760    }
00761 }

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 370 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().

00371 {
00372    return instance->engine->write(instance, frame);
00373 }

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 699 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().

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

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 669 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().

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

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 686 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().

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

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

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

Referenced by sip_write().

01564 {
01565    return instance->engine->red_buffer ? instance->engine->red_buffer(instance, frame) : -1;
01566 }

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

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

Referenced by process_sdp().

01559 {
01560    return instance->engine->red_init ? instance->engine->red_init(instance, buffer_time, payloads, generations) : -1;
01561 }

static void instance_destructor ( void *  obj  )  [static]

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

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

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 804 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().

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

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 973 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().

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

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

Conditionally unref an rtp instance.

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

01244 {
01245    if (*instance) {
01246       ao2_ref(*instance, -1);
01247       *instance = NULL;
01248    }
01249 }


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

struct ast_srtp_policy_res* res_srtp_policy = NULL

Definition at line 45 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 143 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 Mar 19 11:30:54 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7