Mon Mar 19 11:30:48 2012

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 = "88eaa8f5c1bd988bedd71113385e0886" , .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 112 of file func_math.c.

enum TypeOfResult

Enumerator:
FLOAT_RESULT 
INT_RESULT 
HEX_RESULT 
CHAR_RESULT 

Definition at line 131 of file func_math.c.

00131                   {
00132    FLOAT_RESULT,
00133    INT_RESULT,
00134    HEX_RESULT,
00135    CHAR_RESULT
00136 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 536 of file func_math.c.

static void __unreg_module ( void   )  [static]

Definition at line 536 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 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    ast_channel_lock(chan);
00396 
00397    if (!(var = pbx_builtin_getvar_helper(chan, data))) {
00398       ast_log(LOG_NOTICE, "Failed to obtain variable %s, bailing out\n", data);
00399       ast_channel_unlock(chan);
00400       return -1;
00401    }
00402 
00403    if (ast_strlen_zero(var)) {
00404       ast_log(LOG_NOTICE, "Variable %s doesn't exist - are you sure you wrote it correctly?\n", data);
00405       ast_channel_unlock(chan);
00406       return -1;
00407    }
00408 
00409    if (sscanf(var, "%30d%1c", &int_value, &endchar) == 0 || endchar != 0) {
00410       ast_log(LOG_NOTICE, "The content of ${%s} is not a numeric value - bailing out!\n", data);
00411       ast_channel_unlock(chan);
00412       return -1;
00413    }
00414 
00415    /* now we'll actually do something useful */
00416    if (!strcasecmp(cmd, "INC")) {              /* Increment variable */
00417       int_value++;
00418       modify_orig = 1;
00419    } else if (!strcasecmp(cmd, "DEC")) {       /* Decrement variable */
00420       int_value--;
00421       modify_orig = 1;
00422    }
00423 
00424    ast_log(LOG_NOTICE, "The value is now: %d\n", int_value);
00425 
00426    if (snprintf(returnvar, sizeof(returnvar), "%d", int_value) > 0) {
00427       pbx_builtin_setvar_helper(chan, data, returnvar);
00428       if (modify_orig) {
00429          ast_copy_string(buf, returnvar, len);
00430       }
00431       ret = 0;
00432    } else {
00433       pbx_builtin_setvar_helper(chan, data, "0");
00434       if (modify_orig) {
00435          ast_copy_string(buf, "0", len);
00436       }
00437       ast_log(LOG_NOTICE, "Variable %s refused to be %sREMENTED, setting value to 0", data, cmd);
00438       ret = 0;
00439    }
00440 
00441    ast_channel_unlock(chan);
00442 
00443    return ret;
00444 }

static int load_module ( void   )  [static]

Definition at line 524 of file func_math.c.

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

00525 {
00526    int res = 0;
00527 
00528    res |= ast_custom_function_register(&math_function);
00529    res |= ast_custom_function_register(&increment_function);
00530    res |= ast_custom_function_register(&decrement_function);
00531    AST_TEST_REGISTER(test_MATH_function);
00532 
00533    return res;
00534 }

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, DIVIDEFUNCTION, 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 (!mvalue1 || !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 512 of file func_math.c.

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

00513 {
00514    int res = 0;
00515 
00516    res |= ast_custom_function_unregister(&math_function);
00517    res |= ast_custom_function_unregister(&increment_function);
00518    res |= ast_custom_function_unregister(&decrement_function);
00519    AST_TEST_UNREGISTER(test_MATH_function);
00520 
00521    return res;
00522 }


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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 536 of file func_math.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 536 of file func_math.c.

struct ast_custom_function decrement_function [static]

Initial value:

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

Definition at line 457 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 452 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 447 of file func_math.c.

Referenced by load_module(), and unload_module().


Generated on Mon Mar 19 11:30:48 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7