Asterisk - The Open Source Telephony Project  GIT-master-9ed6387
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"

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

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

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

856  {
860  /* note: this entry _MUST_ be the last one in the enum */
862 };

◆ feature_interpret_op

Enumerator
FEATURE_INTERPRET_DETECT 
FEATURE_INTERPRET_DO 
FEATURE_INTERPRET_CHECK 

Definition at line 248 of file features.c.

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

◆ play_tone_action

Enumerator
PLAYTONE_NONE 
PLAYTONE_CHANNEL1 
PLAYTONE_CHANNEL2 
PLAYTONE_BOTH 

Definition at line 715 of file features.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1180 of file features.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1180 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 751 of file features.c.

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.

Referenced by load_module().

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

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

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, ast_datastore::inheritance, LOG_WARNING, ast_dial_features::my_features, NULL, and ast_dial_features::peer_features.

Referenced by add_features_datastores().

291 {
292  struct ast_datastore *datastore;
293  struct ast_dial_features *dialfeatures;
294 
295  ast_channel_lock(chan);
297  ast_channel_unlock(chan);
298  if (datastore) {
299  /* Already exists. */
300  return 1;
301  }
302 
303  /* Create a new datastore with specified feature flags. */
305  if (!datastore) {
306  ast_log(LOG_WARNING, "Unable to create channel features datastore.\n");
307  return 0;
308  }
309  dialfeatures = ast_calloc(1, sizeof(*dialfeatures));
310  if (!dialfeatures) {
311  ast_log(LOG_WARNING, "Unable to allocate memory for feature flags.\n");
312  ast_datastore_free(datastore);
313  return 0;
314  }
315  ast_copy_flags(&dialfeatures->my_features, my_features, AST_FLAGS_ALL);
316  ast_copy_flags(&dialfeatures->peer_features, peer_features, AST_FLAGS_ALL);
318  datastore->data = dialfeatures;
319  ast_channel_lock(chan);
320  ast_channel_datastore_add(chan, datastore);
321  ast_channel_unlock(chan);
322  return 0;
323 }
struct ast_flags peer_features
Definition: features.c:258
#define ast_channel_lock(chan)
Definition: channel.h:2837
static const struct ast_datastore_info dial_features_info
Definition: features.c:274
#define LOG_WARNING
Definition: logger.h:274
struct ast_flags my_features
Definition: features.c:256
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
Structure for a data store object.
Definition: datastore.h:68
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:2379
#define NULL
Definition: resample.c:96
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#define ast_log
Definition: astobj2.c:42
#define ast_channel_unlock(chan)
Definition: channel.h:2838
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define AST_FLAGS_ALL
Definition: utils.h:196
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:193
unsigned int inheritance
Definition: datastore.h:73
void * data
Definition: datastore.h:70
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2365

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

References add_features_datastore(), ast_bridge_config::features_callee, and ast_bridge_config::features_caller.

Referenced by pre_bridge_setup().

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

◆ 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

Return values
reson success.
-1on failure to bridge.

Definition at line 710 of file features.c.

References ast_bridge_call_with_flags().

Referenced by app_exec(), and dial_exec_full().

711 {
712  return ast_bridge_call_with_flags(chan, peer, config, 0);
713 }
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:627

◆ 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 627 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_channel_lock, ast_channel_name(), ast_channel_softhangup_internal_flag(), ast_channel_unlock, AST_SOFTHANGUP_ASYNCGOTO, bridge_failed_peer_goto(), ast_bridge_config::end_bridge_callback, ast_bridge_config::end_bridge_callback_data, NULL, ast_dial_features::peer_features, pre_bridge_setup(), and SCOPE_TRACE.

Referenced by ast_bridge_call(), and try_calling().

