bridge_native_rtp.c File Reference

Native RTP bridging technology module. More...

#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/bridge.h"
#include "asterisk/bridge_technology.h"
#include "asterisk/frame.h"
#include "asterisk/rtp_engine.h"

Include dependency graph for bridge_native_rtp.c:

Go to the source code of this file.

Data Structures

struct  native_rtp_bridge_data
 Internal structure which contains information about bridged RTP channels. More...

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int load_module (void)
static int native_rtp_bridge_capable (struct ast_channel *chan)
 Internal helper function which checks whether the channels are compatible with our native bridging.
static int native_rtp_bridge_compatible (struct ast_bridge *bridge)
static int native_rtp_bridge_framehook_attach (struct ast_bridge_channel *bridge_channel)
 Helper function which adds frame hook to bridge channel.
static void native_rtp_bridge_framehook_detach (struct ast_bridge_channel *bridge_channel)
 Helper function which removes frame hook from bridge channel.
static enum ast_rtp_glue_result native_rtp_bridge_get (struct ast_channel *c0, struct ast_channel *c1, struct ast_rtp_glue **glue0, struct ast_rtp_glue **glue1, struct ast_rtp_instance **instance0, struct ast_rtp_instance **instance1, struct ast_rtp_instance **vinstance0, struct ast_rtp_instance **vinstance1)
 Internal helper function which gets all RTP information (glue and instances) relating to the given channels.
