Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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) , OPT_NOANSWER = (1 << 13)
}
 
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_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, int noanswer)
 
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 }, [ 'n' ] = { .flag = OPT_NOANSWER }, [ '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 
OPT_NOANSWER 

Definition at line 821 of file features.c.

821 {
822 BRIDGE_OPT_PLAYTONE = (1 << 0),
823 OPT_CALLEE_HANGUP = (1 << 1),
824 OPT_CALLER_HANGUP = (1 << 2),
825 OPT_DURATION_LIMIT = (1 << 3),
826 OPT_DURATION_STOP = (1 << 4),
827 OPT_CALLEE_TRANSFER = (1 << 5),
828 OPT_CALLER_TRANSFER = (1 << 6),
829 OPT_CALLEE_MONITOR = (1 << 7),
830 OPT_CALLER_MONITOR = (1 << 8),
831 OPT_CALLEE_PARK = (1 << 9),
832 OPT_CALLER_PARK = (1 << 10),
833 OPT_CALLEE_KILL = (1 << 11),
834 OPT_CALLEE_GO_ON = (1 << 12),
835 OPT_NOANSWER = (1 << 13),
836};
@ OPT_CALLEE_PARK
Definition: features.c:831
@ OPT_DURATION_LIMIT
Definition: features.c:825
@ OPT_DURATION_STOP
Definition: features.c:826
@ OPT_NOANSWER
Definition: features.c:835
@ OPT_CALLEE_TRANSFER
Definition: features.c:827
@ OPT_CALLEE_GO_ON
Definition: features.c:834
@ OPT_CALLER_PARK
Definition: features.c:832
@ OPT_CALLER_MONITOR
Definition: features.c:830
@ OPT_CALLEE_MONITOR
Definition: features.c:829
@ OPT_CALLER_HANGUP
Definition: features.c:824
@ OPT_CALLEE_HANGUP
Definition: features.c:823
@ BRIDGE_OPT_PLAYTONE
Definition: features.c:822
@ OPT_CALLEE_KILL
Definition: features.c:833
@ OPT_CALLER_TRANSFER
Definition: features.c:828

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

838 {
842 /* note: this entry _MUST_ be the last one in the enum */
844};
@ OPT_ARG_CALLEE_GO_ON
Definition: features.c:841
@ OPT_ARG_DURATION_STOP
Definition: features.c:840
@ OPT_ARG_DURATION_LIMIT
Definition: features.c:839
@ OPT_ARG_ARRAY_SIZE
Definition: features.c:843

◆ feature_interpret_op

Enumerator
FEATURE_INTERPRET_DETECT 
FEATURE_INTERPRET_DO 
FEATURE_INTERPRET_CHECK 

Definition at line 261 of file features.c.

261 {
262 FEATURE_INTERPRET_DETECT, /* Used by ast_feature_detect */
263 FEATURE_INTERPRET_DO, /* Used by feature_interpret */
264 FEATURE_INTERPRET_CHECK, /* Used by feature_check */
feature_interpret_op
Definition: features.c:261
@ FEATURE_INTERPRET_CHECK
Definition: features.c:264
@ FEATURE_INTERPRET_DO
Definition: features.c:263
@ FEATURE_INTERPRET_DETECT
Definition: features.c:262

◆ play_tone_action

Enumerator
PLAYTONE_NONE 
PLAYTONE_CHANNEL1 
PLAYTONE_CHANNEL2 
PLAYTONE_BOTH 

Definition at line 696 of file features.c.

696 {
697 PLAYTONE_NONE = 0,
698 PLAYTONE_CHANNEL1 = (1 << 0),
699 PLAYTONE_CHANNEL2 = (1 << 1),
701};
@ PLAYTONE_CHANNEL1
Definition: features.c:698
@ PLAYTONE_CHANNEL2
Definition: features.c:699
@ PLAYTONE_NONE
Definition: features.c:697
@ PLAYTONE_BOTH
Definition: features.c:700

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1165 of file features.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1165 of file features.c.

◆ action_bridge()

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

Bridge channels together.

Parameters
s
m

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

733{
734 const char *channela = astman_get_header(m, "Channel1");
735 const char *channelb = astman_get_header(m, "Channel2");
737 RAII_VAR(struct ast_channel *, chana, NULL, ao2_cleanup);
738 RAII_VAR(struct ast_channel *, chanb, NULL, ao2_cleanup);
739 const char *chana_exten;
740 const char *chana_context;
741 int chana_priority;
742 const char *chanb_exten;
743 const char *chanb_context;
744 int chanb_priority;
745 struct ast_bridge *bridge;
746 char buf[256];
747 RAII_VAR(struct ast_features_xfer_config *, xfer_cfg_a, NULL, ao2_cleanup);
748 RAII_VAR(struct ast_features_xfer_config *, xfer_cfg_b, NULL, ao2_cleanup);
749
750 /* make sure valid channels were specified */
751 if (ast_strlen_zero(channela) || ast_strlen_zero(channelb)) {
752 astman_send_error(s, m, "Missing channel parameter in request");
753 return 0;
754 }
755
756 ast_debug(1, "Performing Bridge action on %s and %s\n", channela, channelb);
757
758 /* Start with chana */
759 chana = ast_channel_get_by_name_prefix(channela, strlen(channela));
760 if (!chana) {
761 snprintf(buf, sizeof(buf), "Channel1 does not exist: %s", channela);
762 astman_send_error(s, m, buf);
763 return 0;
764 }
765 ast_channel_lock(chana);
766 xfer_cfg_a = ast_get_chan_features_xfer_config(chana);
767 chana_exten = ast_strdupa(ast_channel_exten(chana));
768 chana_context = ast_strdupa(ast_channel_context(chana));
769 chana_priority = ast_channel_priority(chana);
771 chana_priority++;
772 }
773 ast_channel_unlock(chana);
774
775 chanb = ast_channel_get_by_name_prefix(channelb, strlen(channelb));
776 if (!chanb) {
777 snprintf(buf, sizeof(buf), "Channel2 does not exist: %s", channelb);
778 astman_send_error(s, m, buf);
779 return 0;
780 }
781 ast_channel_lock(chanb);
782 xfer_cfg_b = ast_get_chan_features_xfer_config(chanb);
783 chanb_exten = ast_strdupa(ast_channel_exten(chanb));
784 chanb_context = ast_strdupa(ast_channel_context(chanb));
785 chanb_priority = ast_channel_priority(chanb);
787 chanb_priority++;
788 }
789 ast_channel_unlock(chanb);
790
791 bridge = ast_bridge_basic_new();
792 if (!bridge) {
793 astman_send_error(s, m, "Unable to create bridge\n");
794 return 0;
795 }
796
797 ast_bridge_set_after_goto(chana, chana_context, chana_exten, chana_priority);
798 if (ast_bridge_add_channel(bridge, chana, NULL, playtone & PLAYTONE_CHANNEL1, xfer_cfg_a ? xfer_cfg_a->xfersound : NULL)) {
799 snprintf(buf, sizeof(buf), "Unable to add Channel1 to bridge: %s", ast_channel_name(chana));
800 astman_send_error(s, m, buf);
801 ast_bridge_destroy(bridge, 0);
802 return 0;
803 }
804
805 ast_bridge_set_after_goto(chanb, chanb_context, chanb_exten, chanb_priority);
806 if (ast_bridge_add_channel(bridge, chanb, NULL, playtone & PLAYTONE_CHANNEL2, xfer_cfg_b ? xfer_cfg_b->xfersound : NULL)) {
807 snprintf(buf, sizeof(buf), "Unable to add Channel2 to bridge: %s", ast_channel_name(chanb));
808 astman_send_error(s, m, buf);
809 ast_bridge_destroy(bridge, 0);
810 return 0;
811 }
812
813 astman_send_ack(s, m, "Channels have been bridged");
814 ao2_cleanup(bridge);
815
816 return 0;
817}
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:1009
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.
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2970
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
int ast_channel_priority(const struct ast_channel *chan)
const char * ast_channel_context(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:1461
@ AST_FLAG_IN_AUTOLOOP
Definition: channel.h:1017
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2971
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
play_tone_action
Definition: features.c:696
static enum play_tone_action parse_playtone(const char *playtone_val)
Definition: features.c:703
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:2540
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:1986
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2018
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:1647
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:353
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:941

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

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

304{
305 struct ast_datastore *datastore;
306 struct ast_dial_features *dialfeatures;
307
308 ast_channel_lock(chan);
310 ast_channel_unlock(chan);
311 if (datastore) {
312 /* Already exists. */
313 return 1;
314 }
315
316 /* Create a new datastore with specified feature flags. */
318 if (!datastore) {
319 ast_log(LOG_WARNING, "Unable to create channel features datastore.\n");
320 return 0;
321 }
322 dialfeatures = ast_calloc(1, sizeof(*dialfeatures));
323 if (!dialfeatures) {
324 ast_log(LOG_WARNING, "Unable to allocate memory for feature flags.\n");
325 ast_datastore_free(datastore);
326 return 0;
327 }
331 datastore->data = dialfeatures;
332 ast_channel_lock(chan);
333 ast_channel_datastore_add(chan, datastore);
334 ast_channel_unlock(chan);
335 return 0;
336}
#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:2414
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:194
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:2428
#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:287
#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:271
struct ast_flags my_features
Definition: features.c:269
#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 434 of file features.c.

435{
436 if (add_features_datastore(caller, &config->features_caller, &config->features_callee)) {
437 /*
438 * If we don't return here, then when we do a builtin_atxfer we
439 * will copy the disconnect flags over from the atxfer to the
440 * callee (Party C).
441 */
442 return;
443 }
444
445 add_features_datastore(callee, &config->features_callee, &config->features_caller);
446}
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:303

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

692{
693 return ast_bridge_call_with_flags(chan, peer, config, 0);
694}
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:601

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

602{
603 int res;
604 struct ast_bridge *bridge;
605 struct ast_bridge_features chan_features;
606 struct ast_bridge_features *peer_features;
607 const char *value;
608 int noanswer;
609 SCOPE_TRACE(1, "%s Peer: %s\n", ast_channel_name(chan), ast_channel_name(peer));
610
611 /* Setup features. */
612 res = ast_bridge_features_init(&chan_features);
613 peer_features = ast_bridge_features_new();
614 if (res || !peer_features) {
615 ast_bridge_features_destroy(peer_features);
616 ast_bridge_features_cleanup(&chan_features);
617 bridge_failed_peer_goto(chan, peer);
618 return -1;
619 }
620
621 ast_channel_lock(chan);
622 value = pbx_builtin_getvar_helper(chan, "BRIDGE_NOANSWER");
623 noanswer = !ast_strlen_zero(value) ? 1 : 0;
624 ast_channel_unlock(chan);
625
626 if (pre_bridge_setup(chan, peer, config, &chan_features, peer_features, noanswer)) {
627 ast_bridge_features_destroy(peer_features);
628 ast_bridge_features_cleanup(&chan_features);
629 bridge_failed_peer_goto(chan, peer);
630 return -1;
631 }
632
633 /* Create bridge */
634 bridge = ast_bridge_basic_new();
635 if (!bridge) {
636 ast_bridge_features_destroy(peer_features);
637 ast_bridge_features_cleanup(&chan_features);
638 bridge_failed_peer_goto(chan, peer);
639 return -1;
640 }
641
642 ast_bridge_basic_set_flags(bridge, flags);
643
644 /* Put peer into the bridge */
645 if (ast_bridge_impart(bridge, peer, NULL, peer_features,
647 ast_bridge_destroy(bridge, 0);
648 ast_bridge_features_cleanup(&chan_features);
649 bridge_failed_peer_goto(chan, peer);
650 return -1;
651 }
652
653 /* Join bridge */
654 ast_bridge_join(bridge, chan, NULL, &chan_features, NULL,
656
657 /*
658 * If the bridge was broken for a hangup that isn't real, then
659 * don't run the h extension, because the channel isn't really
660 * hung up. This should really only happen with
661 * AST_SOFTHANGUP_ASYNCGOTO.
662 */
663 res = -1;
664 ast_channel_lock(chan);
666 res = 0;
667 }
668 ast_channel_unlock(chan);
669
670 ast_bridge_features_cleanup(&chan_features);
671
672 if (res && config->end_bridge_callback) {
673 config->end_bridge_callback(config->end_bridge_callback_data);
674 }
675
676 return res;
677}
@ noanswer
int ast_bridge_join(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, struct ast_bridge_tech_optimizations *tech_args, enum ast_bridge_join_flags flags)
Join a channel to a bridge (blocking)
Definition: bridge.c:1690
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1947
@ AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP
Definition: bridge.h:596
@ AST_BRIDGE_IMPART_CHAN_INDEPENDENT
Definition: bridge.h:594
@ AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP
Definition: bridge.h:541
@ AST_BRIDGE_JOIN_PASS_REFERENCE
Definition: bridge.h:539
void ast_bridge_basic_set_flags(struct ast_bridge *bridge, unsigned int flags)
Set feature flags on a basic bridge.
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3689
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3752
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3722
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3743
int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
@ AST_SOFTHANGUP_ASYNCGOTO
Definition: channel.h:1146
static int pre_bridge_setup(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, struct ast_bridge_features *chan_features, struct ast_bridge_features *peer_features, int noanswer)
Definition: features.c:503
static void bridge_failed_peer_goto(struct ast_channel *chan, struct ast_channel *peer)
Definition: features.c:495
#define SCOPE_TRACE(__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.
Structure that contains features information.
int value
Definition: syslog.c:37

References ast_bridge_basic_new(), ast_bridge_basic_set_flags(), ast_bridge_destroy(), ast_bridge_features_cleanup(), ast_bridge_features_destroy(), ast_bridge_features_init(), ast_bridge_features_new(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_INDEPENDENT, AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP, ast_bridge_join(), AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP, AST_BRIDGE_JOIN_PASS_REFERENCE, ast_channel_lock, ast_channel_name(), ast_channel_softhangup_internal_flag(), ast_channel_unlock, AST_SOFTHANGUP_ASYNCGOTO, ast_strlen_zero(), bridge_failed_peer_goto(), config, noanswer, NULL, pbx_builtin_getvar_helper(), pre_bridge_setup(), SCOPE_TRACE, and value.

Referenced by ast_bridge_call(), and try_calling().

◆ ast_bridge_timelimit()

int ast_bridge_timelimit ( struct ast_channel chan,
struct ast_bridge_config config,
char *  parse,
struct timeval *  calldurationlimit 
)

parse L option and read associated channel variables to set warning, warning frequency, and timelimit

Note
caller must be aware of freeing memory for warning_sound, end_sound, and start_sound

Definition at line 863 of file features.c.

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

References ast_channel_lock, ast_channel_unlock, AST_FEATURE_PLAY_WARNING, ast_log, ast_set_flag, ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_verb, config, LOG_WARNING, NULL, pbx_builtin_getvar_helper(), S_OR, strsep(), and var.

Referenced by bridge_exec(), and dial_exec_full().

◆ ast_channel_log()

void ast_channel_log ( char *  title,
struct ast_channel chan 
)

Definition at line 375 of file features.c.

376{
377 ast_log(LOG_NOTICE, "______ %s (%lx)______\n", title, (unsigned long) chan);
378 ast_log(LOG_NOTICE, "CHAN: name: %s; appl: %s; data: %s; contxt: %s; exten: %s; pri: %d;\n",
381 ast_log(LOG_NOTICE, "CHAN: acctcode: %s; dialcontext: %s; amaflags: %x;\n",
383 ast_log(LOG_NOTICE, "CHAN: masq: %p; masqr: %p; uniqueID: %s; linkedID:%s\n",
386 if (ast_channel_masqr(chan)) {
387 ast_log(LOG_NOTICE, "CHAN: masquerading as: %s; cdr: %p;\n",
389 }
390
391 ast_log(LOG_NOTICE, "===== done ====\n");
392}
const char * ast_channel_linkedid(const struct ast_channel *chan)
struct ast_channel * ast_channel_masq(const struct ast_channel *chan)
const char * ast_channel_data(const struct ast_channel *chan)
struct ast_cdr * ast_channel_cdr(const struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
const char * ast_channel_accountcode(const struct ast_channel *chan)
const char * ast_channel_appl(const struct ast_channel *chan)
enum ama_flags ast_channel_amaflags(const struct ast_channel *chan)
const char * ast_channel_dialcontext(const struct ast_channel *chan)
struct ast_channel * ast_channel_masqr(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_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 1165 of file features.c.

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

474{
475 if (ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING)) {
477 }
478
479 if (ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING)) {
481 }
482
483 caller_limits->duration = config->timelimit;
484 callee_limits->duration = config->timelimit;
485}
static void bridge_config_set_limits_warning_values(struct ast_bridge_config *config, struct ast_bridge_features_limits *limits)
Definition: features.c:448

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

449{
450 if (config->end_sound) {
451 ast_string_field_set(limits, duration_sound, config->end_sound);
452 }
453
454 if (config->warning_sound) {
455 ast_string_field_set(limits, warning_sound, config->warning_sound);
456 }
457
458 if (config->start_sound) {
459 ast_string_field_set(limits, connect_sound, config->start_sound);
460 }
461
462 limits->frequency = config->warning_freq;
463 limits->warning = config->play_warning;
464}
#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 984 of file features.c.

985{
986 struct ast_channel *current_dest_chan = NULL;
987 char *tmp_data = NULL;
988 struct ast_flags opts = { 0, };
989 struct ast_bridge_config bconfig = { { 0, }, };
990 char *opt_args[OPT_ARG_ARRAY_SIZE];
991 struct timeval calldurationlimit = { 0, };
992 const char *context;
993 const char *extension;
994 int priority;
995 int bridge_add_failed;
996 int res = -1;
997 struct ast_bridge_features chan_features;
998 struct ast_bridge_features *peer_features;
999 struct ast_bridge *bridge;
1000 struct ast_features_xfer_config *xfer_cfg;
1001 int noanswer;
1002
1004 AST_APP_ARG(dest_chan);
1006 );
1007
1008 tmp_data = ast_strdupa(data ?: "");
1009 AST_STANDARD_APP_ARGS(args, tmp_data);
1010 if (!ast_strlen_zero(args.options)) {
1011 ast_app_parse_options(bridge_exec_options, &opts, opt_args, args.options);
1012 }
1013
1014 /* make sure we have a valid end point */
1015 if (!ast_strlen_zero(args.dest_chan)) {
1016 current_dest_chan = ast_channel_get_by_name_prefix(args.dest_chan,
1017 strlen(args.dest_chan));
1018 }
1019 if (!current_dest_chan) {
1020 ast_verb(4, "Bridge failed because channel '%s' does not exist\n",
1021 args.dest_chan ?: "");
1022 pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "NONEXISTENT");
1023 return 0;
1024 }
1025
1026 /* avoid bridge with ourselves */
1027 if (chan == current_dest_chan) {
1028 ast_channel_unref(current_dest_chan);
1029 ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", ast_channel_name(chan));
1030 pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "LOOP");
1031 return 0;
1032 }
1033
1036 && ast_bridge_timelimit(chan, &bconfig, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit)) {
1037 goto done;
1038 }
1039
1044 if (ast_test_flag(&opts, OPT_CALLEE_HANGUP))
1046 if (ast_test_flag(&opts, OPT_CALLER_HANGUP))
1052 if (ast_test_flag(&opts, OPT_CALLEE_PARK))
1054 if (ast_test_flag(&opts, OPT_CALLER_PARK))
1057
1058 /* Setup after bridge goto location. */
1059 if (ast_test_flag(&opts, OPT_CALLEE_GO_ON)) {
1060 ast_channel_lock(chan);
1064 ast_channel_unlock(chan);
1066 opt_args[OPT_ARG_CALLEE_GO_ON]);
1067 } else if (!ast_test_flag(&opts, OPT_CALLEE_KILL)) {
1068 ast_channel_lock(current_dest_chan);
1069 context = ast_strdupa(ast_channel_context(current_dest_chan));
1070 extension = ast_strdupa(ast_channel_exten(current_dest_chan));
1071 priority = ast_channel_priority(current_dest_chan);
1072 ast_channel_unlock(current_dest_chan);
1074 }
1075
1076 if (ast_bridge_features_init(&chan_features)) {
1077 ast_bridge_features_cleanup(&chan_features);
1078 goto done;
1079 }
1080
1081 peer_features = ast_bridge_features_new();
1082 if (!peer_features) {
1083 ast_bridge_features_cleanup(&chan_features);
1084 goto done;
1085 }
1086
1087 if (pre_bridge_setup(chan, current_dest_chan, &bconfig, &chan_features, peer_features, noanswer)) {
1088 ast_bridge_features_destroy(peer_features);
1089 ast_bridge_features_cleanup(&chan_features);
1090 goto done;
1091 }
1092
1093 bridge = ast_bridge_basic_new();
1094 if (!bridge) {
1095 ast_bridge_features_destroy(peer_features);
1096 ast_bridge_features_cleanup(&chan_features);
1097 goto done;
1098 }
1099
1100 ast_channel_lock(current_dest_chan);
1101 xfer_cfg = ast_get_chan_features_xfer_config(current_dest_chan);
1102 ast_channel_unlock(current_dest_chan);
1103 bridge_add_failed = ast_bridge_add_channel(bridge, current_dest_chan, peer_features,
1105 xfer_cfg ? xfer_cfg->xfersound : NULL);
1106 ao2_cleanup(xfer_cfg);
1107 if (bridge_add_failed) {
1108 ast_bridge_features_cleanup(&chan_features);
1109 ast_bridge_destroy(bridge, 0);
1110 goto done;
1111 }
1112
1113 /* Don't keep the channel ref in case it was not already in a bridge. */
1114 current_dest_chan = ast_channel_unref(current_dest_chan);
1115
1116 res = ast_bridge_join(bridge, chan, NULL, &chan_features, NULL,
1118
1119 ast_bridge_features_cleanup(&chan_features);
1120
1121done:
1122 if (res == -1) {
1123 pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "FAILURE");
1124 } else {
1125 pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "SUCCESS");
1126 }
1127
1128 ast_free((char *) bconfig.warning_sound);
1129 ast_free((char *) bconfig.end_sound);
1130 ast_free((char *) bconfig.start_sound);
1131
1132 ast_channel_cleanup(current_dest_chan);
1133 return 0;
1134}
#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
@ AST_FEATURE_REDIRECT
Definition: channel.h:1084
@ AST_FEATURE_PARKCALL
Definition: channel.h:1088
@ AST_FEATURE_AUTOMON
Definition: channel.h:1087
@ AST_FEATURE_DISCONNECT
Definition: channel.h:1085
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3006
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:3017
static const struct ast_app_option bridge_exec_options[128]
Definition: features.c:861
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:863
#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:3066
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:1096
const char * end_sound
Definition: channel.h:1107
const char * warning_sound
Definition: channel.h:1106
struct ast_flags features_callee
Definition: channel.h:1098
struct ast_flags features_caller
Definition: channel.h:1097
const char * start_sound
Definition: channel.h:1108
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, voicemailpwcheck::context, done, ast_bridge_config::end_sound, ast_bridge_config::features_callee, ast_bridge_config::features_caller, LOG_WARNING, noanswer, 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, OPT_NOANSWER, 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.

Referenced by load_module().

◆ bridge_failed_peer_goto()

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

Definition at line 495 of file features.c.

496{
498 || ast_pbx_start(peer)) {
500 }
501}
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:349
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4723

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

