From ecbe7eff7a557a4aa55fb43e60299cf4f36165d9 Mon Sep 17 00:00:00 2001 From: Tilghman Lesher Date: Wed, 13 Jan 2010 21:27:34 +0000 Subject: [PATCH] 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 --- include/asterisk/pbx.h | 8 ++++ main/pbx.c | 85 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h index a5c3b2248a..50a18a6240 100644 --- a/include/asterisk/pbx.h +++ b/include/asterisk/pbx.h @@ -146,6 +146,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. diff --git a/main/pbx.c b/main/pbx.c index e06577ee37..5ed2c82962 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -332,6 +332,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") GotoIf IFTIME + TESTTIME @@ -717,6 +718,30 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") RaiseException + + + Sets a time to be used with the channel to test logical conditions. + + + + Date in ISO 8601 format + + + Time in HH:MM:SS format (24-hour time) + + + Timezone name + + + + 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. + + GotoIfTime + + La merde se produit. @@ -7283,11 +7308,15 @@ 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))) @@ -8927,6 +8956,38 @@ static int pbx_builtin_hangup(struct ast_channel *chan, const char *data) return -1; } +/*! + * \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 */ @@ -8934,6 +8995,9 @@ 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