#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 = "ac1f6a56484a8820659555499174e588" , .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 253 of file chan_bridge.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 253 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 81 of file chan_bridge.c.
References bridge_pvt::input, bridge_pvt::output, and ast_channel::tech_pvt.
00082 { 00083 struct bridge_pvt *p = chan->tech_pvt; 00084 return (chan == p->input) ? p->output : bridge; 00085 }
static int bridge_call | ( | struct ast_channel * | ast, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Called when the channel should actually be dialed.
Definition at line 123 of file chan_bridge.c.
References ast_bridge_impart(), ast_channel::bridge, bridge_pvt::input, bridge_pvt::output, and ast_channel::tech_pvt.
00124 { 00125 struct bridge_pvt *p = ast->tech_pvt; 00126 00127 /* If no bridge has been provided on the input channel, bail out */ 00128 if (!ast->bridge) { 00129 return -1; 00130 } 00131 00132 /* Impart the output channel upon the given bridge of the input channel */ 00133 ast_bridge_impart(p->input->bridge, p->output, NULL, NULL); 00134 00135 return 0; 00136 }
static int bridge_hangup | ( | struct ast_channel * | ast | ) | [static] |
Called when a channel should be hung up.
Definition at line 161 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.
00162 { 00163 struct bridge_pvt *p = ast->tech_pvt; 00164 00165 ast_mutex_lock(&p->lock); 00166 00167 /* Figure out which channel this is... and set it to NULL as it has gone, but also queue up a hangup frame. */ 00168 if (p->input == ast) { 00169 if (p->output) { 00170 bridge_queue_hangup(p, ast); 00171 } 00172 p->input = NULL; 00173 } else if (p->output == ast) { 00174 if (p->input) { 00175 bridge_queue_hangup(p, ast); 00176 } 00177 p->output = NULL; 00178 } 00179 00180 /* Deal with the Asterisk portion of it */ 00181 ast->tech_pvt = NULL; 00182 00183 /* If both sides have been terminated free the structure and be done with things */ 00184 if (!p->input && !p->output) { 00185 ast_mutex_unlock(&p->lock); 00186 ast_mutex_destroy(&p->lock); 00187 ast_free(p); 00188 } else { 00189 ast_mutex_unlock(&p->lock); 00190 } 00191 00192 return 0; 00193 }
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 139 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().
00140 { 00141 struct ast_channel *other = (p->input == us ? p->output : p->input); 00142 00143 while (other && ast_channel_trylock(other)) { 00144 ast_mutex_unlock(&p->lock); 00145 do { 00146 CHANNEL_DEADLOCK_AVOIDANCE(us); 00147 } while (ast_mutex_trylock(&p->lock)); 00148 other = (p->input == us ? p->output : p->input); 00149 } 00150 00151 /* We basically queue the frame up on the other channel if present */ 00152 if (other) { 00153 ast_queue_hangup(other); 00154 ast_channel_unlock(other); 00155 } 00156 00157 return; 00158 }
static struct ast_frame * bridge_read | ( | struct ast_channel * | ast | ) | [static] |
Called when a frame should be read from the channel.
Definition at line 88 of file chan_bridge.c.
References ast_null_frame.
00089 { 00090 return &ast_null_frame; 00091 }
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 196 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.
00197 { 00198 struct bridge_pvt *p = NULL; 00199 00200 /* Try to allocate memory for our very minimal pvt structure */ 00201 if (!(p = ast_calloc(1, sizeof(*p)))) { 00202 return NULL; 00203 } 00204 00205 /* Try to grab two Asterisk channels to use as input and output channels */ 00206 if (!(p->input = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", requestor ? requestor->linkedid : NULL, 0, "Bridge/%p-input", p))) { 00207 ast_free(p); 00208 return NULL; 00209 } 00210 if (!(p->output = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", requestor ? requestor->linkedid : NULL, 0, "Bridge/%p-output", p))) { 00211 p->input = ast_channel_release(p->input); 00212 ast_free(p); 00213 return NULL; 00214 } 00215 00216 /* Setup the lock on the pvt structure, we will need that */ 00217 ast_mutex_init(&p->lock); 00218 00219 /* Setup parameters on both new channels */ 00220 p->input->tech = p->output->tech = &bridge_tech; 00221 p->input->tech_pvt = p->output->tech_pvt = p; 00222 p->input->nativeformats = p->output->nativeformats = AST_FORMAT_SLINEAR; 00223 p->input->readformat = p->output->readformat = AST_FORMAT_SLINEAR; 00224 p->input->rawreadformat = p->output->rawreadformat = AST_FORMAT_SLINEAR; 00225 p->input->writeformat = p->output->writeformat = AST_FORMAT_SLINEAR; 00226 p->input->rawwriteformat = p->output->rawwriteformat = AST_FORMAT_SLINEAR; 00227 00228 return p->input; 00229 }
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 94 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.
00095 { 00096 struct bridge_pvt *p = ast->tech_pvt; 00097 struct ast_channel *other; 00098 00099 ast_mutex_lock(&p->lock); 00100 00101 other = (p->input == ast ? p->output : p->input); 00102 00103 while (other && ast_channel_trylock(other)) { 00104 ast_mutex_unlock(&p->lock); 00105 do { 00106 CHANNEL_DEADLOCK_AVOIDANCE(ast); 00107 } while (ast_mutex_trylock(&p->lock)); 00108 other = (p->input == ast ? p->output : p->input); 00109 } 00110 00111 /* We basically queue the frame up on the other channel if present */ 00112 if (other) { 00113 ast_queue_frame(other, f); 00114 ast_channel_unlock(other); 00115 } 00116 00117 ast_mutex_unlock(&p->lock); 00118 00119 return 0; 00120 }
static int load_module | ( | void | ) | [static] |
Load module into PBX, register channel.
Definition at line 232 of file chan_bridge.c.
References ast_channel_register(), ast_log(), AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, bridge_tech, and LOG_ERROR.
00233 { 00234 /* Make sure we can register our channel type */ 00235 if (ast_channel_register(&bridge_tech)) { 00236 ast_log(LOG_ERROR, "Unable to register channel class 'Bridge'\n"); 00237 return AST_MODULE_LOAD_FAILURE; 00238 } 00239 return AST_MODULE_LOAD_SUCCESS; 00240 }
static int unload_module | ( | void | ) | [static] |
Unload the bridge interaction channel from Asterisk.
Definition at line 243 of file chan_bridge.c.
References ast_channel_unregister(), and bridge_tech.
00244 { 00245 ast_channel_unregister(&bridge_tech); 00246 return 0; 00247 }
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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } [static] |
Definition at line 253 of file chan_bridge.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 253 of file chan_bridge.c.
struct ast_channel_tech bridge_tech [static] |
Definition at line 60 of file chan_bridge.c.
Referenced by bridge_request(), load_module(), and unload_module().