275{
276 struct ast_dial_features *df = data, *df_copy;
277
278 if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
279 return NULL;
280 }
281
282 memcpy(df_copy, df, sizeof(*df));
283
284 return df_copy;
285}

References ast_calloc, and NULL.

◆ load_module()

static int load_module ( void  )
static

Definition at line 1147 of file features.c.

1148{
1149 int res;
1150
1151 res = load_features_config();
1154
1156}
static char * app_bridge
Definition: features.c:819
static int action_bridge(struct mansession *s, const struct message *m)
Bridge channels together.
Definition: features.c:732
static int bridge_exec(struct ast_channel *chan, const char *data)
Bridge channels.
Definition: features.c:984
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:203
#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:104
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
Definition: module.h:102
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70

References action_bridge(), app_bridge, ast_manager_register_xml_core, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application2(), bridge_exec(), EVENT_FLAG_CALL, load_features_config(), and NULL.

◆ parse_playtone()

static enum play_tone_action parse_playtone ( const char *  playtone_val)
static

Definition at line 703 of file features.c.

704{
705 if (ast_strlen_zero(playtone_val) || ast_false(playtone_val)) {
706 return PLAYTONE_NONE;
707 } if (!strcasecmp(playtone_val, "channel1")) {
708 return PLAYTONE_CHANNEL1;
709 } else if (!strcasecmp(playtone_val, "channel2") || ast_true(playtone_val)) {
710 return PLAYTONE_CHANNEL2;
711 } else if (!strcasecmp(playtone_val, "both")) {
712 return PLAYTONE_BOTH;
713 } else {
714 /* Invalid input. Assume none */
715 return PLAYTONE_NONE;
716 }
717}
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"....
Definition: utils.c:2216

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

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,
int  noanswer 
)
static

