فهرست منبع

modules/tmrec: Ported Perl's Time::Period module.

- Make Time::Period (http://search.cpan.org/~pryan/Period-1.20/Period.pm)
  available as native C implementation.

Author: Richard Fuchs <[email protected]>
Andreas Granig 13 سال پیش
والد
کامیت
1810746263
5فایلهای تغییر یافته به همراه607 افزوده شده و 1 حذف شده
  1. 71 1
      modules/tmrec/README
  2. 108 0
      modules/tmrec/doc/tmrec_admin.xml
  3. 369 0
      modules/tmrec/period.c
  4. 6 0
      modules/tmrec/period.h
  5. 53 0
      modules/tmrec/tmrec_mod.c

+ 71 - 1
modules/tmrec/README

@@ -37,12 +37,14 @@ Alex Balashov
 
               4.1. tmrec_match(timerec [, timestamp])
               4.2. is_leap_year([year])
+              4.3. time_period_match(period [, timestamp])
 
    List of Examples
 
    1.1. Set separator parameter
    1.2. tmrec_match usage
    1.3. is_leap_year usage
+   1.4. time_period_match usage
 
 Chapter 1. Admin Guide
 
@@ -62,12 +64,14 @@ Chapter 1. Admin Guide
 
         4.1. tmrec_match(timerec [, timestamp])
         4.2. is_leap_year([year])
+        4.3. time_period_match(period [, timestamp])
 
 1. Overview
 
    This module provides time recurrence matching functions. The format of
    recurrence definitions is based on Internet Calendaring and Scheduling
-   Core Object Specification (Calendar COS - RFC 2445).
+   Core Object Specification (Calendar COS - RFC 2445). It also provides a
+   port of the Perl Time::Period module for generic time period matching.
 
 2. Dependencies
 
@@ -105,6 +109,7 @@ modparam("tmrec", "separator", ";")
 
    4.1. tmrec_match(timerec [, timestamp])
    4.2. is_leap_year([year])
+   4.3. time_period_match(period [, timestamp])
 
 4.1.  tmrec_match(timerec [, timestamp])
 
@@ -236,3 +241,68 @@ modparam("tmrec", "separator", ";")
 ...
 if(is_leap_year("2010"))
 ...
+
+4.3.  time_period_match(period [, timestamp])
+
+   Matches the point in time specified by the timestamp parameter, or the
+   current time if the parameter is missing, against the given period
+   specification. Returns 1 if it matches, -1 if it doesn't, and a value
+   <= -2 if there was an error.
+
+   The time period specification follows the Perl Time::Period module. It
+   is a string and consists of zero or more sub-period specifications,
+   separated by commas. The period matches if at least one of the
+   sub-periods matches, or if no sub-periods were given at all (an empty
+   string).
+
+   Each sub-period is a list of one or more scale definitions, optionally
+   separated by space characters. The sub-period matches if all of the
+   given scales within that sub-period match. For each scale given, a
+   single value or a range of values (which is two values separated by a
+   hyphen) can be specified. Multiple values or multiple ranges (or a
+   combination thereof) within a single scale is also possible. If a
+   certain scale is specified more than once, the previous values or
+   ranges for that scale are extended by the newly given ones. If a
+   particular scale is not mentioned at all within a sub-period, then no
+   matching is performed for that scale.
+
+   The following scales are supported and understood. Each scale also has
+   a respective short code, either one can be used. A single scale
+   definition consists of the scale name, followed by an opening brace,
+   followed by the list of values, followed by a closing brace.
+     * year or yr - Either given as a full 4-digit number >= 1970, or as a
+       2-digit number, in which case it will be understood to be within
+       the current century.
+     * month or mo - Month of the year, either a number between 1 and 12,
+       or at least the first 3 letters of a spelled out month name, e.g.
+       “jan”, “janua” or “january” will all work.
+     * week or wk - Week of the month, a number between 1 and 6. The first
+       day of the week is Sunday.
+     * yday or yd - Day of the year, a number between 1 and 366.
+     * mday or md - Day of the month, a number between 1 and 31.
+     * wday or wd - Day of the week, either a number between 1 and 7, or
+       at least the first 2 letters of a spelled out weekday name
+       (analogous to the “month” scale). Sunday is the first day of the
+       week.
+     * hour or hr - A number between 0 and 23. Unlike the Perl
+       Time::Period module, “am” or “pm” specifications are not supported.
+     * minute or min - A number between 0 and 59.
+     * second or sec - A number between 0 and 60 (to allow for leap
+       seconds).
+
+   The parameters can include pseudo-variables. Whitespace (more
+   precisely, the space character only) can occur anywhere, but is
+   optional. Ranges in all scales (with the exception of the “year” scale)
+   are allowed to wrap-around, e.g. a weekday scale of “{fri-tue}” is
+   equivalent to “{fri-sat,sun-tue}”.
+
+   Example 1.4. time_period_match usage
+...
+if(time_period_match("wd{1-5} hr{8-16}, wd{1-5} hr{17} min{0-29}"))
+        xdbg("Monday to Friday, 8:00 to 17:30\n");
+
+if(time_period_match("weekday { sat sun }, weekday {mo-fr} hr {17-8},wd{mo-wed}h
+r{15 16 9}"))
+        xdbg("We're closed - open only Monday to Wednesday 10:00-15:00, Thursday
+ and Friday 9:00-17:00");
+...

+ 108 - 0
modules/tmrec/doc/tmrec_admin.xml

@@ -19,6 +19,8 @@
 		This module provides time recurrence matching functions. The format
 		of recurrence definitions is based on Internet Calendaring and 
 		Scheduling Core Object Specification (Calendar COS - RFC 2445).
+		It also provides a port of the Perl Time::Period module for generic
+		time period matching.
 	</para>
 	</section>
 
@@ -301,6 +303,112 @@ modparam("tmrec", "separator", ";")
 ...
 if(is_leap_year("2010"))
 ...
+</programlisting>
+	    </example>
+	</section>
+
+	<section>
+	    <title>
+		<function moreinfo="none">time_period_match(period [, timestamp])</function>
+	    </title>
+	    <para>
+			Matches the point in time specified by the timestamp parameter, or
+			the current time if the parameter is missing, against the given
+			period specification. Returns 1 if it matches, -1 if it doesn't,
+			and a value &lt;= -2 if there was an error.
+		</para>
+		<para>
+			The time period specification follows the Perl Time::Period module.
+			It is a string and consists of zero or more sub-period specifications,
+			separated by commas. The period matches if at least one of the
+			sub-periods matches, or if no sub-periods were given at all (an
+			empty string).
+		</para>
+		<para>
+			Each sub-period is a list of one or more scale definitions,
+			optionally separated by space characters. The sub-period matches if
+			all of the given scales within that sub-period match. For each scale
+			given, a single value or a range of values (which is two values
+			separated by a hyphen) can be specified. Multiple
+			values or multiple ranges (or a combination thereof) within a single
+			scale is also possible. If a certain scale is specified more than once,
+			the previous values or ranges for that scale are extended by the newly
+			given ones. If a particular scale is not mentioned at all within a
+			sub-period, then no matching is performed for that scale.
+		</para>
+		<para>
+			The following scales are supported and understood. Each scale also has
+			a respective short code, either one can be used. A single scale
+			definition consists of the scale name, followed by an opening brace,
+			followed by the list of values, followed by a closing brace.
+			<itemizedlist>
+				<listitem><para>
+					<emphasis>year</emphasis> or <emphasis>yr</emphasis>
+					- Either given as a full 4-digit number &gt;= 1970, or
+					as a 2-digit number, in which case it will be understood
+					to be within the current century.
+				</para></listitem>
+				<listitem><para>
+					<emphasis>month</emphasis> or <emphasis>mo</emphasis>
+					- Month of the year, either a number between 1 and 12,
+					or at least the first 3 letters of a spelled out month
+					name, e.g. <quote>jan</quote>, <quote>janua</quote>
+					or <quote>january</quote> will all work.
+				</para></listitem>
+				<listitem><para>
+					<emphasis>week</emphasis> or <emphasis>wk</emphasis>
+					- Week of the month, a number between 1 and 6. The
+					first day of the week is Sunday.
+				</para></listitem>
+				<listitem><para>
+					<emphasis>yday</emphasis> or <emphasis>yd</emphasis>
+					- Day of the year, a number between 1 and 366.
+				</para></listitem>
+				<listitem><para>
+					<emphasis>mday</emphasis> or <emphasis>md</emphasis>
+					- Day of the month, a number between 1 and 31.
+				</para></listitem>
+				<listitem><para>
+					<emphasis>wday</emphasis> or <emphasis>wd</emphasis>
+					- Day of the week, either a number between 1 and 7, or
+					at least the first 2 letters of a spelled out weekday
+					name (analogous to the <quote>month</quote> scale).
+					Sunday is the first day of the week.
+				</para></listitem>
+				<listitem><para>
+					<emphasis>hour</emphasis> or <emphasis>hr</emphasis>
+					- A number between 0 and 23. Unlike the Perl Time::Period
+					module, <quote>am</quote> or <quote>pm</quote>
+					specifications are not supported.
+				</para></listitem>
+				<listitem><para>
+					<emphasis>minute</emphasis> or <emphasis>min</emphasis>
+					- A number between 0 and 59.
+				</para></listitem>
+				<listitem><para>
+					<emphasis>second</emphasis> or <emphasis>sec</emphasis>
+					- A number between 0 and 60 (to allow for leap seconds).
+				</para></listitem>
+			</itemizedlist>
+		</para>
+		<para>
+			The parameters can include pseudo-variables. Whitespace (more
+			precisely, the space character only) can occur anywhere, but is
+			optional. Ranges in all scales (with the exception of the
+			<quote>year</quote> scale) are allowed to wrap-around, e.g. a weekday
+			scale of <quote>{fri-tue}</quote> is equivalent to
+			<quote>{fri-sat,sun-tue}</quote>.
+		</para>
+		<example>
+		<title><function>time_period_match</function> usage</title>
+		<programlisting format="linespecific">
+...
+if(time_period_match("wd{1-5} hr{8-16}, wd{1-5} hr{17} min{0-29}"))
+	xdbg("Monday to Friday, 8:00 to 17:30\n");
+
+if(time_period_match("weekday { sat sun }, weekday {mo-fr} hr {17-8},wd{mo-wed}hr{15 16 9}"))
+	xdbg("We're closed - open only Monday to Wednesday 10:00-15:00, Thursday and Friday 9:00-17:00");
+...
 </programlisting>
 	    </example>
 	</section>

+ 369 - 0
modules/tmrec/period.c

@@ -0,0 +1,369 @@
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <stdlib.h>
+
+enum scales {
+	SCALE_YEAR = 0,
+	SCALE_MONTH,
+	SCALE_WEEK,
+	SCALE_MDAY,
+	SCALE_WDAY,
+	SCALE_YDAY,
+	SCALE_HOUR,
+	SCALE_MINUTE,
+	SCALE_SECOND,
+
+	SCALE_MAX
+};
+
+#define MAX_CODES 2
+#define MAX_VALUE_LEN 16 /* for spelled out month names, longest is "September" */
+
+typedef int (*scale_match_func)(const int time_var, const char *from, const char *to);
+
+struct scale_definition {
+	scale_match_func	func;
+	const char		*codes[MAX_CODES];
+	int			flags;
+};
+
+#define FLAG_INTEGER_ARGS		0x1
+
+static int year_fn(const int time_var, const char *from, const char *to);
+static int month_fn(const int time_var, const char *from, const char *to);
+static int week_fn(const int time_var, const char *from, const char *to);
+static int mday_fn(const int time_var, const char *from, const char *to);
+static int wday_fn(const int time_var, const char *from, const char *to);
+static int yday_fn(const int time_var, const char *from, const char *to);
+static int hour_fn(const int time_var, const char *from, const char *to);
+static int minute_fn(const int time_var, const char *from, const char *to);
+static int second_fn(const int time_var, const char *from, const char *to);
+
+static const struct scale_definition defs[SCALE_MAX + 1] = {
+	[SCALE_YEAR  ] = { year_fn,   { "year",   "yr"  }, FLAG_INTEGER_ARGS },
+	[SCALE_MONTH ] = { month_fn,  { "month",  "mo"  }, 0                 },
+	[SCALE_WEEK  ] = { week_fn,   { "week",   "wk"  }, FLAG_INTEGER_ARGS },	/* week of the month */
+	[SCALE_MDAY  ] = { mday_fn,   { "mday",   "md"  }, FLAG_INTEGER_ARGS },	/* day of the month */
+	[SCALE_WDAY  ] = { wday_fn,   { "wday",   "wd"  }, 0                 },	/* day of the week */
+	[SCALE_YDAY  ] = { yday_fn,   { "yday",   "yd"  }, FLAG_INTEGER_ARGS },	/* day of the year */
+	[SCALE_HOUR  ] = { hour_fn,   { "hour",   "hr"  }, FLAG_INTEGER_ARGS },
+	[SCALE_MINUTE] = { minute_fn, { "minute", "min" }, FLAG_INTEGER_ARGS },
+	[SCALE_SECOND] = { second_fn, { "second", "sec" }, FLAG_INTEGER_ARGS },
+	/* XXX week of the year? */
+
+	[SCALE_MAX   ] = { NULL, { NULL, } },
+};
+
+static const char *months[12] = { "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug",
+	"sep", "oct", "nov", "dec" };
+static const char *weekdays[7] = { "su", "mo", "tu", "we", "th", "fr", "sa" };
+
+static void get_time_vars(int time_vars[SCALE_MAX], time_t t) {
+	struct tm tm;
+
+	localtime_r(&t, &tm);
+
+	time_vars[SCALE_YEAR]   = tm.tm_year + 1900;
+	time_vars[SCALE_MONTH]  = tm.tm_mon + 1;
+	time_vars[SCALE_WEEK]   = (tm.tm_mday - 1 + (tm.tm_wday - tm.tm_mday + 1) % 7) / 7 + 1;
+	time_vars[SCALE_MDAY]   = tm.tm_mday;
+	time_vars[SCALE_WDAY]   = tm.tm_wday;
+	time_vars[SCALE_YDAY]   = tm.tm_yday + 1;
+	time_vars[SCALE_HOUR]   = tm.tm_hour;
+	time_vars[SCALE_MINUTE] = tm.tm_min;
+	time_vars[SCALE_SECOND] = tm.tm_sec;
+}
+
+#define WS_SKIP() while (*p == ' ') p++;
+
+int in_period(time_t t, const char *p) {
+	int time_vars[SCALE_MAX];
+	int scale_results[SCALE_MAX];
+	int scale, j, len, res;
+	const char *c, *a1, *a2;
+	char from[MAX_VALUE_LEN], to[MAX_VALUE_LEN], *str;
+
+	/* If no period is given or string is empty, the time always matches */
+	if (!p)
+		return 1;
+	WS_SKIP();
+	if (!*p)
+		return 1;
+
+	/* If "none" or "never" is given, time never matches */
+	if (!strcasecmp(p, "none") || !strcasecmp(p, "never"))
+		return 0;
+
+	get_time_vars(time_vars, t);
+
+	/* Loop through all sub-periods, separated by commas.
+	   string :=  PERIOD [, PERIOD ... ] */
+	while (1) {
+		memset(scale_results, -1, sizeof(scale_results));
+
+		/* Each sub-period consists of one or more scales, separated by spaces.
+		   PERIOD := SCALE { VALUES } [ SCALE { VALUES } ... ] */
+		while (1) {
+			/* XXX could do some hashing here */
+			for (scale = 0; scale < SCALE_MAX; scale++) {
+				for (j = 0; j < MAX_CODES; j++) {
+					c = defs[scale].codes[j];
+					len = strlen(c);
+					if (strncasecmp(p, c, len))
+						continue;
+					if (p[len] == ' ' || p[len] == '{')
+						goto found_scale;
+				}
+			}
+
+			/* No valid scale definition found, syntax error */
+			return -1;
+
+found_scale:
+			/* Skip over scale name, whitespace and brace */
+			p += len;
+			WS_SKIP();
+			if (*p != '{')
+				return -1; /* Syntax error */
+			p++;
+			WS_SKIP();
+
+			/* Keep track of what we've found */
+			if (scale_results[scale] == -1)
+				scale_results[scale] = 0;
+			else if (scale_results[scale] == 1) {
+				/* We already have a valid match for this scale. Skip
+				   over all this nonsense then. */
+				while (*p && *p != '}')
+					p++;
+				if (!*p)
+					return -1; /* Syntax error */
+				goto close_brace;
+			}
+
+			/* We're inside the braces now. Values are separated
+			   by spaces, possibly given as ranges.
+			   VALUES := ( VALUE | RANGE ) [ ( VALUE | RANGE ) ... ]
+			   RANGE := VALUE - VALUE */
+
+			while (1) {
+				str = from;
+				len = sizeof(from) - 1;
+				*from = *to = '\0';
+				while (1) {
+					switch (*p) {
+						case '\0':
+							return -1; /* Syntax error */
+
+						case ' ':
+							WS_SKIP();
+							/* Here, it's either a hyphen or end of value/range */
+							if (*p == '-')
+								goto hyphen;
+							break;
+
+						case '-':
+hyphen:
+							if (!*from)
+								return -1; /* Range given as "-foo", syntax error */
+							if (*to)
+								return -1; /* Range given as "foo-bar-baz", syntax error */
+							/* Terminate "from" string and init for "to" */
+							*str = '\0';
+							str = to;
+							len = sizeof(to) - 1;
+							p++;
+							WS_SKIP();
+							continue;
+
+						case '}':
+							break;
+
+						default:
+							/* everything else gets copied and lowercased */
+							if (len <= 0)
+								return -1; /* String too long, syntax error */
+							*str++ = *p++ | 0x20;	/* works for letters and digits */
+							len--;
+							continue;
+					}
+					break;
+				}
+
+				*str = '\0';
+
+				/* Finished parsing out value or range. An empty result
+				   is valid, e.g. at the end of the list for the scale */
+				if (!*from) {
+					if (*p == '}')
+						break;
+					continue;
+				}
+				a1 = from;
+				a2 = *to ? to : NULL;
+				if ((defs[scale].flags & FLAG_INTEGER_ARGS)) {
+					a1 = (void *) atol(a1);
+					a2 = (void *) (a2 ? atol(a2) : -1);
+				}
+				res = defs[scale].func(time_vars[scale], a1, a2);
+				printf("result: %i\n", res);
+
+				if (res == -1)
+					return -1; /* Syntax error */
+				else if (res == 1)
+					scale_results[scale] = 1;
+			}
+
+close_brace:
+			p++;
+
+			/* Finished with one scale, braces closed. See if there's any more */
+			WS_SKIP();
+			if (!*p || *p == ',') {
+				/* Nope! Evaluate our result */
+				for (scale = 0; scale < SCALE_MAX; scale++) {
+					if (scale_results[scale] == 0)
+						goto no_match;
+				}
+
+				/* All scales that were given matched! We're done! */
+				return 1;
+
+no_match:
+				/* No luck, try next one if there are any more */
+				if (*p == ',') {
+					p++;
+					WS_SKIP();
+					break;
+				}
+
+				return 0;
+			}
+
+			continue;
+		}
+	}
+}
+
+static int generic_fn(const int time_var, const long f, long t, const long min, const long max) {
+	if (t == -1)
+		t = f;
+
+	if (f < min || f > max)
+		return -1;
+	if (t < min || t > max)
+		return -1;
+
+	if (f > t) {
+		if (f <= time_var || t >= time_var)
+			return 1;
+	}
+	else if (f <= time_var && time_var <= t)
+		return 1;
+	return 0;
+}
+
+static int generic_named_fn(const int time_var, const char *from, const char *to,
+		const char **array, int arr_len, int str_len) {
+
+	int i, f = 0, t = 0;
+
+	f = atoi(from);
+	if (!f)
+		for (i = 0; i < arr_len; i++)
+			if (!strncmp(array[i], from, str_len)) {
+				f = i + 1;
+				break;
+			}
+	if (!f)
+		return -1;
+
+	if (!to)
+		t = f;
+	else {
+		t = atoi(to);
+		if (!t)
+			for (i = 0; i < arr_len; i++)
+				if (!strncmp(array[i], to, str_len)) {
+					t = i + 1;
+					break;
+				}
+		if (!t)
+			return -1;
+	}
+
+	return generic_fn(time_var, f, t, 1, arr_len);
+}
+
+static int year_fn(const int time_var, const char *from, const char *to) {
+	long f, t, c;
+	printf("%s %i %li %li\n", __FUNCTION__, time_var, (long) from, (long) to);
+
+	f = (long) from;
+	t = (long) to;
+
+	if (t == -1)
+		t = f;
+
+	c = time_var / 100;	
+
+	if (t < 0)
+		return -1;
+	else if (t <= 99)
+		t += c;
+	else if (t < 1970)
+		return -1;
+
+	if (f < 0)
+		return -1;
+	else if (f <= 99)
+		f += c;
+	else if (f < 1970)
+		return -1;
+
+	if (time_var >= f && time_var <= t)
+		return 1;
+	return 0;
+}
+
+static int month_fn(const int time_var, const char *from, const char *to) {
+	printf("%s %i '%s' '%s'\n", __FUNCTION__, time_var, from, to);
+	return generic_named_fn(time_var, from, to, months, 12, 3);
+}
+
+static int week_fn(const int time_var, const char *from, const char *to) {
+	printf("%s %i %li %li\n", __FUNCTION__, time_var, (long) from, (long) to);
+	return generic_fn(time_var, (long) from, (long) to, 1, 6);
+}
+
+static int mday_fn(const int time_var, const char *from, const char *to) {
+	printf("%s %i %li %li\n", __FUNCTION__, time_var, (long) from, (long) to);
+	return generic_fn(time_var, (long) from, (long) to, 1, 31);
+}
+
+static int wday_fn(const int time_var, const char *from, const char *to) {
+	printf("%s %i '%s' '%s'\n", __FUNCTION__, time_var, from, to);
+	return generic_named_fn(time_var, from, to, weekdays, 7, 2);
+}
+
+static int yday_fn(const int time_var, const char *from, const char *to) {
+	printf("%s %i %li %li\n", __FUNCTION__, time_var, (long) from, (long) to);
+	return generic_fn(time_var, (long) from, (long) to, 1, 366);
+}
+
+static int hour_fn(const int time_var, const char *from, const char *to) {
+	printf("%s %i %li %li\n", __FUNCTION__, time_var, (long) from, (long) to);
+	return generic_fn(time_var, (long) from, (long) to, 0, 23);
+}
+
+static int minute_fn(const int time_var, const char *from, const char *to) {
+	printf("%s %i %li %li\n", __FUNCTION__, time_var, (long) from, (long) to);
+	return generic_fn(time_var, (long) from, (long) to, 0, 59);
+}
+
+static int second_fn(const int time_var, const char *from, const char *to) {
+	printf("%s %i %li %li\n", __FUNCTION__, time_var, (long) from, (long) to);
+	return generic_fn(time_var, (long) from, (long) to, 0, 60); /* allow for leap seconds */
+}

+ 6 - 0
modules/tmrec/period.h

@@ -0,0 +1,6 @@
+#ifndef _PERIOD_H_
+#define _PERIOH_H_
+
+int in_period(time_t t, const char *p);
+
+#endif

+ 53 - 0
modules/tmrec/tmrec_mod.c

@@ -33,6 +33,7 @@
 #include "../../pvar.h"
 #include "../../mod_fix.h"
 #include "../../lib/srutils/tmrec.h"
+#include "period.h"
 
 
 MODULE_VERSION
@@ -45,6 +46,8 @@ static int w_tmrec_match(struct sip_msg* msg, char* rec, char* t);
 static int fixup_tmrec_match(void** param, int param_no);
 static int w_is_leap_year(struct sip_msg* msg, char* t, char* p2);
 static int fixup_is_leap_year(void** param, int param_no);
+static int fixup_time_period_match(void** param, int param_no);
+static int w_time_period_match(struct sip_msg* msg, char* period, char* t);
 
 int tmrec_wday = 0;
 char tmrec_separator = '|';
@@ -59,6 +62,10 @@ static cmd_export_t cmds[]={
 		0, ANY_ROUTE},
 	{"is_leap_year", (cmd_function)w_is_leap_year, 1, fixup_is_leap_year,
 		0, ANY_ROUTE},
+	{"time_period_match", (cmd_function)w_time_period_match, 1, fixup_time_period_match,
+		0, ANY_ROUTE},
+	{"time_period_match", (cmd_function)w_time_period_match, 2, fixup_time_period_match,
+		0, ANY_ROUTE},
 	{0, 0, 0, 0, 0, 0}
 };
 
@@ -220,3 +227,49 @@ static int fixup_tmrec_match(void** param, int param_no)
 	}
 	return 0;
 }
+
+static int fixup_time_period_match(void** param, int param_no)
+{
+	if(param_no==1)
+	{
+		if(fixup_spve_null(param, 1)<0)
+			return -1;
+		return 0;
+	} else if(param_no==2) {
+		if(fixup_igp_null(param, 1)<0)
+			return -1;
+	}
+	return 0;
+}
+
+static int w_time_period_match(struct sip_msg* msg, char* period, char* t)
+{
+	str rv;
+	time_t tv;
+	int ti;
+
+	if(msg==NULL)
+		return -2;
+
+	if(fixup_get_svalue(msg, (gparam_t*)period, &rv)!=0)
+	{
+		LM_ERR("invalid period parameter value\n");
+		return -3;
+	}
+
+	if(t!=NULL)
+	{
+		if(fixup_get_ivalue(msg, (gparam_t*)t, &ti)!=0)
+		{
+			LM_ERR("invalid time stamp parameter value\n");
+			return -4;
+		}
+		tv = (time_t)ti;
+	} else {
+		tv = time(NULL);
+	}
+
+	if (in_period(tv, rv.s))
+		return 1;
+	return -1;
+}