summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTilghman Lesher <tilghman@meg.abyt.es>2010-01-13 21:27:34 +0000
committerTilghman Lesher <tilghman@meg.abyt.es>2010-01-13 21:27:34 +0000
commitecbe7eff7a557a4aa55fb43e60299cf4f36165d9 (patch)
treebd84872c5ca0ec098e3ded6ff22ec2e680cee56f
parent919437428ea4856e5305e2a8f987e8290b38d20a (diff)
Add the TESTTIME() dialplan function, which permits testing GotoIfTime.
Specifically, by setting TESTTIME() to a particular date and time, you can test whether a dialplan correctly branches as was intended. This was developed after recent questions on the -users list on how to test their holiday dialplan logic. (closes issue #16464) Reported by: tilghman Patches: 20100112__issue16464.diff.txt uploaded by tilghman (license 14) Review: https://reviewboard.asterisk.org/r/458/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@239957 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--include/asterisk/pbx.h8
-rw-r--r--main/pbx.c85
2 files changed, 89 insertions, 4 deletions
diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h
index a5c3b2248..50a18a624 100644
--- a/include/asterisk/pbx.h
+++ b/include/asterisk/pbx.h
@@ -147,6 +147,14 @@ int ast_build_timing(struct ast_timing *i, const char *info);
int ast_check_timing(const struct ast_timing *i);
/*!
+ * \brief Evaluate a pre-constructed bitmap as to whether a particular time falls within the range specified.
+ * \param i Pointer to an ast_timing structure.
+ * \param tv Specified time
+ * \retval Returns 1, if the time matches or 0, if the time falls outside of the specified range.
+ */
+int ast_check_timing2(const struct ast_timing *i, const struct timeval tv);
+
+/*!
* \brief Deallocates memory structures associated with a timing bitmap.
* \param i Pointer to an ast_timing structure.
* \retval 0 success
diff --git a/main/pbx.c b/main/pbx.c
index e06577ee3..5ed2c8296 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -332,6 +332,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<see-also>
<ref type="application">GotoIf</ref>
<ref type="function">IFTIME</ref>
+ <ref type="function">TESTTIME</ref>
</see-also>
</application>
<application name="ImportVar" language="en_US">
@@ -717,6 +718,30 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<ref type="application">RaiseException</ref>
</see-also>
</function>
+ <function name="TESTTIME" language="en_US">
+ <synopsis>
+ Sets a time to be used with the channel to test logical conditions.
+ <synopsis>
+ <syntax>
+ <parameter name="date" required="true" argsep=" ">
+ <para>Date in ISO 8601 format</para>
+ </parameter>
+ <parameter name="time" required="true" argsep=" ">
+ <para>Time in HH:MM:SS format (24-hour time)</para>
+ </parameter>
+ <parameter name="zone" required="false">
+ <para>Timezone name</para>
+ </parameter>
+ </syntax>
+ <description>
+ <para>To test dialplan timing conditions at times other than the current time, use
+ this function to set an alternate date and time. For example, you may wish to evaluate
+ whether a location will correctly identify to callers that the area is closed on Christmas
+ Day, when Christmas would otherwise fall on a day when the office is normally open.</para>
+ <see-also>
+ <ref type="application">GotoIfTime</ref>
+ </see-also>
+ </function>
<manager name="ShowDialPlan" language="en_US">
<synopsis>
La merde se produit.
@@ -7284,10 +7309,14 @@ int ast_build_timing(struct ast_timing *i, const char *info_in)
int ast_check_timing(const struct ast_timing *i)
{
+ return ast_check_timing2(i, ast_tvnow());
+}
+
+int ast_check_timing2(const struct ast_timing *i, const struct timeval tv)
+{
struct ast_tm tm;
- struct timeval now = ast_tvnow();
- ast_localtime(&now, &tm, i->timezone);
+ ast_localtime(&tv, &tm, i->timezone);
/* If it's not the right month, return */
if (!(i->monthmask & (1 << tm.tm_mon)))
@@ -8928,12 +8957,47 @@ static int pbx_builtin_hangup(struct ast_channel *chan, const char *data)
}
/*!
+ * \ingroup functions
+ */
+static int testtime_write(struct ast_channel *chan, const char *cmd, char *var, const char *value)
+{
+ struct ast_tm tm;
+ struct timeval tv;
+ char *remainder, result[30], timezone[80];
+
+ /* Turn off testing? */
+ if (!pbx_checkcondition(value)) {
+ pbx_builtin_setvar_helper(chan, "TESTTIME", NULL);
+ return 0;
+ }
+
+ /* Parse specified time */
+ if (!(remainder = ast_strptime(value, "%Y/%m/%d %H:%M:%S", &tm))) {
+ return -1;
+ }
+ sscanf(remainder, "%79s", timezone);
+ tv = ast_mktime(&tm, S_OR(timezone, NULL));
+
+ snprintf(result, sizeof(result), "%ld", (long) tv.tv_sec);
+ pbx_builtin_setvar_helper(chan, "__TESTTIME", result);
+ return 0;
+}
+
+static struct ast_custom_function testtime_function = {
+ .name = "TESTTIME",
+ .write = testtime_write,
+};
+
+/*!
* \ingroup applications
*/
static int pbx_builtin_gotoiftime(struct ast_channel *chan, const char *data)
{
char *s, *ts, *branch1, *branch2, *branch;
struct ast_timing timing;
+ const char *ctime;
+ struct timeval tv = ast_tvnow();
+ long timesecs;
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "GotoIfTime requires an argument:\n <time range>,<days of week>,<days of month>,<months>[,<timezone>]?'labeliftrue':'labeliffalse'\n");
@@ -8942,16 +9006,28 @@ static int pbx_builtin_gotoiftime(struct ast_channel *chan, const char *data)
ts = s = ast_strdupa(data);
+ if (chan) {
+ ast_channel_lock(chan);
+ if ((ctime = pbx_builtin_getvar_helper(chan, "TESTTIME")) && sscanf(ctime, "%ld", &timesecs) == 1) {
+ tv.tv_sec = timesecs;
+ } else if (ctime) {
+ ast_log(LOG_WARNING, "Using current time to evaluate\n");
+ /* Reset when unparseable */
+ pbx_builtin_setvar_helper(chan, "TESTTIME", NULL);
+ }
+ ast_channel_unlock(chan);
+ }
/* Separate the Goto path */
strsep(&ts, "?");
branch1 = strsep(&ts,":");
branch2 = strsep(&ts,"");
/* struct ast_include include contained garbage here, fixed by zeroing it on get_timerange */
- if (ast_build_timing(&timing, s) && ast_check_timing(&timing))
+ if (ast_build_timing(&timing, s) && ast_check_timing2(&timing, tv)) {
branch = branch1;
- else
+ } else {
branch = branch2;
+ }
ast_destroy_timing(&timing);
if (ast_strlen_zero(branch)) {
@@ -9618,6 +9694,7 @@ int load_pbx(void)
ast_verb(1, "Registering builtin applications:\n");
ast_cli_register_multiple(pbx_cli, ARRAY_LEN(pbx_cli));
__ast_custom_function_register(&exception_function, NULL);
+ __ast_custom_function_register(&testtime_function, NULL);
/* Register builtin applications */
for (x = 0; x < ARRAY_LEN(builtins); x++) {