Definition at line 503 of file features.c.

505{
506 int res;
507 SCOPE_TRACE(1, "%s Peer: %s\n", ast_channel_name(chan), ast_channel_name(peer));
508
510 add_features_datastores(chan, peer, config);
511
512 /*
513 * This is an interesting case. One example is if a ringing
514 * channel gets redirected to an extension that picks up a
515 * parked call. This will make sure that the call taken out of
516 * parking gets told that the channel it just got bridged to is
517 * still ringing.
518 */
522 }
523
525
526 /* Answer if need be */
527
528 res = 0;
529
530 if (noanswer) {
531 ast_debug(1, "Skipping answer on %s due to no answer directive\n", ast_channel_name(chan));
532 } else if (ast_channel_state(chan) != AST_STATE_UP) {
533 ast_debug(1, "Answering channel for bridge: %s\n", ast_channel_name(chan));
534 res = ast_raw_answer_with_stream_topology(chan, config->answer_topology);
535 if (res != 0) {
536 return -1;
537 }
538 }
539
540
541#ifdef FOR_DEBUG
542 /* show the two channels and cdrs involved in the bridge for debug & devel purposes */
543 ast_channel_log("Pre-bridge CHAN Channel info", chan);
544 ast_channel_log("Pre-bridge PEER Channel info", peer);
545#endif
546
547 res = 0;
548 ast_channel_lock(chan);
550 res |= ast_bridge_features_ds_append(chan, &config->features_caller);
551 ast_channel_unlock(chan);
552 ast_channel_lock(peer);
554 res |= ast_bridge_features_ds_append(peer, &config->features_callee);
555 ast_channel_unlock(peer);
556
557 if (res) {
558 return -1;
559 }
560
561 if (config->timelimit) {
562 struct ast_bridge_features_limits call_duration_limits_chan;
563 struct ast_bridge_features_limits call_duration_limits_peer;
564 int abandon_call = 0; /* TRUE if set limits fails so we can abandon the call. */
565
566 if (ast_bridge_features_limits_construct(&call_duration_limits_chan)) {
567 ast_log(LOG_ERROR, "Could not construct caller duration limits. Bridge canceled.\n");
568
569 return -1;
570 }
571
572 if (ast_bridge_features_limits_construct(&call_duration_limits_peer)) {
573 ast_log(LOG_ERROR, "Could not construct callee duration limits. Bridge canceled.\n");
574 ast_bridge_features_limits_destroy(&call_duration_limits_chan);
575
576 return -1;
577 }
578
579 bridge_config_set_limits(config, &call_duration_limits_chan, &call_duration_limits_peer);
580
581 if (ast_bridge_features_set_limits(chan_features, &call_duration_limits_chan, 0)) {
582 abandon_call = 1;
583 }
584 if (ast_bridge_features_set_limits(peer_features, &call_duration_limits_peer, 0)) {
585 abandon_call = 1;
586 }
587
588 /* At this point we are done with the limits structs since they have been copied to the individual feature sets. */
589 ast_bridge_features_limits_destroy(&call_duration_limits_chan);
590 ast_bridge_features_limits_destroy(&call_duration_limits_peer);
591
592 if (abandon_call) {
593 ast_log(LOG_ERROR, "Could not set duration limits on one or more sides of the call. Bridge canceled.\n");
594 return -1;
595 }
596 }
597
598 return 0;
599}
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:3481
int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits)
Constructor function for ast_bridge_features_limits.
Definition: bridge.c:3465
void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits)
Destructor function for ast_bridge_features_limits.
Definition: bridge.c:3476
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:2668
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:4294
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:375
static void add_features_datastores(struct ast_channel *caller, struct ast_channel *callee, struct ast_bridge_config *config)
Definition: features.c:434
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:473
static void set_config_flags(struct ast_channel *chan, struct ast_bridge_config *config)
Definition: features.c:346
static void set_bridge_features_on_config(struct ast_bridge_config *config, const char *features)
Definition: features.c:394
@ 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_debug, ast_indicate(), ast_log, ast_max_forwards_reset(), ast_raw_answer_with_stream_topology(), AST_STATE_RINGING, AST_STATE_UP, bridge_config_set_limits(), config, LOG_ERROR, noanswer, 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 394 of file features.c.

