Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Functions | Variables
bridge_after.c File Reference

After Bridge Execution API. More...

#include "asterisk.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/bridge_after.h"

Go to the source code of this file.

Data Structures

struct  after_bridge_cb_ds
 
struct  after_bridge_cb_node
 
struct  after_bridge_goto_ds
 

Functions

static void __after_bridge_set_goto (struct ast_channel *chan, int run_h_exten, int specific, const char *context, const char *exten, int priority, const char *parseable_goto)
 
static void after_bridge_cb_destroy (void *data)
 
static void after_bridge_cb_failed (struct after_bridge_cb_node *node)
 
static struct after_bridge_cb_dsafter_bridge_cb_find (struct ast_channel *chan)
 
static void after_bridge_cb_fixup (void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
 
static void after_bridge_cb_run_discard (struct after_bridge_cb_ds *after_bridge, enum ast_bridge_after_cb_reason reason)
 
static struct after_bridge_cb_dsafter_bridge_cb_setup (struct ast_channel *chan)
 
static void after_bridge_goto_destroy (void *data)
 
static void after_bridge_goto_fixup (void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
 
static struct ast_datastoreafter_bridge_goto_remove (struct ast_channel *chan)
 
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. More...
 
void ast_bridge_discard_after_callback (struct ast_channel *chan, enum ast_bridge_after_cb_reason reason)
 Run discarding any after bridge callbacks. More...
 
void ast_bridge_discard_after_goto (struct ast_channel *chan)
 Discard channel after bridge goto location. More...
 
void ast_bridge_read_after_goto (struct ast_channel *chan, char *buffer, size_t buf_size)
 Read after bridge goto if it exists. More...
 
void ast_bridge_run_after_callback (struct ast_channel *chan)
 Run any after bridge callback. More...
 
void ast_bridge_run_after_goto (struct ast_channel *chan)
 Run a PBX on any after bridge goto location. More...
 
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. More...
 
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. More...
 
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. More...
 
void ast_bridge_set_after_h (struct ast_channel *chan, const char *context)
 Set channel to run the h exten after the bridge. More...
 
int ast_bridge_setup_after_goto (struct ast_channel *chan)
 Setup any after bridge goto location to begin execution. More...
 

Variables

static const struct ast_datastore_info after_bridge_cb_info
 
static const struct ast_datastore_info after_bridge_goto_info
 

Detailed Description

After Bridge Execution API.

Author
Richard Mudgett rmudg.nosp@m.ett@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

See Also:

Definition in file bridge_after.c.

Function Documentation

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.

Since
12.0.0
Parameters
reasonThe reason to interpret to a string
Return values
NULLUnrecognized reason
non-NULLString representation of reason

Definition at line 288 of file bridge_after.c.

References AST_BRIDGE_AFTER_CB_REASON_DEPART, AST_BRIDGE_AFTER_CB_REASON_DESTROY, AST_BRIDGE_AFTER_CB_REASON_IMPART_FAILED, AST_BRIDGE_AFTER_CB_REASON_MASQUERADE, AST_BRIDGE_AFTER_CB_REASON_REMOVED, and AST_BRIDGE_AFTER_CB_REASON_REPLACED.

289 {
290  switch (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";
303  }
304  return "Unknown";
305 }
void ast_bridge_discard_after_callback ( struct ast_channel chan,
enum ast_bridge_after_cb_reason  reason 
)

Run discarding any after bridge callbacks.

Since
12.0.0
Parameters
chanChannel to run after bridge callback.
reason

Definition at line 239 of file bridge_after.c.

Referenced by ast_bridge_impart(), and bridge_channel_depart_thread().

240 {
241  struct after_bridge_cb_ds *after_bridge;
242 
243  after_bridge = after_bridge_cb_find(chan);
244  if (!after_bridge) {
245  return;
246  }
247 
248  after_bridge_cb_run_discard(after_bridge, reason);
249 }
void ast_bridge_discard_after_goto ( struct ast_channel chan)

Discard channel after bridge goto location.

Since
12.0.0
Parameters
chanChannel to discard after bridge goto location.
Note
chan is locked by this function.

Definition at line 384 of file bridge_after.c.

References ast_datastore_free().

Referenced by bridge_channel_depart_thread(), and feature_blind_transfer().

385 {
386  struct ast_datastore *datastore;
387 
388  datastore = after_bridge_goto_remove(chan);
389  if (datastore) {
390  ast_datastore_free(datastore);
391  }
392 }
Structure for a data store object.
Definition: datastore.h:64
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
void ast_bridge_read_after_goto ( struct ast_channel chan,
char *  buffer,
size_t  buf_size 
)

Read after bridge goto if it exists.

Since
12.0.0
Parameters
chanChannel to read the after bridge goto parseable goto string from
bufferBuffer to write the after bridge goto data to
buf_sizesize of the buffer being written to

Definition at line 394 of file bridge_after.c.

References ast_channel_datastore_find(), after_bridge_goto_ds::context, ast_datastore::data, after_bridge_goto_ds::exten, lock, after_bridge_goto_ds::parseable_goto, after_bridge_goto_ds::priority, after_bridge_goto_ds::run_h_exten, and SCOPED_CHANNELLOCK.

395 {
396  struct ast_datastore *datastore;
397  struct after_bridge_goto_ds *after_bridge;
398  char *current_pos = buffer;
399  size_t remaining_size = buf_size;
400 
401  SCOPED_CHANNELLOCK(lock, chan);
402 
403  datastore = ast_channel_datastore_find(chan, &after_bridge_goto_info, NULL);
404  if (!datastore) {
405  buffer[0] = '\0';
406  return;
407  }
408 
409  after_bridge = datastore->data;
410 
411  if (after_bridge->parseable_goto) {
412  snprintf(buffer, buf_size, "%s", after_bridge->parseable_goto);
413  return;
414  }
415 
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);
420  }
421 
422  if (after_bridge->run_h_exten) {
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);
430  }
431 
432  snprintf(current_pos, remaining_size, "%d", after_bridge->priority);
433 }
const char * parseable_goto
Definition: bridge_after.c:309
Structure for a data store object.
Definition: datastore.h:64
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.
Definition: channel.c:2399
ast_mutex_t lock
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:619
const char * context
Definition: bridge_after.c:311
const char * exten
Definition: bridge_after.c:313
void * data
Definition: datastore.h:66
unsigned int run_h_exten
Definition: bridge_after.c:317
void ast_bridge_run_after_callback ( struct ast_channel chan)

