Asterisk - The Open Source Telephony Project  18.5.0
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"
Include dependency graph for bridge_after.c:

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

◆ __after_bridge_set_goto()

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

Definition at line 571 of file bridge_after.c.

References ast_assert, ast_bridge_discard_after_goto(), ast_calloc, ast_channel_datastore_add(), ast_channel_lock, ast_channel_unlock, ast_datastore_alloc, ast_datastore_free(), ast_strdup, after_bridge_goto_ds::context, ast_datastore::data, after_bridge_goto_ds::exten, NULL, after_bridge_goto_ds::parseable_goto, priority, after_bridge_goto_ds::priority, after_bridge_goto_ds::run_h_exten, and after_bridge_goto_ds::specific.

Referenced by ast_bridge_set_after_go_on(), ast_bridge_set_after_goto(), and ast_bridge_set_after_h().

572 {
573  struct ast_datastore *datastore;
574  struct after_bridge_goto_ds *after_bridge;
575 
576  /* Sanity checks. */
577  ast_assert(chan != NULL);
578  if (!chan) {
579  return;
580  }
581  if (run_h_exten) {
583  if (!context) {
584  return;
585  }
586  } else {
587  ast_assert(context && exten && 0 < priority);
588  if (!context || !exten || priority < 1) {
589  return;
590  }
591  }
592 
593  /* Create a new datastore. */
595  if (!datastore) {
596  return;
597  }
598  after_bridge = ast_calloc(1, sizeof(*after_bridge));
599  if (!after_bridge) {
600  ast_datastore_free(datastore);
601  return;
602  }
603 
604  /* Initialize it. */
605  after_bridge->parseable_goto = ast_strdup(parseable_goto);
606  after_bridge->context = ast_strdup(context);
607  after_bridge->exten = ast_strdup(exten);
608  after_bridge->priority = priority;
609  after_bridge->run_h_exten = run_h_exten ? 1 : 0;
610  after_bridge->specific = specific ? 1 : 0;
611  datastore->data = after_bridge;
612  if ((parseable_goto && !after_bridge->parseable_goto)
613  || (context && !after_bridge->context)
614  || (exten && !after_bridge->exten)) {
615  ast_datastore_free(datastore);
616  return;
617  }
618 
619  /* Put it on the channel replacing any existing one. */
620  ast_channel_lock(chan);
622  ast_channel_datastore_add(chan, datastore);
623  ast_channel_unlock(chan);
624 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
const char * parseable_goto
Definition: bridge_after.c:317
static const struct ast_datastore_info after_bridge_goto_info
Definition: bridge_after.c:366
#define ast_assert(a)
Definition: utils.h:695
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
Structure for a data store object.
Definition: datastore.h:68
#define NULL
Definition: resample.c:96
static int priority
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
void ast_bridge_discard_after_goto(struct ast_channel *chan)
Discard channel after bridge goto location.
Definition: bridge_after.c:396
unsigned int specific
Definition: bridge_after.c:327
const char * context
Definition: bridge_after.c:319
const char * exten
Definition: bridge_after.c:321
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void * data
Definition: datastore.h:70
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390
unsigned int run_h_exten
Definition: bridge_after.c:325

◆ after_bridge_cb_destroy()

static void after_bridge_cb_destroy ( void *  data)
static

Definition at line 113 of file bridge_after.c.

References after_bridge_cb_find(), after_bridge_cb_run_discard(), AST_BRIDGE_AFTER_CB_REASON_DESTROY, ast_free, AST_LIST_HEAD_DESTROY, after_bridge_cb_ds::callbacks, and after_bridge_cb_node::data.

114 {
115  struct after_bridge_cb_ds *after_bridge = data;
116 
118 
119  AST_LIST_HEAD_DESTROY(&after_bridge->callbacks);
120  ast_free(after_bridge);
121 }
static void after_bridge_cb_run_discard(struct after_bridge_cb_ds *after_bridge, enum ast_bridge_after_cb_reason reason)
Definition: bridge_after.c:85
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:652
#define ast_free(a)
Definition: astmm.h:182
struct after_bridge_cb_ds::@351 callbacks

◆ after_bridge_cb_failed()

static void after_bridge_cb_failed ( struct after_bridge_cb_node node)
static

Definition at line 67 of file bridge_after.c.

References after_bridge_cb_node::data, after_bridge_cb_node::failed, NULL, and after_bridge_cb_node::reason.

Referenced by after_bridge_cb_run_discard(), and ast_bridge_run_after_callback().

68 {
69  if (node->failed) {
70  node->failed(node->reason, node->data);
71  node->failed = NULL;
72  }
73 }
#define NULL
Definition: resample.c:96
enum ast_bridge_after_cb_reason reason
Definition: bridge_after.c:50
ast_bridge_after_cb_failed failed
Definition: bridge_after.c:46

◆ after_bridge_cb_find()

static struct after_bridge_cb_ds * after_bridge_cb_find ( struct ast_channel chan)
static

Definition at line 170 of file bridge_after.c.

References ast_channel_datastore_find(), ast_datastore::data, lock, NULL, and SCOPED_CHANNELLOCK.

Referenced by after_bridge_cb_destroy(), after_bridge_cb_fixup(), ast_bridge_discard_after_callback(), and ast_bridge_run_after_callback().

171 {
172  struct ast_datastore *datastore;
173  SCOPED_CHANNELLOCK(lock, chan);
174 
176  if (!datastore) {
177  return NULL;
178  }
179  return datastore->data;
180 }
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:617
ast_mutex_t lock
Definition: app_meetme.c:1091
static const struct ast_datastore_info after_bridge_cb_info
Definition: bridge_after.c:154
void * data
Definition: datastore.h:70

◆ after_bridge_cb_fixup()

static void after_bridge_cb_fixup ( void *  data,
struct ast_channel old_chan,
struct ast_channel new_chan 
)
static

Definition at line 136 of file bridge_after.c.

References after_bridge_cb_find(), AST_BRIDGE_AFTER_CB_REASON_MASQUERADE, AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_UNLOCK, after_bridge_cb_ds::callbacks, and after_bridge_cb_node::reason.

137 {
138  struct after_bridge_cb_ds *after_bridge;
139  struct after_bridge_cb_node *node;
140 
141  after_bridge = after_bridge_cb_find(new_chan);
142  if (!after_bridge) {
143  return;
144  }
145 
146  AST_LIST_LOCK(&after_bridge->callbacks);
147  node = AST_LIST_LAST(&after_bridge->callbacks);
148  if (node && !node->reason) {
150  }
151  AST_LIST_UNLOCK(&after_bridge->callbacks);
152 }
Definition: test_heap.c:38
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
enum ast_bridge_after_cb_reason reason
Definition: bridge_after.c:50
static struct after_bridge_cb_ds * after_bridge_cb_find(struct ast_channel *chan)
Definition: bridge_after.c:170
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:428
struct after_bridge_cb_ds::@351 callbacks

◆ after_bridge_cb_run_discard()

static void after_bridge_cb_run_discard ( struct after_bridge_cb_ds after_bridge,
enum ast_bridge_after_cb_reason  reason 
)
static

Definition at line 85 of file bridge_after.c.

References after_bridge_cb_failed(), ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, after_bridge_cb_ds::callbacks, after_bridge_cb_node::list, and after_bridge_cb_node::reason.

Referenced by after_bridge_cb_destroy(), and ast_bridge_discard_after_callback().

86 {
87  struct after_bridge_cb_node *node;
88 
89  for (;;) {
90  AST_LIST_LOCK(&after_bridge->callbacks);
91  node = AST_LIST_REMOVE_HEAD(&after_bridge->callbacks, list);
92  AST_LIST_UNLOCK(&after_bridge->callbacks);
93  if (!node) {
94  break;
95  }
96  if (!node->reason) {
97  node->reason = reason;
98  }
100  ast_free(node);
101  }
102 }
Definition: test_heap.c:38
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
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:832
struct after_bridge_cb_node::@350 list
#define ast_free(a)
Definition: astmm.h:182
struct after_bridge_cb_ds::@351 callbacks
static void after_bridge_cb_failed(struct after_bridge_cb_node *node)
Definition: bridge_after.c:67

◆ after_bridge_cb_setup()

static struct after_bridge_cb_ds* after_bridge_cb_setup ( struct ast_channel chan)
static

Definition at line 192 of file bridge_after.c.

References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc, ast_datastore_free(), AST_LIST_HEAD_INIT, after_bridge_cb_ds::callbacks, ast_datastore::data, lock, NULL, and SCOPED_CHANNELLOCK.

Referenced by ast_bridge_set_after_callback().

193 {
194  struct ast_datastore *datastore;
195  struct after_bridge_cb_ds *after_bridge;
196  SCOPED_CHANNELLOCK(lock, chan);
197 
199  if (datastore) {
200  return datastore->data;
201  }
202 
203  /* Create a new datastore. */
205  if (!datastore) {
206  return NULL;
207  }
208  after_bridge = ast_calloc(1, sizeof(*after_bridge));
209  if (!after_bridge) {
210  ast_datastore_free(datastore);
211  return NULL;
212  }
213  AST_LIST_HEAD_INIT(&after_bridge->callbacks);
214  datastore->data = after_bridge;
215  ast_channel_datastore_add(chan, datastore);
216 
217  return datastore->data;
218 }
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:617
ast_mutex_t lock
Definition: app_meetme.c:1091
static const struct ast_datastore_info after_bridge_cb_info
Definition: bridge_after.c:154
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:625
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void * data
Definition: datastore.h:70
struct after_bridge_cb_ds::@351 callbacks
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390

◆ after_bridge_goto_destroy()

static void after_bridge_goto_destroy ( void *  data)
static

Definition at line 339 of file bridge_after.c.

References ast_free, after_bridge_goto_ds::context, after_bridge_cb_node::data, after_bridge_goto_ds::exten, and after_bridge_goto_ds::parseable_goto.

340 {
341  struct after_bridge_goto_ds *after_bridge = data;
342 
343  ast_free((char *) after_bridge->parseable_goto);
344  ast_free((char *) after_bridge->context);
345  ast_free((char *) after_bridge->exten);
346  ast_free((char *) after_bridge);
347 }
const char * parseable_goto
Definition: bridge_after.c:317
const char * context
Definition: bridge_after.c:319
const char * exten
Definition: bridge_after.c:321
#define ast_free(a)
Definition: astmm.h:182

◆ after_bridge_goto_fixup()

static void after_bridge_goto_fixup ( void *  data,
struct ast_channel old_chan,
struct ast_channel new_chan 
)
static

Definition at line 360 of file bridge_after.c.

References ast_bridge_discard_after_goto().

361 {
362  /* There can be only one. Discard any already on the new channel. */
364 }
void ast_bridge_discard_after_goto(struct ast_channel *chan)
Discard channel after bridge goto location.
Definition: bridge_after.c:396

◆ after_bridge_goto_remove()

static struct ast_datastore* after_bridge_goto_remove ( struct ast_channel chan)
static

Definition at line 382 of file bridge_after.c.

References ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_lock, ast_channel_unlock, and NULL.

Referenced by ast_bridge_discard_after_goto(), and ast_bridge_setup_after_goto().

383 {
384  struct ast_datastore *datastore;
385 
386  ast_channel_lock(chan);
388  if (datastore && ast_channel_datastore_remove(chan, datastore)) {
389  datastore = NULL;
390  }
391  ast_channel_unlock(chan);
392 
393  return datastore;
394 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
static const struct ast_datastore_info after_bridge_goto_info
Definition: bridge_after.c:366
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
#define ast_channel_unlock(chan)
Definition: channel.h:2946
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2399

◆ ast_bridge_after_cb_reason_string()

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 296 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.

Referenced by after_bridge_move_channel_fail(), agent_after_bridge_cb_failed(), bridge_after_cb_failed(), and internal_bridge_after_cb().

297 {
298  switch (reason) {
300  return "Channel destroyed (hungup)";
302  return "Callback was replaced";
304  return "Channel masqueraded";
306  return "Channel was departed from bridge";
308  return "Callback was removed";
310  return "Channel failed joining the bridge";
311  }
312  return "Unknown";
313 }

◆ ast_bridge_discard_after_callback()

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.
Returns
Nothing

Definition at line 247 of file bridge_after.c.

References after_bridge_cb_find(), and after_bridge_cb_run_discard().

Referenced by ast_bridge_impart(), and bridge_channel_depart_thread().

248 {
249  struct after_bridge_cb_ds *after_bridge;
250 
251  after_bridge = after_bridge_cb_find(chan);
252  if (!after_bridge) {
253  return;
254  }
255 
256  after_bridge_cb_run_discard(after_bridge, reason);
257 }
static void after_bridge_cb_run_discard(struct after_bridge_cb_ds *after_bridge, enum ast_bridge_after_cb_reason reason)
Definition: bridge_after.c:85
static struct after_bridge_cb_ds * after_bridge_cb_find(struct ast_channel *chan)
Definition: bridge_after.c:170

◆ ast_bridge_discard_after_goto()

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.
Returns
Nothing

Definition at line 396 of file bridge_after.c.

References after_bridge_goto_remove(), and ast_datastore_free().

Referenced by __after_bridge_set_goto(), after_bridge_goto_fixup(), bridge_channel_depart_thread(), feature_blind_transfer(), and func_channel_write_real().

397 {
398  struct ast_datastore *datastore;
399 
400  datastore = after_bridge_goto_remove(chan);
401  if (datastore) {
402  ast_datastore_free(datastore);
403  }
404 }
Structure for a data store object.
Definition: datastore.h:68
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
static struct ast_datastore * after_bridge_goto_remove(struct ast_channel *chan)
Definition: bridge_after.c:382

◆ ast_bridge_read_after_goto()

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 406 of file bridge_after.c.

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

Referenced by func_channel_read().

407 {
408  struct ast_datastore *datastore;
409  struct after_bridge_goto_ds *after_bridge;
410  char *current_pos = buffer;
411  size_t remaining_size = buf_size;
412 
413  SCOPED_CHANNELLOCK(lock, chan);
414 
416  if (!datastore) {
417  buffer[0] = '\0';
418  return;
419  }
420 
421  after_bridge = datastore->data;
422 
423  if (after_bridge->parseable_goto) {
424  snprintf(buffer, buf_size, "%s", after_bridge->parseable_goto);
425  return;
426  }
427 
428  if (!ast_strlen_zero(after_bridge->context)) {
429  snprintf(current_pos, remaining_size, "%s,", after_bridge->context);
430  remaining_size = remaining_size - strlen(current_pos);
431  current_pos += strlen(current_pos);
432  }
433 
434  if (after_bridge->run_h_exten) {
435  snprintf(current_pos, remaining_size, "h,");
436  remaining_size = remaining_size - strlen(current_pos);
437  current_pos += strlen(current_pos);
438  } else if (!ast_strlen_zero(after_bridge->exten)) {
439  snprintf(current_pos, remaining_size, "%s,", after_bridge->exten);
440  remaining_size = remaining_size - strlen(current_pos);
441  current_pos += strlen(current_pos);
442  }
443 
444  snprintf(current_pos, remaining_size, "%d", after_bridge->priority);
445 }
const char * parseable_goto
Definition: bridge_after.c:317
static const struct ast_datastore_info after_bridge_goto_info
Definition: bridge_after.c:366
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:617
ast_mutex_t lock
Definition: app_meetme.c:1091
const char * context
Definition: bridge_after.c:319
const char * exten
Definition: bridge_after.c:321
void * data
Definition: datastore.h:70
unsigned int run_h_exten
Definition: bridge_after.c:325

◆ ast_bridge_run_after_callback()

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.
Returns
Nothing

Definition at line 220 of file bridge_after.c.

References after_bridge_cb_failed(), after_bridge_cb_find(), ast_free, 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, NULL, and after_bridge_cb_node::reason.

Referenced by ast_bridge_join(), and bridge_channel_ind_thread().

221 {
222  struct after_bridge_cb_ds *after_bridge;
223  struct after_bridge_cb_node *node;
224 
225  after_bridge = after_bridge_cb_find(chan);
226  if (!after_bridge) {
227  return;
228  }
229 
230  for (;;) {
231  AST_LIST_LOCK(&after_bridge->callbacks);
232  node = AST_LIST_REMOVE_HEAD(&after_bridge->callbacks, list);
233  AST_LIST_UNLOCK(&after_bridge->callbacks);
234  if (!node) {
235  break;
236  }
237  if (node->reason) {
239  } else {
240  node->failed = NULL;
241  node->callback(chan, node->data);
242  }
243  ast_free(node);
244  }
245 }
Definition: test_heap.c:38
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
ast_bridge_after_cb callback
Definition: bridge_after.c:44
#define NULL
Definition: resample.c:96
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:832
ast_bridge_after_cb_failed failed
Definition: bridge_after.c:46
static struct after_bridge_cb_ds * after_bridge_cb_find(struct ast_channel *chan)
Definition: bridge_after.c:170
struct after_bridge_cb_node::@350 list
#define ast_free(a)
Definition: astmm.h:182
struct after_bridge_cb_ds::@351 callbacks
static void after_bridge_cb_failed(struct after_bridge_cb_node *node)
Definition: bridge_after.c:67

◆ ast_bridge_run_after_goto()

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.
Returns
Nothing

Definition at line 537 of file bridge_after.c.

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

Referenced by bridge_channel_ind_thread().

538 {
539  int goto_failed;
540 
541  goto_failed = ast_bridge_setup_after_goto(chan);
542  if (goto_failed || ast_pbx_run(chan)) {
543  ast_hangup(chan);
544  }
545 }
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
Definition: bridge_after.c:447
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition: pbx.c:4759

◆ ast_bridge_set_after_callback()

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 259 of file bridge_after.c.

References after_bridge_cb_setup(), ast_assert, 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, NULL, and after_bridge_cb_node::reason.

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

260 {
261  struct after_bridge_cb_ds *after_bridge;
262  struct after_bridge_cb_node *new_node;
263  struct after_bridge_cb_node *last_node;
264 
265  /* Sanity checks. */
266  ast_assert(chan != NULL);
267  if (!chan || !callback) {
268  return -1;
269  }
270 
271  after_bridge = after_bridge_cb_setup(chan);
272  if (!after_bridge) {
273  return -1;
274  }
275 
276  /* Create a new callback node. */
277  new_node = ast_calloc(1, sizeof(*new_node));
278  if (!new_node) {
279  return -1;
280  }
281  new_node->callback = callback;
282  new_node->failed = failed;
283  new_node->data = data;
284 
285  /* Put it in the container disabling any previously active one. */
286  AST_LIST_LOCK(&after_bridge->callbacks);
287  last_node = AST_LIST_LAST(&after_bridge->callbacks);
288  if (last_node && !last_node->reason) {
290  }
291  AST_LIST_INSERT_TAIL(&after_bridge->callbacks, new_node, list);
292  AST_LIST_UNLOCK(&after_bridge->callbacks);
293  return 0;
294 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
ast_bridge_after_cb callback
Definition: bridge_after.c:44
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
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:730
static struct after_bridge_cb_ds * after_bridge_cb_setup(struct ast_channel *chan)
Definition: bridge_after.c:192
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:428
struct after_bridge_cb_node::@350 list
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
struct after_bridge_cb_ds::@351 callbacks

◆ ast_bridge_set_after_go_on()

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.

Returns
Nothing

Definition at line 636 of file bridge_after.c.

References __after_bridge_set_goto(), ast_replace_subargument_delimiter(), ast_strdupa, ast_strlen_zero, and NULL.

Referenced by bridge_exec(), feature_blind_transfer(), func_channel_write_real(), and setup_peer_after_bridge_goto().

637 {
638  char *p_goto;
639 
640  if (!ast_strlen_zero(parseable_goto)) {
641  p_goto = ast_strdupa(parseable_goto);
643  } else {
644  p_goto = NULL;
645  }
646  __after_bridge_set_goto(chan, 0, 0, context, exten, priority, p_goto);
647 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
#define NULL
Definition: resample.c:96
static int priority
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)
Definition: bridge_after.c:571
#define ast_strlen_zero(foo)
Definition: strings.h:52
void ast_replace_subargument_delimiter(char *s)
Replace &#39;^&#39; in a string with &#39;,&#39;.
Definition: main/utils.c:2095
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ ast_bridge_set_after_goto()

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.

Returns
Nothing

Definition at line 626 of file bridge_after.c.

References __after_bridge_set_goto(), and NULL.

Referenced by action_bridge().

627 {
629 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
#define NULL
Definition: resample.c:96
static int priority
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)
Definition: bridge_after.c:571
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ ast_bridge_set_after_h()

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.

Returns
Nothing

Definition at line 631 of file bridge_after.c.

References __after_bridge_set_goto(), and NULL.

Referenced by setup_peer_after_bridge_goto().

632 {
633  __after_bridge_set_goto(chan, 1, 0, context, NULL, 1, NULL);
634 }
#define NULL
Definition: resample.c:96
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)
Definition: bridge_after.c:571
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ ast_bridge_setup_after_goto()

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 447 of file bridge_after.c.

References after_bridge_goto_remove(), ast_channel_caller(), ast_channel_clear_flag(), ast_channel_clear_softhangup(), ast_channel_context(), ast_channel_context_set(), ast_channel_exten(), ast_channel_exten_set(), ast_channel_flags(), ast_channel_priority(), ast_channel_priority_set(), ast_channel_set_unbridged(), ast_channel_softhangup_internal_flag(), 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, ast_strlen_zero, ast_test_flag, context, after_bridge_goto_ds::context, ast_datastore::data, exten, after_bridge_goto_ds::exten, NULL, after_bridge_goto_ds::parseable_goto, priority, after_bridge_goto_ds::priority, after_bridge_goto_ds::run_h_exten, S_COR, and after_bridge_goto_ds::specific.

Referenced by app_control_dial(), ast_bridge_join(), ast_bridge_run_after_goto(), bridge_failed_peer_goto(), dial_exec_full(), and internal_bridge_after_cb().

448 {
449  struct ast_datastore *datastore;
450  struct after_bridge_goto_ds *after_bridge;
451  int goto_failed = -1;
452 
453  /* We are going to be leaving the bridging system now;
454  * clear any pending unbridge flags
455  */
456  ast_channel_set_unbridged(chan, 0);
457 
458  /* Determine if we are going to setup a dialplan location and where. */
460  /* An async goto has already setup a location. */
461  ast_channel_clear_softhangup(chan, AST_SOFTHANGUP_ASYNCGOTO);
462  if (!ast_check_hangup(chan)) {
463  goto_failed = 0;
464  }
465  return goto_failed;
466  }
467 
468  /* Get after bridge goto datastore. */
469  datastore = after_bridge_goto_remove(chan);
470  if (!datastore) {
471  return goto_failed;
472  }
473 
474  after_bridge = datastore->data;
475  if (after_bridge->run_h_exten) {
476  if (ast_exists_extension(chan, after_bridge->context, "h", 1,
477  S_COR(ast_channel_caller(chan)->id.number.valid,
478  ast_channel_caller(chan)->id.number.str, NULL))) {
479  ast_debug(1, "Running after bridge goto h exten %s,h,1\n",
480  ast_channel_context(chan));
481  ast_pbx_h_exten_run(chan, after_bridge->context);
482  }
483  } else if (!ast_check_hangup(chan)) {
484  /* Clear the outgoing flag */
486 
487  if (after_bridge->specific) {
488  goto_failed = ast_explicit_goto(chan, after_bridge->context,
489  after_bridge->exten, after_bridge->priority);
490  } else if (!ast_strlen_zero(after_bridge->parseable_goto)) {
491  char *context;
492  char *exten;
493  int priority;
494 
495  /* Option F(x) for Bridge(), Dial(), and Queue() */
496 
497  /* Save current dialplan location in case of failure. */
498  context = ast_strdupa(ast_channel_context(chan));
499  exten = ast_strdupa(ast_channel_exten(chan));
500  priority = ast_channel_priority(chan);
501 
502  /* Set current dialplan position to default dialplan position */
503  ast_explicit_goto(chan, after_bridge->context, after_bridge->exten,
504  after_bridge->priority);
505 
506  /* Then perform the goto */
507  goto_failed = ast_parseable_goto(chan, after_bridge->parseable_goto);
508  if (goto_failed) {
509  /* Restore original dialplan location. */
510  ast_channel_context_set(chan, context);
511  ast_channel_exten_set(chan, exten);
512  ast_channel_priority_set(chan, priority);
513  }
514  } else {
515  /* Option F() for Bridge(), Dial(), and Queue() */
516  goto_failed = ast_goto_if_exists(chan, after_bridge->context,
517  after_bridge->exten, after_bridge->priority + 1);
518  }
519  if (!goto_failed) {
522  }
523 
524  ast_debug(1, "Setup after bridge goto location to %s,%s,%d.\n",
525  ast_channel_context(chan),
526  ast_channel_exten(chan),
527  ast_channel_priority(chan));
528  }
529  }
530 
531  /* Discard after bridge goto datastore. */
532  ast_datastore_free(datastore);
533 
534  return goto_failed;
535 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_pbx_h_exten_run(struct ast_channel *chan, const char *context)
Run the h exten from the given context.
Definition: pbx.c:4209
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
#define ast_test_flag(p, flag)
Definition: utils.h:63
const char * parseable_goto
Definition: bridge_after.c:317
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Definition: channel.c:11235
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:6987
Structure for a data store object.
Definition: datastore.h:68
#define NULL
Definition: resample.c:96
static int priority
int ast_channel_priority(const struct ast_channel *chan)
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#define ast_strlen_zero(foo)
Definition: strings.h:52
Number structure.
Definition: app_followme.c:154
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
void ast_channel_clear_softhangup(struct ast_channel *chan, int flag)
Clear a set of softhangup flags from a channel.
Definition: channel.c:2437
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
Definition: pbx.c:8859
#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:85
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct ast_datastore * after_bridge_goto_remove(struct ast_channel *chan)
Definition: bridge_after.c:382
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:4179
const char * ast_channel_exten(const struct ast_channel *chan)
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:327
const char * context
Definition: bridge_after.c:319
const char * exten
Definition: bridge_after.c:321
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:8793
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
void * data
Definition: datastore.h:70
void ast_channel_context_set(struct ast_channel *chan, const char *value)
const char * ast_channel_context(const struct ast_channel *chan)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
void ast_channel_priority_set(struct ast_channel *chan, int value)
unsigned int run_h_exten
Definition: bridge_after.c:325
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

◆ after_bridge_cb_info

const struct ast_datastore_info after_bridge_cb_info
static
Initial value:
= {
.type = "after-bridge-cb",
.chan_fixup = after_bridge_cb_fixup,
}
static void after_bridge_cb_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
Definition: bridge_after.c:136
static void after_bridge_cb_destroy(void *data)
Definition: bridge_after.c:113

Definition at line 154 of file bridge_after.c.

◆ after_bridge_goto_info

const struct ast_datastore_info after_bridge_goto_info
static
Initial value:
= {
.type = "after-bridge-goto",
.chan_fixup = after_bridge_goto_fixup,
}
static void after_bridge_goto_destroy(void *data)
Definition: bridge_after.c:339
static void after_bridge_goto_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
Definition: bridge_after.c:360

Definition at line 366 of file bridge_after.c.