Asterisk - The Open Source Telephony Project GIT-master-77d630f
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 2540 of file bridge.c.

2542{
2543 RAII_VAR(struct ast_bridge *, chan_bridge, NULL, ao2_cleanup);
2544 RAII_VAR(struct ast_channel *, yanked_chan, NULL, ao2_cleanup);
2545
2546 ast_moh_stop(chan);
2547
2548 ast_channel_lock(chan);
2549 chan_bridge = ast_channel_get_bridge(chan);
2550 ast_channel_unlock(chan);
2551
2552 if (chan_bridge) {
2553 struct ast_bridge_channel *bridge_channel;
2554
2555 /* The channel is in a bridge so it is not getting any new features. */
2557
2558 ast_bridge_lock_both(bridge, chan_bridge);
2559 bridge_channel = bridge_find_channel(chan_bridge, chan);
2560
2561 if (bridge_move_locked(bridge, chan_bridge, chan, NULL, 1)) {
2562 ast_bridge_unlock(chan_bridge);
2564 return -1;
2565 }
2566
2567 /*
2568 * bridge_move_locked() will implicitly ensure that
2569 * bridge_channel is not NULL.
2570 */
2571 ast_assert(bridge_channel != NULL);
2572
2573 /*
2574 * Additional checks if the channel we just stole dissolves the
2575 * original bridge.
2576 */
2577 bridge_dissolve_check_stolen(chan_bridge, bridge_channel);
2578 ast_bridge_unlock(chan_bridge);
2580 } else {
2581 int noanswer;
2582 const char *value;
2583 /* Slightly less easy case. We need to yank channel A from
2584 * where he currently is and impart him into our bridge.
2585 */
2586 yanked_chan = ast_channel_yank(chan);
2587 if (!yanked_chan) {
2588 ast_log(LOG_WARNING, "Could not gain control of channel %s\n", ast_channel_name(chan));
2590 return -1;
2591 }
2592
2594 value = pbx_builtin_getvar_helper(chan, "BRIDGE_NOANSWER");
2595 noanswer = !ast_strlen_zero(value) ? 1 : 0;
2597 if (noanswer) {
2598 ast_debug(3, "Skipping answer on bridge target channel %s\n", ast_channel_name(chan));
2599 } else if (ast_channel_state(yanked_chan) != AST_STATE_UP) {
2600 ast_answer(yanked_chan);
2601 }
2602
2603 ast_channel_ref(yanked_chan);
2604 if (ast_bridge_impart(bridge, yanked_chan, NULL, features,
2606 /* It is possible for us to yank a channel and have some other
2607 * thread start a PBX on the channel after we yanked it. In particular,
2608 * this can theoretically happen on the ;2 of a Local channel if we
2609 * yank it prior to the ;1 being answered. Make sure that it isn't
2610 * executing a PBX before hanging it up.
2611 */
2612 if (ast_channel_pbx(yanked_chan)) {
2613 ast_channel_unref(yanked_chan);
2614 } else {
2615 ast_hangup(yanked_chan);
2616 }
2617 return -1;
2618 }
2619 }
2620
2621 if (play_tone && !ast_strlen_zero(xfersound)) {
2622 struct ast_channel *play_chan = yanked_chan ?: chan;
2623 RAII_VAR(struct ast_bridge_channel *, play_bridge_channel, NULL, ao2_cleanup);
2624
2625 ast_channel_lock(play_chan);
2626 play_bridge_channel = ast_channel_get_bridge_channel(play_chan);
2627 ast_channel_unlock(play_chan);
2628
2629 if (!play_bridge_channel) {
2630 ast_log(LOG_WARNING, "Unable to play tone for channel %s. No longer in a bridge.\n",
2631 ast_channel_name(play_chan));
2632 } else {
2633 ast_bridge_channel_queue_playfile(play_bridge_channel, NULL, xfersound, NULL);
2634 }
2635 }
2636 return 0;
2637}
@ noanswer
#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:1947
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:2468
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1498
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3753
static void bridge_dissolve_check_stolen(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:374
#define ast_bridge_lock_both(bridge1, bridge2)
Lock two bridges.
Definition: bridge.h:492
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:485
@ AST_BRIDGE_IMPART_CHAN_INDEPENDENT
Definition: bridge.h:594
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:2511
#define ast_channel_lock(chan)
Definition: channel.h:2972
struct ast_channel * ast_channel_yank(struct ast_channel *yankee)
Gain control of a channel in the system.
Definition: channel.c:10607
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2997
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10548
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3008
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:10596
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2776
#define ast_channel_unlock(chan)
Definition: channel.h:2973
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7758
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#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:353
Main Channel structure associated with a channel.
int value
Definition: syslog.c:37
#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:978
#define ast_assert(a)
Definition: utils.h:776

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_debug, 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, noanswer, NULL, pbx_builtin_getvar_helper(), RAII_VAR, and value.

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 694 of file features.c.

695{
696 return ast_bridge_call_with_flags(chan, peer, config, 0);
697}
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:604

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 604 of file features.c.

605{
606 int res;
607 struct ast_bridge *bridge;
608 struct ast_bridge_features chan_features;
609 struct ast_bridge_features *peer_features;
610 const char *value;
611 int noanswer;
612 SCOPE_TRACE(1, "%s Peer: %s\n", ast_channel_name(chan), ast_channel_name(peer));
613
614 /* Setup features. */
615 res = ast_bridge_features_init(&chan_features);
616 peer_features = ast_bridge_features_new();
617 if (res || !peer_features) {
618 ast_bridge_features_destroy(peer_features);
619 ast_bridge_features_cleanup(&chan_features);
620 bridge_failed_peer_goto(chan, peer);
621 return -1;
622 }
623
624 ast_channel_lock(chan);
625 value = pbx_builtin_getvar_helper(chan, "BRIDGE_NOANSWER");
626 noanswer = !ast_strlen_zero(value) ? 1 : 0;
627 ast_channel_unlock(chan);
628
629 if (pre_bridge_setup(chan, peer, config, &chan_features, peer_features, noanswer)) {
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 /* Create bridge */
637 bridge = ast_bridge_basic_new();
638 if (!bridge) {
639 ast_bridge_features_destroy(peer_features);
640 ast_bridge_features_cleanup(&chan_features);
641 bridge_failed_peer_goto(chan, peer);
642 return -1;
643 }
644
645 ast_bridge_basic_set_flags(bridge, flags);
646
647 /* Put peer into the bridge */
648 if (ast_bridge_impart(bridge, peer, NULL, peer_features,
650 ast_bridge_destroy(bridge, 0);
651 ast_bridge_features_cleanup(&chan_features);
652 bridge_failed_peer_goto(chan, peer);
653 return -1;
654 }
655
656 /* Join bridge */
657 ast_bridge_join(bridge, chan, NULL, &chan_features, NULL,
659
660 /*
661 * If the bridge was broken for a hangup that isn't real, then
662 * don't run the h extension, because the channel isn't really
663 * hung up. This should really only happen with
664 * AST_SOFTHANGUP_ASYNCGOTO.
665 */
666 res = -1;
667 ast_channel_lock(chan);
669 res = 0;
670 }
671 ast_channel_unlock(chan);
672
673 ast_bridge_features_cleanup(&chan_features);
674
675 if (res && config->end_bridge_callback) {
676 config->end_bridge_callback(config->end_bridge_callback_data);
677 }
678
679 return res;
680}
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:1690
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:1009
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:1947
@ AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP
Definition: bridge.h:596
@ AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP
Definition: bridge.h:541
@ AST_BRIDGE_JOIN_PASS_REFERENCE
Definition: bridge.h:539
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:3699
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3762
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3732
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3753
@ AST_SOFTHANGUP_ASYNCGOTO
Definition: channel.h:1146
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:506
static void bridge_failed_peer_goto(struct ast_channel *chan, struct ast_channel *peer)
Definition: features.c:498
#define SCOPE_TRACE(__level,...)
Structure that contains features information.

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 866 of file features.c.

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