628 {
629  int res;
630  struct ast_bridge *bridge;
631  struct ast_bridge_features chan_features;
632  struct ast_bridge_features *peer_features;
633  SCOPE_TRACE(1, "%s Peer: %s\n", ast_channel_name(chan), ast_channel_name(peer));
634 
635  /* Setup features. */
636  res = ast_bridge_features_init(&chan_features);
637  peer_features = ast_bridge_features_new();
638  if (res || !peer_features) {
639  ast_bridge_features_destroy(peer_features);
640  ast_bridge_features_cleanup(&chan_features);
641  bridge_failed_peer_goto(chan, peer);
642  return -1;
643  }
644 
645  if (pre_bridge_setup(chan, peer, config, &chan_features, peer_features)) {
646  ast_bridge_features_destroy(peer_features);
647  ast_bridge_features_cleanup(&chan_features);
648  bridge_failed_peer_goto(chan, peer);
649  return -1;
650  }
651 
652  /* Create bridge */
653  bridge = ast_bridge_basic_new();
654  if (!bridge) {
655  ast_bridge_features_destroy(peer_features);
656  ast_bridge_features_cleanup(&chan_features);
657  bridge_failed_peer_goto(chan, peer);
658  return -1;
659  }
660 
661  ast_bridge_basic_set_flags(bridge, flags);
662 
663  /* Put peer into the bridge */
664  if (ast_bridge_impart(bridge, peer, NULL, peer_features,
666  ast_bridge_destroy(bridge, 0);
667  ast_bridge_features_cleanup(&chan_features);
668  bridge_failed_peer_goto(chan, peer);
669  return -1;
670  }
671 
672  /* Join bridge */
673  ast_bridge_join(bridge, chan, NULL, &chan_features, NULL,
675 
676  /*
677  * If the bridge was broken for a hangup that isn't real, then
678  * don't run the h extension, because the channel isn't really
679  * hung up. This should really only happen with
680  * AST_SOFTHANGUP_ASYNCGOTO.
681  */
682  res = -1;
683  ast_channel_lock(chan);
685  res = 0;
686  }
687  ast_channel_unlock(chan);
688 
689  ast_bridge_features_cleanup(&chan_features);
690 
691  if (res && config->end_bridge_callback) {
693  }
694 
695  return res;
696 }
#define ast_channel_lock(chan)
Definition: channel.h:2837
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3711
Structure that contains features information.
#define SCOPE_TRACE(__level,...)
Definition: logger.h:871
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3678
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:970
#define NULL
Definition: resample.c:96
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3732
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:535
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:1915
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:1079
Structure that contains information about a bridge.
Definition: bridge.h:353
#define ast_channel_unlock(chan)
Definition: channel.h:2838
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:1667
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3741
void(* end_bridge_callback)(void *)
Definition: channel.h:1078
int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
const char * ast_channel_name(const struct ast_channel *chan)
static void bridge_failed_peer_goto(struct ast_channel *chan, struct ast_channel *peer)
Definition: features.c:527

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

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, ast_bridge_config::end_sound, ast_bridge_config::features_callee, ast_bridge_config::features_caller, LOG_WARNING, NULL, pbx_builtin_getvar_helper(), ast_bridge_config::play_warning, S_OR, ast_bridge_config::start_sound, strsep(), ast_bridge_config::timelimit, var, ast_bridge_config::warning_freq, and ast_bridge_config::warning_sound.

Referenced by bridge_exec(), and dial_exec_full().

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

◆ ast_channel_log()

void ast_channel_log ( char *  title,
struct ast_channel chan 
)

Definition at line 362 of file features.c.

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(), and set_config_flags().

363 {
364  ast_log(LOG_NOTICE, "______ %s (%lx)______\n", title, (unsigned long) chan);
365  ast_log(LOG_NOTICE, "CHAN: name: %s; appl: %s; data: %s; contxt: %s; exten: %s; pri: %d;\n",
368  ast_log(LOG_NOTICE, "CHAN: acctcode: %s; dialcontext: %s; amaflags: %x; maccontxt: %s; macexten: %s; macpri: %d;\n",
371  ast_log(LOG_NOTICE, "CHAN: masq: %p; masqr: %p; uniqueID: %s; linkedID:%s\n",
372  ast_channel_masq(chan), ast_channel_masqr(chan),
374  if (ast_channel_masqr(chan)) {
375  ast_log(LOG_NOTICE, "CHAN: masquerading as: %s; cdr: %p;\n",
377  }
378 
379  ast_log(LOG_NOTICE, "===== done ====\n");
380 }
struct ast_cdr * ast_channel_cdr(const struct ast_channel *chan)
int ast_channel_priority(const struct ast_channel *chan)
const char * ast_channel_linkedid(const struct ast_channel *chan)
#define ast_log
Definition: astobj2.c:42
const char * ast_channel_accountcode(const struct ast_channel *chan)
int ast_channel_macropriority(const struct ast_channel *chan)
const char * ast_channel_exten(const struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
struct ast_channel * ast_channel_masq(const struct ast_channel *chan)
#define LOG_NOTICE
Definition: logger.h:263
const char * ast_channel_appl(const struct ast_channel *chan)
const char * ast_channel_dialcontext(const struct ast_channel *chan)
const char * ast_channel_data(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
const char * ast_channel_macrocontext(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)
const char * ast_channel_macroexten(const struct ast_channel *chan)

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 1180 of file features.c.

◆ bridge_check_monitor()

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

Definition at line 485 of file features.c.

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().

486 {
487  const char *value;
488  const char *monitor_args = NULL;
489  struct ast_channel *monitor_chan = NULL;
490 
491  ast_channel_lock(chan);
492  value = pbx_builtin_getvar_helper(chan, "AUTO_MONITOR");
493  if (!ast_strlen_zero(value)) {
494  monitor_args = ast_strdupa(value);
495  monitor_chan = chan;
496  }
497  ast_channel_unlock(chan);
498  if (!monitor_chan) {
499  ast_channel_lock(peer);
500  value = pbx_builtin_getvar_helper(peer, "AUTO_MONITOR");
501  if (!ast_strlen_zero(value)) {
502  monitor_args = ast_strdupa(value);
503  monitor_chan = peer;
504  }
505  ast_channel_unlock(peer);
506  }
507  if (monitor_chan) {
508  struct ast_app *monitor_app;
509 
510  monitor_app = pbx_findapp("Monitor");
511  if (monitor_app) {
512  pbx_exec(monitor_chan, monitor_app, monitor_args);
513  }
514  }
515 }
#define ast_channel_lock(chan)
Definition: channel.h:2837
Main Channel structure associated with a channel.
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
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:300
#define ast_strlen_zero(a)
Definition: muted.c:73
#define ast_channel_unlock(chan)
Definition: channel.h:2838
ast_app: A registered application
Definition: pbx_app.c:45
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: ael_main.c:165

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

References AST_FEATURE_PLAY_WARNING, ast_test_flag, bridge_config_set_limits_warning_values(), ast_bridge_features_limits::duration, ast_bridge_config::features_callee, ast_bridge_config::features_caller, and ast_bridge_config::timelimit.

Referenced by pre_bridge_setup().

462 {
464  bridge_config_set_limits_warning_values(config, caller_limits);
465  }
466 
468  bridge_config_set_limits_warning_values(config, callee_limits);
469  }
470 
471  caller_limits->duration = config->timelimit;
472  callee_limits->duration = config->timelimit;
473 }
static void bridge_config_set_limits_warning_values(struct ast_bridge_config *config, struct ast_bridge_features_limits *limits)
Definition: features.c:436
struct ast_flags features_callee
Definition: channel.h:1066
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_flags features_caller
Definition: channel.h:1065

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

References ast_string_field_set, ast_bridge_config::end_sound, ast_bridge_features_limits::frequency, ast_bridge_config::play_warning, ast_bridge_config::start_sound, ast_bridge_features_limits::warning, ast_bridge_config::warning_freq, and ast_bridge_config::warning_sound.

Referenced by bridge_config_set_limits().

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

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

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(), ast_dial_features::peer_features, pre_bridge_setup(), priority, ast_bridge_config::start_sound, ast_bridge_config::warning_sound, and ast_features_xfer_config::xfersound.

Referenced by load_module().

1002 {
1003  struct ast_channel *current_dest_chan = NULL;
1004  char *tmp_data = NULL;
1005  struct ast_flags opts = { 0, };
1006  struct ast_bridge_config bconfig = { { 0, }, };
1007  char *opt_args[OPT_ARG_ARRAY_SIZE];
1008  struct timeval calldurationlimit = { 0, };
1009  const char *context;
1010  const char *extension;
1011  int priority;
1012  int bridge_add_failed;
1013  int res = -1;
1014  struct ast_bridge_features chan_features;
1015  struct ast_bridge_features *peer_features;
1016  struct ast_bridge *bridge;
1017  struct ast_features_xfer_config *xfer_cfg;
1018 
1020  AST_APP_ARG(dest_chan);
1022  );
1023 
1024  tmp_data = ast_strdupa(data ?: "");
1025  AST_STANDARD_APP_ARGS(args, tmp_data);
1026  if (!ast_strlen_zero(args.options)) {
1027  ast_app_parse_options(bridge_exec_options, &opts, opt_args, args.options);
1028  }
1029 
1030  /* make sure we have a valid end point */
1031  if (!ast_strlen_zero(args.dest_chan)) {
1032  current_dest_chan = ast_channel_get_by_name_prefix(args.dest_chan,
1033  strlen(args.dest_chan));
1034  }
1035  if (!current_dest_chan) {
1036  ast_verb(4, "Bridge failed because channel '%s' does not exist\n",
1037  args.dest_chan ?: "");
1038  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "NONEXISTENT");
1039  return 0;
1040  }
1041 
1042  /* avoid bridge with ourselves */
1043  if (chan == current_dest_chan) {
1044  ast_channel_unref(current_dest_chan);
1045  ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", ast_channel_name(chan));
1046  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "LOOP");
1047  return 0;
1048  }
1049 
1050  if (ast_test_flag(&opts, OPT_DURATION_LIMIT)
1052  && ast_bridge_timelimit(chan, &bconfig, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit)) {
1053  goto done;
1054  }
1055 
1056  if (ast_test_flag(&opts, OPT_CALLEE_TRANSFER))
1058  if (ast_test_flag(&opts, OPT_CALLER_TRANSFER))
1060  if (ast_test_flag(&opts, OPT_CALLEE_HANGUP))
1062  if (ast_test_flag(&opts, OPT_CALLER_HANGUP))
1064  if (ast_test_flag(&opts, OPT_CALLEE_MONITOR))
1066  if (ast_test_flag(&opts, OPT_CALLER_MONITOR))
1068  if (ast_test_flag(&opts, OPT_CALLEE_PARK))
1070  if (ast_test_flag(&opts, OPT_CALLER_PARK))
1072 
1073  /* Setup after bridge goto location. */
1074  if (ast_test_flag(&opts, OPT_CALLEE_GO_ON)) {
1075  ast_channel_lock(chan);
1076  context = ast_strdupa(ast_channel_context(chan));
1077  extension = ast_strdupa(ast_channel_exten(chan));
1078  priority = ast_channel_priority(chan);
1079  ast_channel_unlock(chan);
1080  ast_bridge_set_after_go_on(current_dest_chan, context, extension, priority,
1081  opt_args[OPT_ARG_CALLEE_GO_ON]);
1082  } else if (!ast_test_flag(&opts, OPT_CALLEE_KILL)) {
1083  ast_channel_lock(current_dest_chan);
1084  context = ast_strdupa(ast_channel_context(current_dest_chan));
1085  extension = ast_strdupa(ast_channel_exten(current_dest_chan));
1086  priority = ast_channel_priority(current_dest_chan);
1087  ast_channel_unlock(current_dest_chan);
1088  ast_bridge_set_after_go_on(current_dest_chan, context, extension, priority, NULL);
1089  }
1090 
1091  if (ast_bridge_features_init(&chan_features)) {
1092  ast_bridge_features_cleanup(&chan_features);
1093  goto done;
1094  }
1095 
1096  peer_features = ast_bridge_features_new();
1097  if (!peer_features) {
1098  ast_bridge_features_cleanup(&chan_features);
1099  goto done;
1100  }
1101 
1102  if (pre_bridge_setup(chan, current_dest_chan, &bconfig, &chan_features, peer_features)) {
1103  ast_bridge_features_destroy(peer_features);
1104  ast_bridge_features_cleanup(&chan_features);
1105  goto done;
1106  }
1107 
1108  bridge = ast_bridge_basic_new();
1109  if (!bridge) {
1110  ast_bridge_features_destroy(peer_features);
1111  ast_bridge_features_cleanup(&chan_features);
1112  goto done;
1113  }
1114 
1115  ast_channel_lock(current_dest_chan);
1116  xfer_cfg = ast_get_chan_features_xfer_config(current_dest_chan);
1117  ast_channel_unlock(current_dest_chan);
1118  bridge_add_failed = ast_bridge_add_channel(bridge, current_dest_chan, peer_features,
1120  xfer_cfg ? xfer_cfg->xfersound : NULL);
1121  ao2_cleanup(xfer_cfg);
1122  if (bridge_add_failed) {
1123  ast_bridge_features_cleanup(&chan_features);
1124  ast_bridge_destroy(bridge, 0);
1125  goto done;
1126  }
1127 
1128  /* Don't keep the channel ref in case it was not already in a bridge. */
1129  current_dest_chan = ast_channel_unref(current_dest_chan);
1130 
1131  res = ast_bridge_join(bridge, chan, NULL, &chan_features, NULL,
1133 
1134  ast_bridge_features_cleanup(&chan_features);
1135 
1136 done:
1137  if (res == -1) {
1138  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "FAILURE");
1139  } else {
1140  pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "SUCCESS");
1141  }
1142 
1143  ast_free((char *) bconfig.warning_sound);
1144  ast_free((char *) bconfig.end_sound);
1145  ast_free((char *) bconfig.start_sound);
1146 
1147  ast_channel_cleanup(current_dest_chan);
1148  return 0;
1149 }
#define ast_channel_lock(chan)
Definition: channel.h:2837
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.
Definition: bridge.c:3711
Feature configuration relating to transfers.
struct ast_flags features_callee
Definition: channel.h:1066
Structure that contains features information.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2873
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3678
struct ast_features_xfer_config * ast_get_chan_features_xfer_config(struct ast_channel *chan)
Get the transfer configuration options for a channel.
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:970
const char * args
#define NULL
Definition: resample.c:96
static int priority
int ast_channel_priority(const struct ast_channel *chan)
#define ast_verb(level,...)
Definition: logger.h:455
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3732
static const struct ast_app_option bridge_exec_options[128]
Definition: features.c:878
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:535
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:1419
const char * start_sound
Definition: channel.h:1076
int done
Definition: test_amihooks.c:48
#define ast_log
Definition: astobj2.c:42
bridge configuration
Definition: channel.h:1064
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2884
const char * end_sound
Definition: channel.h:1075
structure to hold extensions
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
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:2829
const char * ast_channel_exten(const struct ast_channel *chan)
struct ast_flags features_caller
Definition: channel.h:1065
Structure that contains information about a bridge.
Definition: bridge.h:353
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:2510
#define ast_strlen_zero(a)
Definition: muted.c:73
#define ast_channel_unlock(chan)
Definition: channel.h:2838
#define ast_free(a)
Definition: astmm.h:182
Structure used to handle boolean flags.
Definition: utils.h:199
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:1667
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.
Definition: bridge.c:3741
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
Definition: features.c:880
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
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:636
const char * warning_sound
Definition: channel.h:1074
static struct test_options options
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ bridge_failed_peer_goto()

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

Definition at line 527 of file features.c.

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

Referenced by ast_bridge_call_with_flags().

528 {
530  || ast_pbx_start(peer)) {
532  }
533 }
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4703
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
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
Definition: bridge_after.c:447