395{
396 const char *feature;
397
398 if (ast_strlen_zero(features)) {
399 return;
400 }
401
402 for (feature = features; *feature; feature++) {
403 struct ast_flags *party;
404
405 if (isupper(*feature)) {
406 party = &config->features_caller;
407 } else {
408 party = &config->features_callee;
409 }
410
411 switch (tolower(*feature)) {
412 case 't' :
414 break;
415 case 'k' :
417 break;
418 case 'h' :
420 break;
421 case 'w' :
423 break;
424 case 'x' :
426 break;
427 default :
428 ast_log(LOG_WARNING, "Skipping unknown feature code '%c'\n", *feature);
429 break;
430 }
431 }
432}
@ AST_FEATURE_AUTOMIXMON
Definition: channel.h:1089

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

347{
349
350 if (ast_test_flag(&config->features_caller, AST_FEATURE_DTMF_MASK)) {
352 }
353 if (ast_test_flag(&config->features_callee, AST_FEATURE_DTMF_MASK)) {
355 }
356
358 RAII_VAR(struct ao2_container *, applicationmap, NULL, ao2_cleanup);
359
360 ast_channel_lock(chan);
361 applicationmap = ast_get_chan_applicationmap(chan);
362 ast_channel_unlock(chan);
363
364 if (!applicationmap) {
365 return;
366 }
367
368 /* If an applicationmap exists for this channel at all, then the channel needs the DTMF flag set */
370 }
371}
#define AST_BRIDGE_DTMF_CHANNEL_0
Report DTMF on channel 0.
Definition: channel.h:2418
#define AST_BRIDGE_DTMF_CHANNEL_1
Report DTMF on channel 1.
Definition: channel.h:2420
#define AST_FEATURE_DTMF_MASK
Definition: channel.h:1092
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 1136 of file features.c.

1137{
1139
1140 ast_manager_unregister("Bridge");
1141
1143
1144 return 0;
1145}
void unload_features_config(void)
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7697
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 1165 of file features.c.

◆ app_bridge

char* app_bridge = "Bridge"
static

Definition at line 819 of file features.c.

Referenced by load_module(), and unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1165 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 }, [ 'n' ] = { .flag = OPT_NOANSWER }, [ '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 861 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:274

Definition at line 287 of file features.c.

Referenced by add_features_datastore().