Asterisk - The Open Source Telephony Project  GIT-master-a24979a
Data Structures | Enumerations | Functions | Variables
features.c File Reference

Routines implementing call features as call pickup, parking and transfer. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "features_config.h"
#include <pthread.h>
#include <signal.h>
#include <sys/time.h>
#include <netinet/in.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/causes.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/app.h"
#include "asterisk/say.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/manager.h"
#include "asterisk/utils.h"
#include "asterisk/devicestate.h"
#include "asterisk/audiohook.h"
#include "asterisk/global_datastores.h"
#include "asterisk/astobj2.h"
#include "asterisk/test.h"
#include "asterisk/bridge.h"
#include "asterisk/bridge_features.h"
#include "asterisk/bridge_basic.h"
#include "asterisk/bridge_after.h"
#include "asterisk/stasis.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/features_config.h"
#include "asterisk/max_forwards.h"
#include "asterisk/stream.h"
Include dependency graph for features.c:

Go to the source code of this file.

Data Structures

struct  ast_bridge_thread_obj
 
struct  ast_dial_features
 

Enumerations

enum  {
  BRIDGE_OPT_PLAYTONE = (1 << 0) , OPT_CALLEE_HANGUP = (1 << 1) , OPT_CALLER_HANGUP = (1 << 2) , OPT_DURATION_LIMIT = (1 << 3) ,
  OPT_DURATION_STOP = (1 << 4) , OPT_CALLEE_TRANSFER = (1 << 5) , OPT_CALLER_TRANSFER = (1 << 6) , OPT_CALLEE_MONITOR = (1 << 7) ,
  OPT_CALLER_MONITOR = (1 << 8) , OPT_CALLEE_PARK = (1 << 9) , OPT_CALLER_PARK = (1 << 10) , OPT_CALLEE_KILL = (1 << 11) ,
  OPT_CALLEE_GO_ON = (1 << 12)
}
 
enum  { OPT_ARG_DURATION_LIMIT = 0 , OPT_ARG_DURATION_STOP , OPT_ARG_CALLEE_GO_ON , OPT_ARG_ARRAY_SIZE }
 
enum  feature_interpret_op { FEATURE_INTERPRET_DETECT , FEATURE_INTERPRET_DO , FEATURE_INTERPRET_CHECK }
 
enum  play_tone_action { PLAYTONE_NONE = 0 , PLAYTONE_CHANNEL1 = (1 << 0) , PLAYTONE_CHANNEL2 = (1 << 1) , PLAYTONE_BOTH = PLAYTONE_CHANNEL1 | PLAYTONE_CHANNEL2 }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int action_bridge (struct mansession *s, const struct message *m)
 Bridge channels together. More...
 
static int add_features_datastore (struct ast_channel *chan, const struct ast_flags *my_features, const struct ast_flags *peer_features)
 
