43 #include "features_config.h"
49 #include <netinet/in.h>
76 #include "asterisk/stasis_channels.h"
77 #include "asterisk/features_config.h"
78 #include "asterisk/max_forwards.h"
256 FEATURE_INTERPRET_DETECT,
257 FEATURE_INTERPRET_DO,
258 FEATURE_INTERPRET_CHECK,
259 } feature_interpret_op;
268 static void *dial_features_duplicate(
void *data)
272 if (!(df_copy =
ast_calloc(1,
sizeof(*df)))) {
276 memcpy(df_copy, df,
sizeof(*df));
282 .
type =
"dial-features",
284 .duplicate = dial_features_duplicate,
302 ast_channel_lock(chan);
304 ast_channel_unlock(chan);
311 datastore = ast_datastore_alloc(&dial_features_info, NULL);
313 ast_log(LOG_WARNING,
"Unable to create channel features datastore.\n");
316 dialfeatures =
ast_calloc(1,
sizeof(*dialfeatures));
318 ast_log(LOG_WARNING,
"Unable to allocate memory for feature flags.\n");
322 ast_copy_flags(&dialfeatures->
my_features, my_features, AST_FLAGS_ALL);
323 ast_copy_flags(&dialfeatures->
peer_features, peer_features, AST_FLAGS_ALL);
324 datastore->
inheritance = DATASTORE_INHERIT_FOREVER;
325 datastore->
data = dialfeatures;
326 ast_channel_lock(chan);
328 ast_channel_unlock(chan);
337 unsigned int return_to_pbx:1;
342 ast_clear_flag(config, AST_FLAGS_ALL);
344 if (ast_test_flag(&config->features_caller, AST_FEATURE_DTMF_MASK)) {
347 if (ast_test_flag(&config->features_callee, AST_FEATURE_DTMF_MASK)) {
354 ast_channel_lock(chan);
355 applicationmap = ast_get_chan_applicationmap(chan);
356 ast_channel_unlock(chan);
358 if (!applicationmap) {
367 void ast_channel_log(
char *title,
struct ast_channel *chan);
369 void ast_channel_log(
char *title,
struct ast_channel *chan)
371 ast_log(LOG_NOTICE,
"______ %s (%lx)______\n", title, (
unsigned long) chan);
372 ast_log(LOG_NOTICE,
"CHAN: name: %s; appl: %s; data: %s; contxt: %s; exten: %s; pri: %d;\n",
373 ast_channel_name(chan), ast_channel_appl(chan), ast_channel_data(chan),
374 ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan));
375 ast_log(LOG_NOTICE,
"CHAN: acctcode: %s; dialcontext: %s; amaflags: %x;\n",
376 ast_channel_accountcode(chan), ast_channel_dialcontext(chan), ast_channel_amaflags(chan));
377 ast_log(LOG_NOTICE,
"CHAN: masq: %p; masqr: %p; uniqueID: %s; linkedID:%s\n",
378 ast_channel_masq(chan), ast_channel_masqr(chan),
379 ast_channel_uniqueid(chan), ast_channel_linkedid(chan));
380 if (ast_channel_masqr(chan)) {
381 ast_log(LOG_NOTICE,
"CHAN: masquerading as: %s; cdr: %p;\n",
382 ast_channel_name(ast_channel_masqr(chan)), ast_channel_cdr(ast_channel_masqr(chan)));
385 ast_log(LOG_NOTICE,
"===== done ====\n");
388 static void set_bridge_features_on_config(
struct ast_bridge_config *config,
const char *features)
392 if (ast_strlen_zero(features)) {
396 for (feature = features; *feature; feature++) {
399 if (isupper(*feature)) {
400 party = &config->features_caller;
402 party = &config->features_callee;
405 switch (tolower(*feature)) {
407 ast_set_flag(party, AST_FEATURE_REDIRECT);
410 ast_set_flag(party, AST_FEATURE_PARKCALL);
413 ast_set_flag(party, AST_FEATURE_DISCONNECT);
416 ast_set_flag(party, AST_FEATURE_AUTOMON);
419 ast_set_flag(party, AST_FEATURE_AUTOMIXMON);
422 ast_log(LOG_WARNING,
"Skipping unknown feature code '%c'\n", *feature);
430 if (add_features_datastore(caller, &config->features_caller, &config->features_callee)) {
439 add_features_datastore(callee, &config->features_callee, &config->features_caller);
444 if (config->end_sound) {
448 if (config->warning_sound) {
452 if (config->start_sound) {
456 limits->
frequency = config->warning_freq;
457 limits->
warning = config->play_warning;
469 if (ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING)) {
470 bridge_config_set_limits_warning_values(config, caller_limits);
473 if (ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING)) {
474 bridge_config_set_limits_warning_values(config, callee_limits);
477 caller_limits->
duration = config->timelimit;
478 callee_limits->
duration = config->timelimit;
501 SCOPE_TRACE(1,
"%s Peer: %s\n", ast_channel_name(chan), ast_channel_name(peer));
504 add_features_datastores(chan, peer, config);
518 set_config_flags(chan, config);
525 ast_debug(1,
"Skipping answer on %s due to no answer directive\n", ast_channel_name(chan));
527 ast_debug(1,
"Answering channel for bridge: %s\n", ast_channel_name(chan));
537 ast_channel_log(
"Pre-bridge CHAN Channel info", chan);
538 ast_channel_log(
"Pre-bridge PEER Channel info", peer);
542 ast_channel_lock(chan);
543 ast_max_forwards_reset(chan);
545 ast_channel_unlock(chan);
546 ast_channel_lock(peer);
547 ast_max_forwards_reset(peer);
549 ast_channel_unlock(peer);
555 if (config->timelimit) {
558 int abandon_call = 0;
561 ast_log(LOG_ERROR,
"Could not construct caller duration limits. Bridge canceled.\n");
567 ast_log(LOG_ERROR,
"Could not construct callee duration limits. Bridge canceled.\n");
573 bridge_config_set_limits(config, &call_duration_limits_chan, &call_duration_limits_peer);
587 ast_log(LOG_ERROR,
"Could not set duration limits on one or more sides of the call. Bridge canceled.\n");
603 SCOPE_TRACE(1,
"%s Peer: %s\n", ast_channel_name(chan), ast_channel_name(peer));
608 if (res || !peer_features) {
611 bridge_failed_peer_goto(chan, peer);
615 ast_channel_lock(chan);
617 noanswer = !ast_strlen_zero(value) ? 1 : 0;
618 ast_channel_unlock(chan);
620 if (pre_bridge_setup(chan, peer, config, &chan_features, peer_features, noanswer)) {
623 bridge_failed_peer_goto(chan, peer);
632 bridge_failed_peer_goto(chan, peer);
643 bridge_failed_peer_goto(chan, peer);
658 ast_channel_lock(chan);
662 ast_channel_unlock(chan);
690 enum play_tone_action {
692 PLAYTONE_CHANNEL1 = (1 << 0),
693 PLAYTONE_CHANNEL2 = (1 << 1),
694 PLAYTONE_BOTH = PLAYTONE_CHANNEL1 | PLAYTONE_CHANNEL2,
697 static enum play_tone_action parse_playtone(
const char *playtone_val)
699 if (ast_strlen_zero(playtone_val) ||
ast_false(playtone_val)) {
700 return PLAYTONE_NONE;
701 }
if (!strcasecmp(playtone_val,
"channel1")) {
702 return PLAYTONE_CHANNEL1;
703 }
else if (!strcasecmp(playtone_val,
"channel2") ||
ast_true(playtone_val)) {
704 return PLAYTONE_CHANNEL2;
705 }
else if (!strcasecmp(playtone_val,
"both")) {
706 return PLAYTONE_BOTH;
709 return PLAYTONE_NONE;
733 const char *chana_exten;
734 const char *chana_context;
736 const char *chanb_exten;
737 const char *chanb_context;
745 if (ast_strlen_zero(channela) || ast_strlen_zero(channelb)) {
750 ast_debug(1,
"Performing Bridge action on %s and %s\n", channela, channelb);
755 snprintf(buf,
sizeof(buf),
"Channel1 does not exist: %s", channela);
759 ast_channel_lock(chana);
760 xfer_cfg_a = ast_get_chan_features_xfer_config(chana);
761 chana_exten =
ast_strdupa(ast_channel_exten(chana));
762 chana_context =
ast_strdupa(ast_channel_context(chana));
763 chana_priority = ast_channel_priority(chana);
767 ast_channel_unlock(chana);
771 snprintf(buf,
sizeof(buf),
"Channel2 does not exist: %s", channelb);
775 ast_channel_lock(chanb);
776 xfer_cfg_b = ast_get_chan_features_xfer_config(chanb);
777 chanb_exten =
ast_strdupa(ast_channel_exten(chanb));
778 chanb_context =
ast_strdupa(ast_channel_context(chanb));
779 chanb_priority = ast_channel_priority(chanb);
783 ast_channel_unlock(chanb);
792 if (
ast_bridge_add_channel(bridge, chana, NULL, playtone & PLAYTONE_CHANNEL1, xfer_cfg_a ? xfer_cfg_a->xfersound : NULL)) {
793 snprintf(buf,
sizeof(buf),
"Unable to add Channel1 to bridge: %s", ast_channel_name(chana));
800 if (
ast_bridge_add_channel(bridge, chanb, NULL, playtone & PLAYTONE_CHANNEL2, xfer_cfg_b ? xfer_cfg_b->xfersound : NULL)) {
801 snprintf(buf,
sizeof(buf),
"Unable to add Channel2 to bridge: %s", ast_channel_name(chanb));
813 static char *app_bridge =
"Bridge";
816 BRIDGE_OPT_PLAYTONE = (1 << 0),
817 OPT_CALLEE_HANGUP = (1 << 1),
818 OPT_CALLER_HANGUP = (1 << 2),
819 OPT_DURATION_LIMIT = (1 << 3),
820 OPT_DURATION_STOP = (1 << 4),
821 OPT_CALLEE_TRANSFER = (1 << 5),
822 OPT_CALLER_TRANSFER = (1 << 6),
823 OPT_CALLEE_MONITOR = (1 << 7),
824 OPT_CALLER_MONITOR = (1 << 8),
825 OPT_CALLEE_PARK = (1 << 9),
826 OPT_CALLER_PARK = (1 << 10),
827 OPT_CALLEE_KILL = (1 << 11),
828 OPT_CALLEE_GO_ON = (1 << 12),
829 OPT_NOANSWER = (1 << 13),
833 OPT_ARG_DURATION_LIMIT = 0,
834 OPT_ARG_DURATION_STOP,
835 OPT_ARG_CALLEE_GO_ON,
858 char *parse,
struct timeval *calldurationlimit)
861 char *limit_str, *warning_str, *warnfreq_str;
863 int play_to_caller = 0, play_to_callee = 0;
866 limit_str = strsep(&stringp,
":");
867 warning_str = strsep(&stringp,
":");
868 warnfreq_str = strsep(&stringp,
":");
870 config->timelimit = atol(limit_str);
872 config->play_warning = atol(warning_str);
874 config->warning_freq = atol(warnfreq_str);
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;
881 }
else if ( (delta = config->play_warning - config->timelimit) > 0) {
882 int w = config->warning_freq;
899 config->play_warning = 0;
901 config->play_warning -= w * ( 1 + (delta-1)/w );
902 if (config->play_warning < 1)
903 config->play_warning = config->warning_freq = 0;
907 ast_channel_lock(chan);
910 play_to_caller = var ?
ast_true(var) : 1;
913 play_to_callee = var ?
ast_true(var) : 0;
915 if (!play_to_caller && !play_to_callee)
928 config->end_sound = !ast_strlen_zero(var) ?
ast_strdup(var) : NULL;
931 config->start_sound = !ast_strlen_zero(var) ?
ast_strdup(var) : NULL;
933 ast_channel_unlock(chan);
936 calldurationlimit->tv_sec = 0;
937 calldurationlimit->tv_usec = 0;
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);
947 config->timelimit = 0;
948 config->play_warning = 0;
949 config->warning_freq = 0;
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,
""));
962 ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
964 ast_set_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
981 char *tmp_data = NULL;
984 char *opt_args[OPT_ARG_ARRAY_SIZE];
985 struct timeval calldurationlimit = { 0, };
989 int bridge_add_failed;
1004 if (!ast_strlen_zero(args.options)) {
1009 if (!ast_strlen_zero(args.dest_chan)) {
1011 strlen(args.dest_chan));
1013 if (!current_dest_chan) {
1014 ast_verb(4,
"Bridge failed because channel '%s' does not exist\n",
1015 args.dest_chan ?:
"");
1021 if (chan == current_dest_chan) {
1023 ast_log(LOG_WARNING,
"Unable to bridge channel %s with itself\n", ast_channel_name(chan));
1028 if (ast_test_flag(&opts, OPT_DURATION_LIMIT)
1029 && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])
1030 &&
ast_bridge_timelimit(chan, &bconfig, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit)) {
1034 if (ast_test_flag(&opts, OPT_CALLEE_TRANSFER))
1035 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_REDIRECT);
1036 if (ast_test_flag(&opts, OPT_CALLER_TRANSFER))
1037 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_REDIRECT);
1038 if (ast_test_flag(&opts, OPT_CALLEE_HANGUP))
1039 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_DISCONNECT);
1040 if (ast_test_flag(&opts, OPT_CALLER_HANGUP))
1041 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_DISCONNECT);
1042 if (ast_test_flag(&opts, OPT_CALLEE_MONITOR))
1043 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_AUTOMON);
1044 if (ast_test_flag(&opts, OPT_CALLER_MONITOR))
1045 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_AUTOMON);
1046 if (ast_test_flag(&opts, OPT_CALLEE_PARK))
1047 ast_set_flag(&(bconfig.features_callee), AST_FEATURE_PARKCALL);
1048 if (ast_test_flag(&opts, OPT_CALLER_PARK))
1049 ast_set_flag(&(bconfig.features_caller), AST_FEATURE_PARKCALL);
1050 noanswer = ast_test_flag(&opts, OPT_NOANSWER);
1053 if (ast_test_flag(&opts, OPT_CALLEE_GO_ON)) {
1054 ast_channel_lock(chan);
1057 priority = ast_channel_priority(chan);
1058 ast_channel_unlock(chan);
1060 opt_args[OPT_ARG_CALLEE_GO_ON]);
1061 }
else if (!ast_test_flag(&opts, OPT_CALLEE_KILL)) {
1062 ast_channel_lock(current_dest_chan);
1063 context =
ast_strdupa(ast_channel_context(current_dest_chan));
1064 extension =
ast_strdupa(ast_channel_exten(current_dest_chan));
1065 priority = ast_channel_priority(current_dest_chan);
1066 ast_channel_unlock(current_dest_chan);
1076 if (!peer_features) {
1081 if (pre_bridge_setup(chan, current_dest_chan, &bconfig, &chan_features, peer_features, noanswer)) {
1094 ast_channel_lock(current_dest_chan);
1095 xfer_cfg = ast_get_chan_features_xfer_config(current_dest_chan);
1096 ast_channel_unlock(current_dest_chan);
1098 ast_test_flag(&opts, BRIDGE_OPT_PLAYTONE),
1100 ao2_cleanup(xfer_cfg);
1101 if (bridge_add_failed) {
1122 ast_free((
char *) bconfig.warning_sound);
1123 ast_free((
char *) bconfig.end_sound);
1124 ast_free((
char *) bconfig.start_sound);
1130 static int unload_module(
void)
1132 unload_features_config();
1141 static int load_module(
void)
1145 res = load_features_config();
1152 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER,
"Call Features",
1153 .support_level = AST_MODULE_SUPPORT_CORE,
1154 .load = load_module,
1155 .unload = unload_module,
1156 .reload = reload_features_config,
1158 .requires =
"extconfig",
struct ast_flags peer_features
Main Channel structure associated with a channel.
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Feature configuration relating to transfers.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
int ast_bridge_features_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, enum ast_bridge_hook_remove_flags remove_flags)
Limit the amount of time a channel may stay in the bridge and optionally play warning messages as tim...
static int bridge_exec(struct ast_channel *chan, const char *data)
Bridge channels.
struct ast_stream_topology * answer_topology
Structure that contains features information.
#define ast_channel_unref(c)
Decrease channel reference count.
Support for translation of data formats. translate.c.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
int ast_raw_answer_with_stream_topology(struct ast_channel *chan, struct ast_stream_topology *topology)
Answer a channel passing in a stream topology.
globally accessible channel datastores
Structure for a data store type.
ast_channel_state
ast_channel states
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
struct ast_flags my_features
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
#define ast_strdup(str)
A wrapper for strdup()
Structure for a data store object.
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.
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
int ast_unregister_application(const char *app)
Unregister an application.
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.
void ast_free_ptr(void *ptr)
free() wrapper
void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits)
Destructor function for ast_bridge_features_limits.
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_channel * ast_channel_get_by_name_prefix(const char *name, size_t name_len)
Find a channel by a name prefix.
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
bridge the call and set CDR
Configuration File Parser.
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)
General Asterisk PBX channel definitions.
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.
#define ast_strdupa(s)
duplicate a string in memory from the stack
void ast_bridge_basic_set_flags(struct ast_bridge *bridge, unsigned int flags)
Set feature flags on a basic bridge.
void * end_bridge_callback_data
#define ast_channel_cleanup(c)
Cleanup a channel reference.
structure to hold extensions
In case you didn't read that giant block of text above the mansession_session struct, the mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
#define AST_BRIDGE_DTMF_CHANNEL_1
Report DTMF on channel 1.
#define ast_debug(level,...)
Log a DEBUG message.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Core PBX routines and definitions.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
Structure that contains information about a bridge.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
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.
int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits)
Constructor function for ast_bridge_features_limits.
Structure that contains configuration information for the limits feature.
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
#define ast_calloc(num, len)
A wrapper for calloc()
Module could not be loaded properly.
Prototypes for public functions only of internal interest,.
Basic bridge subclass API.
void ast_autoservice_chan_hangup_peer(struct ast_channel *chan, struct ast_channel *peer)
Put chan into autoservice while hanging up peer.
static int action_bridge(struct mansession *s, const struct message *m)
Bridge channels together.
Structure used to handle boolean flags.
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)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
void(* end_bridge_callback)(void *)
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
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
int ast_bridge_features_ds_append(struct ast_channel *chan, struct ast_flags *flags)
Append basic bridge DTMF feature flags on the channel.
After Bridge Execution API.
Standard Command Line Interface.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
Internal Asterisk hangup causes.
int ast_register_application2(const char *app, int(*execute)(struct ast_channel *, const char *), const char *synopsis, const char *description, void *mod)
Register an application.
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.
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
Say numbers and dates (maybe words one day too)
const ast_string_field xfersound
#define ASTERISK_GPL_KEY
The text the key() function should return.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Asterisk module definitions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
#define AST_BRIDGE_DTMF_CHANNEL_0
Report DTMF on channel 0.
#define AST_APP_ARG(name)
Define an application argument.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.