Run any after bridge callback.

Since
12.0.0
Parameters
chanChannel to run after bridge callback.

Definition at line 212 of file bridge_after.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, after_bridge_cb_node::callback, after_bridge_cb_ds::callbacks, after_bridge_cb_node::data, after_bridge_cb_node::failed, after_bridge_cb_node::list, and after_bridge_cb_node::reason.

Referenced by ast_bridge_join(), and bridge_channel_ind_thread().

213 {
214  struct after_bridge_cb_ds *after_bridge;
215  struct after_bridge_cb_node *node;
216 
217  after_bridge = after_bridge_cb_find(chan);
218  if (!after_bridge) {
219  return;
220  }
221 
222  for (;;) {
223  AST_LIST_LOCK(&after_bridge->callbacks);
224  node = AST_LIST_REMOVE_HEAD(&after_bridge->callbacks, list);
225  AST_LIST_UNLOCK(&after_bridge->callbacks);
226  if (!node) {
227  break;
228  }
229  if (node->reason) {
230  after_bridge_cb_failed(node);
231  } else {
232  node->failed = NULL;
233  node->callback(chan, node->data);
234  }
235  ast_free(node);
236  }
237 }
Definition: test_heap.c:38
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:40
struct after_bridge_cb_node::@314 list
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:140
ast_bridge_after_cb callback
Definition: bridge_after.c:44
enum ast_bridge_after_cb_reason reason
Definition: bridge_after.c:50
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
ast_bridge_after_cb_failed failed
Definition: bridge_after.c:46
struct after_bridge_cb_ds::@315 callbacks
void ast_bridge_run_after_goto ( struct ast_channel chan)