static void add_features_datastores (struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
 
int ast_bridge_call (struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
 bridge the call and set CDR 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...
 
void ast_channel_log (char *title, struct ast_channel *chan)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void bridge_check_monitor (struct ast_channel *chan, struct ast_channel *peer)
 
static void bridge_config_set_limits (struct ast_bridge_config *config, struct ast_bridge_features_limits *caller_limits, struct ast_bridge_features_limits *callee_limits)
 
static void bridge_config_set_limits_warning_values (struct ast_bridge_config *config, struct ast_bridge_features_limits *limits)
 
static int bridge_exec (struct ast_channel *chan, const char *data)
 Bridge channels. More...
 
static void bridge_failed_peer_goto (struct ast_channel *chan, struct ast_channel *peer)
 
static void * dial_features_duplicate (void *data)
 
static int load_module (void)
 
static enum play_tone_action parse_playtone (const char *playtone_val)
 
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)
 
static void set_bridge_features_on_config (struct ast_bridge_config *config, const char *features)
 
static void set_config_flags (struct ast_channel *chan, struct ast_bridge_config *config)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Call Features" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_features_config, .load_pri = AST_MODPRI_CORE, .requires = "extconfig", }
 
static char * app_bridge = "Bridge"
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static const struct ast_app_option bridge_exec_options [128] = { [ 'p' ] = { .flag = BRIDGE_OPT_PLAYTONE }, [ 'F' ] = { .flag = OPT_CALLEE_GO_ON , .arg_index = OPT_ARG_CALLEE_GO_ON + 1 }, [ 'h' ] = { .flag = OPT_CALLEE_HANGUP }, [ 'H' ] = { .flag = OPT_CALLER_HANGUP }, [ 'k' ] = { .flag = OPT_CALLEE_PARK }, [ 'K' ] = { .flag = OPT_CALLER_PARK }, [ 'L' ] = { .flag = OPT_DURATION_LIMIT , .arg_index = OPT_ARG_DURATION_LIMIT + 1 }, [ 'S' ] = { .flag = OPT_DURATION_STOP , .arg_index = OPT_ARG_DURATION_STOP + 1 }, [ 't' ] = { .flag = OPT_CALLEE_TRANSFER }, [ 'T' ] = { .flag = OPT_CALLER_TRANSFER }, [ 'w' ] = { .flag = OPT_CALLEE_MONITOR }, [ 'W' ] = { .flag = OPT_CALLER_MONITOR }, [ 'x' ] = { .flag = OPT_CALLEE_KILL }, }
 
static const struct ast_datastore_info dial_features_info
 

Detailed Description

Routines implementing call features as call pickup, parking and transfer.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file features.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
BRIDGE_OPT_PLAYTONE 
OPT_CALLEE_HANGUP 
OPT_CALLER_HANGUP 
OPT_DURATION_LIMIT 
OPT_DURATION_STOP 
OPT_CALLEE_TRANSFER 
OPT_CALLER_TRANSFER 
OPT_CALLEE_MONITOR 
OPT_CALLER_MONITOR 
OPT_CALLEE_PARK 
OPT_CALLER_PARK 
OPT_CALLEE_KILL 
OPT_CALLEE_GO_ON 

Definition at line 842 of file features.c.

842  {
843  BRIDGE_OPT_PLAYTONE = (1 << 0),
844  OPT_CALLEE_HANGUP = (1 << 1),
845  OPT_CALLER_HANGUP = (1 << 2),
846  OPT_DURATION_LIMIT = (1 << 3),
847  OPT_DURATION_STOP = (1 << 4),
848  OPT_CALLEE_TRANSFER = (1 << 5),
849  OPT_CALLER_TRANSFER = (1 << 6),
850  OPT_CALLEE_MONITOR = (1 << 7),
851  OPT_CALLER_MONITOR = (1 << 8),
852  OPT_CALLEE_PARK = (1 << 9),
853  OPT_CALLER_PARK = (1 << 10),
854  OPT_CALLEE_KILL = (1 << 11),
855  OPT_CALLEE_GO_ON = (1 << 12),
856 };
@ OPT_CALLEE_PARK
Definition: features.c:852
@ OPT_DURATION_LIMIT
Definition: features.c:846
@ OPT_DURATION_STOP
Definition: features.c:847
@ OPT_CALLEE_TRANSFER
Definition: features.c:848
@ OPT_CALLEE_GO_ON
Definition: features.c:855
@ OPT_CALLER_PARK
Definition: features.c:853
@ OPT_CALLER_MONITOR
Definition: features.c:851
@ OPT_CALLEE_MONITOR
Definition: features.c:850
@ OPT_CALLER_HANGUP
Definition: features.c:845
@ OPT_CALLEE_HANGUP
Definition: features.c:844
@ BRIDGE_OPT_PLAYTONE
Definition: features.c:843
@ OPT_CALLEE_KILL
Definition: features.c:854
@ OPT_CALLER_TRANSFER
Definition: features.c:849

◆ anonymous enum

anonymous enum
Enumerator
OPT_ARG_DURATION_LIMIT 
OPT_ARG_DURATION_STOP 
OPT_ARG_CALLEE_GO_ON 
OPT_ARG_ARRAY_SIZE 

Definition at line 858 of file features.c.

858  {
862  /* note: this entry _MUST_ be the last one in the enum */
864 };
@ OPT_ARG_CALLEE_GO_ON
Definition: features.c:861
@ OPT_ARG_DURATION_STOP
Definition: features.c:860
@ OPT_ARG_DURATION_LIMIT
Definition: features.c:859
@ OPT_ARG_ARRAY_SIZE
Definition: features.c:863

◆ feature_interpret_op

Enumerator
FEATURE_INTERPRET_DETECT 
FEATURE_INTERPRET_DO 
FEATURE_INTERPRET_CHECK 

Definition at line 249 of file features.c.

249  {
250  FEATURE_INTERPRET_DETECT, /* Used by ast_feature_detect */
251  FEATURE_INTERPRET_DO, /* Used by feature_interpret */
252  FEATURE_INTERPRET_CHECK, /* Used by feature_check */
feature_interpret_op
Definition: features.c:249
@ FEATURE_INTERPRET_CHECK
Definition: features.c:252
@ FEATURE_INTERPRET_DO
Definition: features.c:251
@ FEATURE_INTERPRET_DETECT
Definition: features.c:250

◆ play_tone_action

Enumerator
PLAYTONE_NONE 
PLAYTONE_CHANNEL1 
PLAYTONE_CHANNEL2 
PLAYTONE_BOTH 

Definition at line 717 of file features.c.

717  {
718  PLAYTONE_NONE = 0,
719  PLAYTONE_CHANNEL1 = (1 << 0),
720  PLAYTONE_CHANNEL2 = (1 << 1),
722 };
@ PLAYTONE_CHANNEL1
Definition: features.c:719
@ PLAYTONE_CHANNEL2
Definition: features.c:720
@ PLAYTONE_NONE
Definition: features.c:718
@ PLAYTONE_BOTH
Definition: features.c:721

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1182 of file features.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1182 of file features.c.

◆ action_bridge()

static int action_bridge ( struct mansession s,
const struct message m 
)
static

Bridge channels together.

Parameters
s
mMake sure valid channels were specified, send errors if any of the channels could not be found/locked, answer channels if needed, create the placeholder channels and grab the other channels make the channels compatible, send error if we fail doing so setup the bridge thread object and start the bridge.
Return values
0

Definition at line 753 of file features.c.

754 {
755  const char *channela = astman_get_header(m, "Channel1");
756  const char *channelb = astman_get_header(m, "Channel2");
758  RAII_VAR(struct ast_channel *, chana, NULL, ao2_cleanup);
759  RAII_VAR(struct ast_channel *, chanb, NULL, ao2_cleanup);
760  const char *chana_exten;
761  const char *chana_context;
762  int chana_priority;
763  const char *chanb_exten;
764  const char *chanb_context;
765  int chanb_priority;
766  struct ast_bridge *bridge;
767  char buf[256];
768  RAII_VAR(struct ast_features_xfer_config *, xfer_cfg_a, NULL, ao2_cleanup);
769  RAII_VAR(struct ast_features_xfer_config *, xfer_cfg_b, NULL, ao2_cleanup);
770 
771  /* make sure valid channels were specified */
772  if (ast_strlen_zero(channela) || ast_strlen_zero(channelb)) {
773  astman_send_error(s, m, "Missing channel parameter in request");
774  return 0;
775  }
776 
777  ast_debug(1, "Performing Bridge action on %s and %s\n", channela, channelb);
778 
779  /* Start with chana */
780  chana = ast_channel_get_by_name_prefix(channela, strlen(channela));
781  if (!chana) {
782  snprintf(buf, sizeof(buf), "Channel1 does not exist: %s", channela);
783  astman_send_error(s, m, buf);
784  return 0;
785  }
786  ast_channel_lock(chana);
787  xfer_cfg_a = ast_get_chan_features_xfer_config(chana);
788  chana_exten = ast_strdupa(ast_channel_exten(chana));
789  chana_context = ast_strdupa(ast_channel_context(chana));
790  chana_priority = ast_channel_priority(chana);
792  chana_priority++;
793  }
794  ast_channel_unlock(chana);
795 
796  chanb = ast_channel_get_by_name_prefix(channelb, strlen(channelb));
797  if (!chanb) {
798  snprintf(buf, sizeof(buf), "Channel2 does not exist: %s", channelb);
799  astman_send_error(s, m, buf);
800  return 0;
801  }
802  ast_channel_lock(chanb);
803  xfer_cfg_b = ast_get_chan_features_xfer_config(chanb);
804  chanb_exten = ast_strdupa(ast_channel_exten(chanb));
805  chanb_context = ast_strdupa(ast_channel_context(chanb));
806  chanb_priority = ast_channel_priority(chanb);
808  chanb_priority++;
809  }
810  ast_channel_unlock(chanb);
811 
812  bridge = ast_bridge_basic_new();
813  if (!bridge) {
814  astman_send_error(s, m, "Unable to create bridge\n");
815  return 0;
816  }
817 
818  ast_bridge_set_after_goto(chana, chana_context, chana_exten, chana_priority);
819  if (ast_bridge_add_channel(bridge, chana, NULL, playtone & PLAYTONE_CHANNEL1, xfer_cfg_a ? xfer_cfg_a->xfersound : NULL)) {
820  snprintf(buf, sizeof(buf), "Unable to add Channel1 to bridge: %s", ast_channel_name(chana));
821  astman_send_error(s, m, buf);
822  ast_bridge_destroy(bridge, 0);
823  return 0;
824  }
825 
826  ast_bridge_set_after_goto(chanb, chanb_context, chanb_exten, chanb_priority);
827  if (ast_bridge_add_channel(bridge, chanb, NULL, playtone & PLAYTONE_CHANNEL2, xfer_cfg_b ? xfer_cfg_b->xfersound : NULL)) {
828  snprintf(buf, sizeof(buf), "Unable to add Channel2 to bridge: %s", ast_channel_name(chanb));
829  astman_send_error(s, m, buf);
830  ast_bridge_destroy(bridge, 0);
831  return 0;
832  }
833 
834  astman_send_ack(s, m, "Channels have been bridged");
835  ao2_cleanup(bridge);
836 
837  return 0;
838 }
static int playtone(struct ast_channel *chan, int tone, int len)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:944
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.
Definition: bridge_after.c:612
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
#define ast_channel_lock(chan)
Definition: channel.h:2922
const char * ast_channel_context(const struct ast_channel *chan)
int ast_channel_priority(const struct ast_channel *chan)
struct ast_channel * ast_channel_get_by_name_prefix(const char *name, size_t name_len)
Find a channel by a name prefix.
Definition: channel.c:1428
const char * ast_channel_name(const struct ast_channel *chan)
@ AST_FLAG_IN_AUTOLOOP
Definition: channel.h:997
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2923
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
play_tone_action
Definition: features.c:717
static enum play_tone_action parse_playtone(const char *playtone_val)
Definition: features.c:724
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.
Definition: bridge.c:2471
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3166
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3198
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:2827
struct ast_features_xfer_config * ast_get_chan_features_xfer_config(struct ast_channel *chan)
Get the transfer configuration options for a channel.
#define ast_debug(level,...)
Log a DEBUG message.
#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 about a bridge.
Definition: bridge.h:349
Main Channel structure associated with a channel.
Feature configuration relating to transfers.
#define ast_test_flag(p, flag)
Definition: utils.h:63
#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:936