static int native_rtp_bridge_join (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
static void native_rtp_bridge_leave (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
static void native_rtp_bridge_start (struct ast_bridge *bridge, struct ast_channel *target)
static void native_rtp_bridge_stop (struct ast_bridge *bridge, struct ast_channel *target)
static void native_rtp_bridge_unsuspend (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
static int native_rtp_bridge_write (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
static struct ast_framenative_rtp_framehook (struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
 Frame hook that is called to intercept hold/unhold.
static int native_rtp_framehook_consume (void *data, enum ast_frame_type type)
 Callback function which informs upstream if we are consuming a frame of a specific type.
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Native RTP bridging module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_bridge_technology native_rtp_bridge


Detailed Description

Native RTP bridging technology module.

Author:
Joshua Colp <jcolp@digium.com>

Definition in file bridge_native_rtp.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 496 of file bridge_native_rtp.c.

static void __unreg_module ( void   )  [static]

Definition at line 496 of file bridge_native_rtp.c.

static int load_module ( void   )  [static]

static int native_rtp_bridge_capable ( struct ast_channel chan  )  [static]

Internal helper function which checks whether the channels are compatible with our native bridging.

Definition at line 298 of file bridge_native_rtp.c.

References ast_channel_has_hook_requiring_audio().

Referenced by native_rtp_bridge_compatible().

00299 {
00300    return !ast_channel_has_hook_requiring_audio(chan);
00301 }

static int native_rtp_bridge_compatible ( struct ast_bridge bridge  )  [static]

Definition at line 303 of file bridge_native_rtp.c.

References ao2_cleanup, ao2_container_count(), ast_channel_name(), ast_channel_rawreadformat(), ast_channel_rawwriteformat(), ast_debug, ast_format_cap_alloc, ast_format_cap_count(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_format_framing(), ast_format_cap_get_names(), ast_format_cap_iscompatible(), AST_LIST_FIRST, AST_LIST_LAST, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, ast_rtp_instance_dtmf_mode_get(), ast_rtp_instance_get_engine(), ast_str_alloca, ast_bridge_channel::chan, ast_bridge::channels, ast_bridge_features::dtmf_hooks, ast_bridge_channel::features, ast_rtp_glue::get_codec, native_rtp_bridge_capable(), native_rtp_bridge_get(), NULL, ast_bridge::num_channels, RAII_VAR, and ast_bridge::uniqueid.

00304 {
00305    struct ast_bridge_channel *bc0 = AST_LIST_FIRST(&bridge->channels);
00306    struct ast_bridge_channel *bc1 = AST_LIST_LAST(&bridge->channels);
00307    enum ast_rtp_glue_result native_type;
00308    struct ast_rtp_glue *glue0, *glue1;
00309    RAII_VAR(struct ast_rtp_instance *, instance0, NULL, ao2_cleanup);
00310    RAII_VAR(struct ast_rtp_instance *, instance1, NULL, ao2_cleanup);
00311    RAII_VAR(struct ast_rtp_instance *, vinstance0, NULL, ao2_cleanup);
00312    RAII_VAR(struct ast_rtp_instance *, vinstance1, NULL, ao2_cleanup);
00313    RAII_VAR(struct ast_format_cap *, cap0, NULL, ao2_cleanup);
00314    RAII_VAR(struct ast_format_cap *, cap1, NULL, ao2_cleanup);
00315    int read_ptime0, read_ptime1, write_ptime0, write_ptime1;
00316 
00317    /* We require two channels before even considering native bridging */
00318    if (bridge->num_channels != 2) {
00319       ast_debug(1, "Bridge '%s' can not use native RTP bridge as two channels are required\n",
00320          bridge->uniqueid);
00321       return 0;
00322    }
00323 
00324    if (!native_rtp_bridge_capable(bc0->chan)) {
00325       ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has features which prevent it\n",
00326          bridge->uniqueid, ast_channel_name(bc0->chan));
00327       return 0;
00328    }
00329 
00330    if (!native_rtp_bridge_capable(bc1->chan)) {
00331       ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has features which prevent it\n",
00332          bridge->uniqueid, ast_channel_name(bc1->chan));
00333       return 0;
00334    }
00335 
00336    if ((native_type = native_rtp_bridge_get(bc0->chan, bc1->chan, &glue0, &glue1, &instance0, &instance1, &vinstance0, &vinstance1))
00337       == AST_RTP_GLUE_RESULT_FORBID) {
00338       ast_debug(1, "Bridge '%s' can not use native RTP bridge as it was forbidden while getting details\n",
00339          bridge->uniqueid);
00340       return 0;
00341    }
00342 
00343    if (ao2_container_count(bc0->features->dtmf_hooks) && ast_rtp_instance_dtmf_mode_get(instance0)) {
00344       ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has DTMF hooks\n",
00345          bridge->uniqueid, ast_channel_name(bc0->chan));
00346       return 0;
00347    }
00348 
00349    if (ao2_container_count(bc1->features->dtmf_hooks) && ast_rtp_instance_dtmf_mode_get(instance1)) {
00350       ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has DTMF hooks\n",
00351          bridge->uniqueid, ast_channel_name(bc1->chan));
00352       return 0;
00353    }
00354 
00355    if ((native_type == AST_RTP_GLUE_RESULT_LOCAL) && ((ast_rtp_instance_get_engine(instance0)->local_bridge !=
00356       ast_rtp_instance_get_engine(instance1)->local_bridge) ||
00357       (ast_rtp_instance_get_engine(instance0)->dtmf_compatible &&
00358          !ast_rtp_instance_get_engine(instance0)->dtmf_compatible(bc0->chan, instance0, bc1->chan, instance1)))) {
00359       ast_debug(1, "Bridge '%s' can not use local native RTP bridge as local bridge or DTMF is not compatible\n",
00360          bridge->uniqueid);
00361       return 0;
00362    }
00363 
00364    cap0 = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
00365    cap1 = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
00366    if (!cap0 || !cap1) {
00367       return 0;
00368    }
00369 
00370    /* Make sure that codecs match */
00371    if (glue0->get_codec) {
00372       glue0->get_codec(bc0->chan, cap0);
00373    }
00374    if (glue1->get_codec) {
00375       glue1->get_codec(bc1->chan, cap1);
00376    }
00377    if (ast_format_cap_count(cap0) != 0 && ast_format_cap_count(cap1) != 0 && !ast_format_cap_iscompatible(cap0, cap1)) {
00378       struct ast_str *codec_buf0 = ast_str_alloca(64);
00379       struct ast_str *codec_buf1 = ast_str_alloca(64);
00380       ast_debug(1, "Channel codec0 = %s is not codec1 = %s, cannot native bridge in RTP.\n",
00381          ast_format_cap_get_names(cap0, &codec_buf0), ast_format_cap_get_names(cap1, &codec_buf1));
00382       return 0;
00383    }
00384 
00385    read_ptime0 = ast_format_cap_get_format_framing(cap0, ast_channel_rawreadformat(bc0->chan));
00386    read_ptime1 = ast_format_cap_get_format_framing(cap1, ast_channel_rawreadformat(bc1->chan));
00387    write_ptime0 = ast_format_cap_get_format_framing(cap0, ast_channel_rawwriteformat(bc0->chan));
00388    write_ptime1 = ast_format_cap_get_format_framing(cap1, ast_channel_rawwriteformat(bc1->chan));
00389 
00390    if (read_ptime0 != write_ptime1 || read_ptime1 != write_ptime0) {
00391       ast_debug(1, "Packetization differs between RTP streams (%d != %d or %d != %d). Cannot native bridge in RTP\n",
00392             read_ptime0, write_ptime1, read_ptime1, write_ptime0);
00393       return 0;
00394    }
00395 
00396    return 1;
00397 }

static int native_rtp_bridge_framehook_attach ( struct ast_bridge_channel bridge_channel  )  [static]

Helper function which adds frame hook to bridge channel.

Definition at line 400 of file bridge_native_rtp.c.

References ao2_alloc, ao2_cleanup, ast_channel_lock, ast_channel_unlock, ast_framehook_attach(), AST_FRAMEHOOK_INTERFACE_VERSION, ast_bridge_channel::chan, native_rtp_bridge_data::id, native_rtp_framehook(), native_rtp_framehook_consume(), NULL, ast_bridge_channel::tech_pvt, and ast_framehook_interface::version.

Referenced by native_rtp_bridge_join().

00401 {
00402    struct native_rtp_bridge_data *data = ao2_alloc(sizeof(*data), NULL);
00403    static struct ast_framehook_interface hook = {
00404       .version = AST_FRAMEHOOK_INTERFACE_VERSION,
00405       .event_cb = native_rtp_framehook,
00406       .consume_cb = native_rtp_framehook_consume,
00407       .disable_inheritance = 1,
00408    };
00409 
00410    if (!data) {
00411       return -1;
00412    }
00413 
00414    ast_channel_lock(bridge_channel->chan);
00415    data->id = ast_framehook_attach(bridge_channel->chan, &hook);
00416    ast_channel_unlock(bridge_channel->chan);
00417    if (data->id < 0) {
00418       ao2_cleanup(data);
00419       return -1;
00420    }
00421 
00422    bridge_channel->tech_pvt = data;
00423 
00424    return 0;
00425 }

static void native_rtp_bridge_framehook_detach ( struct ast_bridge_channel bridge_channel  )  [static]

Helper function which removes frame hook from bridge channel.

Definition at line 428 of file bridge_native_rtp.c.

References ao2_cleanup, ast_channel_lock, ast_channel_unlock, ast_framehook_detach(), ast_bridge_channel::chan, ast_framehook_interface::data, NULL, RAII_VAR, and ast_bridge_channel::tech_pvt.

Referenced by native_rtp_bridge_join(), and native_rtp_bridge_leave().

00429 {
00430    RAII_VAR(struct native_rtp_bridge_data *, data, bridge_channel->tech_pvt, ao2_cleanup);
00431 
00432    if (!data) {
00433       return;
00434    }
00435 
00436    ast_channel_lock(bridge_channel->chan);
00437    ast_framehook_detach(bridge_channel->chan, data->id);
00438    ast_channel_unlock(bridge_channel->chan);
00439    bridge_channel->tech_pvt = NULL;
00440 }

static enum ast_rtp_glue_result native_rtp_bridge_get ( struct ast_channel c0,
struct ast_channel c1,
struct ast_rtp_glue **  glue0,
struct ast_rtp_glue **  glue1,
struct ast_rtp_instance **  instance0,
struct ast_rtp_instance **  instance1,
struct ast_rtp_instance **  vinstance0,
struct ast_rtp_instance **  vinstance1 
) [static]

Internal helper function which gets all RTP information (glue and instances) relating to the given channels.

Definition at line 56 of file bridge_native_rtp.c.

References ast_channel_tech(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_rtp_instance_get_glue(), and type.

Referenced by native_rtp_bridge_compatible(), native_rtp_bridge_start(), and native_rtp_bridge_stop().

00059 {
00060    enum ast_rtp_glue_result audio_glue0_res;
00061    enum ast_rtp_glue_result video_glue0_res;
00062    enum ast_rtp_glue_result audio_glue1_res;
00063    enum ast_rtp_glue_result video_glue1_res;
00064 
00065    if (!(*glue0 = ast_rtp_instance_get_glue(ast_channel_tech(c0)->type)) ||
00066       !(*glue1 = ast_rtp_instance_get_glue(ast_channel_tech(c1)->type))) {
00067       return AST_RTP_GLUE_RESULT_FORBID;
00068    }
00069 
00070    audio_glue0_res = (*glue0)->get_rtp_info(c0, instance0);
00071    video_glue0_res = (*glue0)->get_vrtp_info ? (*glue0)->get_vrtp_info(c0, vinstance0) : AST_RTP_GLUE_RESULT_FORBID;
00072 
00073    audio_glue1_res = (*glue1)->get_rtp_info(c1, instance1);
00074    video_glue1_res = (*glue1)->get_vrtp_info ? (*glue1)->get_vrtp_info(c1, vinstance1) : AST_RTP_GLUE_RESULT_FORBID;
00075 
00076    /* Apply any limitations on direct media bridging that may be present */
00077    if (audio_glue0_res == audio_glue1_res && audio_glue1_res == AST_RTP_GLUE_RESULT_REMOTE) {
00078       if ((*glue0)->allow_rtp_remote && !((*glue0)->allow_rtp_remote(c0, *instance1))) {
00079          /* If the allow_rtp_remote indicates that remote isn't allowed, revert to local bridge */
00080          audio_glue0_res = audio_glue1_res = AST_RTP_GLUE_RESULT_LOCAL;
00081       } else if ((*glue1)->allow_rtp_remote && !((*glue1)->allow_rtp_remote(c1, *instance0))) {
00082          audio_glue0_res = audio_glue1_res = AST_RTP_GLUE_RESULT_LOCAL;
00083       }
00084    }
00085    if (video_glue0_res == video_glue1_res && video_glue1_res == AST_RTP_GLUE_RESULT_REMOTE) {
00086       if ((*glue0)->allow_vrtp_remote && !((*glue0)->allow_vrtp_remote(c0, *instance1))) {
00087          /* if the allow_vrtp_remote indicates that remote isn't allowed, revert to local bridge */
00088          video_glue0_res = video_glue1_res = AST_RTP_GLUE_RESULT_LOCAL;
00089       } else if ((*glue1)->allow_vrtp_remote && !((*glue1)->allow_vrtp_remote(c1, *instance0))) {
00090          video_glue0_res = video_glue1_res = AST_RTP_GLUE_RESULT_LOCAL;
00091       }
00092    }
00093 
00094    /* If we are carrying video, and both sides are not going to remotely bridge... fail the native bridge */
00095    if (video_glue0_res != AST_RTP_GLUE_RESULT_FORBID
00096       && (audio_glue0_res != AST_RTP_GLUE_RESULT_REMOTE
00097          || video_glue0_res != AST_RTP_GLUE_RESULT_REMOTE)) {
00098       audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
00099    }
00100    if (video_glue1_res != AST_RTP_GLUE_RESULT_FORBID
00101       && (audio_glue1_res != AST_RTP_GLUE_RESULT_REMOTE
00102          || video_glue1_res != AST_RTP_GLUE_RESULT_REMOTE)) {
00103       audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
00104    }
00105 
00106    /* The order of preference is: forbid, local, and remote. */
00107    if (audio_glue0_res == AST_RTP_GLUE_RESULT_FORBID ||
00108       audio_glue1_res == AST_RTP_GLUE_RESULT_FORBID) {
00109       /* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
00110       return AST_RTP_GLUE_RESULT_FORBID;
00111    } else if (audio_glue0_res == AST_RTP_GLUE_RESULT_LOCAL ||
00112       audio_glue1_res == AST_RTP_GLUE_RESULT_LOCAL) {
00113       return AST_RTP_GLUE_RESULT_LOCAL;
00114    } else {
00115       return AST_RTP_GLUE_RESULT_REMOTE;
00116    }
00117 }

static int native_rtp_bridge_join ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel 
) [static]

Definition at line 442 of file bridge_native_rtp.c.

References native_rtp_bridge_framehook_attach(), native_rtp_bridge_framehook_detach(), native_rtp_bridge_start(), and NULL.

Referenced by native_rtp_bridge_unsuspend().

00443 {
00444    native_rtp_bridge_framehook_detach(bridge_channel);
00445    if (native_rtp_bridge_framehook_attach(bridge_channel)) {
00446       return -1;
00447    }
00448 
00449    native_rtp_bridge_start(bridge, NULL);
00450    return 0;
00451 }

static void native_rtp_bridge_leave ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel 
) [static]

Definition at line 458 of file bridge_native_rtp.c.

References native_rtp_bridge_framehook_detach(), native_rtp_bridge_stop(), and NULL.

00459 {
00460    native_rtp_bridge_framehook_detach(bridge_channel);
00461    native_rtp_bridge_stop(bridge, NULL);
00462 }

static void native_rtp_bridge_start ( struct ast_bridge bridge,
struct ast_channel target 
) [static]

Definition at line 128 of file bridge_native_rtp.c.

References ao2_cleanup, ast_channel_lock_both, ast_channel_name(), ast_channel_unlock, ast_format_cap_alloc, AST_FORMAT_CAP_FLAG_DEFAULT, AST_LIST_FIRST, AST_LIST_LAST, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_rtp_instance_get_engine(), ast_rtp_instance_set_bridged(), ast_verb, ast_bridge_channel::chan, ast_bridge::channels, ast_rtp_glue::get_codec, ast_rtp_engine::local_bridge, native_rtp_bridge_get(), NULL, RAII_VAR, and ast_rtp_glue::update_peer.

Referenced by native_rtp_bridge_join(), and native_rtp_framehook().

00129 {
00130    struct ast_bridge_channel *bc0 = AST_LIST_FIRST(&bridge->channels);
00131    struct ast_bridge_channel *bc1 = AST_LIST_LAST(&bridge->channels);
00132    enum ast_rtp_glue_result native_type;
00133    struct ast_rtp_glue *glue0, *glue1;
00134    RAII_VAR(struct ast_rtp_instance *, instance0, NULL, ao2_cleanup);
00135    RAII_VAR(struct ast_rtp_instance *, instance1, NULL, ao2_cleanup);
00136    RAII_VAR(struct ast_rtp_instance *, vinstance0, NULL, ao2_cleanup);
00137    RAII_VAR(struct ast_rtp_instance *, vinstance1, NULL, ao2_cleanup);
00138    RAII_VAR(struct ast_rtp_instance *, tinstance0, NULL, ao2_cleanup);
00139    RAII_VAR(struct ast_rtp_instance *, tinstance1, NULL, ao2_cleanup);
00140    RAII_VAR(struct ast_format_cap *, cap0, ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT), ao2_cleanup);
00141    RAII_VAR(struct ast_format_cap *, cap1, ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT), ao2_cleanup);
00142 
00143    if (bc0 == bc1) {
00144       return;
00145    }
00146 
00147    ast_channel_lock_both(bc0->chan, bc1->chan);
00148    native_type = native_rtp_bridge_get(bc0->chan, bc1->chan, &glue0, &glue1, &instance0, &instance1, &vinstance0, &vinstance1);
00149 
00150    switch (native_type) {
00151    case AST_RTP_GLUE_RESULT_LOCAL:
00152       if (ast_rtp_instance_get_engine(instance0)->local_bridge) {
00153          ast_rtp_instance_get_engine(instance0)->local_bridge(instance0, instance1);
00154       }
00155       if (ast_rtp_instance_get_engine(instance1)->local_bridge) {
00156          ast_rtp_instance_get_engine(instance1)->local_bridge(instance1, instance0);
00157       }
00158       ast_rtp_instance_set_bridged(instance0, instance1);
00159       ast_rtp_instance_set_bridged(instance1, instance0);
00160       ast_verb(4, "Locally RTP bridged '%s' and '%s' in stack\n",
00161          ast_channel_name(bc0->chan), ast_channel_name(bc1->chan));
00162       break;
00163 
00164    case AST_RTP_GLUE_RESULT_REMOTE:
00165       if (glue0->get_codec) {
00166          glue0->get_codec(bc0->chan, cap0);
00167       }
00168       if (glue1->get_codec) {
00169          glue1->get_codec(bc1->chan, cap1);
00170       }
00171 
00172       /* If we have a target, it's the channel that received the UNHOLD or UPDATE_RTP_PEER frame and was told to resume */
00173       if (!target) {
00174          glue0->update_peer(bc0->chan, instance1, vinstance1, tinstance1, cap1, 0);
00175          glue1->update_peer(bc1->chan, instance0, vinstance0, tinstance0, cap0, 0);
00176          ast_verb(4, "Remotely bridged '%s' and '%s' - media will flow directly between them\n",
00177             ast_channel_name(bc0->chan), ast_channel_name(bc1->chan));
00178       } else {
00179          /*
00180           * If a target was provided, it is the recipient of an unhold or an update and needs to have
00181           * its media redirected to fit the current remote bridging needs. The other channel is either
00182           * already set up to handle the new media path or will have its own set of updates independent
00183           * of this pass.
00184           */
00185          if (bc0->chan == target) {
00186             glue0->update_peer(bc0->chan, instance1, vinstance1, tinstance1, cap1, 0);
00187          } else {
00188             glue1->update_peer(bc1->chan, instance0, vinstance0, tinstance0, cap0, 0);
00189          }
00190       }
00191       break;
00192    case AST_RTP_GLUE_RESULT_FORBID:
00193       break;
00194    }
00195 
00196    ast_channel_unlock(bc0->chan);
00197    ast_channel_unlock(bc1->chan);
00198 }

static void native_rtp_bridge_stop ( struct ast_bridge bridge,
struct ast_channel target 
) [static]

Definition at line 200 of file bridge_native_rtp.c.

References ao2_cleanup, ast_channel_lock_both, ast_channel_name(), ast_channel_unlock, ast_debug, AST_LIST_FIRST, AST_LIST_LAST, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_rtp_instance_get_engine(), ast_rtp_instance_set_bridged(), ast_bridge_channel::chan, ast_bridge::channels, ast_rtp_engine::local_bridge, native_rtp_bridge_get(), NULL, RAII_VAR, and ast_rtp_glue::update_peer.

Referenced by native_rtp_bridge_leave(), and native_rtp_framehook().

00201 {
00202    struct ast_bridge_channel *bc0 = AST_LIST_FIRST(&bridge->channels);
00203    struct ast_bridge_channel *bc1 = AST_LIST_LAST(&bridge->channels);
00204    enum ast_rtp_glue_result native_type;
00205    struct ast_rtp_glue *glue0, *glue1 = NULL;
00206    RAII_VAR(struct ast_rtp_instance *, instance0, NULL, ao2_cleanup);
00207    RAII_VAR(struct ast_rtp_instance *, instance1, NULL, ao2_cleanup);
00208    RAII_VAR(struct ast_rtp_instance *, vinstance0, NULL, ao2_cleanup);
00209    RAII_VAR(struct ast_rtp_instance *, vinstance1, NULL, ao2_cleanup);
00210 
00211    if (bc0 == bc1) {
00212       return;
00213    }
00214 
00215    ast_channel_lock_both(bc0->chan, bc1->chan);
00216    native_type = native_rtp_bridge_get(bc0->chan, bc1->chan, &glue0, &glue1, &instance0, &instance1, &vinstance0, &vinstance1);
00217 
00218    switch (native_type) {
00219    case AST_RTP_GLUE_RESULT_LOCAL:
00220       if (ast_rtp_instance_get_engine(instance0)->local_bridge) {
00221          ast_rtp_instance_get_engine(instance0)->local_bridge(instance0, NULL);
00222       }
00223       if (instance1 && ast_rtp_instance_get_engine(instance1)->local_bridge) {
00224          ast_rtp_instance_get_engine(instance1)->local_bridge(instance1, NULL);
00225       }
00226       ast_rtp_instance_set_bridged(instance0, NULL);
00227       if (instance1) {
00228          ast_rtp_instance_set_bridged(instance1, NULL);
00229       }
00230       break;
00231    case AST_RTP_GLUE_RESULT_REMOTE:
00232       if (target) {
00233          /*
00234           * If a target was provided, it is being put on hold and should expect to
00235           * receive media from Asterisk instead of what it was previously connected to.
00236           */
00237          if (bc0->chan == target) {
00238             glue0->update_peer(bc0->chan, NULL, NULL, NULL, NULL, 0);
00239          } else {
00240             glue1->update_peer(bc1->chan, NULL, NULL, NULL, NULL, 0);
00241          }
00242       }
00243       break;
00244    case AST_RTP_GLUE_RESULT_FORBID:
00245       break;
00246    }
00247 
00248    if (!target && native_type != AST_RTP_GLUE_RESULT_FORBID) {
00249       glue0->update_peer(bc0->chan, NULL, NULL, NULL, NULL, 0);
00250       glue1->update_peer(bc1->chan, NULL, NULL, NULL, NULL, 0);
00251    }
00252 
00253    ast_debug(2, "Discontinued RTP bridging of '%s' and '%s' - media will flow through Asterisk core\n",
00254       ast_channel_name(bc0->chan), ast_channel_name(bc1->chan));
00255 
00256    ast_channel_unlock(bc0->chan);
00257    ast_channel_unlock(bc1->chan);
00258 }

static void native_rtp_bridge_unsuspend ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel 
) [static]

Definition at line 453 of file bridge_native_rtp.c.

References native_rtp_bridge_join().

00454 {
00455    native_rtp_bridge_join(bridge, bridge_channel);
00456 }

static int native_rtp_bridge_write ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel,
struct ast_frame frame 
) [static]

Definition at line 464 of file bridge_native_rtp.c.

References ast_bridge_queue_everyone_else().

00465 {
00466    return ast_bridge_queue_everyone_else(bridge, bridge_channel, frame);
00467 }

static struct ast_frame* native_rtp_framehook ( struct ast_channel chan,
struct ast_frame f,
enum ast_framehook_event  event,
void *  data 
) [static, read]

Frame hook that is called to intercept hold/unhold.

Definition at line 261 of file bridge_native_rtp.c.

References ao2_cleanup, ast_bridge_lock, ast_bridge_unlock, ast_channel_get_bridge(), ast_channel_lock, ast_channel_unlock, AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_FRAMEHOOK_EVENT_WRITE, ast_frame_subclass::integer, native_rtp_bridge_start(), native_rtp_bridge_stop(), NULL, RAII_VAR, and ast_frame::subclass.

Referenced by native_rtp_bridge_framehook_attach().

00262 {
00263    RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
00264 
00265    if (!f || (event != AST_FRAMEHOOK_EVENT_WRITE)) {
00266       return f;
00267    }
00268 
00269    bridge = ast_channel_get_bridge(chan);
00270 
00271    if (bridge) {
00272       /* native_rtp_bridge_start/stop are not being called from bridging
00273          core so we need to lock the bridge prior to calling these functions
00274          Unfortunately that means unlocking the channel, but as it
00275          should not be modified this should be okay...hopefully */
00276       ast_channel_unlock(chan);
00277       ast_bridge_lock(bridge);
00278       if (f->subclass.integer == AST_CONTROL_HOLD) {
00279          native_rtp_bridge_stop(bridge, chan);
00280       } else if ((f->subclass.integer == AST_CONTROL_UNHOLD) || (f->subclass.integer == AST_CONTROL_UPDATE_RTP_PEER)) {
00281          native_rtp_bridge_start(bridge, chan);
00282       }
00283       ast_bridge_unlock(bridge);
00284       ast_channel_lock(chan);
00285 
00286    }
00287 
00288    return f;
00289 }

static int native_rtp_framehook_consume ( void *  data,
enum ast_frame_type  type 
) [static]

Callback function which informs upstream if we are consuming a frame of a specific type.

Definition at line 292 of file bridge_native_rtp.c.

References AST_FRAME_CONTROL.

Referenced by native_rtp_bridge_framehook_attach().

00293 {
00294    return (type == AST_FRAME_CONTROL ? 1 : 0);
00295 }

static int unload_module ( void   )  [static]

Definition at line 481 of file bridge_native_rtp.c.

References ast_bridge_technology_unregister().

00482 {
00483    ast_bridge_technology_unregister(&native_rtp_bridge);
00484    return 0;
00485 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Native RTP bridging module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, } [static]

Definition at line 496 of file bridge_native_rtp.c.

Definition at line 496 of file bridge_native_rtp.c.

Definition at line 469 of file bridge_native_rtp.c.


Generated on Thu Apr 16 06:29:12 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6