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/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 | |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,"Bridge Interaction Channel",.load=load_module,.unload=unload_module,.load_pri=AST_MODPRI_CHANNEL_DRIVER,) | |
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_channel_tech | bridge_tech |
Bridge Interaction Channel.
Definition in file chan_bridge.c.
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_LOAD_ORDER | , | |||
"Bridge Interaction Channel" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | load_pri = AST_MODPRI_CHANNEL_DRIVER | |||
) |
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 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, read] |
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, read] |
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_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.
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, 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, 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().
00244 { 00245 ast_channel_unregister(&bridge_tech); 00246 return 0; 00247 }
struct ast_channel_tech bridge_tech [static] |
Definition at line 60 of file chan_bridge.c.