References ao2_cleanup, ast_bridge_add_channel(), ast_bridge_basic_new(), ast_bridge_destroy(), ast_bridge_set_after_goto(), ast_channel_context(), ast_channel_exten(), ast_channel_flags(), ast_channel_get_by_name_prefix(), ast_channel_lock, ast_channel_name(), ast_channel_priority(), ast_channel_unlock, ast_debug, AST_FLAG_IN_AUTOLOOP, ast_get_chan_features_xfer_config(), ast_strdupa, ast_strlen_zero(), ast_test_flag, astman_get_header(), astman_send_ack(), astman_send_error(), buf, NULL, parse_playtone(), playtone(), PLAYTONE_CHANNEL1, PLAYTONE_CHANNEL2, and RAII_VAR.

◆ add_features_datastore()

static int add_features_datastore ( struct ast_channel chan,
const struct ast_flags my_features,
const struct ast_flags peer_features 
)
static

Definition at line 291 of file features.c.

292 {
293  struct ast_datastore *datastore;
294  struct ast_dial_features *dialfeatures;
295 
296  ast_channel_lock(chan);
298  ast_channel_unlock(chan);
299  if (datastore) {
300  /* Already exists. */
301  return 1;
302  }
303 
304  /* Create a new datastore with specified feature flags. */
306  if (!datastore) {
307  ast_log(LOG_WARNING, "Unable to create channel features datastore.\n");
308  return 0;
309  }
310  dialfeatures = ast_calloc(1, sizeof(*dialfeatures));
311  if (!dialfeatures) {
312  ast_log(LOG_WARNING, "Unable to allocate memory for feature flags.\n");
313  ast_datastore_free(datastore);
314  return 0;
315  }
319  datastore->data = dialfeatures;
320  ast_channel_lock(chan);
321  ast_channel_datastore_add(chan, datastore);
322  ast_channel_unlock(chan);
323  return 0;
324 }
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2384
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:192
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:2398
#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
static const struct ast_datastore_info dial_features_info
Definition: features.c:275
#define LOG_WARNING
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
unsigned int inheritance
Definition: datastore.h:69
struct ast_flags peer_features
Definition: features.c:259
struct ast_flags my_features
Definition: features.c:257
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
#define AST_FLAGS_ALL
Definition: utils.h:196

References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_copy_flags, ast_datastore_alloc, ast_datastore_free(), AST_FLAGS_ALL, ast_log, ast_datastore::data, DATASTORE_INHERIT_FOREVER, dial_features_info, ast_datastore::inheritance, LOG_WARNING, ast_dial_features::my_features, NULL, and ast_dial_features::peer_features.

Referenced by add_features_datastores().

◆ add_features_datastores()

static void add_features_datastores ( struct ast_channel caller,
struct ast_channel callee,
struct ast_bridge_config config 
)
static

Definition at line 423 of file features.c.

424 {
425  if (add_features_datastore(caller, &config->features_caller, &config->features_callee)) {
426  /*
427  * If we don't return here, then when we do a builtin_atxfer we
428  * will copy the disconnect flags over from the atxfer to the
429  * callee (Party C).
430  */
431  return;
432  }
433 
434  add_features_datastore(callee, &config->features_callee, &config->features_caller);
435 }
static const char config[]
Definition: chan_ooh323.c:111
static int add_features_datastore(struct ast_channel *chan, const struct ast_flags *my_features, const struct ast_flags *peer_features)
Definition: features.c:291

