Asterisk - The Open Source Telephony Project GIT-master-a358458
Enumerations | Functions
features.h File Reference

Call Parking and Pickup API Includes code and algorithms from the Zapata library. More...

#include "asterisk/pbx.h"
#include "asterisk/linkedlists.h"
#include "asterisk/bridge.h"
Include dependency graph for features.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  {
  AST_FEATURE_FLAG_NEEDSDTMF = (1 << 0) , AST_FEATURE_FLAG_ONPEER = (1 << 1) , AST_FEATURE_FLAG_ONSELF = (1 << 2) , AST_FEATURE_FLAG_BYCALLEE = (1 << 3) ,
  AST_FEATURE_FLAG_BYCALLER = (1 << 4) , AST_FEATURE_FLAG_BYBOTH = (3 << 3)
}
 main call feature structure More...
 

Functions

int ast_bridge_add_channel (struct ast_bridge *bridge, struct ast_channel *chan, struct ast_bridge_features *features, int play_tone, const char *xfersound)
 Add an arbitrary channel to a bridge. More...
 
int ast_bridge_call (struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
 Bridge a call, optionally allowing redirection. More...
 
int ast_bridge_call_with_flags (struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, unsigned int flags)
 Bridge a call, and add additional flags to the bridge. More...
 
int ast_bridge_timelimit (struct ast_channel *chan, struct ast_bridge_config *config, char *parse, struct timeval *calldurationlimit)
 parse L option and read associated channel variables to set warning, warning frequency, and timelimit More...
 

Detailed Description

Call Parking and Pickup API Includes code and algorithms from the Zapata library.

Definition in file features.h.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

main call feature structure

Enumerator
AST_FEATURE_FLAG_NEEDSDTMF 
AST_FEATURE_FLAG_ONPEER 
AST_FEATURE_FLAG_ONSELF 
AST_FEATURE_FLAG_BYCALLEE 
AST_FEATURE_FLAG_BYCALLER 
AST_FEATURE_FLAG_BYBOTH 

Definition at line 33 of file features.h.

33 {
35 AST_FEATURE_FLAG_ONPEER = (1 << 1),
36 AST_FEATURE_FLAG_ONSELF = (1 << 2),
39 AST_FEATURE_FLAG_BYBOTH = (3 << 3),
40};
@ AST_FEATURE_FLAG_ONPEER
Definition: features.h:35
@ AST_FEATURE_FLAG_ONSELF
Definition: features.h:36
@ AST_FEATURE_FLAG_BYBOTH
Definition: features.h:39
@ AST_FEATURE_FLAG_BYCALLER
Definition: features.h:38
@ AST_FEATURE_FLAG_NEEDSDTMF
Definition: features.h:34
@ AST_FEATURE_FLAG_BYCALLEE
Definition: features.h:37

Function Documentation

◆ ast_bridge_add_channel()

int ast_bridge_add_channel ( struct ast_bridge bridge,
struct ast_channel chan,
struct ast_bridge_features features,
int  play_tone,
const char *  xfersound 
)

Add an arbitrary channel to a bridge.

Since
12.0.0

The channel that is being added to the bridge can be in any state: unbridged, bridged, answered, unanswered, etc. The channel will be added asynchronously, meaning that when this function returns once the channel has been added to the bridge, not once the channel has been removed from the bridge.

In addition, a tone can optionally be played to the channel once the channel is placed into the bridge.

Note
When this function returns, there is no guarantee that the channel that was passed in is valid any longer. Do not attempt to operate on the channel after this function returns.
Parameters
bridgeBridge to which the channel should be added
chanThe channel to add to the bridge
featuresFeatures for this channel in the bridge
play_toneIndicates if a tone should be played to the channel
xfersoundSound that should be used to indicate transfer with play_tone
Note
The features parameter must be NULL or obtained by ast_bridge_features_new(). You must not dereference features after calling even if the call fails.
Return values
0Success
-1Failure

Definition at line 2471 of file bridge.c.

2473{
2474 RAII_VAR(struct ast_bridge *, chan_bridge, NULL, ao2_cleanup);
2475 RAII_VAR(struct ast_channel *, yanked_chan, NULL, ao2_cleanup);
2476
2477 ast_moh_stop(chan);
2478
2479 ast_channel_lock(chan);
2480 chan_bridge = ast_channel_get_bridge(chan);
2481 ast_channel_unlock(chan);
2482
2483 if (chan_bridge) {
2484 struct ast_bridge_channel *bridge_channel;
2485
2486 /* The channel is in a bridge so it is not getting any new features. */
2488
2489 ast_bridge_lock_both(bridge, chan_bridge);
2490 bridge_channel = bridge_find_channel(chan_bridge, chan);
2491
2492 if (bridge_move_locked(bridge, chan_bridge, chan, NULL, 1)) {
2493 ast_bridge_unlock(chan_bridge);
2495 return -1;
2496 }
2497
2498 /*
2499 * bridge_move_locked() will implicitly ensure that
2500 * bridge_channel is not NULL.
2501 */
2502 ast_assert(bridge_channel != NULL);
2503
2504 /*
2505 * Additional checks if the channel we just stole dissolves the
2506 * original bridge.
2507 */
2508 bridge_dissolve_check_stolen(chan_bridge, bridge_channel);
2509 ast_bridge_unlock(chan_bridge);
2511 } else {
2512 /* Slightly less easy case. We need to yank channel A from
2513 * where he currently is and impart him into our bridge.
2514 */
2515 yanked_chan = ast_channel_yank(chan);
2516 if (!yanked_chan) {
2517 ast_log(LOG_WARNING, "Could not gain control of channel %s\n", ast_channel_name(chan));
2519 return -1;
2520 }
2521 if (ast_channel_state(yanked_chan) != AST_STATE_UP) {
2522 ast_answer(yanked_chan);
2523 }
2524 ast_channel_ref(yanked_chan);
2525 if (ast_bridge_impart(bridge, yanked_chan, NULL, features,
2527 /* It is possible for us to yank a channel and have some other
2528 * thread start a PBX on the channel after we yanked it. In particular,
2529 * this can theoretically happen on the ;2 of a Local channel if we
2530 * yank it prior to the ;1 being answered. Make sure that it isn't
2531 * executing a PBX before hanging it up.
2532 */
2533 if (ast_channel_pbx(yanked_chan)) {
2534 ast_channel_unref(yanked_chan);
2535 } else {
2536 ast_hangup(yanked_chan);
2537 }
2538 return -1;
2539 }
2540 }
2541
2542 if (play_tone && !ast_strlen_zero(xfersound)) {
2543 struct ast_channel *play_chan = yanked_chan ?: chan;
2544 RAII_VAR(struct ast_bridge_channel *, play_bridge_channel, NULL, ao2_cleanup);
2545
2546 ast_channel_lock(play_chan);
2547 play_bridge_channel = ast_channel_get_bridge_channel(play_chan);
2548 ast_channel_unlock(play_chan);
2549
2550 if (!play_bridge_channel) {
2551 ast_log(LOG_WARNING, "Unable to play tone for channel %s. No longer in a bridge.\n",
2552 ast_channel_name(play_chan));
2553 } else {
2554 ast_bridge_channel_queue_playfile(play_bridge_channel, NULL, xfersound, NULL);
2555 }
2556 }
2557 return 0;
2558}
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags)
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1878
static int bridge_move_locked(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_channel *chan, struct ast_channel *swap, int attempt_recovery)
Definition: bridge.c:2399
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1429
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3674
static void bridge_dissolve_check_stolen(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:355
#define ast_bridge_lock_both(bridge1, bridge2)
Lock two bridges.
Definition: bridge.h:488
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:481
@ AST_BRIDGE_IMPART_CHAN_INDEPENDENT
Definition: bridge.h:590
int ast_bridge_channel_queue_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Queue a bridge action play file frame onto the bridge channel.
const char * ast_channel_name(const struct ast_channel *chan)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
#define ast_channel_lock(chan)
Definition: channel.h:2922
struct ast_channel * ast_channel_yank(struct ast_channel *yankee)
Gain control of a channel in the system.
Definition: channel.c:10593
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10534
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel's bridge pointer.
Definition: channel.c:10582
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2805
#define ast_channel_unlock(chan)
Definition: channel.h:2923
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
#define LOG_WARNING
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7776
#define NULL
Definition: resample.c:96
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Structure that contains information regarding a channel in a bridge.
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_bridge_features * features
struct ast_channel * chan
Structure that contains information about a bridge.
Definition: bridge.h:349
Main Channel structure associated with a channel.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define ast_assert(a)
Definition: utils.h:739

References ao2_cleanup, ast_answer(), ast_assert, ast_bridge_channel_queue_playfile(), ast_bridge_features_destroy(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_INDEPENDENT, ast_bridge_lock_both, ast_bridge_unlock, ast_channel_get_bridge(), ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_name(), ast_channel_pbx(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_channel_yank(), ast_hangup(), ast_log, ast_moh_stop(), AST_STATE_UP, ast_strlen_zero(), ast_bridge_channel::bridge, bridge_dissolve_check_stolen(), bridge_find_channel(), bridge_move_locked(), ast_bridge_channel::chan, ast_bridge_channel::features, LOG_WARNING, NULL, and RAII_VAR.

Referenced by action_bridge(), bridge_exec(), and manager_park_unbridged().

◆ ast_bridge_call()

int ast_bridge_call ( struct ast_channel chan,
struct ast_channel peer,
struct ast_bridge_config config 
)

Bridge a call, optionally allowing redirection.

Note
The function caller is assumed to have already done the COLP exchange for the initial bridging of the two channels if it was desired.

Bridge a call, optionally allowing redirection.

Parameters
chanThe bridge considers this channel the caller.
peerThe bridge considers this channel the callee.
configConfiguration for this bridge.

Set start time, check for two channels,check if monitor on check for feature activation, create new CDR

Returns
res on success.
Return values
-1on failure to bridge.

Definition at line 685 of file features.c.

686{
687 return ast_bridge_call_with_flags(chan, peer, config, 0);
688}
static const char config[]
Definition: chan_ooh323.c:111
int ast_bridge_call_with_flags(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, unsigned int flags)
Bridge a call, and add additional flags to the bridge.
Definition: features.c:595

References ast_bridge_call_with_flags(), and config.

Referenced by app_exec(), and dial_exec_full().

◆ ast_bridge_call_with_flags()

int ast_bridge_call_with_flags ( struct ast_channel chan,
struct ast_channel peer,
struct ast_bridge_config config,
unsigned int  flags 
)

Bridge a call, and add additional flags to the bridge.

This does the same thing as ast_bridge_call, except that once the bridge is created, the provided flags are set on the bridge. The provided flags are added to the bridge's flags; they will not clear any flags already set.

Parameters
chanThe calling channel
peerThe called channel
configBridge configuration for the channels
flagsAdditional flags to set on the created bridge
Note
The function caller is assumed to have already done the COLP exchange for the initial bridging of the two channels if it was desired.

Definition at line 595 of file features.c.

596{
597 int res;
598 struct ast_bridge *bridge;
599 struct ast_bridge_features chan_features;
600 struct ast_bridge_features *peer_features;
601 const char *value;
602 int noanswer;
603 SCOPE_TRACE(1, "%s Peer: %s\n", ast_channel_name(chan), ast_channel_name(peer));
604
605 /* Setup features. */
606 res = ast_bridge_features_init(&chan_features);
607 peer_features = ast_bridge_features_new();
608 if (res || !peer_features) {
609 ast_bridge_features_destroy(peer_features);
610 ast_bridge_features_cleanup(&chan_features);
611 bridge_failed_peer_goto(chan, peer);
612 return -1;
613 }
614
615 ast_channel_lock(chan);
616 value = pbx_builtin_getvar_helper(chan, "BRIDGE_NOANSWER");
617 noanswer = !ast_strlen_zero(value) ? 1 : 0;
618 ast_channel_unlock(chan);
619
620 if (pre_bridge_setup(chan, peer, config, &chan_features, peer_features, noanswer)) {
621 ast_bridge_features_destroy(peer_features);
622 ast_bridge_features_cleanup(&chan_features);
623 bridge_failed_peer_goto(chan, peer);
624 return -1;
625 }
626
627 /* Create bridge */
628 bridge = ast_bridge_basic_new();
629 if (!bridge) {
630 ast_bridge_features_destroy(peer_features);
631 ast_bridge_features_cleanup(&chan_features);
632 bridge_failed_peer_goto(chan, peer);
633 return -1;
634 }
635
636 ast_bridge_basic_set_flags(bridge, flags);
637
638 /* Put peer into the bridge */
639 if (ast_bridge_impart(bridge, peer, NULL, peer_features,
641 ast_bridge_destroy(bridge, 0);
642 ast_bridge_features_cleanup(&chan_features);
643 bridge_failed_peer_goto(chan, peer);
644 return -1;
645 }
646
647 /* Join bridge */
648 ast_bridge_join(bridge, chan, NULL, &chan_features, NULL,
650
651 /*
652 * If the bridge was broken for a hangup that isn't real, then
653 * don't run the h extension, because the channel isn't really
654 * hung up. This should really only happen with
655 * AST_SOFTHANGUP_ASYNCGOTO.
656 */
657 res = -1;
658 ast_channel_lock(chan);
660 res = 0;
661 }
662 ast_channel_unlock(chan);
663
664 ast_bridge_features_cleanup(&chan_features);
665
666 if (res && config->end_bridge_callback) {
667 config->end_bridge_callback(config->end_bridge_callback_data);
668 }
669
670 return res;
671}
@ noanswer
int ast_bridge_join(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, struct ast_bridge_tech_optimizations *tech_args, enum ast_bridge_join_flags flags)
Join a channel to a bridge (blocking)
Definition: bridge.c:1621
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:944
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1878
@ AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP
Definition: bridge.h:592
@ AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP
Definition: bridge.h:537
@ AST_BRIDGE_JOIN_PASS_REFERENCE
Definition: bridge.h:535
void ast_bridge_basic_set_flags(struct ast_bridge *bridge, unsigned int flags)
Set feature flags on a basic bridge.
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3620
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3683
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3653
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3674
@ AST_SOFTHANGUP_ASYNCGOTO
Definition: channel.h:1126
int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
static int pre_bridge_setup(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, struct ast_bridge_features *chan_features, struct ast_bridge_features *peer_features, int noanswer)
Definition: features.c:497
static void bridge_failed_peer_goto(struct ast_channel *chan, struct ast_channel *peer)
Definition: features.c:489
#define SCOPE_TRACE(__level,...)
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Structure that contains features information.
int value
Definition: syslog.c:37

References ast_bridge_basic_new(), ast_bridge_basic_set_flags(), ast_bridge_destroy(), ast_bridge_features_cleanup(), ast_bridge_features_destroy(), ast_bridge_features_init(), ast_bridge_features_new(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_INDEPENDENT, AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP, ast_bridge_join(), AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP, AST_BRIDGE_JOIN_PASS_REFERENCE, ast_channel_lock, ast_channel_name(), ast_channel_softhangup_internal_flag(), ast_channel_unlock, AST_SOFTHANGUP_ASYNCGOTO, ast_strlen_zero(), bridge_failed_peer_goto(), config, noanswer, NULL, pbx_builtin_getvar_helper(), pre_bridge_setup(), SCOPE_TRACE, and value.

Referenced by ast_bridge_call(), and try_calling().

◆ ast_bridge_timelimit()

int ast_bridge_timelimit ( struct ast_channel chan,
struct ast_bridge_config config,
char *  parse,
struct timeval *  calldurationlimit 
)

parse L option and read associated channel variables to set warning, warning frequency, and timelimit

Note
caller must be aware of freeing memory for warning_sound, end_sound, and start_sound

Definition at line 857 of file features.c.

859{
860 char *stringp = ast_strdupa(parse);
861 char *limit_str, *warning_str, *warnfreq_str;
862 const char *var;
863 int play_to_caller = 0, play_to_callee = 0;
864 int delta;
865
866 limit_str = strsep(&stringp, ":");
867 warning_str = strsep(&stringp, ":");
868 warnfreq_str = strsep(&stringp, ":");
869
870 config->timelimit = atol(limit_str);
871 if (warning_str)
872 config->play_warning = atol(warning_str);
873 if (warnfreq_str)
874 config->warning_freq = atol(warnfreq_str);
875
876 if (!config->timelimit) {
877 ast_log(LOG_WARNING, "Bridge does not accept L(%s)\n", limit_str);
878 config->timelimit = config->play_warning = config->warning_freq = 0;
879 config->warning_sound = NULL;
880 return -1; /* error */
881 } else if ( (delta = config->play_warning - config->timelimit) > 0) {
882 int w = config->warning_freq;
883
884 /*
885 * If the first warning is requested _after_ the entire call
886 * would end, and no warning frequency is requested, then turn
887 * off the warning. If a warning frequency is requested, reduce
888 * the 'first warning' time by that frequency until it falls
889 * within the call's total time limit.
890 *
891 * Graphically:
892 * timelim->| delta |<-playwarning
893 * 0__________________|_________________|
894 * | w | | | |
895 *
896 * so the number of intervals to cut is 1+(delta-1)/w
897 */
898 if (w == 0) {
899 config->play_warning = 0;
900 } else {
901 config->play_warning -= w * ( 1 + (delta-1)/w );
902 if (config->play_warning < 1)
903 config->play_warning = config->warning_freq = 0;
904 }
905 }
906
907 ast_channel_lock(chan);
908
909 var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLER");
910 play_to_caller = var ? ast_true(var) : 1;
911
912 var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLEE");
913 play_to_callee = var ? ast_true(var) : 0;
914
915 if (!play_to_caller && !play_to_callee)
916 play_to_caller = 1;
917
918 var = pbx_builtin_getvar_helper(chan, "LIMIT_WARNING_FILE");
919 config->warning_sound = !ast_strlen_zero(var) ? ast_strdup(var) : ast_strdup("timeleft");
920
921 /* The code looking at config wants a NULL, not just "", to decide
922 * that the message should not be played, so we replace "" with NULL.
923 * Note, pbx_builtin_getvar_helper _can_ return NULL if the variable is
924 * not found.
925 */
926
927 var = pbx_builtin_getvar_helper(chan, "LIMIT_TIMEOUT_FILE");
928 config->end_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
929
930 var = pbx_builtin_getvar_helper(chan, "LIMIT_CONNECT_FILE");
931 config->start_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
932
933 ast_channel_unlock(chan);
934
935 /* undo effect of S(x) in case they are both used */
936 calldurationlimit->tv_sec = 0;
937 calldurationlimit->tv_usec = 0;
938
939 /* more efficient to do it like S(x) does since no advanced opts */
940 if (!config->play_warning && !config->start_sound && !config->end_sound && config->timelimit) {
941 calldurationlimit->tv_sec = config->timelimit / 1000;
942 calldurationlimit->tv_usec = (config->timelimit % 1000) * 1000;
943 ast_verb(3, "Setting call duration limit to %.3lf seconds.\n",
944 calldurationlimit->tv_sec + calldurationlimit->tv_usec / 1000000.0);
945 play_to_caller = 0;
946 play_to_callee = 0;
947 config->timelimit = 0;
948 config->play_warning = 0;
949 config->warning_freq = 0;
950 } else {
951 ast_verb(4, "Limit Data for this call:\n");
952 ast_verb(4, "timelimit = %ld ms (%.3lf s)\n", config->timelimit, config->timelimit / 1000.0);
953 ast_verb(4, "play_warning = %ld ms (%.3lf s)\n", config->play_warning, config->play_warning / 1000.0);
954 ast_verb(4, "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
955 ast_verb(4, "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
956 ast_verb(4, "warning_freq = %ld ms (%.3lf s)\n", config->warning_freq, config->warning_freq / 1000.0);
957 ast_verb(4, "start_sound = %s\n", S_OR(config->start_sound, ""));
958 ast_verb(4, "warning_sound = %s\n", config->warning_sound);
959 ast_verb(4, "end_sound = %s\n", S_OR(config->end_sound, ""));
960 }
961 if (play_to_caller)
962 ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
963 if (play_to_callee)
964 ast_set_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
965 return 0;
966}
#define var
Definition: ast_expr2f.c:605
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
@ AST_FEATURE_PLAY_WARNING
Definition: channel.h:1063
char * strsep(char **str, const char *delims)
#define ast_verb(level,...)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
#define ast_set_flag(p, flag)
Definition: utils.h:70

References ast_channel_lock, ast_channel_unlock, AST_FEATURE_PLAY_WARNING, ast_log, ast_set_flag, ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_verb, config, LOG_WARNING, NULL, pbx_builtin_getvar_helper(), S_OR, strsep(), and var.

Referenced by bridge_exec(), and dial_exec_full().