summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2016-01-25 10:23:18 -0600
committerMark Michelson <mmichelson@digium.com>2016-01-26 10:22:59 -0600
commit4a3275abb9e6528f5bacbb454446a3e2e7115d88 (patch)
treea35221f09112577c6c942d86098cef8b923b709c
parentfcb6c1737d586d5e574d3c2f865157a9632979a7 (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
-rw-r--r--res/stasis/control.c49
1 files changed, 45 insertions, 4 deletions
diff --git a/res/stasis/control.c b/res/stasis/control.c
index 57b5e9964..ebb7e0194 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;
}