#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/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/bridging.h"
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_channel * | bridge_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_frame * | bridge_read (struct ast_channel *ast) |
Called when a frame should be read from the channel. | |
static struct ast_channel * | bridge_request (const char *type, format_t format, const struct ast_channel *requestor, 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_LOAD_ORDER , .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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } |
static struct ast_module_info * | ast_module_info = &__mod_info |
static struct ast_channel_tech | bridge_tech |
Definition in file chan_bridge.c.
static void __reg_module | ( | void | ) | [static] |
Definition at line 249 of file chan_bridge.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 249 of file chan_bridge.c.
static struct ast_channel * bridge_bridgedchannel | ( | struct ast_channel * | chan, | |
struct ast_channel * | bridge | |||
) | [static] |
Called when the user of this channel wants to get the actual channel in the bridge.
Definition at line 77 of file chan_bridge.c.
References bridge_pvt::input, bridge_pvt::output, and ast_channel::tech_pvt.
00078 { 00079 struct bridge_pvt *p = chan->tech_pvt; 00080 return (chan == p->input) ? p->output : bridge; 00081 }
static int bridge_call | ( | struct ast_channel * | ast, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Called when the channel should actually be dialed.
Definition at line 119 of file chan_bridge.c.
References ast_bridge_impart(), ast_channel::bridge, bridge_pvt::input, bridge_pvt::output, and ast_channel::tech_pvt.
00120 { 00121 struct bridge_pvt *p = ast->tech_pvt; 00122 00123 /* If no bridge has been provided on the input channel, bail out */ 00124 if (!ast->bridge) { 00125 return -1; 00126 } 00127 00128 /* Impart the output channel upon the given bridge of the input channel */ 00129 ast_bridge_impart(p->input->bridge, p->output, NULL, NULL); 00130 00131 return 0; 00132 }
static int bridge_hangup | ( | struct ast_channel * | ast | ) | [static] |
Called when a channel should be hung up.
Definition at line 157 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.
00158 { 00159 struct bridge_pvt *p = ast->tech_pvt; 00160 00161 ast_mutex_lock(&p->lock); 00162 00163 /* Figure out which channel this is... and set it to NULL as it has gone, but also queue up a hangup frame. */ 00164 if (p->input == ast) { 00165 if (p->output) { 00166 bridge_queue_hangup(p, ast); 00167 } 00168 p->input = NULL; 00169 } else if (p->output == ast) { 00170 if (p->input) { 00171 bridge_queue_hangup(p, ast); 00172 } 00173 p->output = NULL; 00174 } 00175 00176 /* Deal with the Asterisk portion of it */ 00177 ast->tech_pvt = NULL; 00178 00179 /* If both sides have been terminated free the structure and be done with things */ 00180 if (!p->input && !p->output) { 00181 ast_mutex_unlock(&p->lock); 00182 ast_mutex_destroy(&p->lock); 00183 ast_free(p); 00184 } else { 00185 ast_mutex_unlock(&p->lock); 00186 } 00187 00188 return 0; 00189 }
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 135 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().
00136 { 00137 struct ast_channel *other = (p->input == us ? p->output : p->input); 00138 00139 while (other && ast_channel_trylock(other)) { 00140 ast_mutex_unlock(&p->lock); 00141 do { 00142 CHANNEL_DEADLOCK_AVOIDANCE(us); 00143 } while (ast_mutex_trylock(&p->lock)); 00144 other = (p->input == us ? p->output : p->input); 00145 } 00146 00147 /* We basically queue the frame up on the other channel if present */ 00148 if (other) { 00149 ast_queue_hangup(other); 00150 ast_channel_unlock(other); 00151 } 00152 00153 return; 00154 }
static struct ast_frame * bridge_read | ( | struct ast_channel * | ast | ) | [static] |
Called when a frame should be read from the channel.
Definition at line 84 of file chan_bridge.c.
References ast_null_frame.
00085 { 00086 return &ast_null_frame; 00087 }
static struct ast_channel * bridge_request | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Called when we want to place a call somewhere, but not actually call it... yet.
Definition at line 192 of file chan_bridge.c.
References ast_calloc, ast_channel_alloc, ast_channel_release(), AST_FORMAT_SLINEAR, ast_free, ast_mutex_init, AST_STATE_UP, bridge_tech, and ast_channel::linkedid.
00193 { 00194 struct bridge_pvt *p = NULL; 00195 00196 /* Try to allocate memory for our very minimal pvt structure */ 00197 if (!(p = ast_calloc(1, sizeof(*p)))) { 00198 return NULL; 00199 } 00200 00201 /* Try to grab two Asterisk channels to use as input and output channels */ 00202 if (!(p->input = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", requestor ? requestor->linkedid : NULL, 0, "Bridge/%p-input", p))) { 00203 ast_free(p); 00204 return NULL; 00205 } 00206 if (!(p->output = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", requestor ? requestor->linkedid : NULL, 0, "Bridge/%p-output", p))) { 00207 p->input = ast_channel_release(p->input); 00208 ast_free(p); 00209 return NULL; 00210 } 00211 00212 /* Setup the lock on the pvt structure, we will need that */ 00213 ast_mutex_init(&p->lock); 00214 00215 /* Setup parameters on both new channels */ 00216 p->input->tech = p->output->tech = &bridge_tech; 00217 p->input->tech_pvt = p->output->tech_pvt = p; 00218 p->input->nativeformats = p->output->nativeformats = AST_FORMAT_SLINEAR; 00219 p->input->readformat = p->output->readformat = AST_FORMAT_SLINEAR; 00220 p->input->rawreadformat = p->output->rawreadformat = AST_FORMAT_SLINEAR; 00221 p->input->writeformat = p->output->writeformat = AST_FORMAT_SLINEAR; 00222 p->input->rawwriteformat = p->output->rawwriteformat = AST_FORMAT_SLINEAR; 00223 00224 return p->input; 00225 }
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 90 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, f, bridge_pvt::input, bridge_pvt::lock, bridge_pvt::output, and ast_channel::tech_pvt.
00091 { 00092 struct bridge_pvt *p = ast->tech_pvt; 00093 struct ast_channel *other; 00094 00095 ast_mutex_lock(&p->lock); 00096 00097 other = (p->input == ast ? p->output : p->input); 00098 00099 while (other && ast_channel_trylock(other)) { 00100 ast_mutex_unlock(&p->lock); 00101 do { 00102 CHANNEL_DEADLOCK_AVOIDANCE(ast); 00103 } while (ast_mutex_trylock(&p->lock)); 00104 other = (p->input == ast ? p->output : p->input); 00105 } 00106 00107 /* We basically queue the frame up on the other channel if present */ 00108 if (other) { 00109 ast_queue_frame(other, f); 00110 ast_channel_unlock(other); 00111 } 00112 00113 ast_mutex_unlock(&p->lock); 00114 00115 return 0; 00116 }
static int load_module | ( | void | ) | [static] |
Load module into PBX, register channel.
Definition at line 228 of file chan_bridge.c.
References ast_channel_register(), ast_log(), AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, bridge_tech, and LOG_ERROR.
00229 { 00230 /* Make sure we can register our channel type */ 00231 if (ast_channel_register(&bridge_tech)) { 00232 ast_log(LOG_ERROR, "Unable to register channel class 'Bridge'\n"); 00233 return AST_MODULE_LOAD_FAILURE; 00234 } 00235 return AST_MODULE_LOAD_SUCCESS; 00236 }
static int unload_module | ( | void | ) | [static] |
Unload the bridge interaction channel from Asterisk.
Definition at line 239 of file chan_bridge.c.
References ast_channel_unregister(), and bridge_tech.
00240 { 00241 ast_channel_unregister(&bridge_tech); 00242 return 0; 00243 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } [static] |
Definition at line 249 of file chan_bridge.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 249 of file chan_bridge.c.
struct ast_channel_tech bridge_tech [static] |
Definition at line 56 of file chan_bridge.c.
Referenced by bridge_request(), load_module(), and unload_module().