Asterisk - The Open Source Telephony Project GIT-master-f36a736
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 557 of file bridge_after.c.

558{
559 struct ast_datastore *datastore;
560 struct after_bridge_goto_ds *after_bridge;
561
562 /* Sanity checks. */
563 ast_assert(chan != NULL);
564 if (!chan) {
565 return;
566 }
567 if (run_h_exten) {
569 if (!context) {
570 return;
571 }
572 } else {
573 ast_assert(context && exten && 0 < priority);
574 if (!context || !exten || priority < 1) {
575 return;
576 }
577 }
578
579 /* Create a new datastore. */
581 if (!datastore) {
582 return;
583 }
584 after_bridge = ast_calloc(1, sizeof(*after_bridge));
585 if (!after_bridge) {
586 ast_datastore_free(datastore);
587 return;
588 }
589
590 /* Initialize it. */
592 after_bridge->context = ast_strdup(context);
593 after_bridge->exten = ast_strdup(exten);
594 after_bridge->priority = priority;
595 after_bridge->run_h_exten = run_h_exten ? 1 : 0;
596 after_bridge->specific = specific ? 1 : 0;
597 datastore->data = after_bridge;
598 if ((parseable_goto && !after_bridge->parseable_goto)
599 || (context && !after_bridge->context)
600 || (exten && !after_bridge->exten)) {
601 ast_datastore_free(datastore);
602 return;
603 }
604
605 /* Put it on the channel replacing any existing one. */
606 ast_channel_lock(chan);
608 ast_channel_datastore_add(chan, datastore);
609 ast_channel_unlock(chan);
610}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
void ast_bridge_discard_after_goto(struct ast_channel *chan)
Discard channel after bridge goto location.
Definition: bridge_after.c:384
static const struct ast_datastore_info after_bridge_goto_info
Definition: bridge_after.c:354
static int priority
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2404
#define ast_channel_lock(chan)
Definition: channel.h:2968
#define ast_channel_unlock(chan)
Definition: channel.h:2969
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#define NULL
Definition: resample.c:96
unsigned int run_h_exten
Definition: bridge_after.c:317
const char * exten
Definition: bridge_after.c:313
unsigned int specific
Definition: bridge_after.c:319
const char * context
Definition: bridge_after.c:311
const char * parseable_goto
Definition: bridge_after.c:309
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
#define ast_assert(a)
Definition: utils.h:739

References after_bridge_goto_info, 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, voicemailpwcheck::context, 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().

◆ after_bridge_cb_destroy()

static void after_bridge_cb_destroy ( void *  data)
static

Definition at line 107 of file bridge_after.c.

108{
109 struct after_bridge_cb_ds *after_bridge = data;
110
112
113 AST_LIST_HEAD_DESTROY(&after_bridge->callbacks);
114 ast_free(after_bridge);
115}
#define ast_free(a)
Definition: astmm.h:180
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:81
@ AST_BRIDGE_AFTER_CB_REASON_DESTROY
Definition: bridge_after.h:39
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:653
struct after_bridge_cb_ds::@311 callbacks

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

◆ after_bridge_cb_failed()

static void after_bridge_cb_failed ( struct after_bridge_cb_node node)
static

Definition at line 65 of file bridge_after.c.

66{
67 if (node->failed) {
68 node->failed(node->reason, node->data);
69 node->failed = NULL;
70 }
71}
Definition: test_heap.c:38

References NULL.

Referenced by after_bridge_cb_run_discard(), and ast_bridge_run_after_callback().

◆ after_bridge_cb_find()

static struct after_bridge_cb_ds * after_bridge_cb_find ( struct ast_channel chan)
static

Definition at line 162 of file bridge_after.c.

163{
164 struct ast_datastore *datastore;
166
168 if (!datastore) {
169 return NULL;
170 }
171 return datastore->data;
172}
ast_mutex_t lock
Definition: app_sla.c:331
static const struct ast_datastore_info after_bridge_cb_info
Definition: bridge_after.c:146
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:2418
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:619

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

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

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