◆ dial_features_duplicate()

static void* dial_features_duplicate ( void *  data)
static

Definition at line 261 of file features.c.

References ast_calloc, and NULL.

262 {
263  struct ast_dial_features *df = data, *df_copy;
264 
265  if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
266  return NULL;
267  }
268 
269  memcpy(df_copy, df, sizeof(*df));
270 
271  return df_copy;
272 }
#define NULL
Definition: resample.c:96
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204

◆ load_module()

static int load_module ( void  )
static

Definition at line 1162 of file features.c.

References action_bridge(), ast_manager_register_xml_core, AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CORE, AST_MODULE_INFO(), AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, AST_MODULE_SUPPORT_CORE, ast_register_application2(), ASTERISK_GPL_KEY, bridge_exec(), EVENT_FLAG_CALL, load_features_config(), NULL, reload(), reload_features_config(), and unload_module().

1163 {
1164  int res;
1165 
1166  res = load_features_config();
1169 
1171 }
int load_features_config(void)
static int bridge_exec(struct ast_channel *chan, const char *data)
Bridge channels.
Definition: features.c:1001
#define EVENT_FLAG_CALL
Definition: manager.h:72
#define NULL
Definition: resample.c:96
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:197
static char * app_bridge
Definition: features.c:838
Module could not be loaded properly.
Definition: module.h:102
static int action_bridge(struct mansession *s, const struct message *m)
Bridge channels together.
Definition: features.c:751
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

