Math related dialplan function. More...
#include "asterisk.h"
#include <math.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/config.h"
#include "asterisk/test.h"
Go to the source code of this file.
Enumerations | |
enum | TypeOfFunctions { ADDFUNCTION, DIVIDEFUNCTION, MULTIPLYFUNCTION, SUBTRACTFUNCTION, MODULUSFUNCTION, POWFUNCTION, SHLEFTFUNCTION, SHRIGHTFUNCTION, BITWISEANDFUNCTION, BITWISEXORFUNCTION, BITWISEORFUNCTION, GTFUNCTION, LTFUNCTION, GTEFUNCTION, LTEFUNCTION, EQFUNCTION } |
enum | TypeOfResult { FLOAT_RESULT, INT_RESULT, HEX_RESULT, CHAR_RESULT } |
Functions | |
AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Mathematical dialplan function") | |
static int | crement_function_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
static int | load_module (void) |
static int | math (struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len) |
static int | unload_module (void) |
Variables | |
static struct ast_custom_function | decrement_function |
static struct ast_custom_function | increment_function |
static struct ast_custom_function | math_function |
Math related dialplan function.
Definition in file func_math.c.
enum TypeOfFunctions |
Definition at line 112 of file func_math.c.
00112 { 00113 ADDFUNCTION, 00114 DIVIDEFUNCTION, 00115 MULTIPLYFUNCTION, 00116 SUBTRACTFUNCTION, 00117 MODULUSFUNCTION, 00118 POWFUNCTION, 00119 SHLEFTFUNCTION, 00120 SHRIGHTFUNCTION, 00121 BITWISEANDFUNCTION, 00122 BITWISEXORFUNCTION, 00123 BITWISEORFUNCTION, 00124 GTFUNCTION, 00125 LTFUNCTION, 00126 GTEFUNCTION, 00127 LTEFUNCTION, 00128 EQFUNCTION 00129 };
enum TypeOfResult |
Definition at line 131 of file func_math.c.
00131 { 00132 FLOAT_RESULT, 00133 INT_RESULT, 00134 HEX_RESULT, 00135 CHAR_RESULT 00136 };
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"Mathematical dialplan function" | ||||
) |
static int crement_function_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 381 of file func_math.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), ast_strlen_zero(), LOG_NOTICE, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and var.
00383 { 00384 int ret = -1; 00385 int int_value = 0; 00386 int modify_orig = 0; 00387 const char *var; 00388 char endchar = 0, returnvar[12]; /* If you need a variable longer than 11 digits - something is way wrong */ 00389 00390 if (ast_strlen_zero(data)) { 00391 ast_log(LOG_WARNING, "Syntax: %s(<data>) - missing argument!\n", cmd); 00392 return -1; 00393 } 00394 00395 if (!chan) { 00396 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd); 00397 return -1; 00398 } 00399 00400 ast_channel_lock(chan); 00401 00402 if (!(var = pbx_builtin_getvar_helper(chan, data))) { 00403 ast_log(LOG_NOTICE, "Failed to obtain variable %s, bailing out\n", data); 00404 ast_channel_unlock(chan); 00405 return -1; 00406 } 00407 00408 if (ast_strlen_zero(var)) { 00409 ast_log(LOG_NOTICE, "Variable %s doesn't exist - are you sure you wrote it correctly?\n", data); 00410 ast_channel_unlock(chan); 00411 return -1; 00412 } 00413 00414 if (sscanf(var, "%30d%1c", &int_value, &endchar) == 0 || endchar != 0) { 00415 ast_log(LOG_NOTICE, "The content of ${%s} is not a numeric value - bailing out!\n", data); 00416 ast_channel_unlock(chan); 00417 return -1; 00418 } 00419 00420 /* now we'll actually do something useful */ 00421 if (!strcasecmp(cmd, "INC")) { /* Increment variable */ 00422 int_value++; 00423 modify_orig = 1; 00424 } else if (!strcasecmp(cmd, "DEC")) { /* Decrement variable */ 00425 int_value--; 00426 modify_orig = 1; 00427 } 00428 00429 if (snprintf(returnvar, sizeof(returnvar), "%d", int_value) > 0) { 00430 pbx_builtin_setvar_helper(chan, data, returnvar); 00431 if (modify_orig) { 00432 ast_copy_string(buf, returnvar, len); 00433 } 00434 ret = 0; 00435 } else { 00436 pbx_builtin_setvar_helper(chan, data, "0"); 00437 if (modify_orig) { 00438 ast_copy_string(buf, "0", len); 00439 } 00440 ast_log(LOG_NOTICE, "Variable %s refused to be %sREMENTED, setting value to 0", data, cmd); 00441 ret = 0; 00442 } 00443 00444 ast_channel_unlock(chan); 00445 00446 return ret; 00447 }
static int load_module | ( | void | ) | [static] |
Definition at line 530 of file func_math.c.
References ast_custom_function_register, and AST_TEST_REGISTER.
00531 { 00532 int res = 0; 00533 00534 res |= ast_custom_function_register(&math_function); 00535 res |= ast_custom_function_register(&increment_function); 00536 res |= ast_custom_function_register(&decrement_function); 00537 AST_TEST_REGISTER(test_MATH_function); 00538 00539 return res; 00540 }
static int math | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 138 of file func_math.c.
References ADDFUNCTION, args, AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), BITWISEANDFUNCTION, BITWISEORFUNCTION, BITWISEXORFUNCTION, CHAR_RESULT, DIVIDEFUNCTION, EQFUNCTION, FLOAT_RESULT, GTEFUNCTION, GTFUNCTION, HEX_RESULT, INT_RESULT, LOG_WARNING, LTEFUNCTION, LTFUNCTION, MODULUSFUNCTION, MULTIPLYFUNCTION, POWFUNCTION, SHLEFTFUNCTION, SHRIGHTFUNCTION, and SUBTRACTFUNCTION.
00140 { 00141 double fnum1; 00142 double fnum2; 00143 double ftmp = 0; 00144 char *op; 00145 int iaction = -1; 00146 int type_of_result = FLOAT_RESULT; 00147 char *mvalue1, *mvalue2 = NULL, *mtype_of_result; 00148 int negvalue1 = 0; 00149 AST_DECLARE_APP_ARGS(args, 00150 AST_APP_ARG(argv0); 00151 AST_APP_ARG(argv1); 00152 ); 00153 00154 if (ast_strlen_zero(parse)) { 00155 ast_log(LOG_WARNING, "Syntax: MATH(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n"); 00156 return -1; 00157 } 00158 00159 AST_STANDARD_APP_ARGS(args, parse); 00160 00161 if (args.argc < 1) { 00162 ast_log(LOG_WARNING, "Syntax: MATH(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n"); 00163 return -1; 00164 } 00165 00166 mvalue1 = args.argv0; 00167 00168 if (mvalue1[0] == '-') { 00169 negvalue1 = 1; 00170 mvalue1++; 00171 } 00172 00173 if ((op = strchr(mvalue1, '*'))) { 00174 iaction = MULTIPLYFUNCTION; 00175 *op = '\0'; 00176 } else if ((op = strchr(mvalue1, '/'))) { 00177 iaction = DIVIDEFUNCTION; 00178 *op = '\0'; 00179 } else if ((op = strchr(mvalue1, '%'))) { 00180 iaction = MODULUSFUNCTION; 00181 *op = '\0'; 00182 } else if ((op = strchr(mvalue1, '^'))) { 00183 iaction = POWFUNCTION; 00184 *op = '\0'; 00185 } else if ((op = strstr(mvalue1, "AND"))) { 00186 iaction = BITWISEANDFUNCTION; 00187 *op = '\0'; 00188 op += 2; 00189 } else if ((op = strstr(mvalue1, "XOR"))) { 00190 iaction = BITWISEXORFUNCTION; 00191 *op = '\0'; 00192 op += 2; 00193 } else if ((op = strstr(mvalue1, "OR"))) { 00194 iaction = BITWISEORFUNCTION; 00195 *op = '\0'; 00196 ++op; 00197 } else if ((op = strchr(mvalue1, '>'))) { 00198 iaction = GTFUNCTION; 00199 *op = '\0'; 00200 if (*(op + 1) == '=') { 00201 iaction = GTEFUNCTION; 00202 ++op; 00203 } else if (*(op + 1) == '>') { 00204 iaction = SHRIGHTFUNCTION; 00205 ++op; 00206 } 00207 } else if ((op = strchr(mvalue1, '<'))) { 00208 iaction = LTFUNCTION; 00209 *op = '\0'; 00210 if (*(op + 1) == '=') { 00211 iaction = LTEFUNCTION; 00212 ++op; 00213 } else if (*(op + 1) == '<') { 00214 iaction = SHLEFTFUNCTION; 00215 ++op; 00216 } 00217 } else if ((op = strchr(mvalue1, '='))) { 00218 *op = '\0'; 00219 if (*(op + 1) == '=') { 00220 iaction = EQFUNCTION; 00221 ++op; 00222 } else 00223 op = NULL; 00224 } else if ((op = strchr(mvalue1, '+'))) { 00225 iaction = ADDFUNCTION; 00226 *op = '\0'; 00227 } else if ((op = strchr(mvalue1, '-'))) { /* subtraction MUST always be last, in case we have a negative second number */ 00228 iaction = SUBTRACTFUNCTION; 00229 *op = '\0'; 00230 } 00231 00232 if (op) 00233 mvalue2 = op + 1; 00234 00235 /* detect wanted type of result */ 00236 mtype_of_result = args.argv1; 00237 if (mtype_of_result) { 00238 if (!strcasecmp(mtype_of_result, "float") 00239 || !strcasecmp(mtype_of_result, "f")) 00240 type_of_result = FLOAT_RESULT; 00241 else if (!strcasecmp(mtype_of_result, "int") 00242 || !strcasecmp(mtype_of_result, "i")) 00243 type_of_result = INT_RESULT; 00244 else if (!strcasecmp(mtype_of_result, "hex") 00245 || !strcasecmp(mtype_of_result, "h")) 00246 type_of_result = HEX_RESULT; 00247 else if (!strcasecmp(mtype_of_result, "char") 00248 || !strcasecmp(mtype_of_result, "c")) 00249 type_of_result = CHAR_RESULT; 00250 else { 00251 ast_log(LOG_WARNING, "Unknown type of result requested '%s'.\n", 00252 mtype_of_result); 00253 return -1; 00254 } 00255 } 00256 00257 if (!mvalue2) { 00258 ast_log(LOG_WARNING, 00259 "Supply all the parameters - just this once, please\n"); 00260 return -1; 00261 } 00262 00263 if (sscanf(mvalue1, "%30lf", &fnum1) != 1) { 00264 ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue1); 00265 return -1; 00266 } 00267 00268 if (sscanf(mvalue2, "%30lf", &fnum2) != 1) { 00269 ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue2); 00270 return -1; 00271 } 00272 00273 if (negvalue1) 00274 fnum1 = 0 - fnum1; 00275 00276 switch (iaction) { 00277 case ADDFUNCTION: 00278 ftmp = fnum1 + fnum2; 00279 break; 00280 case DIVIDEFUNCTION: 00281 if (fnum2 <= 0) 00282 ftmp = 0; /* can't do a divide by 0 */ 00283 else 00284 ftmp = (fnum1 / fnum2); 00285 break; 00286 case MULTIPLYFUNCTION: 00287 ftmp = (fnum1 * fnum2); 00288 break; 00289 case SUBTRACTFUNCTION: 00290 ftmp = (fnum1 - fnum2); 00291 break; 00292 case MODULUSFUNCTION: 00293 { 00294 int inum1 = fnum1; 00295 int inum2 = fnum2; 00296 00297 if (inum2 == 0) { 00298 ftmp = 0; 00299 } else { 00300 ftmp = (inum1 % inum2); 00301 } 00302 00303 break; 00304 } 00305 case POWFUNCTION: 00306 ftmp = pow(fnum1, fnum2); 00307 break; 00308 case SHLEFTFUNCTION: 00309 { 00310 int inum1 = fnum1; 00311 int inum2 = fnum2; 00312 00313 ftmp = (inum1 << inum2); 00314 break; 00315 } 00316 case SHRIGHTFUNCTION: 00317 { 00318 int inum1 = fnum1; 00319 int inum2 = fnum2; 00320 00321 ftmp = (inum1 >> inum2); 00322 break; 00323 } 00324 case BITWISEANDFUNCTION: 00325 { 00326 int inum1 = fnum1; 00327 int inum2 = fnum2; 00328 ftmp = (inum1 & inum2); 00329 break; 00330 } 00331 case BITWISEXORFUNCTION: 00332 { 00333 int inum1 = fnum1; 00334 int inum2 = fnum2; 00335 ftmp = (inum1 ^ inum2); 00336 break; 00337 } 00338 case BITWISEORFUNCTION: 00339 { 00340 int inum1 = fnum1; 00341 int inum2 = fnum2; 00342 ftmp = (inum1 | inum2); 00343 break; 00344 } 00345 case GTFUNCTION: 00346 ast_copy_string(buf, (fnum1 > fnum2) ? "TRUE" : "FALSE", len); 00347 break; 00348 case LTFUNCTION: 00349 ast_copy_string(buf, (fnum1 < fnum2) ? "TRUE" : "FALSE", len); 00350 break; 00351 case GTEFUNCTION: 00352 ast_copy_string(buf, (fnum1 >= fnum2) ? "TRUE" : "FALSE", len); 00353 break; 00354 case LTEFUNCTION: 00355 ast_copy_string(buf, (fnum1 <= fnum2) ? "TRUE" : "FALSE", len); 00356 break; 00357 case EQFUNCTION: 00358 ast_copy_string(buf, (fnum1 == fnum2) ? "TRUE" : "FALSE", len); 00359 break; 00360 default: 00361 ast_log(LOG_WARNING, 00362 "Something happened that neither of us should be proud of %d\n", 00363 iaction); 00364 return -1; 00365 } 00366 00367 if (iaction < GTFUNCTION || iaction > EQFUNCTION) { 00368 if (type_of_result == FLOAT_RESULT) 00369 snprintf(buf, len, "%f", ftmp); 00370 else if (type_of_result == INT_RESULT) 00371 snprintf(buf, len, "%i", (int) ftmp); 00372 else if (type_of_result == HEX_RESULT) 00373 snprintf(buf, len, "%x", (unsigned int) ftmp); 00374 else if (type_of_result == CHAR_RESULT) 00375 snprintf(buf, len, "%c", (unsigned char) ftmp); 00376 } 00377 00378 return 0; 00379 }
static int unload_module | ( | void | ) | [static] |
Definition at line 518 of file func_math.c.
References ast_custom_function_unregister(), and AST_TEST_UNREGISTER.
00519 { 00520 int res = 0; 00521 00522 res |= ast_custom_function_unregister(&math_function); 00523 res |= ast_custom_function_unregister(&increment_function); 00524 res |= ast_custom_function_unregister(&decrement_function); 00525 AST_TEST_UNREGISTER(test_MATH_function); 00526 00527 return res; 00528 }
struct ast_custom_function decrement_function [static] |
{ .name = "DEC", .read = crement_function_read, }
Definition at line 460 of file func_math.c.
struct ast_custom_function increment_function [static] |
{ .name = "INC", .read = crement_function_read, }
Definition at line 455 of file func_math.c.
struct ast_custom_function math_function [static] |
{ .name = "MATH", .read = math }
Definition at line 450 of file func_math.c.