Run a PBX on any after bridge goto location.

Since
12.0.0
Parameters
chanChannel to execute after bridge goto location.
Note
chan is locked by this function.

Pull off any after bridge goto location datastore and run a PBX at that location.

Note
On return, the chan pointer is no longer valid because the channel has hung up.

Definition at line 525 of file bridge_after.c.

References ast_bridge_setup_after_goto(), ast_hangup(), and ast_pbx_run().

Referenced by bridge_channel_ind_thread().

526 {
527  int goto_failed;
528 
529  goto_failed = ast_bridge_setup_after_goto(chan);
530  if (goto_failed || ast_pbx_run(chan)) {
531  ast_hangup(chan);
532  }
533 }
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
Definition: bridge_after.c:435
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition: pbx.c:4755
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.

Since
12.0.0
Parameters
chanChannel to setup an after bridge callback on.
callbackFunction to call when the channel leaves the bridging system.
failedFunction to call when it will not be calling the callback.
dataExtra data to pass with the callback.
Note
chan is locked by this function.
failed is called when the channel leaves the bridging system or is destroyed.
Return values
0on success.
-1on error.

Definition at line 251 of file bridge_after.c.

References AST_BRIDGE_AFTER_CB_REASON_REPLACED, ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_UNLOCK, after_bridge_cb_node::callback, after_bridge_cb_ds::callbacks, after_bridge_cb_node::data, after_bridge_cb_node::failed, after_bridge_cb_node::list, and after_bridge_cb_node::reason.

Referenced by add_to_dial_bridge(), bridge_agent_hold_push(), control_swap_channel_in_bridge(), and stasis_app_bridge_playback_channel_add().

