diff options
-rwxr-xr-x | apps/Makefile | 2 | ||||
-rwxr-xr-x | apps/app_math.c | 289 | ||||
-rwxr-xr-x | doc/README.math | 70 |
3 files changed, 360 insertions, 1 deletions
diff --git a/apps/Makefile b/apps/Makefile index ce0fef4ca..3c3838278 100755 --- a/apps/Makefile +++ b/apps/Makefile @@ -29,7 +29,7 @@ APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_mp3.so\ app_nbscat.so app_sendtext.so app_exec.so app_sms.so \ app_groupcount.so app_txtcidname.so app_controlplayback.so \ app_talkdetect.so app_alarmreceiver.so app_userevent.so app_verbose.so \ - app_test.so app_forkcdr.so + app_test.so app_forkcdr.so app_math.so ifneq (${OSARCH},Darwin) APPS+=app_intercom.so diff --git a/apps/app_math.c b/apps/app_math.c new file mode 100755 index 000000000..481146dcb --- /dev/null +++ b/apps/app_math.c @@ -0,0 +1,289 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * + * simple maths application + * + * Copyright (C) 2004, Andy Powell + * + * Updated by Mark Spencer <markster@digium.com> + * + */ + +#include <asterisk/lock.h> +#include <asterisk/file.h> +#include <asterisk/logger.h> +#include <asterisk/channel.h> +#include <asterisk/channel_pvt.h> +#include <asterisk/pbx.h> +#include <asterisk/options.h> +#include <asterisk/config.h> +#include <asterisk/say.h> +#include <asterisk/module.h> +#include <asterisk/app.h> +#include <asterisk/manager.h> +#include <asterisk/localtime.h> +#include <asterisk/cli.h> +#include <asterisk/utils.h> +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <time.h> +#include <dirent.h> +#include <asterisk/module.h> +#include <asterisk/translate.h> +#include <ctype.h> +#include <sys/file.h> +#include "../astconf.h" + + + +static char *tdesc = "Basic maths functions"; + +static char *app_math = "Math"; + +static char *math_synopsis = "Performs Mathematical Functions"; + + +static char *math_descrip = +"Math(returnvar,<number1><op><number 2>\n\n" +"Perform floating point calculation on number 1 to number 2 and \n" +"store the result in returnvar. Valid ops are: \n" +" +,-,/,*,%,<,>,>=,<=,==\n" +"and behave as their C equivalents. Always returns 0.\n"; + + +#define ADDFUNCTION 0 +#define DIVIDEFUNCTION 1 +#define MULTIPLYFUNCTION 2 +#define SUBTRACTFUNCTION 3 +#define MODULUSFUNCTION 4 + +#define GTFUNCTION 5 +#define LTFUNCTION 6 +#define GTEFUNCTION 7 +#define LTEFUNCTION 8 +#define EQFUNCTION 9 + + + +STANDARD_LOCAL_USER; + +LOCAL_USER_DECL; + +static int math_exec(struct ast_channel *chan, void *data) { + + float fnum1; + float fnum2; + float ftmp = 0; + char *op; + int iaction=-1; + + /* dunno, big calulations :D */ + char user_result[30]; + + char *s; + char *mvar, *mvalue1, *mvalue2=NULL; + + struct localuser *u; + + if (!data) { + ast_log(LOG_WARNING, "No parameters passed. !\n"); + return -1; + } + + LOCAL_USER_ADD(u); + + + + s = ast_strdupa((void *) data); + + mvar = strsep(&s, "|"); + mvalue1 = strsep(&s, "|"); + + + if ((op = strchr(mvalue1, '+'))) { + iaction = ADDFUNCTION; + *op = '\0'; + } else if ((op = strchr(mvalue1, '-'))) { + iaction = SUBTRACTFUNCTION; + *op = '\0'; + } else if ((op = strchr(mvalue1, '*'))) { + iaction = MULTIPLYFUNCTION; + *op = '\0'; + } else if ((op = strchr(mvalue1, '/'))) { + iaction = DIVIDEFUNCTION; + *op = '\0'; + } else if ((op = strchr(mvalue1, '>'))) { + iaction = GTFUNCTION; + *op = '\0'; + if (*(op+1) == '=') { + op++; + *op = '\0'; + iaction = GTEFUNCTION; + } + } else if ((op = strchr(mvalue1, '<'))) { + iaction = LTFUNCTION; + *op = '\0'; + if (*(op+1) == '=') { + op++; + *op = '\0'; + iaction = LTEFUNCTION; + } + } else if ((op = strchr(mvalue1, '='))) { + iaction = GTFUNCTION; + *op = '\0'; + if (*(op+1) == '=') { + op++; + *op = '\0'; + iaction = EQFUNCTION; + } else + op = NULL; + } + + if (op) + mvalue2 = op + 1; + + + if (!mvar || !mvalue1 || !mvalue2) { + ast_log(LOG_WARNING, "Supply all the parameters - just this once, please\n"); + LOCAL_USER_REMOVE(u); + return -1; + } + + if (!strcmp(mvar,"")) { + ast_log(LOG_WARNING, "No return variable set.\n"); + LOCAL_USER_REMOVE(u); + return -1; + } + + + if (sscanf(mvalue1, "%f", &fnum1) != 1) { + ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue1); + LOCAL_USER_REMOVE(u); + return -1; + } + + if (sscanf(mvalue2, "%f", &fnum2) != 1) { + ast_log(LOG_WARNING, "'%s' is not a valid number\n", mvalue2); + LOCAL_USER_REMOVE(u); + return -1; + } + + + switch (iaction) { + case ADDFUNCTION : + ftmp = fnum1 + fnum2; + break; + + case DIVIDEFUNCTION : + if (fnum2 <=0) + ftmp = 0; /* can't do a divide by 0 */ + else + ftmp = (fnum1 / fnum2); + break; + case MULTIPLYFUNCTION : + ftmp = (fnum1 * fnum2); + break; + case SUBTRACTFUNCTION : + ftmp = (fnum2 - fnum1); + break; + case MODULUSFUNCTION : { + int inum1 = fnum1; + int inum2 = fnum2; + + ftmp = (inum1 % inum2); + + break; + } + case GTFUNCTION : + if (fnum1 > fnum2) + strncpy (user_result, "TRUE", sizeof (user_result) - 1); + else + strncpy (user_result, "FALSE", sizeof (user_result) - 1); + break; + case LTFUNCTION : + if (fnum1 < fnum2) + strncpy (user_result, "TRUE", sizeof (user_result) - 1); + else + strncpy (user_result, "FALSE", sizeof (user_result) - 1); + break; + case GTEFUNCTION : + if (fnum1 >= fnum2) + strncpy (user_result, "TRUE", sizeof (user_result) - 1); + else + strncpy (user_result, "FALSE", sizeof (user_result) - 1); + break; + case LTEFUNCTION : + if (fnum1 <= fnum2) + strncpy (user_result, "TRUE", sizeof (user_result) - 1); + else + strncpy (user_result, "FALSE", sizeof (user_result) - 1); + break; + case EQFUNCTION : + if (fnum1 == fnum2) + strncpy (user_result, "TRUE", sizeof (user_result) - 1); + else + strncpy (user_result, "FALSE", sizeof (user_result) - 1); + break; + default : + ast_log(LOG_WARNING, "Something happened that neither of us should be proud of %d\n", iaction); + LOCAL_USER_REMOVE(u); + return -1; + + } + + if (iaction < GTFUNCTION || iaction > EQFUNCTION) + snprintf(user_result,sizeof(user_result),"%f",ftmp); + + pbx_builtin_setvar_helper(chan, mvar, user_result); + + LOCAL_USER_REMOVE(u); + return 0; +} + +int unload_module(void) +{ + int res; + STANDARD_HANGUP_LOCALUSERS; + + res = ast_unregister_application(app_math); + return res; +} + +int load_module(void) +{ + int res; + res = ast_register_application(app_math, math_exec, math_synopsis, math_descrip); + return res; +} + +char *description(void) +{ + return tdesc; +} + +int usecount(void) +{ + int res; + STANDARD_USECOUNT(res); + return res; +} + +char *key() +{ + return ASTERISK_GPL_KEY; +} + + + +/* Fading everything to black and blue... */ + + + + diff --git a/doc/README.math b/doc/README.math new file mode 100755 index 000000000..5a06fce29 --- /dev/null +++ b/doc/README.math @@ -0,0 +1,70 @@ + +Mathematical functions application + +Yeah, I thought it was a little insane too.. + +adds: + +Sum, Multiply, Divide, Subtract, Modulus, GT, LT, GTE, LTE, EQ functions to asterisk + +All functions follow the same basic pattern for parameters: + +parameter 1 = the name of the return variable +parameter 2 = the first number +parameter 3 = the second number + +Each action is perfromed as + + Action param1 on param2 + +eg: + + Action = Divide + Param1 = 10 + Param2 = 2 + +Results in + + Divide 10 by 2 + + +Example dialplan: + +exten => 11099,1,SUM(RV,1,20) +exten => 11099,2,NOOP(${RV}) +exten => 11099,3,MULTIPLY(RV,10,2) +exten => 11099,4,NOOP(${RV}) +exten => 11099,5,DIVIDE(RV,10,2) +exten => 11099,6,NOOP(${RV}) +exten => 11099,7,SUBTRACT(RV,10,2) +exten => 11099,8,NOOP(${RV}) +exten => 11099,9,MODULUS(RV,2,10) +exten => 11099,10,NOOP(${RV}) +exten => 11099,11,DIVIDE(RV,10,0) +exten => 11099,12,NOOP(${RV}) +exten => 11099,13,SUBTRACT(RV,10,200) +exten => 11099,14,NOOP(${RV}) +exten => 11099,15,DIVIDE(RV,1,20) +exten => 11099,16,NOOP(${RV}) +exten => 11099,17,LT(RV,1,20) +exten => 11099,18,NOOP(${RV}) +exten => 11099,19,GTE(RV,1,20) +exten => 11099,20,NOOP(${RV}) +exten => 11099,21,GT(RV,101,20) +exten => 11099,22,NOOP(${RV}) +exten => 11099,23,EQ(RV,1,20) +exten => 11099,24,NOOP(${RV}) +exten => 11099,25,LTE(RV,20,20) +exten => 11099,26,NOOP(${RV}) + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Makefile stuff: + + +APPS+=app_math.so + + +app_math.so: app_math.c + $(CC) -D_GNU_SOURCE -shared -Xlinker -x -o $@ $< -lz -L/usr/lib + |