diff options
author | Mark Michelson <mmichelson@digium.com> | 2016-01-25 10:23:18 -0600 |
---|---|---|
committer | Mark Michelson <mmichelson@digium.com> | 2016-01-26 10:25:43 -0600 |
commit | a706ad44e6834da6034ce6b179195d161f782a61 (patch) | |
tree | 1d1adecedf7e8d9904bfcc52ed71fce2fe1179ec /res | |
parent | f8bf72a417bf5e6d6149b657fa806174b82430ce (diff) |
Stasis: Use custom structure when setting variables.
A recent change to queue channel variable setting to the Stasis control
queue caused a regression. When setting channel variables, it is
possible to give a NULL channel variable value in order to unset the
variable (i.e. remove it from the channel variable list). The change
introduced a call to ast_variable_new(), which is not tolerant of NULL
channel variable values.
This new change switches from using ast_variable to using a custom
channel variable struct that is lighter weight and NULL value-tolerant.
Change-Id: I784d7beaaa3c036ea936d103e7caf0bb1562162d
Diffstat (limited to 'res')
-rw-r--r-- | res/stasis/control.c | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/res/stasis/control.c b/res/stasis/control.c index 903b5752d..41d538cbe 100644 --- a/res/stasis/control.c +++ b/res/stasis/control.c @@ -623,10 +623,36 @@ int stasis_app_control_unmute(struct stasis_app_control *control, unsigned int d return 0; } +/*! + * \brief structure for queuing ARI channel variable setting + * + * It may seem weird to define this custom structure given that we already have + * ast_var_t and ast_variable defined elsewhere. The problem with those is that + * they are not tolerant of NULL channel variable value pointers. In fact, in both + * cases, the best they could do is to have a zero-length variable value. However, + * when un-setting a channel variable, it is important to pass a NULL value, not + * a zero-length string. + */ +struct chanvar { + /*! Name of variable to set/unset */ + char *name; + /*! Value of variable to set. If unsetting, this will be NULL */ + char *value; +}; + +static void free_chanvar(void *data) +{ + struct chanvar *var = data; + + ast_free(var->name); + ast_free(var->value); + ast_free(var); +} + static int app_control_set_channel_var(struct stasis_app_control *control, struct ast_channel *chan, void *data) { - struct ast_variable *var = data; + struct chanvar *var = data; pbx_builtin_setvar_helper(control->channel, var->name, var->value); @@ -635,14 +661,29 @@ static int app_control_set_channel_var(struct stasis_app_control *control, int stasis_app_control_set_channel_var(struct stasis_app_control *control, const char *variable, const char *value) { - struct ast_variable *var; + struct chanvar *var; - var = ast_variable_new(variable, value, "ARI"); + var = ast_calloc(1, sizeof(*var)); if (!var) { return -1; } - stasis_app_send_command_async(control, app_control_set_channel_var, var, ast_free_ptr); + var->name = ast_strdup(variable); + if (!var->name) { + free_chanvar(var); + return -1; + } + + /* It's kosher for value to be NULL. It means the variable is being unset */ + if (value) { + var->value = ast_strdup(value); + if (!var->value) { + free_chanvar(var); + return -1; + } + } + + stasis_app_send_command_async(control, app_control_set_channel_var, var, free_chanvar); return 0; } |