Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:47:48 2009

## Asterisk developer's documentation

# app_math.c

Go to the documentation of this file.

    00001 /*
    00002  * Asterisk -- An open source telephony toolkit.
    00003  *
    00004  * Copyright (C) 2004 - 2005, Andy Powell
    00005  *
    00006  * Updated by Mark Spencer <markster@digium.com>
    00007  *
    00008  * See http://www.asterisk.org for more information about
    00009  * the Asterisk project. Please do not directly contact
    00010  * any of the maintainers of this project for assistance;
    00011  * the project provides a web site, mailing lists and IRC
    00012  * channels for your use.
    00013  *
    00014  * This program is free software, distributed under the terms of
    00015  * the GNU General Public License Version 2. See the LICENSE file
    00016  * at the top of the source tree.
    00017  */
    00018
    00019 /*! \file
    00020  *
    00021  * \brief A simple math application
    00022  *
    00023  * \ingroup applications
    00024  */
    00025
    00026 #include <stdlib.h>
    00027 #include <errno.h>
    00028 #include <unistd.h>
    00029 #include <string.h>
    00030 #include <stdlib.h>
    00031 #include <stdio.h>
    00032 #include <sys/time.h>
    00033 #include <sys/stat.h>
    00034 #include <sys/types.h>
    00035 #include <time.h>
    00036 #include <dirent.h>
    00037 #include <ctype.h>
    00038 #include <sys/file.h>
    00039
    00040 #include "asterisk.h"
    00041
    00042 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 211526 $")
    00043
    00044 #include "asterisk/lock.h"
    00045 #include "asterisk/file.h"
    00046 #include "asterisk/logger.h"
    00047 #include "asterisk/channel.h"
    00048 #include "asterisk/pbx.h"
    00049 #include "asterisk/options.h"
    00050 #include "asterisk/config.h"
    00051 #include "asterisk/say.h"
    00052 #include "asterisk/module.h"
    00053 #include "asterisk/app.h"
    00054 #include "asterisk/manager.h"
    00055 #include "asterisk/localtime.h"
    00056 #include "asterisk/cli.h"
    00057 #include "asterisk/utils.h"
    00058 #include "asterisk/module.h"
    00059 #include "asterisk/translate.h"
    00060
    00061 static char *tdesc = "Basic Math Functions";
    00062
    00063 static char *app_math = "Math";
    00064
    00065 static char *math_synopsis = "Performs Mathematical Functions";
    00066
    00067 static char *math_descrip =
    00068 "Math(returnvar,<number1><op><number 2>\n\n"
    00069 "Perform floating point calculation on number 1 to number 2 and \n"
    00070 "store the result in returnvar.  Valid ops are: \n"
    00071 "    +,-,/,*,%,<,>,>=,<=,==\n"
    00072 "and behave as their C equivalents.\n"
    00073 "  This application has been deprecated in favor of the MATH function.\n";
    00074
    00075 #define ADDFUNCTION 0
    00076 #define DIVIDEFUNCTION 1
    00077 #define MULTIPLYFUNCTION 2
    00078 #define SUBTRACTFUNCTION 3
    00079 #define MODULUSFUNCTION 4
    00080
    00081 #define GTFUNCTION 5
    00082 #define LTFUNCTION 6
    00083 #define GTEFUNCTION 7
    00084 #define LTEFUNCTION 8
    00085 #define EQFUNCTION 9
    00086
    00087 STANDARD_LOCAL_USER;
    00088
    00089 LOCAL_USER_DECL;
    00090
    00091 static int math_exec(struct ast_channel *chan, void *data)
    00092 {
    00093    float fnum1;
    00094    float fnum2;
    00095    float ftmp = 0;
    00096    char *op;
    00097    int iaction=-1;
    00098    static int deprecation_warning = 0;
    00099
    00100    /* dunno, big calulations :D */
    00101    char user_result[30];
    00102
    00103    char *s;
    00104    char *mvar, *mvalue1, *mvalue2=NULL;
    00105
    00106    struct localuser *u;
    00107
    00108    if (!deprecation_warning) {
    00109       ast_log(LOG_WARNING, "Math() is deprecated, please use Set(var=${MATH(...)} instead.\n");
    00110       deprecation_warning = 1;
    00111    }
    00112
    00113    if (ast_strlen_zero(data)) {
    00114       ast_log(LOG_WARNING, "No parameters passed. !\n");
    00115       return -1;
    00116    }
    00117
    00118    LOCAL_USER_ADD(u);
    00119
    00120    s = ast_strdupa(data);
    00121    if (!s) {
    00122       ast_log(LOG_ERROR, "Out of memory\n");
    00123       LOCAL_USER_REMOVE(u);
    00124       return -1;
    00125    }
    00126
    00127    mvar = strsep(&s, "|");
    00128    mvalue1 = strsep(&s, "|");
    00129
    00130    if ((op = strchr(mvalue1, '+'))) {
    00131       iaction = ADDFUNCTION;
    00132       *op = '\0';
    00133    } else if ((op = strchr(mvalue1, '-'))) {
    00134       iaction = SUBTRACTFUNCTION;
    00135       *op = '\0';
    00136    } else if ((op = strchr(mvalue1, '*'))) {
    00137       iaction = MULTIPLYFUNCTION;
    00138       *op = '\0';
    00139    } else if ((op = strchr(mvalue1, '/'))) {
    00140       iaction = DIVIDEFUNCTION;
    00141       *op = '\0';
    00142    } else if ((op = strchr(mvalue1, '>'))) {
    00143       iaction = GTFUNCTION;
    00144       *op = '\0';
    00145       if (*(op+1) == '=') {
    00146          op++;
    00147          *op = '\0';
    00148          iaction = GTEFUNCTION;
    00149       }
    00150    } else if ((op = strchr(mvalue1, '<'))) {
    00151       iaction = LTFUNCTION;
    00152       *op = '\0';
    00153       if (*(op+1) == '=') {
    00154          op++;
    00155          *op = '\0';
    00156          iaction = LTEFUNCTION;
    00157       }
    00158    } else if ((op = strchr(mvalue1, '='))) {
    00159       iaction = GTFUNCTION;
    00160       *op = '\0';
    00161       if (*(op+1) == '=') {
    00162          op++;
    00163          *op = '\0';
    00164          iaction = EQFUNCTION;
    00165       } else
    00166          op = NULL;
    00167    }
    00168
    00169    if (op)
    00170       mvalue2 = op + 1;
    00171
    00172    if (!mvar || !mvalue1 || !mvalue2) {
    00173       ast_log(LOG_WARNING, "Supply all the parameters - just this once, please\n");
    00174       LOCAL_USER_REMOVE(u);
    00175       return -1;
    00176    }
    00177
    00178    if (!strcmp(mvar,"")) {
    00179       ast_log(LOG_WARNING, "No return variable set.\n");
    00180       LOCAL_USER_REMOVE(u);
    00181       return -1;
    00182    }
    00183
    00184    if (sscanf(mvalue1, "%30f", &fnum1) != 1) {
    00185       ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue1);
    00186       LOCAL_USER_REMOVE(u);
    00187       return -1;
    00188    }
    00189
    00190    if (sscanf(mvalue2, "%30f", &fnum2) != 1) {
    00191       ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue2);
    00192       LOCAL_USER_REMOVE(u);
    00193       return -1;
    00194    }
    00195
    00196    switch (iaction) {
    00197    case ADDFUNCTION :
    00198       ftmp = fnum1 + fnum2;
    00199       break;
    00200    case DIVIDEFUNCTION :
    00201       if (fnum2 <=0)
    00202          ftmp = 0; /* can't do a divide by 0 */
    00203       else
    00204          ftmp = (fnum1 / fnum2);
    00205       break;
    00206    case MULTIPLYFUNCTION :
    00207       ftmp = (fnum1 * fnum2);
    00208       break;
    00209    case SUBTRACTFUNCTION :
    00210       ftmp = (fnum1 - fnum2);
    00211       break;
    00212    case MODULUSFUNCTION : {
    00213       int inum1 = fnum1;
    00214       int inum2 = fnum2;
    00215
    00216       ftmp = (inum1 % inum2);
    00217
    00218       break;
    00219       }
    00220    case GTFUNCTION :
    00221       if (fnum1 > fnum2)
    00222          strcpy(user_result, "TRUE");
    00223       else
    00224          strcpy(user_result, "FALSE");
    00225       break;
    00226    case LTFUNCTION :
    00227       if (fnum1 < fnum2)
    00228          strcpy(user_result, "TRUE");
    00229       else
    00230          strcpy(user_result, "FALSE");
    00231       break;
    00232    case GTEFUNCTION :
    00233       if (fnum1 >= fnum2)
    00234          strcpy(user_result, "TRUE");
    00235       else
    00236          strcpy(user_result, "FALSE");
    00237       break;
    00238    case LTEFUNCTION :
    00239       if (fnum1 <= fnum2)
    00240          strcpy(user_result, "TRUE");
    00241       else
    00242          strcpy(user_result, "FALSE");
    00243       break;
    00244    case EQFUNCTION :
    00245       if (fnum1 == fnum2)
    00246          strcpy(user_result, "TRUE");
    00247       else
    00248          strcpy(user_result, "FALSE");
    00249       break;
    00250    default :
    00251       ast_log(LOG_WARNING, "Something happened that neither of us should be proud of %d\n", iaction);
    00252       LOCAL_USER_REMOVE(u);
    00253       return -1;
    00254    }
    00255
    00256    if (iaction < GTFUNCTION || iaction > EQFUNCTION)
    00257       snprintf(user_result,sizeof(user_result),"%f",ftmp);
    00258
    00259    pbx_builtin_setvar_helper(chan, mvar, user_result);
    00260
    00261    LOCAL_USER_REMOVE(u);
    00262    return 0;
    00263 }
    00264
    00265 int unload_module(void)
    00266 {
    00267    int res;
    00268
    00269    res = ast_unregister_application(app_math);
    00270
    00271    STANDARD_HANGUP_LOCALUSERS;
    00272
    00273    return res;
    00274 }
    00275
    00276 int load_module(void)
    00277 {
    00278    return ast_register_application(app_math, math_exec, math_synopsis, math_descrip);
    00279 }
    00280
    00281 char *description(void)
    00282 {
    00283    return tdesc;
    00284 }
    00285
    00286 int usecount(void)
    00287 {
    00288    int res;
    00289    STANDARD_USECOUNT(res);
    00290    return res;
    00291 }
    00292
    00293 char *key()
    00294 {
    00295    return ASTERISK_GPL_KEY;
    00296 }
    00297
    00298 /* Fading everything to black and blue... */