OCSRM_SRC + 'psinterface.c',
OCSRM_SRC + 'srmresourcestrings.c',
OCSRM_SRC + 'srmutility.c',
+ OCSRM_SRC + 'iotvticalendar.c',
OCSRM_SRC + 'base64.c'
]
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef IOTVT_ICALENDAR_H
+#define IOTVT_ICALENDAR_H
+
+//Not supported on Arduino due lack of absolute time need to implement iCalendar
+#ifndef WITH_ARDUINO
+
+#include <stdint.h> // for uint8_t typedef
+#include <stdbool.h>
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define FREQ_DAILY (1)
+#define MAX_BYDAY_SIZE (7) //7 days of week
+#define TM_YEAR_OFFSET (1900) //tm_year field of c-lang tm date-time struct
+ //represents number of years since 1900.
+#define TM_DST_OFFSET (1) //c-lang tm struct Daylight Saving Time offset.
+#define TOTAL_HOURS (24) //Total hours in a day.
+
+typedef struct IotvtICalRecur IotvtICalRecur_t;
+typedef struct IotvtICalPeriod IotvtICalPeriod_t;
+
+/*
+ * date-time = date "T" time
+ *
+ * date = date-value
+ * date-value = date-fullyear date-month date-mday
+ * date-fullyear = 4DIGIT
+ * date-month = 2DIGIT ;01-12
+ * date-mday = 2DIGIT ;01-28, 01-29, 01-30, 01-31
+ * ;based on month/year
+ *
+ * time = time-hour time-minute time-second [time-utc]
+ * time-hour = 2DIGIT ;00-23
+ * time-minute = 2DIGIT ;00-59
+ * time-second = 2DIGIT ;00-60
+ * ;The "60" value is used to account for "leap" seconds.
+ *
+ * Date-Time Forms:
+ * 1. Date with Local time
+ * 20150626T150000
+ */
+typedef struct tm IotvtICalDateTime_t; //c-lang tm date-time struct
+
+/*
+ * Bit mask for weekdays
+ */
+typedef enum
+{
+ NO_WEEKDAY = 0X0,
+ SUNDAY = (0x1 << 0),
+ MONDAY = (0x1 << 1),
+ TUESDAY = (0x1 << 2),
+ WEDNESDAY = (0x1 << 3),
+ THURSDAY = (0x1 << 4),
+ FRIDAY = (0x1 << 5),
+ SATURDAY = (0x1 << 6)
+}IotvtICalWeekdayBM_t;
+
+/*
+ * Result code for IotvtICalendar
+ */
+typedef enum
+{
+ IOTVTICAL_SUCCESS = 0, //successfully completed operation
+ IOTVTICAL_VALID_ACCESS, //access is within allowable time
+ IOTVTICAL_INVALID_ACCESS, //access is not within allowable time
+ IOTVTICAL_INVALID_PARAMETER, //invalid method parameter
+ IOTVTICAL_INVALID_RRULE, //rrule is not well form, missing FREQ
+ IOTVTICAL_INVALID_PERIOD, //period is not well form, start-datetime is after end-datetime
+ IOTVTICAL_ERROR //encounter error
+}IotvtICalResult_t;
+
+/*
+ * Grammar for iCalendar data type PERIOD
+ *
+ * period = date-time "/" date-time ; start-time / end-time.
+ * ;The start-time MUST be before the end-time.
+ *
+ */
+struct IotvtICalPeriod
+{
+ IotvtICalDateTime_t startDateTime;
+ IotvtICalDateTime_t endDateTime;
+};
+
+/*
+ * Grammar for iCalendar data type RECUR
+ *
+ * recur = "FREQ"=freq *(
+ * ( ";" "UNTIL" "=" enddate ) /
+ * ( ";" "BYDAY" "=" bywdaylist ) /
+ * )
+ *
+ * freq = "DAILY"
+ * enddate = date
+ * bywdaylist = weekday/ ( weekday *("," weekday) )
+ * weekday = "SU" / "MO" / "TU" / "WE" / "TH" / "FR" / "SA"
+ *
+ * Example:
+ * 1."Allow access on every Monday, Wednesday & Friday between 3pm to 5pm"
+ * PERIOD:20150626T150000/20150626T170000
+ * RRULE: FREQ=DAILY; BYDAY=MO, WE, FR
+ * 2."Allow access every Monday, Wednesday & Friday from 3pm to 5pm until
+ * July 3rd, 2015"
+ * PERIOD:20150626T150000/20150626T170000
+ * RRULE: FREQ=DAILY; UNTIL=20150703; BYDAY=MO, WE, FR
+ */
+struct IotvtICalRecur
+{
+ uint16_t freq;
+ IotvtICalDateTime_t until;
+ IotvtICalWeekdayBM_t byDay;
+};
+
+/**
+ * This API is used by policy engine to checks if the
+ * request to access resource is within valid time.
+ *
+ * @param period string representing period.
+ * @param recur string representing recurrence rule
+ *
+ * @return IOTVTICAL_VALID_ACCESS -- if the request is within valid time period
+ * IOTVTICAL_INVALID_ACCESS -- if the request is not within valid time period
+ * IOTVTICAL_INVALID_PARAMETER -- if parameter are invalid
+ * IOTVTICAL_INVALID_PERIOD -- if period string has invalid format
+ * IOTVTICAL_INVALID_RRULE -- if rrule string has invalid format
+ *
+ *Eg: if(IOTVTICAL_VALID_ACCESS == IsRequestWithinValidTime(period, recur))
+ * {
+ * //Access within allowable time
+ * }
+ * else
+ * {
+ * //Access is not within allowable time.
+ * }
+ */
+IotvtICalResult_t IsRequestWithinValidTime(char *period, char *recur);
+
+/**
+ * Parses periodStr and populate struct IotvtICalPeriod_t
+ *
+ * @param periodStr string to be parsed.
+ * @param period IotvtICalPeriod_t struct to be populated.
+ *
+ * @return IOTVTICAL_INVALID_PARAMETER -- if parameter are invalid
+ * IOTVTICAL_INVALID_PERIOD -- if period string has invalid format
+ * IOTVTICAL_INVALID_SUCCESS -- if no error while parsing
+ */
+IotvtICalResult_t ParsePeriod(const char *periodStr, IotvtICalPeriod_t *period);
+
+/**
+ * Parses recurStr and populate struct IotvtICalRecur_t
+ *
+ * @param recurStr string to be parsed.
+ * @param recur IotvtICalPeriod_t struct to be populated.
+ *
+ * @return IOTVTICAL_INVALID_PARAMETER -- if parameter are invalid
+ * IOTVTICAL_INVALID_PERIOD -- if period string has invalid format
+ * IOTVTICAL_INVALID_RRULE -- if rrule string has invalid format
+ */
+IotvtICalResult_t ParseRecur(const char *recurStr, IotvtICalRecur_t *recur);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+#endif //IOTVT_ICALENDAR_H
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+//Not supported on Arduino due lack of absolute time need to implement iCalendar
+#ifndef WITH_ARDUINO
+
+#define _XOPEN_SOURCE //Needed by strptime
+#include <string.h>
+#include "iotvticalendar.h"
+#include "oic_string.h"
+
+static char dtFormat[] = "%Y%m%dT%H%M%S"; //date-time format
+static char dFormat[] = "%Y%m%d"; // date format
+
+static const char FREQ[] = "FREQ";
+static const char UNTIL[] = "UNTIL";
+static const char BYDAY[] = "BYDAY";
+static const char DAILY[] = "DAILY";
+
+
+/**
+ * Parses periodStr and populate struct IotvtICalPeriod_t
+ *
+ * @param periodStr string to be parsed.
+ * @param period IotvtICalPeriod_t struct to be populated.
+ *
+ * @return IOTVTICAL_INVALID_PARAMETER -- if parameter are invalid
+ * IOTVTICAL_INVALID_PERIOD -- if period string has invalid format
+ * IOTVTICAL_INVALID_SUCCESS -- if no error while parsing
+ */
+IotvtICalResult_t ParsePeriod(const char *periodStr, IotvtICalPeriod_t *period)
+{
+ if((NULL == periodStr) || (NULL == period))
+ {
+ return IOTVTICAL_INVALID_PARAMETER;
+ }
+
+ char *endDTPos;
+ char *fmt = "";
+ int startDTLen;
+ int endDTLen;
+
+ //Finding length of startDateTime and endDateTime in period
+ //startDateTime and endDateTime can have form YYYYmmdd or YYYYmmddTHHMMSS
+ //startDateTime and endDateTime must be same form
+ //Eg: periodStr = "20150629T153050/20150630T203055"
+ // periodStr = "20150629/20150630"
+ if(NULL == (endDTPos = strchr(periodStr, '/')))
+ {
+ return IOTVTICAL_INVALID_PERIOD;
+ }
+ endDTPos += 1;
+ startDTLen = endDTPos - periodStr - 1;
+ endDTLen = strlen(endDTPos);
+
+ //Checking if both startDateTime and endDateTime are of same form
+ if(startDTLen == endDTLen)
+ {
+ if(8 == startDTLen) //YYYYmmdd
+ {
+ fmt = dFormat;
+ }
+ else if(15 == startDTLen) //YYYYmmddTHHMMSS
+ {
+ fmt = dtFormat;
+ }
+ else
+ {
+ return IOTVTICAL_INVALID_PERIOD;
+ }
+ }
+ else
+ {
+ return IOTVTICAL_INVALID_PERIOD;
+ }
+
+ //Checking if startDateTime has right format
+ if(NULL != strptime(periodStr, fmt, &period->startDateTime))
+ {
+ //Checking if endDateTime has right format
+ if(NULL != strptime(endDTPos, fmt, &period->endDateTime))
+ {
+ //Checking if endDateTime is after startDateTime
+ if(difftime(mktime(&period->endDateTime),
+ mktime(&period->startDateTime)) > 0)
+ {
+ //mktime increases value of tm_hour by 1 if tm_isdst is set.
+ //The tm_hour value in period's startDateTime and endDatetime
+ //should remain same irrespective of daylight saving time.
+ if(period->startDateTime.tm_isdst)
+ {
+ period->startDateTime.tm_hour =
+ (period->startDateTime.tm_hour + TOTAL_HOURS - TM_DST_OFFSET) % TOTAL_HOURS;
+ }
+ if(period->endDateTime.tm_isdst)
+ {
+ period->endDateTime.tm_hour =
+ (period->endDateTime.tm_hour + TOTAL_HOURS - TM_DST_OFFSET) % TOTAL_HOURS;
+ }
+ return IOTVTICAL_SUCCESS;
+ }
+ }
+ }
+ return IOTVTICAL_INVALID_PERIOD;
+}
+
+
+/**
+ * Parses untilRule and populate "until" field of struct IotvtICalRecur_t
+ *
+ * @param untilRule string to be parsed.
+ * @param recur IotvtICalRecur_t struct to be populated.
+ *
+ * @return IOTVTICAL_ERRRO -- if untilRule has invalid format
+ * IOTVTICAL_INVALID_SUCCESS -- if no error while parsing
+ */
+static IotvtICalResult_t ParseDate(char *untilRule, IotvtICalRecur_t *recur)
+{
+ char *date = strchr(untilRule, '=');
+
+ if(NULL == date)
+ {
+ return IOTVTICAL_ERROR;
+ }
+ date += 1;
+
+ if(strlen(date) == 8) //YYYYmmdd
+ {
+ if(NULL != strptime(date, dFormat, &recur->until))
+ {
+ return IOTVTICAL_SUCCESS;
+ }
+ }
+ return IOTVTICAL_ERROR;
+}
+
+
+/**
+ * Parses bydayRule and populate "byDay" field of struct IotvtICalRecur_t
+ *
+ * @param bydayRule string to be parsed.
+ * @param recur IotvtICalRecur_t struct to be populated.
+ *
+ * @return IOTVTICAL_ERRRO -- if bydayRule has empty weekday list or invalid weekdays
+ * IOTVTICAL_INVALID_SUCCESS -- if no error while parsing
+ */
+static IotvtICalResult_t ParseByday(char *bydayRule, IotvtICalRecur_t *recur)
+{
+ if(strstr(bydayRule, "SU"))
+ {
+ recur->byDay = recur->byDay | SUNDAY;
+ }
+ if(strstr(bydayRule, "MO"))
+ {
+ recur->byDay = recur->byDay | MONDAY;
+ }
+ if(strstr(bydayRule, "TU"))
+ {
+ recur->byDay = recur->byDay | TUESDAY;
+ }
+ if(strstr(bydayRule, "WE"))
+ {
+ recur->byDay = recur->byDay | WEDNESDAY;
+ }
+ if(strstr(bydayRule, "TH"))
+ {
+ recur->byDay = recur->byDay | THURSDAY;
+ }
+ if(strstr(bydayRule, "FR"))
+ {
+ recur->byDay = recur->byDay | FRIDAY;
+ }
+ if(strstr(bydayRule, "SA"))
+ {
+ recur->byDay = recur->byDay | SATURDAY;
+ }
+
+ //Checking if byDay list is empty or has inValid weekdays
+ if(recur->byDay == NO_WEEKDAY)
+ {
+ return IOTVTICAL_ERROR;
+ }
+
+ return IOTVTICAL_SUCCESS;
+}
+
+
+/**
+ * Parses recurStr and populate struct IotvtICalRecur_t
+ *
+ * @param recurStr string to be parsed.
+ * @param recur IotvtICalPeriod_t struct to be populated.
+ *
+ * @return IOTVTICAL_INVALID_PARAMETER -- if parameter are invalid
+ * IOTVTICAL_INVALID_PERIOD -- if period string has invalid format
+ * IOTVTICAL_INVALID_RRULE -- if rrule string has invalid format
+ */
+IotvtICalResult_t ParseRecur(const char *recurStr, IotvtICalRecur_t *recur)
+{
+
+ if((NULL == recurStr) || (NULL == recur))
+ {
+ return IOTVTICAL_INVALID_PARAMETER;
+ }
+
+ const char *startPos="";
+ const char *endPos="";
+ char buf[50];
+ int freqFlag = 0; //valid RRULE must have "FREQ" parameter.
+ //flag to track if RRULE has "FREQ" or not
+
+ startPos = recurStr;
+ //Iterates though recurrence rule
+ //Eg, RRULE: FREQ=DAILY; UNTIL=20150703; BYDAY=MO, WE, FR
+ while('\0' != startPos)
+ {
+ endPos = strchr(startPos, ';');
+ if(endPos)
+ {
+ endPos += 1;
+ }
+ OICStrcpy(buf, (endPos - startPos), startPos);
+ if(NULL != strstr(buf, FREQ))
+ {
+ if(NULL != strstr(buf, DAILY))
+ {
+ recur->freq = FREQ_DAILY;
+ freqFlag = 1;
+ }
+ else
+ {
+ return IOTVTICAL_INVALID_RRULE;
+ }
+ }
+ else if(NULL != strstr(buf, UNTIL))
+ {
+ if(IOTVTICAL_SUCCESS != ParseDate(buf, recur))
+ {
+ return IOTVTICAL_INVALID_RRULE;
+ }
+ }
+ else if(NULL != strstr(buf, BYDAY))
+ {
+ if(IOTVTICAL_SUCCESS != ParseByday(buf, recur))
+ {
+ return IOTVTICAL_INVALID_RRULE;
+ };
+ }
+ startPos = endPos;
+ }
+
+ if(1 != freqFlag)
+ {
+ return IOTVTICAL_INVALID_RRULE;
+ }
+
+ return IOTVTICAL_SUCCESS;
+}
+
+
+/**
+ * Computes number of days between two dates.
+ *
+ * @param date1 earlier date.
+ * @param date2 later date.
+ *
+ * @return number of days between date1 & date2.
+ */
+static int DiffDays(IotvtICalDateTime_t *date1, IotvtICalDateTime_t *date2)
+{
+ int days;
+ int leapDays=0;
+
+ if(date2->tm_year > date1->tm_year)
+ {
+ for(int y = date1->tm_year; y < date2->tm_year; y++)
+ {
+ y += TM_YEAR_OFFSET;
+ if(y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
+ {
+ leapDays += 1;
+ }
+ }
+ }
+
+ days = (365 * date2->tm_year + date2->tm_yday + leapDays) -
+ (365 * date1->tm_year + date1->tm_yday);
+
+ return days;
+}
+
+
+/**
+ * Computes number of seconds between two time.
+ *
+ * @param time1 earlier time.
+ * @param date2 later time.
+ *
+ * @return number of seconds between time1 and time2.
+ */
+static int DiffSecs(IotvtICalDateTime_t *time1, IotvtICalDateTime_t *time2)
+{
+ return (3600 * time2->tm_hour + 60 * time2->tm_min + time2->tm_sec) -
+ (3600 * time1->tm_hour + 60 * time1->tm_min + time1->tm_sec);
+}
+
+
+/**
+ * This API is used by policy engine to checks if the
+ * request to access resource is within valid time.
+ *
+ * @param period string representing period.
+ * @param recur string representing recurrence rule
+ *
+ * @return IOTVTICAL_VALID_ACCESS -- if the request is within valid time period
+ * IOTVTICAL_INVALID_ACCESS -- if the request is not within valid time period
+ * IOTVTICAL_INVALID_PARAMETER -- if parameter are invalid
+ * IOTVTICAL_INVALID_PERIOD -- if period string has invalid format
+ * IOTVTICAL_INVALID_RRULE -- if rrule string has invalid format
+ */
+
+IotvtICalResult_t IsRequestWithinValidTime(char *periodStr, char *recurStr)
+{
+ //NULL recur rule means no recurring patter exist.
+ //Period can't be null. Period is used with or without
+ //recur rule to compute allowable access time.
+ if(NULL == periodStr)
+ {
+ return IOTVTICAL_INVALID_PARAMETER;
+ }
+
+ IotvtICalPeriod_t period = {};
+ IotvtICalRecur_t recur = {};
+ IotvtICalResult_t ret = IOTVTICAL_INVALID_ACCESS;
+
+ time_t rawTime = time(0);
+ IotvtICalDateTime_t *currentTime = localtime(&rawTime);
+
+ ret = ParsePeriod(periodStr, &period);
+ if(ret != IOTVTICAL_SUCCESS)
+ {
+ return ret;
+ }
+
+ //If recur is NULL then the access time is between period's startDate and endDate
+ if(NULL == recurStr)
+ {
+ if((0 <= DiffDays(&period.startDateTime, currentTime)) &&
+ (0 <= DiffDays(currentTime, &period.endDateTime)))
+ {
+ ret = IOTVTICAL_VALID_ACCESS;
+ }
+ }
+
+ //If recur is not NULL then the access time is between period's startTime and
+ //endTime on days specified in "BYDAY" list. The first instance of recurrence
+ //is computed from period's startDate and the last instance is computed from
+ //"UNTIL". If "UNTIL" is not specified then the recurrence goes for forever.
+ //Eg, RRULE: FREQ=DAILY; UNTIL=20150703; BYDAY=MO, WE, FR
+ if(NULL != recurStr)
+ {
+ ret = ParseRecur(recurStr, &recur);
+ if(ret != IOTVTICAL_SUCCESS)
+ {
+ return ret;
+ }
+
+ if((0 <= DiffSecs(&period.startDateTime, currentTime))&&
+ (0 <= DiffSecs(currentTime, &period.endDateTime)) &&
+ (0 <= DiffDays(&period.startDateTime, currentTime)))
+ {
+ IotvtICalDateTime_t emptyDT = {};
+ ret = IOTVTICAL_VALID_ACCESS;
+
+ //"UNTIL" is an optional parameter of RRULE, checking if until present in recur
+ if(0 != memcmp(&recur.until, &emptyDT, sizeof(IotvtICalDateTime_t)))
+ {
+ if(0 > DiffDays(currentTime, &recur.until))
+ {
+ ret = IOTVTICAL_INVALID_ACCESS;
+ }
+ }
+
+ //"BYDAY" is an optional parameter of RRULE, checking if byday present in recur
+ if(NO_WEEKDAY != recur.byDay)
+ {
+
+ int isValidWD = (0x1 << currentTime->tm_wday) & recur.byDay; //Valid weekdays
+ if(!isValidWD)
+ {
+ ret = IOTVTICAL_INVALID_ACCESS;
+ }
+ }
+ }
+ else
+ {
+ ret = IOTVTICAL_INVALID_ACCESS;
+ }
+ }
+ return ret;
+}
+#endif
'securityresourcemanager.cpp',
'credentialresource.cpp',
'srmutility.cpp',
+ 'iotvticalendartest.cpp',
'base64tests.cpp',
'svcresourcetest.cpp',
'srmtestcommon.cpp'])
--- /dev/null
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+//Not supported on Arduino due lack of absolute time need to implement iCalendar
+#ifndef WITH_ARDUINO
+
+#include "gtest/gtest.h"
+#include "iotvticalendar.h"
+#include "logger.h"
+
+#define TAG PCF("CALENDAR-UT")
+
+static void printPeriod(IotvtICalPeriod_t *period)
+{
+ OC_LOG_V(INFO, TAG, PCF("period->startDateTime.tm_year = %d"),period->startDateTime.tm_year);
+ OC_LOG_V(INFO, TAG, PCF("period->startDateTime.tm_mon = %d"),period->startDateTime.tm_mon);
+ OC_LOG_V(INFO, TAG, PCF("period->startDateTime.tm_mday = %d"),period->startDateTime.tm_mday);
+ OC_LOG_V(INFO, TAG, PCF("period->startDateTime.tm_hour = %d"),period->startDateTime.tm_hour);
+ OC_LOG_V(INFO, TAG, PCF("period->startDateTime.tm_min = %d"),period->startDateTime.tm_min);
+ OC_LOG_V(INFO, TAG, PCF("period->startDateTime.tm_sec = %d"),period->startDateTime.tm_sec);
+
+ OC_LOG_V(INFO, TAG, PCF("period->endDateTime.tm_year = %d"),period->endDateTime.tm_year);
+ OC_LOG_V(INFO, TAG, PCF("period->endDateTime.tm_mon = %d"),period->endDateTime.tm_mon);
+ OC_LOG_V(INFO, TAG, PCF("period->endDateTime.tm_mday = %d"),period->endDateTime.tm_mday);
+ OC_LOG_V(INFO, TAG, PCF("period->endDateTime.tm_hour = %d"),period->endDateTime.tm_hour);
+ OC_LOG_V(INFO, TAG, PCF("period->endDateTime.tm_min = %d"),period->endDateTime.tm_min);
+ OC_LOG_V(INFO, TAG, PCF("period->startDateTime.tm_sec = %d"),period->endDateTime.tm_sec);
+}
+
+static void printRecur(IotvtICalRecur_t *recur)
+{
+ OC_LOG_V(INFO, TAG, PCF("recur->freq = %d"), recur->freq);
+ OC_LOG_V(INFO, TAG, PCF("recur->until.tm_year = %d"), recur->until.tm_year);
+ OC_LOG_V(INFO, TAG, PCF("recur->until.tm_mon = %d"), recur->until.tm_mon);
+ OC_LOG_V(INFO, TAG, PCF("recur->until.tm_mday = %d"), recur->until.tm_mday);
+
+ if(recur->byDay & SUNDAY)
+ {
+ OC_LOG_V(INFO, TAG, PCF("recur->byDay = %s"), "Sunday");
+ }
+ if(recur->byDay & MONDAY)
+ {
+ OC_LOG_V(INFO, TAG, PCF("recur->byDay = %s"), "Monday");
+ }
+ if(recur->byDay & TUESDAY)
+ {
+ OC_LOG_V(INFO, TAG, PCF("recur->byDay = %s"), "Tuesday");
+ }
+ if(recur->byDay & WEDNESDAY)
+ {
+ OC_LOG_V(INFO, TAG, PCF("recur->byDay = %s"), "Wednesday");
+ }
+ if(recur->byDay & THURSDAY)
+ {
+ OC_LOG_V(INFO, TAG, PCF("recur->byDay = %s"), "Thursday");
+ }
+ if(recur->byDay & FRIDAY)
+ {
+ OC_LOG_V(INFO, TAG, PCF("recur->byDay = %s"), "Friday");
+ }
+ if(recur->byDay & SATURDAY)
+ {
+ OC_LOG_V(INFO, TAG, PCF("recur->byDay = %s"), "Saturday");
+ }
+}
+
+//ParsePeriod Tests
+TEST(ParsePeriodTest, ParsePeriodValidDateTime)
+{
+ char periodStr[] = "20150629T153050/20150630T233055";
+ IotvtICalPeriod_t period = {};
+ EXPECT_EQ(IOTVTICAL_SUCCESS, ParsePeriod(periodStr,&period));
+ printPeriod(&period);
+}
+
+TEST(ParsePeriodTest, ParsePeriodValidDate)
+{
+ char periodStr[] = "20150629/20150630";
+ IotvtICalPeriod_t period = {};
+ EXPECT_EQ(IOTVTICAL_SUCCESS, ParsePeriod(periodStr,&period));
+ printPeriod(&period);
+}
+
+TEST(ParsePeriodTest, ParsePeriodMismatchStartDTEndDT1)
+{
+ char periodStr[] = "20150629T153050/20150630";
+ IotvtICalPeriod_t period = {};
+ EXPECT_EQ(IOTVTICAL_INVALID_PERIOD, ParsePeriod(periodStr,&period));
+}
+
+TEST(ParsePeriodTest, ParsePeriodMismatchStartDTEndDT2)
+{
+ char periodStr[] = "20150629/20150630T203055";
+ IotvtICalPeriod_t period = {};
+ EXPECT_EQ(IOTVTICAL_INVALID_PERIOD, ParsePeriod(periodStr,&period));
+}
+
+TEST(ParsePeriodTest, ParsePeriodInvalidStartDT1)
+{
+ char periodStr[] = "20150629T1530/20150630T203055";
+ IotvtICalPeriod_t period = {};
+ EXPECT_EQ(IOTVTICAL_INVALID_PERIOD, ParsePeriod(periodStr,&period));
+}
+
+TEST(ParsePeriodTest, ParsePeriodInvalidEndtDT2)
+{
+ char periodStr[] = "20150629T153050/20150630203055";
+ IotvtICalPeriod_t period = {};
+ EXPECT_EQ(IOTVTICAL_INVALID_PERIOD, ParsePeriod(periodStr,&period));
+}
+
+TEST(ParsePeriodTest, ParsePeriodInvalidStartD3)
+{
+ char periodStr[] = "201506/20150630";
+ IotvtICalPeriod_t period = {};
+ EXPECT_EQ(IOTVTICAL_INVALID_PERIOD, ParsePeriod(periodStr,&period));
+}
+
+TEST(ParsePeriodTest, ParsePeriodInvalidEndD4)
+{
+ char periodStr[] = "20150629/201530";
+ IotvtICalPeriod_t period = {};
+ EXPECT_EQ(IOTVTICAL_INVALID_PERIOD, ParsePeriod(periodStr,&period));
+}
+
+TEST(ParsePeriodTest, ParsePeriodEndDTBeforeStartDT)
+{
+ char periodStr[] = "20150630T203055/20150629T153050";
+ IotvtICalPeriod_t period = {};
+ EXPECT_EQ(IOTVTICAL_INVALID_PERIOD, ParsePeriod(periodStr,&period));
+}
+TEST(ParsePeriodTest, ParsePeriodEndDBeforeStartD)
+{
+ char periodStr[] = "20150630/20150629";
+ IotvtICalPeriod_t period = {};
+ EXPECT_EQ(IOTVTICAL_INVALID_PERIOD, ParsePeriod(periodStr,&period));
+}
+
+TEST(ParseRecurTest, ParseRecurValid1)
+{
+ char recurStr[] = "FREQ=DAILY; UNTIL=20150703; BYDAY=MO, WE, FR";
+ IotvtICalRecur_t recur = {};
+ EXPECT_EQ(IOTVTICAL_SUCCESS, ParseRecur(recurStr, &recur));
+ printRecur(&recur);
+}
+
+TEST(ParseRecurTest, ParseRecurValid2)
+{
+ char recurStr[] = "FREQ=DAILY";
+ IotvtICalRecur_t recur = {};
+ EXPECT_EQ(IOTVTICAL_SUCCESS, ParseRecur(recurStr, &recur));
+ printRecur(&recur);
+}
+
+TEST(ParseRecurTest, ParseRecurInValidFreq1)
+{
+ char recurStr[] = "FREQ=WEEKLY; UNTIL=20150703; BYDAY=TU";
+ IotvtICalRecur_t recur = {};
+ EXPECT_EQ(IOTVTICAL_INVALID_RRULE, ParseRecur(recurStr, &recur));
+}
+
+TEST(ParseRecurTest, ParseRecurInValidFreq2)
+{
+ char recurStr[] = "UNTIL=20150703; BYDAY=TU";
+ IotvtICalRecur_t recur = {};
+ EXPECT_EQ(IOTVTICAL_INVALID_RRULE, ParseRecur(recurStr, &recur));
+}
+
+TEST(ParseRecurTest, ParseRecurInValidUntil)
+{
+ char recurStr[] = "FREQ=DAILY; UNTIL=20150703T095055; BYDAY=MO, WE, FR";
+ IotvtICalRecur_t recur = {};
+ EXPECT_EQ(IOTVTICAL_INVALID_RRULE, ParseRecur(recurStr, &recur));
+}
+
+TEST(ParseRecurTest, ParseRecurInValidByday)
+{
+ char recurStr[] = "FREQ=DAILY; UNTIL=20150703; BYDAY=";
+ IotvtICalRecur_t recur = {};
+ EXPECT_EQ(IOTVTICAL_INVALID_RRULE, ParseRecur(recurStr, &recur));
+}
+
+//FIXME: ALL IsRequestWithinValidTime tests will fail after 20151230
+TEST(IsRequestWithinValidTimeTest, IsRequestWithinValidTimeValidPeriod1)
+{
+ char periodStr[] = "20150630/20151230";
+ EXPECT_EQ(IOTVTICAL_VALID_ACCESS, IsRequestWithinValidTime(periodStr, NULL));
+}
+
+TEST(IsRequestWithinValidTimeTest, IsRequestWithinValidTimeValidPeriodAndRecur1)
+{
+ //Daily on days MO, WE & FR from 6:00:00am to 8:00:00pm until 20151230
+ char recurStr[] = "FREQ=DAILY; UNTIL=20151230; BYDAY=MO, WE, FR";
+ char periodStr[] = "20150630T060000/20150630T200000";
+
+ time_t rt = time(0);
+ IotvtICalDateTime_t *ct = localtime(&rt);
+
+ int byDay = MONDAY | WEDNESDAY | FRIDAY;
+ int isValidWD = (0x1 << ct->tm_wday) & byDay;
+
+ if(isValidWD && 6 <= ct->tm_hour && 20>= ct->tm_hour)
+ {
+ EXPECT_EQ(IOTVTICAL_VALID_ACCESS, IsRequestWithinValidTime(periodStr, recurStr));
+ }
+ else
+ {
+ EXPECT_EQ(IOTVTICAL_INVALID_ACCESS, IsRequestWithinValidTime(periodStr, recurStr));
+ }
+}
+
+TEST(IsRequestWithinValidTimeTest, IsRequestWithinValidTimeValidPeriodAndRecur2)
+{
+ //Daily forever from 6:00:00am to 8:00:00pm
+ char recurStr[] = "FREQ=DAILY";
+ char periodStr[] = "20150630T060000/20150630T200000";
+
+ time_t rt = time(0);
+ IotvtICalDateTime_t *ct = localtime(&rt);
+
+ if(6 <= ct->tm_hour && 20>= ct->tm_hour)
+ {
+ EXPECT_EQ(IOTVTICAL_VALID_ACCESS, IsRequestWithinValidTime(periodStr, recurStr));
+ }
+ else
+ {
+ EXPECT_EQ(IOTVTICAL_INVALID_ACCESS, IsRequestWithinValidTime(periodStr, recurStr));
+ }
+}
+
+TEST(IsRequestWithinValidTimeTest, IsRequestWithinValidTimeValidPeriodAndRecur3)
+{
+ //Daily until 20151230 from 6:00:00am to 8:00:00pm
+ char recurStr[] = "FREQ=DAILY; UNTIL=20151230";
+ char periodStr[] = "20150630T060000/20150630T200000";
+
+ time_t rt = time(0);
+ IotvtICalDateTime_t *ct = localtime(&rt);
+
+ if(6 <= ct->tm_hour && 20>= ct->tm_hour)
+ {
+ EXPECT_EQ(IOTVTICAL_VALID_ACCESS, IsRequestWithinValidTime(periodStr, recurStr));
+ }
+ else
+ {
+ EXPECT_EQ(IOTVTICAL_INVALID_ACCESS, IsRequestWithinValidTime(periodStr, recurStr));
+ }
+}
+
+TEST(IsRequestWithinValidTimeTest, IsRequestWithinValidTimeValidPeriodAndRecur4)
+{
+ //Daily forever on days MO, WE & Fr from 6:00:00am to 8:00:00pm
+ char recurStr[] = "FREQ=DAILY; BYDAY=MO, WE, FR";
+ char periodStr[] = "20150630T060000/20150630T200000";
+
+ time_t rt = time(0);
+ IotvtICalDateTime_t *ct = localtime(&rt);
+
+ int byDay = MONDAY | WEDNESDAY | FRIDAY;
+ int isValidWD = (0x1 << ct->tm_wday) & byDay;
+
+ if(isValidWD && 6 <= ct->tm_hour && 20>= ct->tm_hour)
+ {
+ EXPECT_EQ(IOTVTICAL_VALID_ACCESS, IsRequestWithinValidTime(periodStr, recurStr));
+ }
+ else
+ {
+ EXPECT_EQ(IOTVTICAL_INVALID_ACCESS, IsRequestWithinValidTime(periodStr, recurStr));
+ }
+}
+
+TEST(IsRequestWithinValidTimeTest, IsRequestWithinValidTimeInValidPeriodAndValidRecur)
+{
+ //Daily forever on days MO, WE & Fr
+ char recurStr[] = "FREQ=DAILY; BYDAY=MO, WE, FR";
+ char periodStr[] = "20150630/20150730";
+
+ EXPECT_EQ(IOTVTICAL_INVALID_ACCESS, IsRequestWithinValidTime(periodStr, recurStr));
+}
+
+#endif