References add_features_datastore(), and config.

Referenced by pre_bridge_setup().

◆ ast_bridge_call()

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

bridge the call and set CDR

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

713 {
714  return ast_bridge_call_with_flags(chan, peer, config, 0);
715 }
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:629

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

630 {
631  int res;
632  struct ast_bridge *bridge;
633  struct ast_bridge_features chan_features;
634  struct ast_bridge_features *peer_features;
635  SCOPE_TRACE(1, "%s Peer: %s\n", ast_channel_name(chan), ast_channel_name(peer));
636 
637  /* Setup features. */
638  res = ast_bridge_features_init(&chan_features);
639  peer_features = ast_bridge_features_new();
640  if (res || !peer_features) {
641  ast_bridge_features_destroy(peer_features);
642  ast_bridge_features_cleanup(&chan_features);
643  bridge_failed_peer_goto(chan, peer);
644  return -1;
645  }
646 
647  if (pre_bridge_setup(chan, peer, config, &chan_features, peer_features)) {
648  ast_bridge_features_destroy(peer_features);
649  ast_bridge_features_cleanup(&chan_features);
650  bridge_failed_peer_goto(chan, peer);
651  return -1;
652  }
653 
654  /* Create bridge */
655  bridge = ast_bridge_basic_new();
656  if (!bridge) {
657  ast_bridge_features_destroy(peer_features);
658  ast_bridge_features_cleanup(&chan_features);
659  bridge_failed_peer_goto(chan, peer);
660  return -1;
661  }
662 
663  ast_bridge_basic_set_flags(bridge, flags);
664 
665  /* Put peer into the bridge */
666  if (ast_bridge_impart(bridge, peer, NULL, peer_features,
668  ast_bridge_destroy(bridge, 0);
669  ast_bridge_features_cleanup(&chan_features);
670  bridge_failed_peer_goto(chan, peer);
671  return -1;
672  }
673 
674  /* Join bridge */
675  ast_bridge_join(bridge, chan, NULL, &chan_features, NULL,
677 
678  /*
679  * If the bridge was broken for a hangup that isn't real, then
680  * don't run the h extension, because the channel isn't really
681  * hung up. This should really only happen with
682  * AST_SOFTHANGUP_ASYNCGOTO.
683  */
684  res = -1;
685  ast_channel_lock(chan);
687  res = 0;
688  }
689  ast_channel_unlock(chan);
690 
691  ast_bridge_features_cleanup(&chan_features);
692 
693  if (res && config->end_bridge_callback) {
694  config->end_bridge_callback(config->end_bridge_callback_data);
695  }
696 
697  return res;
698 }
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_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_IMPART_CHAN_INDEPENDENT
Definition: bridge.h:590
@ 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.
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3620
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3653
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3683
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)
Definition: features.c:532
static void bridge_failed_peer_goto(struct ast_channel *chan, struct ast_channel *peer)
Definition: features.c:524
#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, bridge_failed_peer_goto(), config, NULL, pre_bridge_setup(), and SCOPE_TRACE.

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

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

Referenced by bridge_exec(), and dial_exec_full().

◆ ast_channel_log()

void ast_channel_log ( char *  title,
struct ast_channel chan 
)

Definition at line 363 of file features.c.

