Wed Apr 6 11:30:05 2011

Asterisk developer's documentation


func_math.c File Reference

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

static void __reg_module (void)
static void __unreg_module (void)
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_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Mathematical dialplan function" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_custom_function decrement_function
static struct ast_custom_function increment_function
static struct ast_custom_function math_function


Detailed Description

Math related dialplan function.

Author:
Andy Powell

Mark Spencer <markster@digium.com>

Nir Simionovich <nirs@greenfieldtech.net>

Definition in file func_math.c.


Enumeration Type Documentation

enum TypeOfFunctions

Enumerator:
ADDFUNCTION 
DIVIDEFUNCTION 
MULTIPLYFUNCTION 
SUBTRACTFUNCTION 
MODULUSFUNCTION 
POWFUNCTION 
SHLEFTFUNCTION 
SHRIGHTFUNCTION 
BITWISEANDFUNCTION 
BITWISEXORFUNCTION 
BITWISEORFUNCTION 
GTFUNCTION 
LTFUNCTION 
GTEFUNCTION 
LTEFUNCTION 
EQFUNCTION 

Definition at line 108 of file func_math.c.

enum TypeOfResult

Enumerator:
FLOAT_RESULT 
INT_RESULT 
HEX_RESULT 
CHAR_RESULT 

Definition at line 127 of file func_math.c.