◆ parse_playtone()

static enum play_tone_action parse_playtone ( const char *  playtone_val)
static

Definition at line 722 of file features.c.

References ast_false(), ast_strlen_zero, ast_true(), PLAYTONE_BOTH, PLAYTONE_CHANNEL1, PLAYTONE_CHANNEL2, and PLAYTONE_NONE.

Referenced by action_bridge().

723 {
724  if (ast_strlen_zero(playtone_val) || ast_false(playtone_val)) {
725  return PLAYTONE_NONE;
726  } if (!strcasecmp(playtone_val, "channel1")) {
727  return PLAYTONE_CHANNEL1;
728  } else if (!strcasecmp(playtone_val, "channel2") || ast_true(playtone_val)) {
729  return PLAYTONE_CHANNEL2;
730  } else if (!strcasecmp(playtone_val, "both")) {
731  return PLAYTONE_BOTH;
732  } else {
733  /* Invalid input. Assume none */
734  return PLAYTONE_NONE;
735  }
736 }
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: main/utils.c:1822
#define ast_strlen_zero(a)
Definition: muted.c:73
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:1839

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

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(), AST_STATE_RINGING, AST_STATE_UP, bridge_check_monitor(), bridge_config_set_limits(), ast_bridge_config::features_callee, ast_bridge_config::features_caller, LOG_ERROR, pbx_builtin_getvar_helper(), SCOPE_TRACE, set_bridge_features_on_config(), set_config_flags(), and ast_bridge_config::timelimit.