364 {
365  ast_log(LOG_NOTICE, "______ %s (%lx)______\n", title, (unsigned long) chan);
366  ast_log(LOG_NOTICE, "CHAN: name: %s; appl: %s; data: %s; contxt: %s; exten: %s; pri: %d;\n",
369  ast_log(LOG_NOTICE, "CHAN: acctcode: %s; dialcontext: %s; amaflags: %x; maccontxt: %s; macexten: %s; macpri: %d;\n",
372  ast_log(LOG_NOTICE, "CHAN: masq: %p; masqr: %p; uniqueID: %s; linkedID:%s\n",
373  ast_channel_masq(chan), ast_channel_masqr(chan),
375  if (ast_channel_masqr(chan)) {
376  ast_log(LOG_NOTICE, "CHAN: masquerading as: %s; cdr: %p;\n",
378  }
379 
380  ast_log(LOG_NOTICE, "===== done ====\n");
381 }
const char * ast_channel_accountcode(const struct ast_channel *chan)
int ast_channel_macropriority(const struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
const char * ast_channel_data(const struct ast_channel *chan)
enum ama_flags ast_channel_amaflags(const struct ast_channel *chan)
struct ast_channel * ast_channel_masqr(const struct ast_channel *chan)
struct ast_channel * ast_channel_masq(const struct ast_channel *chan)
const char * ast_channel_linkedid(const struct ast_channel *chan)
const char * ast_channel_dialcontext(const struct ast_channel *chan)
struct ast_cdr * ast_channel_cdr(const struct ast_channel *chan)
const char * ast_channel_appl(const struct ast_channel *chan)
const char * ast_channel_macroexten(const struct ast_channel *chan)
const char * ast_channel_macrocontext(const struct ast_channel *chan)
#define LOG_NOTICE

References ast_channel_accountcode(), ast_channel_amaflags(), ast_channel_appl(), ast_channel_cdr(), ast_channel_context(), ast_channel_data(), ast_channel_dialcontext(), ast_channel_exten(), ast_channel_linkedid(), ast_channel_macrocontext(), ast_channel_macroexten(), ast_channel_macropriority(), ast_channel_masq(), ast_channel_masqr(), ast_channel_name(), ast_channel_priority(), ast_channel_uniqueid(), ast_log, and LOG_NOTICE.

Referenced by pre_bridge_setup().

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 1182 of file features.c.

◆ bridge_check_monitor()

static void bridge_check_monitor ( struct ast_channel chan,
struct ast_channel peer 
)
static

Definition at line 484 of file features.c.

485 {
486  const char *value;
487  const char *monitor_args = NULL;
488  struct ast_channel *monitor_chan = NULL;
489 
490  ast_channel_lock(chan);
491  value = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR");
492  if (!ast_strlen_zero(value)) {
493  monitor_args = ast_strdupa(value);
494  monitor_chan = chan;
495  }
496  ast_channel_unlock(chan);
497  if (!monitor_chan) {
498  ast_channel_lock(peer);
499  value = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR");
500  if (!ast_strlen_zero(value)) {
501  monitor_args = ast_strdupa(value);
502  monitor_chan = peer;
503  }
504  ast_channel_unlock(peer);
505  }
506  if (monitor_chan) {
507  struct ast_app *monitor_app;
508 
509  monitor_app = pbx_findapp("Monitor");
510  if (monitor_app) {
511  pbx_exec(monitor_chan, monitor_app, monitor_args);
512  }
513  }
514 }
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: ael_main.c:165
ast_app: A registered application
Definition: pbx_app.c:45
int value
Definition: syslog.c:37

References ast_channel_lock, ast_channel_unlock, ast_strdupa, ast_strlen_zero(), NULL, pbx_builtin_getvar_helper(), pbx_exec(), pbx_findapp(), and value.

Referenced by pre_bridge_setup().

◆ bridge_config_set_limits()

static void bridge_config_set_limits ( struct ast_bridge_config config,
struct ast_bridge_features_limits caller_limits,
struct ast_bridge_features_limits callee_limits 
)
static

Definition at line 462 of file features.c.

463 {
464  if (ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING)) {
466  }
467 
468  if (ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING)) {
470  }
471 
472  caller_limits->duration = config->timelimit;
473  callee_limits->duration = config->timelimit;
474 }
static void bridge_config_set_limits_warning_values(struct ast_bridge_config *config, struct ast_bridge_features_limits *limits)
Definition: features.c:437

References AST_FEATURE_PLAY_WARNING, ast_test_flag, bridge_config_set_limits_warning_values(), config, and ast_bridge_features_limits::duration.

Referenced by pre_bridge_setup().

◆ bridge_config_set_limits_warning_values()

static void bridge_config_set_limits_warning_values ( struct ast_bridge_config config,
struct ast_bridge_features_limits limits 
)
static

Definition at line 437 of file features.c.

438 {
439  if (config->end_sound) {
440  ast_string_field_set(limits, duration_sound, config->end_sound);
441  }
442 
443  if (config->warning_sound) {
444  ast_string_field_set(limits, warning_sound, config->warning_sound);
445  }
446 
447  if (config->start_sound) {
448  ast_string_field_set(limits, connect_sound, config->start_sound);
449  }
450 
451  limits->frequency = config->warning_freq;
452  limits->warning = config->play_warning;
453 }
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521

References ast_string_field_set, and config.

Referenced by bridge_config_set_limits().

◆ bridge_exec()

static int bridge_exec ( struct ast_channel chan,
const char *  data 
)
static

Bridge channels.

Parameters
chan
datachannel to bridge with.

Split data, check we aren't bridging with ourself, check valid channel, answer call if not already, check compatible channels, setup bridge config now bridge call, if transferred party hangs up return to PBX extension.

Definition at line 1003 of file features.c.

1004 {
1005  struct ast_channel *current_dest_chan = NULL;
1006  char *tmp_data = NULL;
1007  struct ast_flags opts = { 0, };
1008  struct ast_bridge_config bconfig = { { 0, }, };
1009  char *opt_args[OPT_ARG_ARRAY_SIZE];
1010  struct timeval calldurationlimit = { 0, };
1011  const char *context;
1012  const char *extension;
1013  int priority;
1014  int bridge_add_failed;
1015  int res = -1;
1016  struct ast_bridge_features chan_features;
1017  struct ast_bridge_features *peer_features;
1018  struct ast_bridge *bridge;
1019  struct ast_features_xfer_config *xfer_cfg;
1020 
1022  AST_APP_ARG(dest_chan);
1024  );
1025 
1026  tmp_data = ast_strdupa(data ?: "");
1027  AST_STANDARD_APP_ARGS(args, tmp_data);
1028  if (!ast_strlen_zero(args.options)) {
1029  ast_app_parse_options(bridge_exec_options, &opts, opt_args, args.options);
1030  }
1031 
1032  /* make sure we have a valid end point */
1033  if (!ast_strlen_zero(args.dest_chan)) {
1034  current_dest_chan = ast_channel_get_by_name_prefix(args.dest_chan,
1035  strlen(args.dest_chan));
1036  }
1037  if (!current_dest_chan) {
1038  ast_verb(4, "Bridge failed because channel '%s' does not exist\n",
1039  args.dest_chan ?: "");
1040  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "NONEXISTENT");
1041  return 0;
1042  }
1043 
1044  /* avoid bridge with ourselves */
1045  if (chan == current_dest_chan) {
1046  ast_channel_unref(current_dest_chan);
1047  ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", ast_channel_name(chan));
1048  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "LOOP");
1049  return 0;
1050  }
1051 
1052  if (ast_test_flag(&opts, OPT_DURATION_LIMIT)
1054  && ast_bridge_timelimit(chan, &bconfig, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit)) {
1055  goto done;
1056  }
1057 
1058  if (ast_test_flag(&opts, OPT_CALLEE_TRANSFER))
1060  if (ast_test_flag(&opts, OPT_CALLER_TRANSFER))
1062  if (ast_test_flag(&opts, OPT_CALLEE_HANGUP))
1064  if (ast_test_flag(&opts, OPT_CALLER_HANGUP))
1066  if (ast_test_flag(&opts, OPT_CALLEE_MONITOR))
1068  if (ast_test_flag(&opts, OPT_CALLER_MONITOR))
1070  if (ast_test_flag(&opts, OPT_CALLEE_PARK))
1072  if (ast_test_flag(&opts, OPT_CALLER_PARK))
1074 
1075  /* Setup after bridge goto location. */
1076  if (ast_test_flag(&opts, OPT_CALLEE_GO_ON)) {
1077  ast_channel_lock(chan);
1081  ast_channel_unlock(chan);
1083  opt_args[OPT_ARG_CALLEE_GO_ON]);
1084  } else if (!ast_test_flag(&opts, OPT_CALLEE_KILL)) {
1085  ast_channel_lock(current_dest_chan);
1086  context = ast_strdupa(ast_channel_context(current_dest_chan));
1087  extension = ast_strdupa(ast_channel_exten(current_dest_chan));
1088  priority = ast_channel_priority(current_dest_chan);
1089  ast_channel_unlock(current_dest_chan);
1090  ast_bridge_set_after_go_on(current_dest_chan, context, extension, priority, NULL);
1091  }
1092 
1093  if (ast_bridge_features_init(&chan_features)) {
1094  ast_bridge_features_cleanup(&chan_features);
1095  goto done;
1096  }
1097 
1098  peer_features = ast_bridge_features_new();
1099  if (!peer_features) {
1100  ast_bridge_features_cleanup(&chan_features);
1101  goto done;
1102  }
1103 
1104  if (pre_bridge_setup(chan, current_dest_chan, &bconfig, &chan_features, peer_features)) {
1105  ast_bridge_features_destroy(peer_features);
1106  ast_bridge_features_cleanup(&chan_features);
1107  goto done;
1108  }
1109 
1110  bridge = ast_bridge_basic_new();
1111  if (!bridge) {
1112  ast_bridge_features_destroy(peer_features);
1113  ast_bridge_features_cleanup(&chan_features);
1114  goto done;
1115  }
1116 
1117  ast_channel_lock(current_dest_chan);
1118  xfer_cfg = ast_get_chan_features_xfer_config(current_dest_chan);
1119  ast_channel_unlock(current_dest_chan);
1120  bridge_add_failed = ast_bridge_add_channel(bridge, current_dest_chan, peer_features,
1122  xfer_cfg ? xfer_cfg->xfersound : NULL);
1123  ao2_cleanup(xfer_cfg);
1124  if (bridge_add_failed) {
1125  ast_bridge_features_cleanup(&chan_features);
1126  ast_bridge_destroy(bridge, 0);
1127  goto done;
1128  }
1129 
1130  /* Don't keep the channel ref in case it was not already in a bridge. */
1131  current_dest_chan = ast_channel_unref(current_dest_chan);
1132 
1133  res = ast_bridge_join(bridge, chan, NULL, &chan_features, NULL,
1135 
1136  ast_bridge_features_cleanup(&chan_features);
1137 
1138 done:
1139  if (res == -1) {
1140  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "FAILURE");
1141  } else {
1142  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "SUCCESS");
1143  }
1144 
1145  ast_free((char *) bconfig.warning_sound);
1146  ast_free((char *) bconfig.end_sound);
1147  ast_free((char *) bconfig.start_sound);
1148 
1149  ast_channel_cleanup(current_dest_chan);
1150  return 0;
1151 }
#define ast_free(a)
Definition: astmm.h:180
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.
Definition: bridge_after.c:622
static int priority
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:120
@ AST_FEATURE_REDIRECT
Definition: channel.h:1064
@ AST_FEATURE_PARKCALL
Definition: channel.h:1068
@ AST_FEATURE_AUTOMON
Definition: channel.h:1067
@ AST_FEATURE_DISCONNECT
Definition: channel.h:1065
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
static const struct ast_app_option bridge_exec_options[128]
Definition: features.c:880
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,...
Definition: features.c:882
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
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.
Definition: main/app.c:3126
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.
bridge configuration
Definition: channel.h:1076
const char * end_sound
Definition: channel.h:1087
const char * warning_sound
Definition: channel.h:1086
struct ast_flags features_callee
Definition: channel.h:1078
struct ast_flags features_caller
Definition: channel.h:1077
const char * start_sound
Definition: channel.h:1088
Structure used to handle boolean flags.
Definition: utils.h:199
structure to hold extensions
int done
Definition: test_amihooks.c:48
const char * args
static struct test_options options