129{
130 struct after_bridge_cb_ds *after_bridge;
132
133 after_bridge = after_bridge_cb_find(new_chan);
134 if (!after_bridge) {
135 return;
136 }
137
138 AST_LIST_LOCK(&after_bridge->callbacks);
139 node = AST_LIST_LAST(&after_bridge->callbacks);
140 if (node && !node->reason) {
142 }
143 AST_LIST_UNLOCK(&after_bridge->callbacks);
144}
static struct after_bridge_cb_ds * after_bridge_cb_find(struct ast_channel *chan)
Definition: bridge_after.c:162
@ AST_BRIDGE_AFTER_CB_REASON_MASQUERADE
Definition: bridge_after.h:43
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:429
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:40
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:140

References after_bridge_cb_find(), AST_BRIDGE_AFTER_CB_REASON_MASQUERADE, AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_UNLOCK, and after_bridge_cb_ds::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 81 of file bridge_after.c.

82{
84
85 for (;;) {
86 AST_LIST_LOCK(&after_bridge->callbacks);
87 node = AST_LIST_REMOVE_HEAD(&after_bridge->callbacks, list);
88 AST_LIST_UNLOCK(&after_bridge->callbacks);
89 if (!node) {
90 break;
91 }
92 if (!node->reason) {
93 node->reason = reason;
94 }
97 }
98}
static void after_bridge_cb_failed(struct after_bridge_cb_node *node)
Definition: bridge_after.c:65
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
enum ast_bridge_after_cb_reason reason
Definition: bridge_after.c:50
struct after_bridge_cb_node::@310 list

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

◆ after_bridge_cb_setup()

static struct after_bridge_cb_ds * after_bridge_cb_setup ( struct ast_channel chan)
static

Definition at line 184 of file bridge_after.c.

185{
186 struct ast_datastore *datastore;
187 struct after_bridge_cb_ds *after_bridge;
189
191 if (datastore) {
192 return datastore->data;
193 }
194
195 /* Create a new datastore. */
197 if (!datastore) {
198 return NULL;
199 }
200 after_bridge = ast_calloc(1, sizeof(*after_bridge));
201 if (!after_bridge) {
202 ast_datastore_free(datastore);
203 return NULL;
204 }
205 AST_LIST_HEAD_INIT(&after_bridge->callbacks);
206 datastore->data = after_bridge;
207 ast_channel_datastore_add(chan, datastore);
208
209 return datastore->data;
210}
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:626

References after_bridge_cb_info, 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().

◆ after_bridge_goto_destroy()

static void after_bridge_goto_destroy ( void *  data)
static

Definition at line 329 of file bridge_after.c.

330{
331 struct after_bridge_goto_ds *after_bridge = data;
332
333 ast_free((char *) after_bridge->parseable_goto);
334 ast_free((char *) after_bridge->context);
335 ast_free((char *) after_bridge->exten);
336 ast_free((char *) after_bridge);
337}

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

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

349{
350 /* There can be only one. Discard any already on the new channel. */
352}

References ast_bridge_discard_after_goto().

◆ after_bridge_goto_remove()

static struct ast_datastore * after_bridge_goto_remove ( struct ast_channel chan)
static

Definition at line 370 of file bridge_after.c.

371{
372 struct ast_datastore *datastore;
373
374 ast_channel_lock(chan);
376 if (datastore && ast_channel_datastore_remove(chan, datastore)) {
377 datastore = NULL;
378 }
379 ast_channel_unlock(chan);
380
381 return datastore;
382}
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2413

References after_bridge_goto_info, 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().

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

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}
@ AST_BRIDGE_AFTER_CB_REASON_IMPART_FAILED
Definition: bridge_after.h:49
@ AST_BRIDGE_AFTER_CB_REASON_REMOVED
Definition: bridge_after.h:47
@ AST_BRIDGE_AFTER_CB_REASON_DEPART
Definition: bridge_after.h:45
@ AST_BRIDGE_AFTER_CB_REASON_REPLACED
Definition: bridge_after.h:41

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, AST_BRIDGE_AFTER_CB_REASON_REPLACED, and after_bridge_cb_node::reason.

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

◆ 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.
reason

Definition at line 239 of file bridge_after.c.

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}

References after_bridge_cb_find(), and after_bridge_cb_run_discard().

Referenced by ast_bridge_impart(), and bridge_channel_depart_thread().

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