252 {
253  struct after_bridge_cb_ds *after_bridge;
254  struct after_bridge_cb_node *new_node;
255  struct after_bridge_cb_node *last_node;
256 
257  /* Sanity checks. */
258  ast_assert(chan != NULL);
259  if (!chan || !callback) {
260  return -1;
261  }
262 
263  after_bridge = after_bridge_cb_setup(chan);
264  if (!after_bridge) {
265  return -1;
266  }
267 
268  /* Create a new callback node. */
269  new_node = ast_calloc(1, sizeof(*new_node));
270  if (!new_node) {
271  return -1;
272  }
273  new_node->callback = callback;
274  new_node->failed = failed;
275  new_node->data = data;
276 
277  /* Put it in the container disabling any previously active one. */
278  AST_LIST_LOCK(&after_bridge->callbacks);
279  last_node = AST_LIST_LAST(&after_bridge->callbacks);
280  if (last_node && !last_node->reason) {
282  }
283  AST_LIST_INSERT_TAIL(&after_bridge->callbacks, new_node, list);
284  AST_LIST_UNLOCK(&after_bridge->callbacks);
285  return 0;
286 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:40
struct after_bridge_cb_node::@314 list
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:140
ast_bridge_after_cb callback
Definition: bridge_after.c:44
enum ast_bridge_after_cb_reason reason
Definition: bridge_after.c:50
ast_bridge_after_cb_failed failed
Definition: bridge_after.c:46
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:429
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
struct after_bridge_cb_ds::@315 callbacks
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.

Since
12.0.0
Parameters
chanChannel to setup after bridge goto location.
contextCurrent context of the caller channel.
extenCurrent exten of the caller channel.
priorityCurrent priority of the caller channel
parseable_gotoUser specified goto string from dialplan.
Note
chan is locked by this function.

Add a channel datastore to setup the goto location when the channel leaves the bridge and run a PBX from there.

If parseable_goto then use the given context/exten/priority as the relative position for the parseable_goto. Else goto the given context/exten/priority+1.

Definition at line 622 of file bridge_after.c.

References ast_replace_subargument_delimiter(), and ast_strdupa.

Referenced by bridge_exec(), and feature_blind_transfer().

623 {
624  char *p_goto;
625 
626  if (!ast_strlen_zero(parseable_goto)) {
627  p_goto = ast_strdupa(parseable_goto);
629  } else {
630  p_goto = NULL;
631  }
632  __after_bridge_set_goto(chan, 0, 0, context, exten, priority, p_goto);
633 }
void ast_replace_subargument_delimiter(char *s)
Replace '^' in a string with ','.
Definition: utils.c:2343
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
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.

Since
12.0.0
Parameters
chanChannel to setup after bridge goto location.
contextContext to goto after bridge.
extenExten to goto after bridge.
priorityPriority to goto after bridge.
Note
chan is locked by this function.

Add a channel datastore to setup the goto location when the channel leaves the bridge and run a PBX from there.

Definition at line 612 of file bridge_after.c.

Referenced by action_bridge().

613 {
614  __after_bridge_set_goto(chan, 0, 1, context, exten, priority, NULL);
615 }
void ast_bridge_set_after_h ( struct ast_channel chan,
const char *  context 
)

Set channel to run the h exten after the bridge.

Since
12.0.0
Parameters
chanChannel to setup after bridge goto location.
contextContext to goto after bridge.
Note
chan is locked by this function.

Add a channel datastore to setup the goto location when the channel leaves the bridge and run a PBX from there.

Definition at line 617 of file bridge_after.c.

618 {
619  __after_bridge_set_goto(chan, 1, 0, context, NULL, 1, NULL);
620 }
int ast_bridge_setup_after_goto ( struct ast_channel chan)

Setup any after bridge goto location to begin execution.

Since
12.0.0
Parameters
chanChannel to setup after bridge goto location.
Note
chan is locked by this function.

Pull off any after bridge goto location datastore and setup for dialplan execution there.

Return values
0on success. The goto location is set for a PBX to run it.
non-zeroon error or no goto location.
Note
If the after bridge goto is set to run an h exten it is run here immediately.

Definition at line 435 of file bridge_after.c.

References ast_channel_clear_flag(), ast_channel_clear_softhangup(), ast_channel_set_unbridged(), ast_check_hangup(), ast_datastore_free(), ast_debug, ast_exists_extension(), ast_explicit_goto(), AST_FLAG_IN_AUTOLOOP, AST_FLAG_OUTGOING, ast_goto_if_exists(), ast_parseable_goto(), ast_pbx_h_exten_run(), AST_SOFTHANGUP_ASYNCGOTO, ast_strdupa, after_bridge_goto_ds::context, ast_datastore::data, after_bridge_goto_ds::exten, after_bridge_goto_ds::parseable_goto, after_bridge_goto_ds::priority, after_bridge_goto_ds::run_h_exten, S_COR, and after_bridge_goto_ds::specific.

Referenced by ast_bridge_join(), ast_bridge_run_after_goto(), and dial_exec_full().

436 {
437  struct ast_datastore *datastore;
438  struct after_bridge_goto_ds *after_bridge;
439  int goto_failed = -1;
440 
441  /* We are going to be leaving the bridging system now;
442  * clear any pending unbridge flags
443  */
444  ast_channel_set_unbridged(chan, 0);
445 
446  /* Determine if we are going to setup a dialplan location and where. */
447  if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO) {
448  /* An async goto has already setup a location. */
449  ast_channel_clear_softhangup(chan, AST_SOFTHANGUP_ASYNCGOTO);
450  if (!ast_check_hangup(chan)) {
451  goto_failed = 0;
452  }
453  return goto_failed;
454  }
455 
456  /* Get after bridge goto datastore. */
457  datastore = after_bridge_goto_remove(chan);
458  if (!datastore) {
459  return goto_failed;
460  }
461 
462  after_bridge = datastore->data;
463  if (after_bridge->run_h_exten) {
464  if (ast_exists_extension(chan, after_bridge->context, "h", 1,
465  S_COR(ast_channel_caller(chan)->id.number.valid,
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));
469  ast_pbx_h_exten_run(chan, after_bridge->context);
470  }
471  } else if (!ast_check_hangup(chan)) {
472  /* Clear the outgoing flag */
474 
475  if (after_bridge->specific) {
476  goto_failed = ast_explicit_goto(chan, after_bridge->context,
477  after_bridge->exten, after_bridge->priority);
478  } else if (!ast_strlen_zero(after_bridge->parseable_goto)) {
479  char *context;
480  char *exten;
481  int priority;
482 
483  /* Option F(x) for Bridge(), Dial(), and Queue() */
484 
485  /* Save current dialplan location in case of failure. */
486  context = ast_strdupa(ast_channel_context(chan));
487  exten = ast_strdupa(ast_channel_exten(chan));
488  priority = ast_channel_priority(chan);
489 
490  /* Set current dialplan position to default dialplan position */
491  ast_explicit_goto(chan, after_bridge->context, after_bridge->exten,
492  after_bridge->priority);
493 
494  /* Then perform the goto */
495  goto_failed = ast_parseable_goto(chan, after_bridge->parseable_goto);
496  if (goto_failed) {
497  /* Restore original dialplan location. */
498  ast_channel_context_set(chan, context);
499  ast_channel_exten_set(chan, exten);
500  ast_channel_priority_set(chan, priority);
501  }
502  } else {
503  /* Option F() for Bridge(), Dial(), and Queue() */
504  goto_failed = ast_goto_if_exists(chan, after_bridge->context,
505  after_bridge->exten, after_bridge->priority + 1);
506  }
507  if (!goto_failed) {
508  if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP)) {
509  ast_channel_priority_set(chan, ast_channel_priority(chan) + 1);
510  }
511 
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));
516  }
517  }
518 
519  /* Discard after bridge goto datastore. */
520  ast_datastore_free(datastore);
521 
522  return goto_failed;
523 }
void ast_pbx_h_exten_run(struct ast_channel *chan, const char *context)
Run the h exten from the given context.
Definition: pbx.c:4205
const char * parseable_goto
Definition: bridge_after.c:309
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition: channel.c:11034
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:6945
Structure for a data store object.
Definition: datastore.h:64
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
Number structure.
Definition: app_followme.c:154
void ast_channel_clear_softhangup(struct ast_channel *chan, int flag)
Clear a set of softhangup flags from a channel.
Definition: channel.c:2432
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
Definition: pbx.c:8866
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
#define ast_debug(level,...)
Log a DEBUG message.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4175
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
unsigned int specific
Definition: bridge_after.c:319
const char * context
Definition: bridge_after.c:311
const char * exten
Definition: bridge_after.c:313
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:8781
void * data
Definition: datastore.h:66
unsigned int run_h_exten
Definition: bridge_after.c:317
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...

Variable Documentation

const struct ast_datastore_info after_bridge_cb_info
static
Initial value:
= {
.type = "after-bridge-cb",
.destroy = after_bridge_cb_destroy,
.chan_fixup = after_bridge_cb_fixup,
}

Definition at line 146 of file bridge_after.c.

const struct ast_datastore_info after_bridge_goto_info
static
Initial value:
= {
.type = "after-bridge-goto",
.destroy = after_bridge_goto_destroy,
.chan_fixup = after_bridge_goto_fixup,
}

Definition at line 354 of file bridge_after.c.