Referenced by ast_bridge_call_with_flags(), and bridge_exec().

537 {
538  int res;
539  SCOPE_TRACE(1, "%s Peer: %s\n", ast_channel_name(chan), ast_channel_name(peer));
540 
541  set_bridge_features_on_config(config, pbx_builtin_getvar_helper(chan, "BRIDGE_FEATURES"));
542  add_features_datastores(chan, peer, config);
543 
544  /*
545  * This is an interesting case. One example is if a ringing
546  * channel gets redirected to an extension that picks up a
547  * parked call. This will make sure that the call taken out of
548  * parking gets told that the channel it just got bridged to is
549  * still ringing.
550  */
554  }
555 
556  bridge_check_monitor(chan, peer);
557 
558  set_config_flags(chan, config);
559 
560  /* Answer if need be */
561  if (ast_channel_state(chan) != AST_STATE_UP) {
562  if (ast_raw_answer(chan)) {
563  return -1;
564  }
565  }
566 
567 #ifdef FOR_DEBUG
568  /* show the two channels and cdrs involved in the bridge for debug & devel purposes */
569  ast_channel_log("Pre-bridge CHAN Channel info", chan);
570  ast_channel_log("Pre-bridge PEER Channel info", peer);
571 #endif
572 
573  res = 0;
574  ast_channel_lock(chan);
576  res |= ast_bridge_features_ds_append(chan, &config->features_caller);
577  ast_channel_unlock(chan);
578  ast_channel_lock(peer);
580  res |= ast_bridge_features_ds_append(peer, &config->features_callee);
581  ast_channel_unlock(peer);
582 
583  if (res) {
584  return -1;
585  }
586 
587  if (config->timelimit) {
588  struct ast_bridge_features_limits call_duration_limits_chan;
589  struct ast_bridge_features_limits call_duration_limits_peer;
590  int abandon_call = 0; /* TRUE if set limits fails so we can abandon the call. */
591 
592  if (ast_bridge_features_limits_construct(&call_duration_limits_chan)) {
593  ast_log(LOG_ERROR, "Could not construct caller duration limits. Bridge canceled.\n");
594 
595  return -1;
596  }
597 
598  if (ast_bridge_features_limits_construct(&call_duration_limits_peer)) {
599  ast_log(LOG_ERROR, "Could not construct callee duration limits. Bridge canceled.\n");
600  ast_bridge_features_limits_destroy(&call_duration_limits_chan);
601 
602  return -1;
603  }
604 
605  bridge_config_set_limits(config, &call_duration_limits_chan, &call_duration_limits_peer);
606 
607  if (ast_bridge_features_set_limits(chan_features, &call_duration_limits_chan, 0)) {
608  abandon_call = 1;
609  }
610  if (ast_bridge_features_set_limits(peer_features, &call_duration_limits_peer, 0)) {
611  abandon_call = 1;
612  }
613 
614  /* At this point we are done with the limits structs since they have been copied to the individual feature sets. */
615  ast_bridge_features_limits_destroy(&call_duration_limits_chan);
616  ast_bridge_features_limits_destroy(&call_duration_limits_peer);
617 
618  if (abandon_call) {
619  ast_log(LOG_ERROR, "Could not set duration limits on one or more sides of the call. Bridge canceled.\n");
620  return -1;
621  }
622  }
623 
624  return 0;
625 }
#define ast_channel_lock(chan)
Definition: channel.h:2837
static void bridge_check_monitor(struct ast_channel *chan, struct ast_channel *peer)
Definition: features.c:485
struct ast_flags features_callee
Definition: channel.h:1066
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:3466
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
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4271
#define SCOPE_TRACE(__level,...)
Definition: logger.h:871
static void add_features_datastores(struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
Definition: features.c:422
ast_channel_state
ast_channel states
Definition: channelstate.h:35
static void set_config_flags(struct ast_channel *chan, struct ast_bridge_config *config)
Definition: features.c:333
void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits)
Destructor function for ast_bridge_features_limits.
Definition: bridge.c:3461
int ast_raw_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2622
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_log
Definition: astobj2.c:42
int ast_channel_visible_indication(const struct ast_channel *chan)
struct ast_flags features_caller
Definition: channel.h:1065
#define LOG_ERROR
Definition: logger.h:285
int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits)
Constructor function for ast_bridge_features_limits.
Definition: bridge.c:3450
Structure that contains configuration information for the limits feature.
#define ast_channel_unlock(chan)
Definition: channel.h:2838
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
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:461
const char * ast_channel_name(const struct ast_channel *chan)
static void set_bridge_features_on_config(struct ast_bridge_config *config, const char *features)
Definition: features.c:382
void ast_channel_log(char *title, struct ast_channel *chan)
Definition: features.c:362

