add dialplan functions for Caller ID, language and timeouts (bug #4219, with mods)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5679 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.2-netsec
Kevin P. Fleming 20 years ago
parent bb1f05fba7
commit fa60672d58

@ -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

@ -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, '|');

@ -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, '|');

@ -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

@ -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)))

@ -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 <stdlib.h>
#include <string.h>
#include <sys/types.h>
#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:
*/

@ -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:
*/

@ -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 <stdlib.h>
#include <string.h>
#include <sys/types.h>
#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:
*/

@ -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 <stdlib.h>
#include <string.h>
#include <sys/types.h>
#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:
*/

32
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;

Loading…
Cancel
Save