Index: funcs/func_math.c =================================================================== --- funcs/func_math.c (revision 192353) +++ funcs/func_math.c (working copy) @@ -4,6 +4,7 @@ * Copyright (C) 2004 - 2006, Andy Powell * * Updated by Mark Spencer + * Updated by Nir Simionovich * * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact @@ -22,6 +23,7 @@ * * \author Andy Powell * \author Mark Spencer + * \author Nir Simionovich * * \ingroup functions */ @@ -66,6 +68,40 @@ Example: Set(i=${MATH(123%16,int)}) - sets var i=11 + + + Increments the value of a variable, while returning the updated value to the dialplan + + + + + The variable name to be manipulated, without the braces. + + + + + Increments the value of a variable, while returning the updated value to the dialplan + Example: INC(MyVAR) - Increments MyVar + Note: INC(${MyVAR}) - Is wrong, as INC expects the variable name, not its value + + + + + Decrements the value of a variable, while returning the updated value to the dialplan + + + + + The variable name to be manipulated, without the braces. + + + + + Decrements the value of a variable, while returning the updated value to the dialplan + Example: DEC(MyVAR) - Increments MyVar + Note: DEC(${MyVAR}) - Is wrong, as INC expects the variable name, not its value + + ***/ enum TypeOfFunctions { @@ -333,19 +369,106 @@ return 0; } +static int var_function_read(struct ast_channel *chan, const char *cmd, + char *data, char *buf, size_t len) +{ + int ret = -1; + int int_value = 0; + int modify_orig = 0; + const char *var; + char returnvar[32]; /* If you need a variable longer than 32 digits - something is way wrong */ + + if (ast_strlen_zero(data)) { + ast_log(LOG_WARNING, "Syntax: %s() - missing argument!\n",cmd); + return -1; + } + + ast_channel_lock(chan); + + if ((var = pbx_builtin_getvar_helper(chan, data))) { + var = ast_strdupa(var); + } + + if (ast_strlen_zero(var)) { + ast_log(LOG_NOTICE, "Variable %s doesn't exist - are you sure you wrote it corrrectly?\n",data); + ast_channel_unlock(chan); + return -1; + } + + if (!ast_is_numeric(var)) { + ast_log(LOG_NOTICE, "The content of %s is not a numeric value - bailing out!\n",data); + ast_channel_unlock(chan); + return -1; + } + + /* now we convert from the string in var to int_value */ + int_value = atoi(var); + + /* now we'll actually do something useful */ + if (!strcasecmp(cmd, "INC")) { /* INC variable */ + int_value++; + modify_orig = 1; + } else if (!strcasecmp(cmd, "DEC")) { /* DEC variable */ + int_value--; + modify_orig = 1; + } + + ast_log(LOG_NOTICE,"The value is now: %d\n",int_value); + + if (snprintf(returnvar,sizeof(returnvar),"%d",int_value) > 0) { + pbx_builtin_setvar_helper(chan, data, returnvar); + if (modify_orig) + ast_copy_string(buf, returnvar, len); + ret = 0; + } else { + pbx_builtin_setvar_helper(chan, data, "0"); + if (modify_orig) + ast_copy_string(buf, "0", len); + ast_log(LOG_NOTICE, "Variable %s refused to be %sREMENTED, setting value to 0",data,cmd); + ret = 0; + } + + ast_channel_unlock(chan); + + return ret; +} + + static struct ast_custom_function math_function = { .name = "MATH", .read = math }; +static struct ast_custom_function var_inc_function = { + .name = "INC", + .read = var_function_read, +}; + +static struct ast_custom_function var_dec_function = { + .name = "DEC", + .read = var_function_read, +}; + static int unload_module(void) { - return ast_custom_function_unregister(&math_function); + int res = 0; + + res |= ast_custom_function_unregister(&math_function); + res |= ast_custom_function_unregister(&var_inc_function); + res |= ast_custom_function_unregister(&var_dec_function); + + return res; } static int load_module(void) { - return ast_custom_function_register(&math_function); + int res = 0; + + res |= ast_custom_function_register(&math_function); + res |= ast_custom_function_register(&var_inc_function); + res |= ast_custom_function_register(&var_dec_function); + + return res; } AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Mathematical dialplan function");