◆ set_bridge_features_on_config()

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

Definition at line 382 of file features.c.

References AST_FEATURE_AUTOMIXMON, AST_FEATURE_AUTOMON, AST_FEATURE_DISCONNECT, AST_FEATURE_PARKCALL, AST_FEATURE_REDIRECT, ast_log, ast_set_flag, ast_strlen_zero, ast_bridge_config::features_callee, ast_bridge_config::features_caller, and LOG_WARNING.

Referenced by pre_bridge_setup().

383 {
384  const char *feature;
385 
386  if (ast_strlen_zero(features)) {
387  return;
388  }
389 
390  for (feature = features; *feature; feature++) {
391  struct ast_flags *party;
392 
393  if (isupper(*feature)) {
394  party = &config->features_caller;
395  } else {
396  party = &config->features_callee;
397  }
398 
399  switch (tolower(*feature)) {
400  case 't' :
402  break;
403  case 'k' :
405  break;
406  case 'h' :
408  break;
409  case 'w' :
411  break;
412  case 'x' :
414  break;
415  default :
416  ast_log(LOG_WARNING, "Skipping unknown feature code '%c'\n", *feature);
417  break;
418  }
419  }
420 }
struct ast_flags features_callee
Definition: channel.h:1066
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
struct ast_flags features_caller
Definition: channel.h:1065
#define ast_strlen_zero(a)
Definition: muted.c:73
Structure used to handle boolean flags.
Definition: utils.h:199

