95 after_bridge_cb_failed(node);
107 static void after_bridge_cb_destroy(
void *
data)
114 ast_free(after_bridge);
133 after_bridge = after_bridge_cb_find(new_chan);
140 if (node && !node->
reason) {
147 .
type =
"after-bridge-cb",
148 .destroy = after_bridge_cb_destroy,
149 .chan_fixup = after_bridge_cb_fixup,
171 return datastore->
data;
192 return datastore->
data;
196 datastore = ast_datastore_alloc(&after_bridge_cb_info, NULL);
200 after_bridge =
ast_calloc(1,
sizeof(*after_bridge));
206 datastore->
data = after_bridge;
209 return datastore->
data;
217 after_bridge = after_bridge_cb_find(chan);
230 after_bridge_cb_failed(node);
243 after_bridge = after_bridge_cb_find(chan);
248 after_bridge_cb_run_discard(after_bridge, reason);
258 ast_assert(chan != NULL);
259 if (!chan || !callback) {
263 after_bridge = after_bridge_cb_setup(chan);
280 if (last_node && !last_node->
reason) {
292 return "Channel destroyed (hungup)";
294 return "Callback was replaced";
296 return "Channel masqueraded";
298 return "Channel was departed from bridge";
300 return "Callback was removed";
302 return "Channel failed joining the bridge";
329 static void after_bridge_goto_destroy(
void *data)
334 ast_free((
char *) after_bridge->
context);
335 ast_free((
char *) after_bridge->
exten);
336 ast_free((
char *) after_bridge);
348 static void after_bridge_goto_fixup(
void *data,
struct ast_channel *old_chan,
struct ast_channel *new_chan)
355 .
type =
"after-bridge-goto",
356 .destroy = after_bridge_goto_destroy,
357 .chan_fixup = after_bridge_goto_fixup,
374 ast_channel_lock(chan);
379 ast_channel_unlock(chan);
388 datastore = after_bridge_goto_remove(chan);
398 char *current_pos = buffer;
399 size_t remaining_size = buf_size;
409 after_bridge = datastore->
data;
416 if (!ast_strlen_zero(after_bridge->
context)) {
417 snprintf(current_pos, remaining_size,
"%s,", after_bridge->
context);
418 remaining_size = remaining_size - strlen(current_pos);
419 current_pos += strlen(current_pos);
423 snprintf(current_pos, remaining_size,
"h,");
424 remaining_size = remaining_size - strlen(current_pos);
425 current_pos += strlen(current_pos);
426 }
else if (!ast_strlen_zero(after_bridge->
exten)) {
427 snprintf(current_pos, remaining_size,
"%s,", after_bridge->
exten);
428 remaining_size = remaining_size - strlen(current_pos);
429 current_pos += strlen(current_pos);
432 snprintf(current_pos, remaining_size,
"%d", after_bridge->
priority);
439 int goto_failed = -1;
457 datastore = after_bridge_goto_remove(chan);
462 after_bridge = datastore->
data;
466 ast_channel_caller(chan)->
id.
number.str, NULL))) {
467 ast_debug(1,
"Running after bridge goto h exten %s,h,1\n",
468 ast_channel_context(chan));
488 priority = ast_channel_priority(chan);
498 ast_channel_context_set(chan, context);
499 ast_channel_exten_set(chan, exten);
500 ast_channel_priority_set(chan, priority);
509 ast_channel_priority_set(chan, ast_channel_priority(chan) + 1);
512 ast_debug(1,
"Setup after bridge goto location to %s,%s,%d.\n",
513 ast_channel_context(chan),
514 ast_channel_exten(chan),
515 ast_channel_priority(chan));
563 ast_assert(chan != NULL);
568 ast_assert(run_h_exten && context);
573 ast_assert(context && exten && 0 < priority);
574 if (!context || !exten || priority < 1) {
580 datastore = ast_datastore_alloc(&after_bridge_goto_info, NULL);
584 after_bridge =
ast_calloc(1,
sizeof(*after_bridge));
596 after_bridge->
specific = specific ? 1 : 0;
597 datastore->
data = after_bridge;
599 || (context && !after_bridge->
context)
600 || (exten && !after_bridge->
exten)) {
606 ast_channel_lock(chan);
609 ast_channel_unlock(chan);
614 __after_bridge_set_goto(chan, 0, 1, context, exten, priority, NULL);
619 __after_bridge_set_goto(chan, 1, 0, context, NULL, 1, NULL);
626 if (!ast_strlen_zero(parseable_goto)) {
632 __after_bridge_set_goto(chan, 0, 0, context, exten, priority, p_goto);
void ast_pbx_h_exten_run(struct ast_channel *chan, const char *context)
Run the h exten from the given context.
Main Channel structure associated with a channel.
void ast_bridge_run_after_callback(struct ast_channel *chan)
Run any after bridge callback.
#define AST_LIST_LOCK(head)
Locks a list.
Asterisk main include file. File version handling, generic pbx functions.
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
const char * parseable_goto
struct after_bridge_cb_node::@314 list
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
ast_bridge_after_cb callback
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
void ast_bridge_read_after_goto(struct ast_channel *chan, char *buffer, size_t buf_size)
Read after bridge goto if it exists.
Structure for a data store type.
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
#define ast_strdup(str)
A wrapper for strdup()
Structure for a data store object.
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
enum ast_bridge_after_cb_reason reason
void ast_bridge_run_after_goto(struct ast_channel *chan)
Run a PBX on any after bridge goto location.
int ast_bridge_set_after_callback(struct ast_channel *chan, ast_bridge_after_cb callback, ast_bridge_after_cb_failed failed, void *data)
Setup an after bridge callback for when the channel leaves the bridging system.
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
ast_bridge_after_cb_reason
void ast_replace_subargument_delimiter(char *s)
Replace '^' in a string with ','.
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
General Asterisk PBX channel definitions.
const char * ast_bridge_after_cb_reason_string(enum ast_bridge_after_cb_reason reason)
Get a string representation of an after bridge callback reason.
void ast_channel_clear_softhangup(struct ast_channel *chan, int flag)
Clear a set of softhangup flags from a channel.
#define ast_strdupa(s)
duplicate a string in memory from the stack
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
void ast_bridge_discard_after_goto(struct ast_channel *chan)
Discard channel after bridge goto location.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Core PBX routines and definitions.
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
ast_bridge_after_cb_failed failed
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
void ast_bridge_set_after_go_on(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *parseable_goto)
Set channel to go on in the dialplan after the bridge.
void ast_bridge_set_after_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set channel to goto specific location after the bridge.
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
#define ast_calloc(num, len)
A wrapper for calloc()
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Support for logging to various files, console and syslog Configuration in file logger.conf.
After Bridge Execution API.
struct after_bridge_cb_ds::@315 callbacks
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
void ast_bridge_discard_after_callback(struct ast_channel *chan, enum ast_bridge_after_cb_reason reason)
Run discarding any after bridge callbacks.
void(* ast_bridge_after_cb)(struct ast_channel *chan, void *data)
After bridge callback function.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
void(* ast_bridge_after_cb_failed)(enum ast_bridge_after_cb_reason reason, void *data)
After bridge callback failed.
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
void ast_channel_set_unbridged(struct ast_channel *chan, int value)
Sets the unbridged flag and queues a NULL frame on the channel to trigger a check by bridge_channel_w...
void ast_bridge_set_after_h(struct ast_channel *chan, const char *context)
Set channel to run the h exten after the bridge.