mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-18 02:32:36 +00:00
Fix feature inheritance with builtin features
When using builtin features like parking and transfers, the AST_FEATURE_* flags would not be set correctly for all instances when either performing a builtin attended transfer, or parking a call and getting the timeout callback. Also, there was no way on a per-call basis to specify what features someone should have on picking up a parked call (since that doesn't involve the Dial() command). There was a global option for setting whether or not all users who pickup a parked call should have AST_FEATURE_REDIRECT set, but nothing for DISCONNECT, AUTOMON, or PARKCALL. This patch: 1) adds the BRIDGE_FEATURES dialplan variable which can be set either in the dialplan or with setvar in channels that support it. This variable can be set to any combination of 't', 'k', 'w', and 'h' (case insensitive matching of the equivalent dial options), to set what features should be activated on this channel. The patch moves the setting of the features datastores into the bridging code instead of app_dial to help facilitate this. 2) adds global options parkedcallparking, parkedcallhangup, and parkedcallrecording to be similar to the parkedcalltransfers option for globally setting features. 3) has builtin_atxfer call builtin_parkcall if being transfered to the parking extension since tracking everything through multiple masquerades, etc. is difficult and error-prone 4) attempts to fix all cases of return calls from parking and completed builtin transfers not having the correct permissions (closes issue #14274) Reported by: aragon Patches: fix_feature_inheritence.diff.txt uploaded by otherwiseguy (license 396) Tested by: aragon, otherwiseguy Review http://reviewboard.digium.com/r/138/ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@172517 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -806,35 +806,6 @@ static int valid_priv_reply(struct ast_flags *opts, int res)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_dial_features(struct ast_flags *opts, struct ast_dial_features *features)
|
||||
{
|
||||
struct ast_flags perm_opts = {.flags = 0};
|
||||
|
||||
ast_copy_flags(&perm_opts, opts,
|
||||
OPT_CALLER_TRANSFER | OPT_CALLER_PARK | OPT_CALLER_MONITOR | OPT_CALLER_HANGUP |
|
||||
OPT_CALLEE_TRANSFER | OPT_CALLEE_PARK | OPT_CALLEE_MONITOR | OPT_CALLEE_HANGUP);
|
||||
|
||||
memset(features->options, 0, sizeof(features->options));
|
||||
|
||||
ast_app_options2str(dial_exec_options, &perm_opts, features->options, sizeof(features->options));
|
||||
if (ast_test_flag(&perm_opts, OPT_CALLEE_TRANSFER))
|
||||
ast_set_flag(&(features->features_callee), AST_FEATURE_REDIRECT);
|
||||
if (ast_test_flag(&perm_opts, OPT_CALLER_TRANSFER))
|
||||
ast_set_flag(&(features->features_caller), AST_FEATURE_REDIRECT);
|
||||
if (ast_test_flag(&perm_opts, OPT_CALLEE_HANGUP))
|
||||
ast_set_flag(&(features->features_callee), AST_FEATURE_DISCONNECT);
|
||||
if (ast_test_flag(&perm_opts, OPT_CALLER_HANGUP))
|
||||
ast_set_flag(&(features->features_caller), AST_FEATURE_DISCONNECT);
|
||||
if (ast_test_flag(&perm_opts, OPT_CALLEE_MONITOR))
|
||||
ast_set_flag(&(features->features_callee), AST_FEATURE_AUTOMON);
|
||||
if (ast_test_flag(&perm_opts, OPT_CALLER_MONITOR))
|
||||
ast_set_flag(&(features->features_caller), AST_FEATURE_AUTOMON);
|
||||
if (ast_test_flag(&perm_opts, OPT_CALLEE_PARK))
|
||||
ast_set_flag(&(features->features_callee), AST_FEATURE_PARKCALL);
|
||||
if (ast_test_flag(&perm_opts, OPT_CALLER_PARK))
|
||||
ast_set_flag(&(features->features_caller), AST_FEATURE_PARKCALL);
|
||||
}
|
||||
|
||||
static void end_bridge_callback (void *data)
|
||||
{
|
||||
char buf[80];
|
||||
@@ -906,9 +877,6 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
|
||||
struct ast_flags opts = { 0, };
|
||||
char *opt_args[OPT_ARG_ARRAY_SIZE];
|
||||
struct ast_datastore *datastore = NULL;
|
||||
struct ast_datastore *ds_caller_features = NULL;
|
||||
struct ast_datastore *ds_callee_features = NULL;
|
||||
struct ast_dial_features *caller_features;
|
||||
int fulldial = 0, num_dialed = 0;
|
||||
|
||||
if (ast_strlen_zero(data)) {
|
||||
@@ -1172,25 +1140,6 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
|
||||
|
||||
ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING);
|
||||
|
||||
/* Create datastore for channel dial features for caller */
|
||||
if (!(ds_caller_features = ast_channel_datastore_alloc(&dial_features_info, NULL))) {
|
||||
ast_log(LOG_WARNING, "Unable to create channel datastore for dial features. Aborting!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(caller_features = ast_calloc(1, sizeof(*caller_features)))) {
|
||||
ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ast_channel_lock(chan);
|
||||
caller_features->is_caller = 1;
|
||||
set_dial_features(&opts, caller_features);
|
||||
ds_caller_features->inheritance = -1;
|
||||
ds_caller_features->data = caller_features;
|
||||
ast_channel_datastore_add(chan, ds_caller_features);
|
||||
ast_channel_unlock(chan);
|
||||
|
||||
/* loop through the list of dial destinations */
|
||||
rest = args.peers;
|
||||
while ((cur = strsep(&rest, "&")) ) {
|
||||
@@ -1201,7 +1150,6 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
|
||||
char *tech = strsep(&number, "/");
|
||||
/* find if we already dialed this interface */
|
||||
struct ast_dialed_interface *di;
|
||||
struct ast_dial_features *callee_features;
|
||||
AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
|
||||
num_dialed++;
|
||||
if (!number) {
|
||||
@@ -1351,27 +1299,6 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
|
||||
else
|
||||
ast_copy_string(tmp->chan->exten, chan->exten, sizeof(tmp->chan->exten));
|
||||
|
||||
/* Save callee features */
|
||||
if (!(ds_callee_features = ast_channel_datastore_alloc(&dial_features_info, NULL))) {
|
||||
ast_log(LOG_WARNING, "Unable to create channel datastore for dial features. Aborting!\n");
|
||||
ast_free(tmp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(callee_features = ast_calloc(1, sizeof(*callee_features)))) {
|
||||
ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n");
|
||||
ast_free(tmp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ast_channel_lock(tmp->chan);
|
||||
callee_features->is_caller = 0;
|
||||
set_dial_features(&opts, callee_features);
|
||||
ds_callee_features->inheritance = -1;
|
||||
ds_callee_features->data = callee_features;
|
||||
ast_channel_datastore_add(tmp->chan, ds_callee_features);
|
||||
ast_channel_unlock(tmp->chan);
|
||||
|
||||
/* Place the call, but don't wait on the answer */
|
||||
res = ast_call(tmp->chan, numsubst, 0);
|
||||
|
||||
|
Reference in New Issue
Block a user