00127                   {
00128    FLOAT_RESULT,
00129    INT_RESULT,
00130    HEX_RESULT,
00131    CHAR_RESULT
00132 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 532 of file func_math.c.

static void __unreg_module ( void   )  [static]

Definition at line 532 of file func_math.c.

static int crement_function_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Definition at line 377 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.

00379 {
00380    int ret = -1;
00381    int int_value = 0;
00382    int modify_orig = 0;
00383    const char *var;
00384    char endchar = 0, returnvar[12]; /* If you need a variable longer than 11 digits - something is way wrong */
00385 
00386    if (ast_strlen_zero(data)) {
00387       ast_log(LOG_WARNING, "Syntax: %s(<data>) - missing argument!\n", cmd);
00388       return -1;
00389    }
00390 
00391    ast_channel_lock(chan);
00392 
00393    if (!(var = pbx_builtin_getvar_helper(chan, data))) {
00394       ast_log(LOG_NOTICE, "Failed to obtain variable %s, bailing out\n", data);
00395       ast_channel_unlock(chan);
00396       return -1;
00397    }
00398 
00399    if (ast_strlen_zero(var)) {
00400       ast_log(LOG_NOTICE, "Variable %s doesn't exist - are you sure you wrote it correctly?\n", data);
00401       ast_channel_unlock(chan);
00402       return -1;
00403    }
00404 
00405    if (sscanf(var, "%30d%1c", &int_value, &endchar) == 0 || endchar != 0) {
00406       ast_log(LOG_NOTICE, "The content of ${%s} is not a numeric value - bailing out!\n", data);
00407       ast_channel_unlock(chan);
00408       return -1;
00409    }
00410 
00411    /* now we'll actually do something useful */
00412    if (!strcasecmp(cmd, "INC")) {              /* Increment variable */
00413       int_value++;
00414       modify_orig = 1;
00415    } else if (!strcasecmp(cmd, "DEC")) {       /* Decrement variable */
00416       int_value--;
00417       modify_orig = 1;
00418    }
00419 
00420    ast_log(LOG_NOTICE, "The value is now: %d\n", int_value);
00421 
00422    if (snprintf(returnvar, sizeof(returnvar), "%d", int_value) > 0) {
00423       pbx_builtin_setvar_helper(chan, data, returnvar);
00424       if (modify_orig) {
00425          ast_copy_string(buf, returnvar, len);
00426       }
00427       ret = 0;
00428    } else {
00429       pbx_builtin_setvar_helper(chan, data, "0");
00430       if (modify_orig) {
00431          ast_copy_string(buf, "0", len);
00432       }
00433       ast_log(LOG_NOTICE, "Variable %s refused to be %sREMENTED, setting value to 0", data, cmd);
00434       ret = 0;
00435    }
00436 
00437    ast_channel_unlock(chan);
00438 
00439    return ret;
00440 }

static int load_module ( void   )  [static]

Definition at line 520 of file func_math.c.

References ast_custom_function_register, AST_TEST_REGISTER, decrement_function, increment_function, and math_function.

00521 {
00522    int res = 0;
00523 
00524    res |= ast_custom_function_register(&math_function);
00525    res |= ast_custom_function_register(&increment_function);
00526    res |= ast_custom_function_register(&decrement_function);
00527    AST_TEST_REGISTER(test_MATH_function);
00528 
00529    return res;
00530 }

static int math ( struct ast_channel chan,
const char *  cmd,
char *  parse,
char *  buf,
size_t  len 
) [static]

Definition at line 134 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, DIVIDEFUNCTION, FLOAT_RESULT, GTEFUNCTION, GTFUNCTION, HEX_RESULT, INT_RESULT, LOG_WARNING, LTEFUNCTION, LTFUNCTION, MODULUSFUNCTION, MULTIPLYFUNCTION, POWFUNCTION, SHLEFTFUNCTION, SHRIGHTFUNCTION, and SUBTRACTFUNCTION.

00136 {
00137    double fnum1;
00138    double fnum2;
00139    double ftmp = 0;
00140    char *op;
00141    int iaction = -1;
00142    int type_of_result = FLOAT_RESULT;
00143    char *mvalue1, *mvalue2 = NULL, *mtype_of_result;
00144    int negvalue1 = 0;
00145    AST_DECLARE_APP_ARGS(args,
00146               AST_APP_ARG(argv0);
00147               AST_APP_ARG(argv1);
00148    );
00149 
00150    if (ast_strlen_zero(parse)) {
00151       ast_log(LOG_WARNING, "Syntax: MATH(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n");
00152       return -1;
00153    }
00154 
00155    AST_STANDARD_APP_ARGS(args, parse);
00156 
00157    if (args.argc < 1) {
00158       ast_log(LOG_WARNING, "Syntax: MATH(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n");
00159       return -1;
00160    }
00161 
00162    mvalue1 = args.argv0;
00163 
00164    if (mvalue1[0] == '-') {
00165       negvalue1 = 1;
00166       mvalue1++;
00167    }
00168 
00169    if ((op = strchr(mvalue1, '*'))) {
00170       iaction = MULTIPLYFUNCTION;
00171       *op = '\0';
00172    } else if ((op = strchr(mvalue1, '/'))) {
00173       iaction = DIVIDEFUNCTION;
00174       *op = '\0';
00175    } else if ((op = strchr(mvalue1, '%'))) {
00176       iaction = MODULUSFUNCTION;
00177       *op = '\0';
00178    } else if ((op = strchr(mvalue1, '^'))) {
00179       iaction = POWFUNCTION;
00180       *op = '\0';
00181    } else if ((op = strstr(mvalue1, "AND"))) {
00182       iaction = BITWISEANDFUNCTION;
00183       *op = '\0';
00184       op += 2;
00185    } else if ((op = strstr(mvalue1, "XOR"))) {
00186       iaction = BITWISEXORFUNCTION;
00187       *op = '\0';
00188       op += 2;
00189    } else if ((op = strstr(mvalue1, "OR"))) {
00190       iaction = BITWISEORFUNCTION;
00191       *op = '\0';
00192       ++op;
00193    } else if ((op = strchr(mvalue1, '>'))) {
00194       iaction = GTFUNCTION;
00195       *op = '\0';
00196       if (*(op + 1) == '=') {
00197          iaction = GTEFUNCTION;
00198          ++op;
00199       } else if (*(op + 1) == '>') {
00200          iaction = SHRIGHTFUNCTION;
00201          ++op;
00202       }
00203    } else if ((op = strchr(mvalue1, '<'))) {
00204       iaction = LTFUNCTION;
00205       *op = '\0';
00206       if (*(op + 1) == '=') {
00207          iaction = LTEFUNCTION;
00208          ++op;
00209       } else if (*(op + 1) == '<') {
00210          iaction = SHLEFTFUNCTION;
00211          ++op;
00212       }
00213    } else if ((op = strchr(mvalue1, '='))) {
00214       *op = '\0';
00215       if (*(op + 1) == '=') {
00216          iaction = EQFUNCTION;
00217          ++op;
00218       } else
00219          op = NULL;
00220    } else if ((op = strchr(mvalue1, '+'))) {
00221       iaction = ADDFUNCTION;
00222       *op = '\0';
00223    } else if ((op = strchr(mvalue1, '-'))) { /* subtraction MUST always be last, in case we have a negative second number */
00224       iaction = SUBTRACTFUNCTION;
00225       *op = '\0';
00226    }
00227 
00228    if (op)
00229       mvalue2 = op + 1;
00230 
00231    /* detect wanted type of result */
00232    mtype_of_result = args.argv1;
00233    if (mtype_of_result) {
00234       if (!strcasecmp(mtype_of_result, "float")
00235           || !strcasecmp(mtype_of_result, "f"))
00236          type_of_result = FLOAT_RESULT;
00237       else if (!strcasecmp(mtype_of_result, "int")
00238           || !strcasecmp(mtype_of_result, "i"))
00239          type_of_result = INT_RESULT;
00240       else if (!strcasecmp(mtype_of_result, "hex")
00241           || !strcasecmp(mtype_of_result, "h"))
00242          type_of_result = HEX_RESULT;
00243       else if (!strcasecmp(mtype_of_result, "char")
00244           || !strcasecmp(mtype_of_result, "c"))
00245          type_of_result = CHAR_RESULT;
00246       else {
00247          ast_log(LOG_WARNING, "Unknown type of result requested '%s'.\n",
00248                mtype_of_result);
00249          return -1;
00250       }
00251    }
00252 
00253    if (!mvalue1 || !mvalue2) {
00254       ast_log(LOG_WARNING,
00255             "Supply all the parameters - just this once, please\n");
00256       return -1;
00257    }
00258 
00259    if (sscanf(mvalue1, "%30lf", &fnum1) != 1) {
00260       ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue1);
00261       return -1;
00262    }
00263 
00264    if (sscanf(mvalue2, "%30lf", &fnum2) != 1) {
00265       ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue2);
00266       return -1;
00267    }
00268 
00269    if (negvalue1)
00270       fnum1 = 0 - fnum1;
00271 
00272    switch (iaction) {
00273    case ADDFUNCTION:
00274       ftmp = fnum1 + fnum2;
00275       break;
00276    case DIVIDEFUNCTION:
00277       if (fnum2 <= 0)
00278          ftmp = 0;         /* can't do a divide by 0 */
00279       else
00280          ftmp = (fnum1 / fnum2);
00281       break;
00282    case MULTIPLYFUNCTION:
00283       ftmp = (fnum1 * fnum2);
00284       break;
00285    case SUBTRACTFUNCTION:
00286       ftmp = (fnum1 - fnum2);
00287       break;
00288    case MODULUSFUNCTION:
00289       {
00290          int inum1 = fnum1;
00291          int inum2 = fnum2;
00292 
00293          if (inum2 == 0) {
00294             ftmp = 0;
00295          } else {
00296             ftmp = (inum1 % inum2);
00297          }
00298 
00299          break;
00300       }
00301    case POWFUNCTION:
00302       ftmp = pow(fnum1, fnum2);
00303       break;
00304    case SHLEFTFUNCTION:
00305       {
00306          int inum1 = fnum1;
00307          int inum2 = fnum2;
00308 
00309          ftmp = (inum1 << inum2);
00310          break;
00311       }
00312    case SHRIGHTFUNCTION:
00313       {
00314          int inum1 = fnum1;
00315          int inum2 = fnum2;
00316 
00317          ftmp = (inum1 >> inum2);
00318          break;
00319       }
00320    case BITWISEANDFUNCTION:
00321       {
00322          int inum1 = fnum1;
00323          int inum2 = fnum2;
00324          ftmp = (inum1 & inum2);
00325          break;
00326       }
00327    case BITWISEXORFUNCTION:
00328       {
00329          int inum1 = fnum1;
00330          int inum2 = fnum2;
00331          ftmp = (inum1 ^ inum2);
00332          break;
00333       }
00334    case BITWISEORFUNCTION:
00335       {
00336          int inum1 = fnum1;
00337          int inum2 = fnum2;
00338          ftmp = (inum1 | inum2);
00339          break;
00340       }
00341    case GTFUNCTION:
00342       ast_copy_string(buf, (fnum1 > fnum2) ? "TRUE" : "FALSE", len);
00343       break;
00344    case LTFUNCTION:
00345       ast_copy_string(buf, (fnum1 < fnum2) ? "TRUE" : "FALSE", len);
00346       break;
00347    case GTEFUNCTION:
00348       ast_copy_string(buf, (fnum1 >= fnum2) ? "TRUE" : "FALSE", len);
00349       break;
00350    case LTEFUNCTION:
00351       ast_copy_string(buf, (fnum1 <= fnum2) ? "TRUE" : "FALSE", len);
00352       break;
00353    case EQFUNCTION:
00354       ast_copy_string(buf, (fnum1 == fnum2) ? "TRUE" : "FALSE", len);
00355       break;
00356    default:
00357       ast_log(LOG_WARNING,
00358             "Something happened that neither of us should be proud of %d\n",
00359             iaction);
00360       return -1;
00361    }
00362 
00363    if (iaction < GTFUNCTION || iaction > EQFUNCTION) {
00364       if (type_of_result == FLOAT_RESULT)
00365          snprintf(buf, len, "%f", ftmp);
00366       else if (type_of_result == INT_RESULT)
00367          snprintf(buf, len, "%i", (int) ftmp);
00368       else if (type_of_result == HEX_RESULT)
00369          snprintf(buf, len, "%x", (unsigned int) ftmp);
00370       else if (type_of_result == CHAR_RESULT)
00371          snprintf(buf, len, "%c", (unsigned char) ftmp);
00372    }
00373 
00374    return 0;
00375 }

static int unload_module ( void   )  [static]

Definition at line 508 of file func_math.c.

References ast_custom_function_unregister(), AST_TEST_UNREGISTER, decrement_function, increment_function, and math_function.

00509 {
00510    int res = 0;
00511 
00512    res |= ast_custom_function_unregister(&math_function);
00513    res |= ast_custom_function_unregister(&increment_function);
00514    res |= ast_custom_function_unregister(&decrement_function);
00515    AST_TEST_UNREGISTER(test_MATH_function);
00516 
00517    return res;
00518 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Mathematical dialplan function" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 532 of file func_math.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 532 of file func_math.c.

struct ast_custom_function decrement_function [static]

Initial value:

 {
   .name = "DEC",
   .read = crement_function_read,
}

Definition at line 453 of file func_math.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function increment_function [static]

Initial value:

 {
   .name = "INC",
   .read = crement_function_read,
}

Definition at line 448 of file func_math.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function math_function [static]

Initial value:

 {
   .name = "MATH",
   .read = math
}

Definition at line 443 of file func_math.c.

Referenced by load_module(), and unload_module().


Generated on Wed Apr 6 11:30:05 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7