mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-10 03:48:34 +00:00
Backport fix for 11520--for some reason I didn't do this back in February when I patched for trunk.
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@121992 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -789,6 +789,19 @@ static int valid_priv_reply(struct ast_flags *opts, int res)
|
|||||||
return 0;
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags, int *continue_exec)
|
static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags, int *continue_exec)
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
@@ -831,6 +844,9 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
|
|||||||
struct ast_flags opts = { 0, };
|
struct ast_flags opts = { 0, };
|
||||||
char *opt_args[OPT_ARG_ARRAY_SIZE];
|
char *opt_args[OPT_ARG_ARRAY_SIZE];
|
||||||
struct ast_datastore *datastore = NULL;
|
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;
|
int fulldial = 0, num_dialed = 0;
|
||||||
|
|
||||||
if (ast_strlen_zero(data)) {
|
if (ast_strlen_zero(data)) {
|
||||||
@@ -1086,6 +1102,28 @@ 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);
|
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_malloc(sizeof(*caller_features)))) {
|
||||||
|
ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 */
|
/* loop through the list of dial destinations */
|
||||||
rest = args.peers;
|
rest = args.peers;
|
||||||
while ((cur = strsep(&rest, "&")) ) {
|
while ((cur = strsep(&rest, "&")) ) {
|
||||||
@@ -1096,6 +1134,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
|
|||||||
char *tech = strsep(&number, "/");
|
char *tech = strsep(&number, "/");
|
||||||
/* find if we already dialed this interface */
|
/* find if we already dialed this interface */
|
||||||
struct ast_dialed_interface *di;
|
struct ast_dialed_interface *di;
|
||||||
|
struct ast_dial_features *callee_features;
|
||||||
AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
|
AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
|
||||||
num_dialed++;
|
num_dialed++;
|
||||||
if (!number) {
|
if (!number) {
|
||||||
@@ -1245,6 +1284,30 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
|
|||||||
else
|
else
|
||||||
ast_copy_string(tmp->chan->exten, chan->exten, sizeof(tmp->chan->exten));
|
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_malloc(sizeof(*callee_features)))) {
|
||||||
|
ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n");
|
||||||
|
ast_free(tmp);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(tmp->chan);
|
||||||
|
ast_channel_datastore_add(tmp->chan, ds_callee_features);
|
||||||
|
ast_channel_unlock(tmp->chan);
|
||||||
|
|
||||||
|
|
||||||
/* Place the call, but don't wait on the answer */
|
/* Place the call, but don't wait on the answer */
|
||||||
res = ast_call(tmp->chan, numsubst, 0);
|
res = ast_call(tmp->chan, numsubst, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -411,6 +411,14 @@ struct ast_app_option {
|
|||||||
*/
|
*/
|
||||||
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr);
|
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr);
|
||||||
|
|
||||||
|
/*! \brief Given a list of options array, return an option string based on passed flags
|
||||||
|
\param options The array of possible options declared with AST_APP_OPTIONS
|
||||||
|
\param flags The flags of the options that you wish to populate the buffer with
|
||||||
|
\param buf The buffer to fill with the string of options
|
||||||
|
\param len The maximum length of buf
|
||||||
|
*/
|
||||||
|
void ast_app_options2str(const struct ast_app_option *options, struct ast_flags *flags, char *buf, size_t len);
|
||||||
|
|
||||||
/*! \brief Present a dialtone and collect a certain length extension.
|
/*! \brief Present a dialtone and collect a certain length extension.
|
||||||
\return Returns 1 on valid extension entered, -1 on hangup, or 0 on invalid extension.
|
\return Returns 1 on valid extension entered, -1 on hangup, or 0 on invalid extension.
|
||||||
\note Note that if 'collect' holds digits already, new digits will be appended, so be sure it's initialized properly */
|
\note Note that if 'collect' holds digits already, new digits will be appended, so be sure it's initialized properly */
|
||||||
|
|||||||
@@ -26,11 +26,22 @@
|
|||||||
|
|
||||||
#include "asterisk/channel.h"
|
#include "asterisk/channel.h"
|
||||||
|
|
||||||
|
#define MAX_DIAL_FEATURE_OPTIONS 30
|
||||||
|
|
||||||
extern const struct ast_datastore_info dialed_interface_info;
|
extern const struct ast_datastore_info dialed_interface_info;
|
||||||
|
|
||||||
|
extern const struct ast_datastore_info dial_features_info;
|
||||||
|
|
||||||
struct ast_dialed_interface {
|
struct ast_dialed_interface {
|
||||||
AST_LIST_ENTRY(ast_dialed_interface) list;
|
AST_LIST_ENTRY(ast_dialed_interface) list;
|
||||||
char interface[1];
|
char interface[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ast_dial_features {
|
||||||
|
struct ast_flags features_caller;
|
||||||
|
struct ast_flags features_callee;
|
||||||
|
char options[MAX_DIAL_FEATURE_OPTIONS];
|
||||||
|
int is_caller;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
12
main/app.c
12
main/app.c
@@ -1387,6 +1387,18 @@ char *ast_read_textfile(const char *filename)
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ast_app_options2str(const struct ast_app_option *options, struct ast_flags *flags, char *buf, size_t len)
|
||||||
|
{
|
||||||
|
unsigned int i, found = 0;
|
||||||
|
|
||||||
|
for (i = 32; i < 128 && found < len;i++) {
|
||||||
|
if (ast_test_flag(flags, options[i].flag)) {
|
||||||
|
buf[found++] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf[found] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
|
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
|
|||||||
@@ -35,8 +35,9 @@ static void dialed_interface_destroy(void *data)
|
|||||||
struct ast_dialed_interface *di = NULL;
|
struct ast_dialed_interface *di = NULL;
|
||||||
AST_LIST_HEAD(, ast_dialed_interface) *dialed_interface_list = data;
|
AST_LIST_HEAD(, ast_dialed_interface) *dialed_interface_list = data;
|
||||||
|
|
||||||
if (!dialed_interface_list)
|
if (!dialed_interface_list) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
AST_LIST_LOCK(dialed_interface_list);
|
AST_LIST_LOCK(dialed_interface_list);
|
||||||
while ((di = AST_LIST_REMOVE_HEAD(dialed_interface_list, list)))
|
while ((di = AST_LIST_REMOVE_HEAD(dialed_interface_list, list)))
|
||||||
@@ -53,11 +54,13 @@ static void *dialed_interface_duplicate(void *data)
|
|||||||
AST_LIST_HEAD(, ast_dialed_interface) *old_list;
|
AST_LIST_HEAD(, ast_dialed_interface) *old_list;
|
||||||
AST_LIST_HEAD(, ast_dialed_interface) *new_list = NULL;
|
AST_LIST_HEAD(, ast_dialed_interface) *new_list = NULL;
|
||||||
|
|
||||||
if(!(old_list = data))
|
if(!(old_list = data)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if(!(new_list = ast_calloc(1, sizeof(*new_list))))
|
if(!(new_list = ast_calloc(1, sizeof(*new_list)))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
AST_LIST_HEAD_INIT(new_list);
|
AST_LIST_HEAD_INIT(new_list);
|
||||||
AST_LIST_LOCK(old_list);
|
AST_LIST_LOCK(old_list);
|
||||||
@@ -76,8 +79,35 @@ static void *dialed_interface_duplicate(void *data)
|
|||||||
return new_list;
|
return new_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void *dial_features_duplicate(void *data)
|
||||||
|
{
|
||||||
|
struct ast_dial_features *df = data, *df_copy;
|
||||||
|
|
||||||
|
if (!(df_copy = ast_calloc(1, sizeof(*df)))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(df_copy, df, sizeof(*df));
|
||||||
|
|
||||||
|
return df_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dial_features_destroy(void *data) {
|
||||||
|
struct ast_dial_features *df = data;
|
||||||
|
if (df) {
|
||||||
|
ast_free(df);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const struct ast_datastore_info dialed_interface_info = {
|
const struct ast_datastore_info dialed_interface_info = {
|
||||||
.type ="dialed-interface",
|
.type = "dialed-interface",
|
||||||
.destroy = dialed_interface_destroy,
|
.destroy = dialed_interface_destroy,
|
||||||
.duplicate = dialed_interface_duplicate,
|
.duplicate = dialed_interface_duplicate,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct ast_datastore_info dial_features_info = {
|
||||||
|
.type = "dial-features",
|
||||||
|
.destroy = dial_features_destroy,
|
||||||
|
.duplicate = dial_features_duplicate,
|
||||||
|
};
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
#include "asterisk/adsi.h"
|
#include "asterisk/adsi.h"
|
||||||
#include "asterisk/devicestate.h"
|
#include "asterisk/devicestate.h"
|
||||||
#include "asterisk/monitor.h"
|
#include "asterisk/monitor.h"
|
||||||
|
#include "asterisk/global_datastores.h"
|
||||||
|
|
||||||
#define DEFAULT_PARK_TIME 45000
|
#define DEFAULT_PARK_TIME 45000
|
||||||
#define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
|
#define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
|
||||||
@@ -1711,7 +1712,21 @@ static void *do_parking_thread(void *ignore)
|
|||||||
}
|
}
|
||||||
if (con) {
|
if (con) {
|
||||||
char returnexten[AST_MAX_EXTENSION];
|
char returnexten[AST_MAX_EXTENSION];
|
||||||
|
struct ast_datastore *features_datastore;
|
||||||
|
struct ast_dial_features *dialfeatures = NULL;
|
||||||
|
|
||||||
|
ast_channel_lock(chan);
|
||||||
|
|
||||||
|
if ((features_datastore = ast_channel_datastore_find(chan, &dial_features_info, NULL)))
|
||||||
|
dialfeatures = features_datastore->data;
|
||||||
|
|
||||||
|
ast_channel_unlock(chan);
|
||||||
|
|
||||||
|
if (dialfeatures)
|
||||||
|
snprintf(returnexten, sizeof(returnexten), "%s|30|%s", peername, dialfeatures->options);
|
||||||
|
else /* Existing default */
|
||||||
snprintf(returnexten, sizeof(returnexten), "%s|30|t", peername);
|
snprintf(returnexten, sizeof(returnexten), "%s|30|t", peername);
|
||||||
|
|
||||||
ast_add_extension2(con, 1, peername, 1, NULL, NULL, "Dial", strdup(returnexten), ast_free, registrar);
|
ast_add_extension2(con, 1, peername, 1, NULL, NULL, "Dial", strdup(returnexten), ast_free, registrar);
|
||||||
}
|
}
|
||||||
set_c_e_p(chan, parking_con_dial, peername, 1);
|
set_c_e_p(chan, parking_con_dial, peername, 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user