Fri Nov 12 11:55:04 2010

Asterisk developer's documentation


chan_bridge.c File Reference

Bridge Interaction Channel. More...

#include "asterisk.h"
#include <fcntl.h>
#include <sys/signal.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/bridging.h"
Include dependency graph for chan_bridge.c:

Go to the source code of this file.

Data Structures

struct  bridge_pvt

Functions

static void __reg_module (void)
static void __unreg_module (void)
static struct ast_channelbridge_bridgedchannel (struct ast_channel *chan, struct ast_channel *bridge)
 Called when the user of this channel wants to get the actual channel in the bridge.
static int bridge_call (struct ast_channel *ast, char *dest, int timeout)
 Called when the channel should actually be dialed.
static int bridge_hangup (struct ast_channel *ast)
 Called when a channel should be hung up.
static void bridge_queue_hangup (struct bridge_pvt *p, struct ast_channel *us)
 Helper function to not deadlock when queueing the hangup frame.
static struct ast_framebridge_read (struct ast_channel *ast)
 Called when a frame should be read from the channel.
static struct ast_channelbridge_request (const char *type, int format, void *data, int *cause)
 Called when we want to place a call somewhere, but not actually call it... yet.
static int bridge_write (struct ast_channel *ast, struct ast_frame *f)
 Called when a frame should be written out to a channel.
static int load_module (void)
 Load module into PBX, register channel.
static int unload_module (void)
 Unload the bridge interaction channel from Asterisk.

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Bridge Interaction Channel" , .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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, }
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_channel_tech bridge_tech

Detailed Description

Bridge Interaction Channel.

Author:
Joshua Colp <jcolp@digium.com>

Definition in file chan_bridge.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 246 of file chan_bridge.c.

static void __unreg_module ( void   )  [static]

Definition at line 246 of file chan_bridge.c.

static struct ast_channel * bridge_bridgedchannel ( struct ast_channel chan,
struct ast_channel bridge 
) [static, read]

Called when the user of this channel wants to get the actual channel in the bridge.

Definition at line 78 of file chan_bridge.c.

References bridge_pvt::input, bridge_pvt::output, and ast_channel::tech_pvt.

00079 {
00080    struct bridge_pvt *p = chan->tech_pvt;
00081    return (chan == p->input) ? p->output : bridge;
00082 }

static int bridge_call ( struct ast_channel ast,
char *  dest,
int  timeout 
) [static]

Called when the channel should actually be dialed.

Definition at line 120 of file chan_bridge.c.

References ast_bridge_impart(), ast_channel::bridge, bridge_pvt::input, bridge_pvt::output, and ast_channel::tech_pvt.

00121 {
00122    struct bridge_pvt *p = ast->tech_pvt;
00123 
00124    /* If no bridge has been provided on the input channel, bail out */
00125    if (!ast->bridge) {
00126       return -1;
00127    }
00128 
00129    /* Impart the output channel upon the given bridge of the input channel */
00130    ast_bridge_impart(p->input->bridge, p->output, NULL, NULL);
00131 
00132    return 0;
00133 }

static int bridge_hangup ( struct ast_channel ast  )  [static]

Called when a channel should be hung up.

Definition at line 158 of file chan_bridge.c.

References ast_free, ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), bridge_queue_hangup(), bridge_pvt::input, bridge_pvt::lock, bridge_pvt::output, and ast_channel::tech_pvt.

00159 {
00160    struct bridge_pvt *p = ast->tech_pvt;
00161 
00162    ast_mutex_lock(&p->lock);
00163 
00164    /* Figure out which channel this is... and set it to NULL as it has gone, but also queue up a hangup frame. */
00165    if (p->input == ast) {
00166       if (p->output) {
00167          bridge_queue_hangup(p, ast);
00168       }
00169       p->input = NULL;
00170    } else if (p->output == ast) {
00171       if (p->input) {
00172          bridge_queue_hangup(p, ast);
00173       }
00174       p->output = NULL;
00175    }
00176 
00177    /* Deal with the Asterisk portion of it */
00178    ast->tech_pvt = NULL;
00179 
00180    /* If both sides have been terminated free the structure and be done with things */
00181    if (!p->input && !p->output) {
00182       ast_mutex_unlock(&p->lock);
00183       ast_mutex_destroy(&p->lock);
00184       ast_free(p);
00185    } else {
00186       ast_mutex_unlock(&p->lock);
00187    }
00188 
00189    return 0;
00190 }

static void bridge_queue_hangup ( struct bridge_pvt p,
struct ast_channel us 
) [static]

Helper function to not deadlock when queueing the hangup frame.

Definition at line 136 of file chan_bridge.c.

References ast_channel_trylock, ast_channel_unlock, ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), CHANNEL_DEADLOCK_AVOIDANCE, bridge_pvt::input, bridge_pvt::lock, and bridge_pvt::output.

Referenced by bridge_hangup().