◆ set_config_flags()

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

Definition at line 333 of file features.c.

References ao2_cleanup, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, ast_channel_lock, ast_channel_log(), ast_channel_unlock, ast_clear_flag, AST_FEATURE_DTMF_MASK, AST_FLAGS_ALL, ast_get_chan_applicationmap(), ast_set_flag, ast_test_flag, ast_bridge_config::features_callee, ast_bridge_config::features_caller, NULL, and RAII_VAR.

Referenced by pre_bridge_setup().

334 {
335  ast_clear_flag(config, AST_FLAGS_ALL);
336 
339  }
342  }
343 
345  RAII_VAR(struct ao2_container *, applicationmap, NULL, ao2_cleanup);
346 
347  ast_channel_lock(chan);
348  applicationmap = ast_get_chan_applicationmap(chan);
349  ast_channel_unlock(chan);
350 
351  if (!applicationmap) {
352  return;
353  }
354 
355  /* If an applicationmap exists for this channel at all, then the channel needs the DTMF flag set */
357  }
358 }
#define ast_channel_lock(chan)
Definition: channel.h:2837
struct ast_flags features_callee
Definition: channel.h:1066
struct ao2_container * ast_get_chan_applicationmap(struct ast_channel *chan)
Get the applicationmap for a given channel.
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define NULL
Definition: resample.c:96
#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:851
#define AST_BRIDGE_DTMF_CHANNEL_1
Report DTMF on channel 1.
Definition: channel.h:2288
struct ast_flags features_caller
Definition: channel.h:1065
#define AST_FEATURE_DTMF_MASK
Definition: channel.h:1060
#define ast_channel_unlock(chan)
Definition: channel.h:2838
#define AST_FLAGS_ALL
Definition: utils.h:196
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Generic container type.
#define AST_BRIDGE_DTMF_CHANNEL_0
Report DTMF on channel 0.
Definition: channel.h:2286

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1151 of file features.c.

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

Referenced by load_module().

1152 {
1154 
1155  ast_manager_unregister("Bridge");
1156 
1158 
1159  return 0;
1160 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7258
static char * app_bridge
Definition: features.c:838
void unload_features_config(void)

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

◆ app_bridge

char* app_bridge = "Bridge"
static

Definition at line 838 of file features.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1180 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 878 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,
}
static void * dial_features_duplicate(void *data)
Definition: features.c:261
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771

Definition at line 274 of file features.c.