References ao2_cleanup, args, AST_APP_ARG, ast_app_parse_options(), ast_bridge_add_channel(), ast_bridge_basic_new(), ast_bridge_destroy(), ast_bridge_features_cleanup(), ast_bridge_features_destroy(), ast_bridge_features_init(), ast_bridge_features_new(), ast_bridge_join(), AST_BRIDGE_JOIN_PASS_REFERENCE, ast_bridge_set_after_go_on(), ast_bridge_timelimit(), ast_channel_cleanup, ast_channel_context(), ast_channel_exten(), ast_channel_get_by_name_prefix(), ast_channel_lock, ast_channel_name(), ast_channel_priority(), ast_channel_unlock, ast_channel_unref, AST_DECLARE_APP_ARGS, AST_FEATURE_AUTOMON, AST_FEATURE_DISCONNECT, AST_FEATURE_PARKCALL, AST_FEATURE_REDIRECT, ast_free, ast_get_chan_features_xfer_config(), ast_log, ast_set_flag, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_verb, bridge_exec_options, BRIDGE_OPT_PLAYTONE, context, done, ast_bridge_config::end_sound, ast_bridge_config::features_callee, ast_bridge_config::features_caller, LOG_WARNING, NULL, OPT_ARG_ARRAY_SIZE, OPT_ARG_CALLEE_GO_ON, OPT_ARG_DURATION_LIMIT, OPT_CALLEE_GO_ON, OPT_CALLEE_HANGUP, OPT_CALLEE_KILL, OPT_CALLEE_MONITOR, OPT_CALLEE_PARK, OPT_CALLEE_TRANSFER, OPT_CALLER_HANGUP, OPT_CALLER_MONITOR, OPT_CALLER_PARK, OPT_CALLER_TRANSFER, OPT_DURATION_LIMIT, options, pbx_builtin_setvar_helper(), pre_bridge_setup(), priority, ast_bridge_config::start_sound, ast_bridge_config::warning_sound, and ast_features_xfer_config::xfersound.

◆ bridge_failed_peer_goto()

static void bridge_failed_peer_goto ( struct ast_channel chan,
struct ast_channel peer 
)
static

Definition at line 524 of file features.c.

525 {
527  || ast_pbx_start(peer)) {
529  }
530 }
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_autoservice_chan_hangup_peer(struct ast_channel *chan, struct ast_channel *peer)
Put chan into autoservice while hanging up peer.
Definition: autoservice.c:342
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4715

References ast_autoservice_chan_hangup_peer(), ast_bridge_setup_after_goto(), and ast_pbx_start().

Referenced by ast_bridge_call_with_flags().

◆ dial_features_duplicate()

static void* dial_features_duplicate ( void *  data)
static

Definition at line 262 of file features.c.

263 {
264  struct ast_dial_features *df = data, *df_copy;
265 
266  if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
267  return NULL;
268  }
269 
270  memcpy(df_copy, df, sizeof(*df));
271 
272  return df_copy;
273 }

References ast_calloc, and NULL.

