diff options
Diffstat (limited to 'apps/app_dial.c')
-rw-r--r-- | apps/app_dial.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/apps/app_dial.c b/apps/app_dial.c index dc818fac7..f93ba0de9 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -1208,6 +1208,19 @@ static int setup_privacy_args(struct privacy_args *pa, return 1; /* success */ } +static void set_dial_features(struct ast_flags64 *opts, struct ast_dial_features *features) +{ + struct ast_flags64 perm_opts = {.flags = 0}; + + ast_copy_flags64(&perm_opts, opts, + OPT_CALLER_TRANSFER | OPT_CALLER_PARK | OPT_CALLER_MONITOR | OPT_CALLER_MIXMONITOR | OPT_CALLER_HANGUP | + OPT_CALLEE_TRANSFER | OPT_CALLEE_PARK | OPT_CALLEE_MONITOR | OPT_CALLEE_MIXMONITOR | OPT_CALLEE_HANGUP); + + memset(features->options, 0, sizeof(features->options)); + + ast_app_options2str64(dial_exec_options, &perm_opts, features->options, sizeof(features->options)); +} + static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags64 *peerflags, int *continue_exec) { int res = -1; /* default: error */ @@ -1243,6 +1256,9 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags struct ast_flags64 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)) { @@ -1316,6 +1332,29 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags } ast_copy_flags64(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_malloc(sizeof(*caller_features)))) { + ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n"); + goto out; + } + + ast_copy_flags(&(caller_features->features_callee), &(config.features_caller), AST_FLAGS_ALL); + caller_features->is_caller = 1; + set_dial_features(&opts, caller_features); + + ds_caller_features->inheritance = DATASTORE_INHERIT_FOREVER; + ds_caller_features->data = caller_features; + + ast_channel_lock(chan); + 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, "&")) ) { @@ -1327,6 +1366,7 @@ 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) { @@ -1466,6 +1506,30 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags else ast_copy_string(tc->exten, chan->exten, sizeof(tc->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_malloc(sizeof(*callee_features)))) { + ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n"); + ast_free(tmp); + goto out; + } + + ast_copy_flags(&(callee_features->features_callee), &(config.features_callee), AST_FLAGS_ALL); + callee_features->is_caller = 0; + set_dial_features(&opts, callee_features); + + ds_callee_features->inheritance = DATASTORE_INHERIT_FOREVER; + ds_callee_features->data = callee_features; + + ast_channel_lock(chan); + ast_channel_datastore_add(tc, ds_callee_features); + ast_channel_unlock(chan); + res = ast_call(tc, numsubst, 0); /* Place the call, but don't wait on the answer */ /* Save the info in cdr's that we called them */ |