Asterisk - The Open Source Telephony Project  21.4.1
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"

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
 

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.

Function Documentation

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.

References ast_answer(), 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_ref, ast_channel_unref, ast_channel_yank(), ast_hangup(), ast_moh_stop(), AST_STATE_UP, and RAII_VAR.

Referenced by action_bridge(), and bridge_exec().

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. */
2487  ast_bridge_features_destroy(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);
2494  ast_bridge_unlock(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);
2510  ast_bridge_unlock(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));
2518  ast_bridge_features_destroy(features);
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 }
Main Channel structure associated with a channel.
#define ast_bridge_lock_both(bridge1, bridge2)
Lock two bridges.
Definition: bridge.h:488
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
ast_channel_state
ast_channel states
Definition: channelstate.h:35
struct ast_channel * ast_channel_yank(struct ast_channel *yankee)
Gain control of a channel in the system.
Definition: channel.c:10593
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7776
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10534
Structure that contains information about a bridge.
Definition: bridge.h:349
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
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:481
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3674
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
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
Structure that contains information regarding a channel in a bridge.
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
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.
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2805
#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
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.

References ast_bridge_call_with_flags().

Referenced by dial_exec_full().

686 {
687  return ast_bridge_call_with_flags(chan, peer, config, 0);
688 }
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
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.

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_SOFTHANGUP_ASYNCGOTO, ast_bridge_config::end_bridge_callback, ast_bridge_config::end_bridge_callback_data, and pbx_builtin_getvar_helper().

Referenced by ast_bridge_call().

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);
659  if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO) {
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) {
668  }
669 
670  return res;
671 }
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3653
Structure that contains features information.
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3620
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:944
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3674
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
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
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
Definition: channel.h:1091
Structure that contains information about a bridge.
Definition: bridge.h:349
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
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3683
void(* end_bridge_callback)(void *)
Definition: channel.h:1090
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
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.

References ast_strdup, ast_strdupa, ast_true(), pbx_builtin_getvar_helper(), and S_OR.

Referenced by bridge_exec(), and dial_exec_full().

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 ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
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 ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
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".
Definition: utils.c:2199
#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