◆ load_module()

static int load_module ( void  )
static

Definition at line 1164 of file features.c.

1165 {
1166  int res;
1167 
1168  res = load_features_config();
1171 
1173 }
static char * app_bridge
Definition: features.c:840
static int action_bridge(struct mansession *s, const struct message *m)
Bridge channels together.
Definition: features.c:753
static int bridge_exec(struct ast_channel *chan, const char *data)
Bridge channels.
Definition: features.c:1003
int load_features_config(void)
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:202
#define EVENT_FLAG_CALL
Definition: manager.h:76
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.
Definition: pbx_app.c:103
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
Definition: module.h:102
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70

◆ parse_playtone()

static enum play_tone_action parse_playtone ( const char *  playtone_val)
static

Definition at line 712 of file features.c.

725 {
726  if (ast_strlen_zero(playtone_val) || ast_false(playtone_val)) {
727  return PLAYTONE_NONE;
728  } if (!strcasecmp(playtone_val, "channel1")) {
729  return PLAYTONE_CHANNEL1;
730  } else if (!strcasecmp(playtone_val, "channel2") || ast_true(playtone_val)) {
731  return PLAYTONE_CHANNEL2;
732  } else if (!strcasecmp(playtone_val, "both")) {
733  return PLAYTONE_BOTH;
734  } else {
735  /* Invalid input. Assume none */
736  return PLAYTONE_NONE;
737  }
738 }
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"....
Definition: main/utils.c:2114

Referenced by action_bridge().

◆ pre_bridge_setup()

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 
)
static

Definition at line 532 of file features.c.

534 {
535  int res;
536  SCOPE_TRACE(1, "%s Peer: %s\n", ast_channel_name(chan), ast_channel_name(peer));
537 
539  add_features_datastores(chan, peer, config);
540 
541  /*
542  * This is an interesting case. One example is if a ringing
543  * channel gets redirected to an extension that picks up a
544  * parked call. This will make sure that the call taken out of
545  * parking gets told that the channel it just got bridged to is
546  * still ringing.
547  */
551  }
552 
553  bridge_check_monitor(chan, peer);
554 
555  set_config_flags(chan, config);
556 
557  /* Answer if need be */
558 
559  res = 0;
560 
561  if (ast_channel_state(chan) != AST_STATE_UP) {
562  res = ast_raw_answer_with_stream_topology(chan, config->answer_topology);
563  if (res != 0) {
564  return -1;
565  }
566  }
567 
568 
569 #ifdef FOR_DEBUG
570  /* show the two channels and cdrs involved in the bridge for debug & devel purposes */
571  ast_channel_log("Pre-bridge CHAN Channel info", chan);
572  ast_channel_log("Pre-bridge PEER Channel info", peer);
573 #endif
574 
575  res = 0;
576  ast_channel_lock(chan);
578  res |= ast_bridge_features_ds_append(chan, &config->features_caller);
579  ast_channel_unlock(chan);
580  ast_channel_lock(peer);
582  res |= ast_bridge_features_ds_append(peer, &config->features_callee);
583  ast_channel_unlock(peer);
584 
585  if (res) {
586  return -1;
587  }
588 
589  if (config->timelimit) {
590  struct ast_bridge_features_limits call_duration_limits_chan;
591  struct ast_bridge_features_limits call_duration_limits_peer;
592  int abandon_call = 0; /* TRUE if set limits fails so we can abandon the call. */
593 
594  if (ast_bridge_features_limits_construct(&call_duration_limits_chan)) {
595  ast_log(LOG_ERROR, "Could not construct caller duration limits. Bridge canceled.\n");
596 
597  return -1;
598  }
599 
600  if (ast_bridge_features_limits_construct(&call_duration_limits_peer)) {
601  ast_log(LOG_ERROR, "Could not construct callee duration limits. Bridge canceled.\n");
602  ast_bridge_features_limits_destroy(&call_duration_limits_chan);
603 
604  return -1;
605  }
606 
607  bridge_config_set_limits(config, &call_duration_limits_chan, &call_duration_limits_peer);
608 
609  if (ast_bridge_features_set_limits(chan_features, &call_duration_limits_chan, 0)) {
610  abandon_call = 1;
611  }
612  if (ast_bridge_features_set_limits(peer_features, &call_duration_limits_peer, 0)) {
613  abandon_call = 1;
614  }
615 
616  /* At this point we are done with the limits structs since they have been copied to the individual feature sets. */
617  ast_bridge_features_limits_destroy(&call_duration_limits_chan);
618  ast_bridge_features_limits_destroy(&call_duration_limits_peer);
619 
620  if (abandon_call) {
621  ast_log(LOG_ERROR, "Could not set duration limits on one or more sides of the call. Bridge canceled.\n");
622  return -1;
623  }
624  }
625 
626  return 0;
627 }
int ast_bridge_features_ds_append(struct ast_channel *chan, struct ast_flags *flags)
Append basic bridge DTMF feature flags on the channel.
Definition: bridge_basic.c:263
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...
Definition: bridge.c:3412
int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits)
Constructor function for ast_bridge_features_limits.
Definition: bridge.c:3396
void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits)
Destructor function for ast_bridge_features_limits.
Definition: bridge.c:3407
int ast_raw_answer_with_stream_topology(struct ast_channel *chan, struct ast_stream_topology *topology)
Answer a channel passing in a stream topology.
Definition: channel.c:2640
int ast_channel_visible_indication(const struct ast_channel *chan)
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4312
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_RINGING
Definition: channelstate.h:41
@ AST_STATE_UP
Definition: channelstate.h:42
void ast_channel_log(char *title, struct ast_channel *chan)
Definition: features.c:363
static void add_features_datastores(struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
Definition: features.c:423
static void bridge_config_set_limits(struct ast_bridge_config *config, struct ast_bridge_features_limits *caller_limits, struct ast_bridge_features_limits *callee_limits)
Definition: features.c:462
static void set_config_flags(struct ast_channel *chan, struct ast_bridge_config *config)
Definition: features.c:334
static void set_bridge_features_on_config(struct ast_bridge_config *config, const char *features)
Definition: features.c:383
static void bridge_check_monitor(struct ast_channel *chan, struct ast_channel *peer)
Definition: features.c:484
@ AST_CONTROL_RINGING
#define LOG_ERROR
int ast_max_forwards_reset(struct ast_channel *chan)
Reset the max forwards on a channel to its starting value.
Definition: max_forwards.c:151
Structure that contains configuration information for the limits feature.

References add_features_datastores(), ast_bridge_features_ds_append(), ast_bridge_features_limits_construct(), ast_bridge_features_limits_destroy(), ast_bridge_features_set_limits(), ast_channel_lock, ast_channel_log(), ast_channel_name(), ast_channel_unlock, ast_channel_visible_indication(), AST_CONTROL_RINGING, ast_indicate(), ast_log, ast_max_forwards_reset(), ast_raw_answer_with_stream_topology(), AST_STATE_RINGING, AST_STATE_UP, bridge_check_monitor(), bridge_config_set_limits(), config, LOG_ERROR, pbx_builtin_getvar_helper(), SCOPE_TRACE, set_bridge_features_on_config(), and set_config_flags().

Referenced by ast_bridge_call_with_flags(), and bridge_exec().

◆ set_bridge_features_on_config()

static void set_bridge_features_on_config ( struct ast_bridge_config config,
const char *  features 
)
static

Definition at line 383 of file features.c.

384 {
385  const char *feature;
386 
387  if (ast_strlen_zero(features)) {
388  return;
389  }
390 
391  for (feature = features; *feature; feature++) {
392  struct ast_flags *party;
393 
394  if (isupper(*feature)) {
395  party = &config->features_caller;
396  } else {
397  party = &config->features_callee;
398  }
399 
400  switch (tolower(*feature)) {
401  case 't' :
403  break;
404  case 'k' :
406  break;
407  case 'h' :
409  break;
410  case 'w' :
412  break;
413  case 'x' :
415  break;
416  default :
417  ast_log(LOG_WARNING, "Skipping unknown feature code '%c'\n", *feature);
418  break;
419  }
420  }
421 }
@ AST_FEATURE_AUTOMIXMON
Definition: channel.h:1069

References AST_FEATURE_AUTOMIXMON, AST_FEATURE_AUTOMON, AST_FEATURE_DISCONNECT, AST_FEATURE_PARKCALL, AST_FEATURE_REDIRECT, ast_log, ast_set_flag, ast_strlen_zero(), config, and LOG_WARNING.

Referenced by pre_bridge_setup().

◆ set_config_flags()

static void set_config_flags ( struct ast_channel chan,
struct ast_bridge_config config 
)
static

Definition at line 334 of file features.c.

335 {
337 
338  if (ast_test_flag(&config->features_caller, AST_FEATURE_DTMF_MASK)) {
340  }
341  if (ast_test_flag(&config->features_callee, AST_FEATURE_DTMF_MASK)) {
343  }
344 
346  RAII_VAR(struct ao2_container *, applicationmap, NULL, ao2_cleanup);
347 
348  ast_channel_lock(chan);
349  applicationmap = ast_get_chan_applicationmap(chan);
350  ast_channel_unlock(chan);
351 
352  if (!applicationmap) {
353  return;
354  }
355 
356  /* If an applicationmap exists for this channel at all, then the channel needs the DTMF flag set */
358  }
359 }
#define AST_BRIDGE_DTMF_CHANNEL_0
Report DTMF on channel 0.
Definition: channel.h:2370
#define AST_BRIDGE_DTMF_CHANNEL_1
Report DTMF on channel 1.
Definition: channel.h:2372
#define AST_FEATURE_DTMF_MASK
Definition: channel.h:1072
struct ao2_container * ast_get_chan_applicationmap(struct ast_channel *chan)
Get the applicationmap for a given channel.
Generic container type.
#define ast_clear_flag(p, flag)
Definition: utils.h:77

