From 025aeb8f62d8b5c199846c20c73ff25720dae21e Mon Sep 17 00:00:00 2001 From: kpfleming Date: Sun, 15 May 2005 17:45:30 +0000 Subject: add dialplan functions for Caller ID, language and timeouts (bug #4219, with mods) git-svn-id: http://svn.digium.com/svn/asterisk/trunk@5679 f38db490-d61c-443f-a65b-d21fe96a405b --- UPGRADE.txt | 27 ++++++++ apps/app_setcidname.c | 11 +++- apps/app_setcidnum.c | 11 +++- apps/app_setrdnis.c | 11 +++- funcs/Makefile | 11 +++- funcs/func_callerid.c | 129 +++++++++++++++++++++++++++++++++++++++ funcs/func_groupcount.c | 7 +++ funcs/func_language.c | 60 ++++++++++++++++++ funcs/func_timeout.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++ pbx.c | 32 ++++++++++ 10 files changed, 453 insertions(+), 5 deletions(-) create mode 100755 funcs/func_callerid.c create mode 100755 funcs/func_language.c create mode 100755 funcs/func_timeout.c diff --git a/UPGRADE.txt b/UPGRADE.txt index 188ff43fd..54ada6c95 100755 --- a/UPGRADE.txt +++ b/UPGRADE.txt @@ -59,6 +59,33 @@ Applications: DBGet(foo=family/key) SetVar(foo=${DB(family/key)}) DBPut(family/key=${foo}) SetVar(${DB(family/key)}=${foo}) +* The application SetLanguage has been deprecated in favor of the + function LANGUAGE(). + + SetLanguage(fr) SetVar(LANGUAGE()=fr) + + The LANGUAGE function can also return the currently set language: + + SetVar(MYLANG=${LANGUAGE()}) + +* The applications AbsoluteTimeout, DigitTimeout, and ResponseTimeout + have been deprecated in favor of the function TIMEOUT(timeouttype): + + AbsoluteTimeout(300) SetVar(TIMEOUT(absolute)=300) + DigitTimeout(15) SetVar(TIMEOUT(digit)=15) + ResponseTimeout(15) SetVar(TIMEOUT(response)=15) + + The TIMEOUT() function can also return the currently set timeouts: + + SetVar(DTIMEOUT=${TIMEOUT(digit)}) + +* The applications SetCIDName, SetCIDNum, and SetRDNIS have been + deprecated in favor of the CALLERID(datatype) function: + + SetCIDName(Joe Cool) SetVar(CALLERID(name)=Joe Cool) + SetCIDNum(2025551212) SetVar(CALLERID(number)=2025551212) + SetRDNIS(2024561414) SetVar(CALLERID(RDNIS)=2024561414) + Queues: * A queue is now considered empty not only if there are no members but if diff --git a/apps/app_setcidname.c b/apps/app_setcidname.c index 88e847651..b3bd3745c 100755 --- a/apps/app_setcidname.c +++ b/apps/app_setcidname.c @@ -34,7 +34,9 @@ static char *descrip = " SetCIDName(cname[|a]): Set Caller*ID Name on a call to a new\n" "value, while preserving the original Caller*ID number. This is\n" "useful for providing additional information to the called\n" -"party. Always returns 0\n"; +"party. Always returns 0\n" +"SetCIDName has been deprecated in favor of the function\n" +"CALLERID(name)\n"; STANDARD_LOCAL_USER; @@ -46,6 +48,13 @@ static int setcallerid_exec(struct ast_channel *chan, void *data) char tmp[256] = ""; struct localuser *u; char *opt; + static int deprecation_warning = 0; + + if (!deprecation_warning) { + ast_log(LOG_WARNING, "SetCIDName is deprecated, please use SetVar(CALLERID(name)=value) instead.\n"); + deprecation_warning = 1; + } + if (data) strncpy(tmp, (char *)data, sizeof(tmp) - 1); opt = strchr(tmp, '|'); diff --git a/apps/app_setcidnum.c b/apps/app_setcidnum.c index e7324da3d..fb75b9e78 100755 --- a/apps/app_setcidnum.c +++ b/apps/app_setcidnum.c @@ -35,7 +35,9 @@ static char *descrip = " SetCIDNum(cnum[|a]): Set Caller*ID Number on a call to a new\n" "value, while preserving the original Caller*ID name. This is\n" "useful for providing additional information to the called\n" -"party. Sets ANI as well if a flag is used. Always returns 0\n"; +"party. Sets ANI as well if a flag is used. Always returns 0\n" +"SetCIDNum has been deprecated in favor of the function\n" +"CALLERID(number)\n"; STANDARD_LOCAL_USER; @@ -48,6 +50,13 @@ static int setcallerid_exec(struct ast_channel *chan, void *data) char *opt; int anitoo = 0; char tmp[256]; + static int deprecation_warning = 0; + + if (!deprecation_warning) { + ast_log(LOG_WARNING, "SetCIDNum is deprecated, please use SetVar(CALLERID(number)=value) instead.\n"); + deprecation_warning = 1; + } + if (data) strncpy(tmp, (char *)data, sizeof(tmp) - 1); opt = strchr(tmp, '|'); diff --git a/apps/app_setrdnis.c b/apps/app_setrdnis.c index 4c42c9567..1321bae35 100755 --- a/apps/app_setrdnis.c +++ b/apps/app_setrdnis.c @@ -33,7 +33,9 @@ static char *synopsis = "Set RDNIS Number"; static char *descrip = " SetRDNIS(cnum): Set RDNIS Number on a call to a new\n" -"value. Always returns 0\n"; +"value. Always returns 0\n" +"SetRDNIS has been deprecated in favor of the function\n" +"CALLERID(rdnis)\n"; STANDARD_LOCAL_USER; @@ -44,6 +46,13 @@ static int setrdnis_exec(struct ast_channel *chan, void *data) struct localuser *u; char *opt, *n, *l; char tmp[256]; + static int deprecation_warning = 0; + + if (!deprecation_warning) { + ast_log(LOG_WARNING, "SetRDNIS is deprecated, please use SetVar(CALLERID(rdnis)=value) instead.\n"); + deprecation_warning = 1; + } + if (data) strncpy(tmp, (char *)data, sizeof(tmp) - 1); else diff --git a/funcs/Makefile b/funcs/Makefile index c7bdd042c..fa240fd30 100755 --- a/funcs/Makefile +++ b/funcs/Makefile @@ -13,8 +13,15 @@ FUNCS=pbx_functions.so -BUILTINS=func_md5.o func_groupcount.o func_strings.o func_cdr.o \ - func_logic.o func_env.o func_db.o +BUILTINS=func_md5.o \ + func_groupcount.o \ + func_strings.o \ + func_cdr.o \ + func_logic.o \ + func_env.o \ + func_db.o \ + func_timeout.o \ + func_language.o \ STANDALONE_FUNCS=$(filter-out $(BUILTINS),$(patsubst %.c,%.o,$(wildcard func*.c))) diff --git a/funcs/func_callerid.c b/funcs/func_callerid.c new file mode 100755 index 000000000..fb70269a2 --- /dev/null +++ b/funcs/func_callerid.c @@ -0,0 +1,129 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * + * Caller ID related dialplan functions + * + * Copyright (C) 2005, Digium, Inc. + * + * This program is free software, distributed under the terms of + * the GNU General Public License + */ + +#include +#include +#include + +#ifndef BUILTIN_FUNC +#include "asterisk/module.h" +#endif /* BUILTIN_FUNC */ +#include "asterisk/channel.h" +#include "asterisk/pbx.h" +#include "asterisk/logger.h" +#include "asterisk/utils.h" +#include "asterisk/app.h" +#include "asterisk/options.h" + +static char *callerid_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) +{ + if (strncasecmp("name", data, 4) == 0) { + if (chan->cid.cid_name) { + ast_copy_string(buf, chan->cid.cid_name, len); + } + } else if (strncasecmp("num", data, 3) == 0 || strncasecmp("number", data, 6) == 0) { + if (chan->cid.cid_num) { + ast_copy_string(buf, chan->cid.cid_num, len); + } + } else if (strncasecmp("ani", data, 3) == 0) { + if (chan->cid.cid_ani) { + ast_copy_string(buf, chan->cid.cid_ani, len); + } + } else if (strncasecmp("dnid", data, 4) == 0) { + if (chan->cid.cid_dnid) { + ast_copy_string(buf, chan->cid.cid_dnid, len); + } + } else if (strncasecmp("rdnis", data, 5) == 0) { + if (chan->cid.cid_rdnis) { + ast_copy_string(buf, chan->cid.cid_rdnis, len); + } + } else { + ast_log(LOG_ERROR, "Unknown callerid data type.\n"); + } + + return buf; +} + +static void callerid_write(struct ast_channel *chan, char *cmd, char *data, const char *value) +{ + if (!value) + return; + + if (strncasecmp("name", data, 4) == 0) { + ast_set_callerid(chan, NULL, value, NULL); + } else if (strncasecmp("num", data, 3) == 0 || strncasecmp("number", data, 6) == 0) { + ast_set_callerid(chan, value, NULL, NULL); + } else if (strncasecmp("ani", data, 3) == 0) { + ast_set_callerid(chan, NULL, NULL, value); + } else if (strncasecmp("dnid", data, 4) == 0) { + /* do we need to lock chan here? */ + if (chan->cid.cid_dnid) + free(chan->cid.cid_dnid); + chan->cid.cid_dnid = ast_strlen_zero(value) ? NULL : strdup(value); + } else if (strncasecmp("rdnis", data, 5) == 0) { + /* do we need to lock chan here? */ + if (chan->cid.cid_rdnis) + free(chan->cid.cid_rdnis); + chan->cid.cid_rdnis = ast_strlen_zero(value) ? NULL : strdup(value); + } else { + ast_log(LOG_ERROR, "Unknown callerid data type.\n"); + } +} + +#ifndef BUILTIN_FUNC +static +#endif /* BUILTIN_FUNC */ +struct ast_custom_function callerid_function = { + .name = "CALLERID", + .synopsis = "Gets or sets Caller*ID data on the channel.", + .syntax = "CALLERID(datatype)", + .desc = "Gets or sets Caller*ID data on the channel. The allowable datatypes\n" + "are \"name\", \"number\", \"ANI\", \"DNID\", \"RDNIS\".\n", + .read = callerid_read, + .write = callerid_write, +}; + +#ifndef BUILTIN_FUNC +static char *tdesc = "Caller ID related dialplan function"; + +int unload_module(void) +{ + return ast_custom_function_unregister(&callerid_function); +} + +int load_module(void) +{ + return ast_custom_function_register(&callerid_function); +} + +char *description(void) +{ + return tdesc; +} + +int usecount(void) +{ + return 0; +} + +char *key() +{ + return ASTERISK_GPL_KEY; +} +#endif /* BUILTIN_FUNC */ + +/* +Local Variables: +mode: C +c-file-style: "linux" +indent-tabs-mode: nil +End: +*/ diff --git a/funcs/func_groupcount.c b/funcs/func_groupcount.c index ff838703f..d76c95724 100755 --- a/funcs/func_groupcount.c +++ b/funcs/func_groupcount.c @@ -165,3 +165,10 @@ struct ast_custom_function group_list_function = { .write = NULL, }; +/* +Local Variables: +mode: C +c-file-style: "linux" +indent-tabs-mode: nil +End: +*/ diff --git a/funcs/func_language.c b/funcs/func_language.c new file mode 100755 index 000000000..2584e6261 --- /dev/null +++ b/funcs/func_language.c @@ -0,0 +1,60 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * + * Language related dialplan functions + * + * Copyright (C) 2005, Digium, Inc. + * + * This program is free software, distributed under the terms of + * the GNU General Public License + */ + +#include +#include +#include + +#include "asterisk/channel.h" +#include "asterisk/pbx.h" +#include "asterisk/logger.h" +#include "asterisk/utils.h" +#include "asterisk/app.h" + +static char *builtin_function_language_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) +{ + ast_copy_string(buf, chan->language, len); + + return buf; +} + +static void builtin_function_language_write(struct ast_channel *chan, char *cmd, char *data, const char *value) +{ + if (value) + ast_copy_string(chan->language, value, sizeof(chan->language)); +} + +#ifndef BUILTIN_FUNC +static +#endif +struct ast_custom_function language_function = { + .name = "LANGUAGE", + .synopsis = "Gets or sets the channel's language.", + .syntax = "LANGUAGE()", + .desc = "Gets or sets the channel language. This information is used for the\n" + "syntax in generation of numbers, and to choose a natural language file\n" + "when available. For example, if language is set to 'fr' and the file\n" + "'demo-congrats' is requested to be played, if the file\n" + "'fr/demo-congrats' exists, then it will play that file, and if not\n" + "will play the normal 'demo-congrats'. For some language codes,\n" + "changing the language also changes the syntax of some Asterisk\n" + "functions, like SayNumber.\n", + .read = builtin_function_language_read, + .write = builtin_function_language_write, +}; + +/* +Local Variables: +mode: C +c-file-style: "linux" +indent-tabs-mode: nil +End: +*/ diff --git a/funcs/func_timeout.c b/funcs/func_timeout.c new file mode 100755 index 000000000..950e134c0 --- /dev/null +++ b/funcs/func_timeout.c @@ -0,0 +1,159 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * + * Channel timeout related dialplan functions + * + * Copyright (C) 2005, Digium, Inc. + * + * This program is free software, distributed under the terms of + * the GNU General Public License + */ + +#include +#include +#include + +#include "asterisk/channel.h" +#include "asterisk/pbx.h" +#include "asterisk/logger.h" +#include "asterisk/utils.h" +#include "asterisk/app.h" +#include "asterisk/options.h" + +static char *builtin_function_timeout_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) +{ + time_t myt; + + if (!data) { + ast_log(LOG_ERROR, "Must specify type of timeout to get."); + return NULL; + } + + switch(*data) { + case 'a': + case 'A': + if (chan->whentohangup == 0) { + ast_copy_string(buf, "0", len); + } else { + time(&myt); + snprintf(buf, len, "%d", (int) (chan->whentohangup - myt)); + } + break; + + case 'r': + case 'R': + if (chan->pbx) { + snprintf(buf, len, "%d", chan->pbx->rtimeout); + } + break; + + case 'd': + case 'D': + if (chan->pbx) { + snprintf(buf, len, "%d", chan->pbx->dtimeout); + } + break; + + default: + ast_log(LOG_ERROR, "Unknown timeout type specified."); + break; + } + + return buf; +} + +static void builtin_function_timeout_write(struct ast_channel *chan, char *cmd, char *data, const char *value) +{ + int x; + char timestr[64]; + struct tm myt; + + if (!data) { + ast_log(LOG_ERROR, "Must specify type of timeout to set."); + return; + } + + if (!value) + return; + + x = atoi(value); + + switch(*data) { + case 'a': + case 'A': + ast_channel_setwhentohangup(chan, x); + if (option_verbose > 2) { + if (chan->whentohangup) { + strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S UTC", gmtime_r(&chan->whentohangup, &myt)); + ast_verbose( VERBOSE_PREFIX_3 "Channel will hangup at %s.\n", timestr); + } else { + ast_verbose( VERBOSE_PREFIX_3 "Channel hangup cancelled.\n"); + } + } + break; + + case 'r': + case 'R': + if (chan->pbx) { + chan->pbx->rtimeout = x; + if (option_verbose > 2) + ast_verbose( VERBOSE_PREFIX_3 "Response timeout set to %d\n", chan->pbx->rtimeout); + } + break; + + case 'd': + case 'D': + if (chan->pbx) { + chan->pbx->dtimeout = x; + if (option_verbose > 2) + ast_verbose( VERBOSE_PREFIX_3 "Digit timeout set to %d\n", chan->pbx->dtimeout); + } + break; + + default: + ast_log(LOG_ERROR, "Unknown timeout type specified."); + break; + } +} + +#ifndef BUILTIN_FUNC +static +#endif +struct ast_custom_function timeout_function = { + .name = "TIMEOUT", + .synopsis = "Gets or sets timeouts on the channel.", + .syntax = "TIMEOUT(timeouttype)", + .desc = "Gets or sets various channel timeouts. The timeouts that can be\n" + "manipulated are:\n" + "\n" + "absolute: The absolute maximum amount of time permitted for a call. A\n" + " setting of 0 disables the timeout.\n" + "\n" + "digit: The maximum amount of time permitted between digits when the\n" + " user is typing in an extension. When this timeout expires,\n" + " after the user has started to type in an extension, the\n" + " extension will be considered complete, and will be\n" + " interpreted. Note that if an extension typed in is valid,\n" + " it will not have to timeout to be tested, so typically at\n" + " the expiry of this timeout, the extension will be considered\n" + " invalid (and thus control would be passed to the 'i'\n" + " extension, or if it doesn't exist the call would be\n" + " terminated). The default timeout is 5 seconds.\n" + "\n" + "response: The maximum amount of time permitted after falling through a\n" + " series of priorities for a channel in which the user may\n" + " begin typing an extension. If the user does not type an\n" + " extension in this amount of time, control will pass to the\n" + " 't' extension if it exists, and if not the call would be\n" + " terminated. The default timeout is 10 seconds.\n", + .read = builtin_function_timeout_read, + .write = builtin_function_timeout_write, +}; + +/* +Local Variables: +mode: C +c-file-style: "linux" +indent-tabs-mode: nil +End: +*/ diff --git a/pbx.c b/pbx.c index 0bbf27152..f173a8682 100755 --- a/pbx.c +++ b/pbx.c @@ -231,6 +231,7 @@ static struct pbx_builtin { "Set absolute maximum time of call", " AbsoluteTimeout(seconds): Set the absolute maximum amount of time permitted\n" "for a call. A setting of 0 disables the timeout. Always returns 0.\n" + "AbsoluteTimeout has been deprecated in favor of SetVar(TIMEOUT(absolute)=timeout)\n" }, { "Answer", pbx_builtin_answer, @@ -283,6 +284,7 @@ static struct pbx_builtin { "(and thus control would be passed to the 'i' extension, or if it doesn't\n" "exist the call would be terminated). The default timeout is 5 seconds.\n" "Always returns 0.\n" + "DigitTimeout has been deprecated in favor of SetVar(TIMEOUT(digit)=timeout)\n" }, { "Goto", pbx_builtin_goto, @@ -366,6 +368,7 @@ static struct pbx_builtin { "amount of time, control will pass to the 't' extension if it exists, and\n" "if not the call would be terminated. The default timeout is 10 seconds.\n" "Always returns 0.\n" + "ResponseTimeout has been deprecated in favor of SetVar(TIMEOUT(response)=timeout)\n" }, { "Ringing", pbx_builtin_ringing, @@ -425,6 +428,7 @@ static struct pbx_builtin { "For some language codes, SetLanguage also changes the syntax of some\n" "Asterisk functions, like SayNumber.\n" "Always returns 0.\n" + "SetLanguage has been deprecated in favor of SetVar(LANGUAGE()=language)\n" }, { "SetVar", pbx_builtin_setvar, @@ -5253,9 +5257,17 @@ static int pbx_builtin_answer(struct ast_channel *chan, void *data) static int pbx_builtin_setlanguage(struct ast_channel *chan, void *data) { + static int deprecation_warning = 0; + + if (!deprecation_warning) { + ast_log(LOG_WARNING, "SetLanguage is deprecated, please use SetVar(LANGUAGE()=language) instead.\n"); + deprecation_warning = 1; + } + /* Copy the language as specified */ if (data) strncpy(chan->language, (char *)data, sizeof(chan->language)-1); + return 0; } @@ -5564,8 +5576,14 @@ static int pbx_builtin_background(struct ast_channel *chan, void *data) static int pbx_builtin_atimeout(struct ast_channel *chan, void *data) { + static int deprecation_warning = 0; int x = atoi((char *) data); + if (!deprecation_warning) { + ast_log(LOG_WARNING, "AbsoluteTimeout is deprecated, please use SetVar(TIMEOUT(absolute)=timeout) instead.\n"); + deprecation_warning = 1; + } + /* Set the absolute maximum time how long a call can be connected */ ast_channel_setwhentohangup(chan,x); if (option_verbose > 2) @@ -5575,6 +5593,13 @@ static int pbx_builtin_atimeout(struct ast_channel *chan, void *data) static int pbx_builtin_rtimeout(struct ast_channel *chan, void *data) { + static int deprecation_warning = 0; + + if (!deprecation_warning) { + ast_log(LOG_WARNING, "ResponseTimeout is deprecated, please use SetVar(TIMEOUT(response)=timeout) instead.\n"); + deprecation_warning = 1; + } + /* If the channel is not in a PBX, return now */ if (!chan->pbx) return 0; @@ -5588,6 +5613,13 @@ static int pbx_builtin_rtimeout(struct ast_channel *chan, void *data) static int pbx_builtin_dtimeout(struct ast_channel *chan, void *data) { + static int deprecation_warning = 0; + + if (!deprecation_warning) { + ast_log(LOG_WARNING, "DigitTimeout is deprecated, please use SetVar(TIMEOUT(digit)=timeout) instead.\n"); + deprecation_warning = 1; + } + /* If the channel is not in a PBX, return now */ if (!chan->pbx) return 0; -- cgit v1.2.3