Wed Jan 8 2020 09:49:59

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/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_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. More...
 
static int bridge_call (struct ast_channel *ast, char *dest, int timeout)
 Called when the channel should actually be dialed. More...
 
static int bridge_hangup (struct ast_channel *ast)
 Called when a channel should be hung up. More...
 
static void bridge_queue_hangup (struct bridge_pvt *p, struct ast_channel *us)
 Helper function to not deadlock when queueing the hangup frame. More...
 
static struct ast_framebridge_read (struct ast_channel *ast)
 Called when a frame should be read from the channel. More...
 
static struct ast_channelbridge_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. More...
 
static int bridge_write (struct ast_channel *ast, struct ast_frame *f)
 Called when a frame should be written out to a channel. More...
 
static int load_module (void)
 Load module into PBX, register channel. More...
 
static int unload_module (void)
 Unload the bridge interaction channel from Asterisk. More...
 

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_infoast_module_info = &__mod_info
 
static struct ast_channel_tech bridge_tech
 

Detailed Description

Bridge Interaction Channel.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file chan_bridge.c.

Function Documentation

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.

82 {
83  struct bridge_pvt *p = chan->tech_pvt;
84  return (chan == p->input) ? p->output : bridge;
85 }
void * tech_pvt
Definition: channel.h:744
struct ast_channel * output
Definition: chan_bridge.c:77
struct ast_channel * input
Definition: chan_bridge.c:76
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.

124 {
125  struct bridge_pvt *p = ast->tech_pvt;
126 
127  /* If no bridge has been provided on the input channel, bail out */
128  if (!ast->bridge) {
129  return -1;
130  }
131 
132  /* Impart the output channel upon the given bridge of the input channel */
133  ast_bridge_impart(p->input->bridge, p->output, NULL, NULL);
134 
135  return 0;
136 }
void * tech_pvt
Definition: channel.h:744
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features)
Impart (non-blocking) a channel on a bridge.
Definition: bridging.c:1043
struct ast_bridge * bridge
Definition: channel.h:865
struct ast_channel * output
Definition: chan_bridge.c:77
struct ast_channel * input
Definition: chan_bridge.c:76
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.

162 {
163  struct bridge_pvt *p = ast->tech_pvt;
164 
165  ast_mutex_lock(&p->lock);
166 
167  /* Figure out which channel this is... and set it to NULL as it has gone, but also queue up a hangup frame. */
168  if (p->input == ast) {
169  if (p->output) {
170  bridge_queue_hangup(p, ast);
171  }
172  p->input = NULL;
173  } else if (p->output == ast) {
174  if (p->input) {
175  bridge_queue_hangup(p, ast);
176  }
177  p->output = NULL;
178  }
179 
180  /* Deal with the Asterisk portion of it */
181  ast->tech_pvt = NULL;
182 
183  /* If both sides have been terminated free the structure and be done with things */
184  if (!p->input && !p->output) {
185  ast_mutex_unlock(&p->lock);
186  ast_mutex_destroy(&p->lock);
187  ast_free(p);
188  } else {
189  ast_mutex_unlock(&p->lock);
190  }
191 
192  return 0;
193 }
void * tech_pvt
Definition: channel.h:744
ast_mutex_t lock
Definition: chan_bridge.c:75
#define ast_mutex_lock(a)
Definition: lock.h:155
static void bridge_queue_hangup(struct bridge_pvt *p, struct ast_channel *us)
Helper function to not deadlock when queueing the hangup frame.
Definition: chan_bridge.c:139
#define ast_free(a)
Definition: astmm.h:97
struct ast_channel * output
Definition: chan_bridge.c:77
#define ast_mutex_destroy(a)
Definition: lock.h:154
struct ast_channel * input
Definition: chan_bridge.c:76
#define ast_mutex_unlock(a)
Definition: lock.h:156
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().

140 {
141  struct ast_channel *other = (p->input == us ? p->output : p->input);
142 
143  while (other && ast_channel_trylock(other)) {
144  ast_mutex_unlock(&p->lock);
145  do {
147  } while (ast_mutex_trylock(&p->lock));
148  other = (p->input == us ? p->output : p->input);
149  }
150 
151  /* We basically queue the frame up on the other channel if present */
152  if (other) {
153  ast_queue_hangup(other);
154  ast_channel_unlock(other);
155  }
156 
157  return;
158 }
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1569
Main Channel structure associated with a channel.
Definition: channel.h:742
ast_mutex_t lock
Definition: chan_bridge.c:75
#define ast_mutex_trylock(a)
Definition: lock.h:157
#define ast_channel_unlock(chan)
Definition: channel.h:2467
struct ast_channel * output
Definition: chan_bridge.c:77
#define CHANNEL_DEADLOCK_AVOIDANCE(chan)
Definition: lock.h:480
#define ast_channel_trylock(chan)
Definition: channel.h:2468
struct ast_channel * input
Definition: chan_bridge.c:76
#define ast_mutex_unlock(a)
Definition: lock.h:156
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.