References ao2_cleanup, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, ast_channel_lock, ast_channel_unlock, ast_clear_flag, AST_FEATURE_DTMF_MASK, AST_FLAGS_ALL, ast_get_chan_applicationmap(), ast_set_flag, ast_test_flag, config, NULL, and RAII_VAR.

Referenced by pre_bridge_setup().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1153 of file features.c.

1154 {
1156 
1157  ast_manager_unregister("Bridge");
1158 
1160 
1161  return 0;
1162 }
void unload_features_config(void)
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7268
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392

References app_bridge, ast_manager_unregister(), ast_unregister_application(), and unload_features_config().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Call Features" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_features_config, .load_pri = AST_MODPRI_CORE, .requires = "extconfig", }
static

Definition at line 1164 of file features.c.

◆ app_bridge

char* app_bridge = "Bridge"
static

Definition at line 840 of file features.c.

Referenced by unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1182 of file features.c.

◆ bridge_exec_options

const struct ast_app_option bridge_exec_options[128] = { [ 'p' ] = { .flag = BRIDGE_OPT_PLAYTONE }, [ 'F' ] = { .flag = OPT_CALLEE_GO_ON , .arg_index = OPT_ARG_CALLEE_GO_ON + 1 }, [ 'h' ] = { .flag = OPT_CALLEE_HANGUP }, [ 'H' ] = { .flag = OPT_CALLER_HANGUP }, [ 'k' ] = { .flag = OPT_CALLEE_PARK }, [ 'K' ] = { .flag = OPT_CALLER_PARK }, [ 'L' ] = { .flag = OPT_DURATION_LIMIT , .arg_index = OPT_ARG_DURATION_LIMIT + 1 }, [ 'S' ] = { .flag = OPT_DURATION_STOP , .arg_index = OPT_ARG_DURATION_STOP + 1 }, [ 't' ] = { .flag = OPT_CALLEE_TRANSFER }, [ 'T' ] = { .flag = OPT_CALLER_TRANSFER }, [ 'w' ] = { .flag = OPT_CALLEE_MONITOR }, [ 'W' ] = { .flag = OPT_CALLER_MONITOR }, [ 'x' ] = { .flag = OPT_CALLEE_KILL }, }
static

Definition at line 840 of file features.c.

Referenced by bridge_exec().

◆ dial_features_info

const struct ast_datastore_info dial_features_info
static
Initial value:
= {
.type = "dial-features",
.destroy = ast_free_ptr,
}
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1739
static void * dial_features_duplicate(void *data)
Definition: features.c:262

Definition at line 262 of file features.c.

Referenced by add_features_datastore().