00137 {
00138    struct ast_channel *other = (p->input == us ? p->output : p->input);
00139 
00140    while (other && ast_channel_trylock(other)) {
00141       ast_mutex_unlock(&p->lock);
00142       do {
00143          CHANNEL_DEADLOCK_AVOIDANCE(us);
00144       } while (ast_mutex_trylock(&p->lock));
00145       other = (p->input == us ? p->output : p->input);
00146    }
00147 
00148    /* We basically queue the frame up on the other channel if present */
00149    if (other) {
00150       ast_queue_hangup(other);
00151       ast_channel_unlock(other);
00152    }
00153 
00154    return;
00155 }

static struct ast_frame * bridge_read ( struct ast_channel ast  )  [static, read]

Called when a frame should be read from the channel.

Definition at line 85 of file chan_bridge.c.

References ast_null_frame.

00086 {
00087    return &ast_null_frame;
00088 }

static struct ast_channel * bridge_request ( const char *  type,
int  format,
void *  data,
int *  cause 
) [static, read]

Called when we want to place a call somewhere, but not actually call it... yet.

Definition at line 193 of file chan_bridge.c.

References ast_calloc, ast_channel_alloc, ast_channel_free(), AST_FORMAT_SLINEAR, ast_free, ast_mutex_init(), AST_STATE_UP, bridge_pvt::input, bridge_pvt::lock, ast_channel::nativeformats, bridge_pvt::output, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, and ast_channel::writeformat.

00194 {
00195    struct bridge_pvt *p = NULL;
00196 
00197    /* Try to allocate memory for our very minimal pvt structure */
00198    if (!(p = ast_calloc(1, sizeof(*p)))) {
00199       return NULL;
00200    }
00201 
00202    /* Try to grab two Asterisk channels to use as input and output channels */
00203    if (!(p->input = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", 0, "Bridge/%p-input", p))) {
00204       ast_free(p);
00205       return NULL;
00206    }
00207    if (!(p->output = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", 0, "Bridge/%p-output", p))) {
00208       ast_channel_free(p->input);
00209       ast_free(p);
00210       return NULL;
00211    }
00212 
00213    /* Setup the lock on the pvt structure, we will need that */
00214    ast_mutex_init(&p->lock);
00215 
00216    /* Setup parameters on both new channels */
00217    p->input->tech = p->output->tech = &bridge_tech;
00218    p->input->tech_pvt = p->output->tech_pvt = p;
00219    p->input->nativeformats = p->output->nativeformats = AST_FORMAT_SLINEAR;
00220    p->input->readformat = p->output->readformat = AST_FORMAT_SLINEAR;
00221    p->input->rawreadformat = p->output->rawreadformat = AST_FORMAT_SLINEAR;
00222    p->input->writeformat = p->output->writeformat = AST_FORMAT_SLINEAR;
00223    p->input->rawwriteformat = p->output->rawwriteformat = AST_FORMAT_SLINEAR;
00224 
00225    return p->input;
00226 }

static int bridge_write ( struct ast_channel ast,
struct ast_frame f 
) [static]

Called when a frame should be written out to a channel.

Definition at line 91 of file chan_bridge.c.

References ast_channel_trylock, ast_channel_unlock, ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), CHANNEL_DEADLOCK_AVOIDANCE, bridge_pvt::input, bridge_pvt::lock, bridge_pvt::output, and ast_channel::tech_pvt.

00092 {
00093    struct bridge_pvt *p = ast->tech_pvt;
00094    struct ast_channel *other;
00095 
00096    ast_mutex_lock(&p->lock);
00097 
00098    other = (p->input == ast ? p->output : p->input);
00099 
00100    while (other && ast_channel_trylock(other)) {
00101       ast_mutex_unlock(&p->lock);
00102       do {
00103          CHANNEL_DEADLOCK_AVOIDANCE(ast);
00104       } while (ast_mutex_trylock(&p->lock));
00105       other = (p->input == ast ? p->output : p->input);
00106    }
00107 
00108    /* We basically queue the frame up on the other channel if present */
00109    if (other) {
00110       ast_queue_frame(other, f);
00111       ast_channel_unlock(other);
00112    }
00113 
00114    ast_mutex_unlock(&p->lock);
00115 
00116    return 0;
00117 }

static int load_module ( void   )  [static]

Load module into PBX, register channel.

Definition at line 229 of file chan_bridge.c.

References ast_channel_register(), ast_log(), AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, and LOG_ERROR.

00230 {
00231    /* Make sure we can register our channel type */
00232    if (ast_channel_register(&bridge_tech)) {
00233       ast_log(LOG_ERROR, "Unable to register channel class 'Bridge'\n");
00234       return AST_MODULE_LOAD_FAILURE;
00235    }
00236    return AST_MODULE_LOAD_SUCCESS;
00237 }

static int unload_module ( void   )  [static]

Unload the bridge interaction channel from Asterisk.

Definition at line 240 of file chan_bridge.c.

References ast_channel_unregister().

00241 {
00242    ast_channel_unregister(&bridge_tech);
00243    return 0;
00244 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Bridge Interaction Channel" , .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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 246 of file chan_bridge.c.

Definition at line 246 of file chan_bridge.c.

struct ast_channel_tech bridge_tech [static]

Definition at line 57 of file chan_bridge.c.


Generated by  doxygen 1.6.2