Definition at line 384 of file bridge_after.c.

385{
386 struct ast_datastore *datastore;
387
388 datastore = after_bridge_goto_remove(chan);
389 if (datastore) {
390 ast_datastore_free(datastore);
391 }
392}
static struct ast_datastore * after_bridge_goto_remove(struct ast_channel *chan)
Definition: bridge_after.c:370

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

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

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
402
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}
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

References after_bridge_goto_info, 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().

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

Definition at line 212 of file bridge_after.c.

213{
214 struct after_bridge_cb_ds *after_bridge;
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) {
231 } else {
232 node->failed = NULL;
233 node->callback(chan, node->data);
234 }
235 ast_free(node);
236 }
237}

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

Referenced by ast_bridge_join(), and bridge_channel_ind_thread().

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

Definition at line 525 of file bridge_after.c.

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:2560
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition: pbx.c:4755

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

Referenced by bridge_channel_ind_thread().

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

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}
static struct after_bridge_cb_ds * after_bridge_cb_setup(struct ast_channel *chan)
Definition: bridge_after.c:184
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
ast_bridge_after_cb_failed failed
Definition: bridge_after.c:46
ast_bridge_after_cb callback
Definition: bridge_after.c:44

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

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

Definition at line 622 of file bridge_after.c.

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}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
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:557
void ast_replace_subargument_delimiter(char *s)
Replace '^' in a string with ','.
Definition: utils.c:2343

References __after_bridge_set_goto(), ast_replace_subargument_delimiter(), ast_strdupa, ast_strlen_zero(), voicemailpwcheck::context, after_bridge_goto_ds::exten, NULL, after_bridge_goto_ds::parseable_goto, and priority.

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

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

Definition at line 612 of file bridge_after.c.

613{
614 __after_bridge_set_goto(chan, 0, 1, context, exten, priority, NULL);
615}

References __after_bridge_set_goto(), voicemailpwcheck::context, after_bridge_goto_ds::exten, NULL, and priority.

Referenced by action_bridge().

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

Definition at line 617 of file bridge_after.c.

618{
619 __after_bridge_set_goto(chan, 1, 0, context, NULL, 1, NULL);
620}

References __after_bridge_set_goto(), voicemailpwcheck::context, and NULL.

Referenced by setup_peer_after_bridge_goto().

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

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 */
445
446 /* Determine if we are going to setup a dialplan location and where. */
448 /* An async goto has already setup a location. */
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. */
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. */
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) {
510 }
511
512 ast_debug(1, "Setup after bridge goto location to %s,%s,%d.\n",
514 ast_channel_exten(chan),
516 }
517 }
518
519 /* Discard after bridge goto datastore. */
520 ast_datastore_free(datastore);
521
522 return goto_failed;
523}
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition: channel.c:11056
void ast_channel_clear_softhangup(struct ast_channel *chan, int flag)
Clear a set of softhangup flags from a channel.
Definition: channel.c:2451
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
int ast_channel_priority(const struct ast_channel *chan)
const char * ast_channel_context(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
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...
@ AST_SOFTHANGUP_ASYNCGOTO
Definition: channel.h:1146
void ast_channel_context_set(struct ast_channel *chan, const char *value)
@ AST_FLAG_OUTGOING
Definition: channel.h:1019
@ AST_FLAG_IN_AUTOLOOP
Definition: channel.h:1017
int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_channel_priority_set(struct ast_channel *chan, int value)
const char * ast_channel_exten(const struct ast_channel *chan)
#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_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:8781
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
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:6945
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
Number structure.
Definition: app_followme.c:154
#define ast_test_flag(p, flag)
Definition: utils.h:63

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, voicemailpwcheck::context, 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, 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().

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:128
static void after_bridge_cb_destroy(void *data)
Definition: bridge_after.c:107

Definition at line 146 of file bridge_after.c.

Referenced by after_bridge_cb_find(), and after_bridge_cb_setup().

◆ 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:329
static void after_bridge_goto_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
Definition: bridge_after.c:348

Definition at line 354 of file bridge_after.c.

Referenced by __after_bridge_set_goto(), after_bridge_goto_remove(), and ast_bridge_read_after_goto().