89 {
90  return &ast_null_frame;
91 }
struct ast_frame ast_null_frame
Definition: frame.c:131
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, bridge_pvt::input, ast_channel::linkedid, 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.

197 {
198  struct bridge_pvt *p = NULL;
199 
200  /* Try to allocate memory for our very minimal pvt structure */
201  if (!(p = ast_calloc(1, sizeof(*p)))) {
202  return NULL;
203  }
204 
205  /* Try to grab two Asterisk channels to use as input and output channels */
206  if (!(p->input = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", requestor ? requestor->linkedid : NULL, 0, "Bridge/%p-input", p))) {
207  ast_free(p);
208  return NULL;
209  }
210  if (!(p->output = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", requestor ? requestor->linkedid : NULL, 0, "Bridge/%p-output", p))) {
212  ast_free(p);
213  return NULL;
214  }
215 
216  /* Setup the lock on the pvt structure, we will need that */
217  ast_mutex_init(&p->lock);
218 
219  /* Setup parameters on both new channels */
220  p->input->tech = p->output->tech = &bridge_tech;
221  p->input->tech_pvt = p->output->tech_pvt = p;
227 
228  return p->input;
229 }
format_t writeformat
Definition: channel.h:854
void * tech_pvt
Definition: channel.h:744
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1921
format_t rawwriteformat
Definition: channel.h:856
ast_mutex_t lock
Definition: chan_bridge.c:75
format_t nativeformats
Definition: channel.h:852
static struct ast_channel_tech bridge_tech
Definition: chan_bridge.c:60
const ast_string_field linkedid
Definition: channel.h:787
format_t rawreadformat
Definition: channel.h:855
struct ast_channel * ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *name_fmt,...)
Definition: channel.c:9825
#define ast_free(a)
Definition: astmm.h:97
struct ast_channel * output
Definition: chan_bridge.c:77
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
format_t readformat
Definition: channel.h:853
#define ast_calloc(a, b)
Definition: astmm.h:82
#define ast_mutex_init(pmutex)
Definition: lock.h:152
struct ast_channel_tech * tech
Definition: channel.h:743
struct ast_channel * input
Definition: chan_bridge.c:76
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.

95 {
96  struct bridge_pvt *p = ast->tech_pvt;
97  struct ast_channel *other;
98 
99  ast_mutex_lock(&p->lock);
100 
101  other = (p->input == ast ? p->output : p->input);
102 
103  while (other && ast_channel_trylock(other)) {
104  ast_mutex_unlock(&p->lock);
105  do {
107  } while (ast_mutex_trylock(&p->lock));
108  other = (p->input == ast ? p->output : p->input);
109  }
110 
111  /* We basically queue the frame up on the other channel if present */
112  if (other) {
113  ast_queue_frame(other, f);
114  ast_channel_unlock(other);
115  }
116 
117  ast_mutex_unlock(&p->lock);
118 
119  return 0;
120 }
Main Channel structure associated with a channel.
Definition: channel.h:742
void * tech_pvt
Definition: channel.h:744
ast_mutex_t lock
Definition: chan_bridge.c:75
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_mutex_trylock(a)
Definition: lock.h:157
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
#define ast_channel_unlock(chan)
Definition: channel.h:2467
struct ast_channel * output
Definition: chan_bridge.c:77
#define CHANNEL_DEADLOCK_AVOIDANCE(chan)
Definition: lock.h:480
#define ast_channel_trylock(chan)
Definition: channel.h:2468
struct ast_channel * input
Definition: chan_bridge.c:76
#define ast_mutex_unlock(a)
Definition: lock.h:156
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.

233 {
234  /* Make sure we can register our channel type */
236  ast_log(LOG_ERROR, "Unable to register channel class 'Bridge'\n");
238  }
240 }
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:907
static struct ast_channel_tech bridge_tech
Definition: chan_bridge.c:60
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
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().

244 {
246  return 0;
247 }
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:938
static struct ast_channel_tech bridge_tech
Definition: chan_bridge.c:60

Variable Documentation

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.

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().