Fixed custom headers and Basic authorization, added support for redirection, functional file download interface can be used for SW updates and more.

Dependents:   Sample_HTTPClient Sample_HTTPClient LWM2M_NanoService_Ethernet LWM2M_NanoService_Ethernet ... more

Fork of HTTPClient by Vincent Wochnik

More recent changes - added iCal processing.

Derivative of a derivative, however this one works when it comes to supplying Basic authorization to access a protected resource. Some additional changes to the debug interface to clean it up for consistency with many other components I have.

Committer:
WiredHome
Date:
Wed Apr 03 22:00:31 2019 +0000
Revision:
48:61c26e0111c9
Parent:
46:ac12edc84261
Minor change to a memory allocation for header parsing.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 39:21fc7a4b6927 1 #include "HTTPiCal.h"
WiredHome 39:21fc7a4b6927 2
WiredHome 42:ab259a9d1d36 3 //#include "Utility.h" // private memory manager
WiredHome 41:37e7df011c1f 4 #ifndef UTILITY_H
WiredHome 41:37e7df011c1f 5 #define swMalloc malloc // use the standard
WiredHome 41:37e7df011c1f 6 #define swFree free
WiredHome 41:37e7df011c1f 7 #endif
WiredHome 41:37e7df011c1f 8
WiredHome 40:bcb19f8dbba3 9 //#define DEBUG "iCal"
WiredHome 39:21fc7a4b6927 10 #include <cstdio>
WiredHome 39:21fc7a4b6927 11 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
WiredHome 46:ac12edc84261 12 #define DBG(x, ...) std::printf("[DBG %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 46:ac12edc84261 13 #define WARN(x, ...) std::printf("[WRN %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 46:ac12edc84261 14 #define ERR(x, ...) std::printf("[ERR %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 46:ac12edc84261 15 #define INFO(x, ...) std::printf("[INF %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 39:21fc7a4b6927 16 #else
WiredHome 39:21fc7a4b6927 17 #define DBG(x, ...)
WiredHome 39:21fc7a4b6927 18 #define WARN(x, ...)
WiredHome 39:21fc7a4b6927 19 #define ERR(x, ...)
WiredHome 39:21fc7a4b6927 20 #define INFO(x, ...)
WiredHome 39:21fc7a4b6927 21 #endif
WiredHome 39:21fc7a4b6927 22
WiredHome 39:21fc7a4b6927 23 HTTPiCal::HTTPiCal(int count) {
WiredHome 41:37e7df011c1f 24 EventList = (Event_T *)swMalloc(count * sizeof(Event_T));
WiredHome 39:21fc7a4b6927 25 if (EventList) {
WiredHome 39:21fc7a4b6927 26 EventSpaceCount = count;
WiredHome 39:21fc7a4b6927 27 EventCount = 0;
WiredHome 39:21fc7a4b6927 28 seeking = idle;
WiredHome 39:21fc7a4b6927 29 } else {
WiredHome 39:21fc7a4b6927 30 error("no space for event list");
WiredHome 39:21fc7a4b6927 31 }
WiredHome 39:21fc7a4b6927 32 }
WiredHome 39:21fc7a4b6927 33
WiredHome 39:21fc7a4b6927 34 HTTPiCal::~HTTPiCal() {
WiredHome 39:21fc7a4b6927 35 if (EventList)
WiredHome 41:37e7df011c1f 36 swFree(EventList);
WiredHome 39:21fc7a4b6927 37 }
WiredHome 39:21fc7a4b6927 38
WiredHome 39:21fc7a4b6927 39 void HTTPiCal::SetTimeWindow(time_t StartTime, time_t EndTime) {
WiredHome 39:21fc7a4b6927 40 gridStartTime = StartTime;
WiredHome 39:21fc7a4b6927 41 gridEndTime = EndTime;
WiredHome 39:21fc7a4b6927 42 }
WiredHome 39:21fc7a4b6927 43
WiredHome 39:21fc7a4b6927 44 bool HTTPiCal::GetEvent(unsigned int i, Event_T * event) {
WiredHome 39:21fc7a4b6927 45 if (i < EventCount) {
WiredHome 39:21fc7a4b6927 46 *event = EventList[i];
WiredHome 39:21fc7a4b6927 47 return true;
WiredHome 39:21fc7a4b6927 48 } else {
WiredHome 39:21fc7a4b6927 49 return false;
WiredHome 39:21fc7a4b6927 50 }
WiredHome 39:21fc7a4b6927 51 }
WiredHome 39:21fc7a4b6927 52
WiredHome 39:21fc7a4b6927 53 void HTTPiCal::writeReset() {
WiredHome 39:21fc7a4b6927 54 //INFO("writeReset()");
WiredHome 39:21fc7a4b6927 55 EventCount = 0;
WiredHome 40:bcb19f8dbba3 56 seeking = idle;
WiredHome 39:21fc7a4b6927 57 lineBuf[0] = '\0';
WiredHome 39:21fc7a4b6927 58 }
WiredHome 39:21fc7a4b6927 59
WiredHome 39:21fc7a4b6927 60 int HTTPiCal::write(const char * buf, size_t len) {
WiredHome 39:21fc7a4b6927 61 const char * pStart = buf;
WiredHome 39:21fc7a4b6927 62 const char * pEOL;
WiredHome 39:21fc7a4b6927 63 size_t origLen = len;
WiredHome 39:21fc7a4b6927 64
WiredHome 39:21fc7a4b6927 65 pEOL = strchr(pStart, '\n');
WiredHome 39:21fc7a4b6927 66 //INFO("\r\n\r\nwrite[%d:%d] = \r\n%s\r\nend-write\r\n", len, pEOL - pStart, buf);
WiredHome 40:bcb19f8dbba3 67 //printf("lineBuf:[%d] %s\r\n", len, buf);
WiredHome 39:21fc7a4b6927 68 while (pEOL && (pEOL - pStart) < len) {
WiredHome 39:21fc7a4b6927 69 int lbLen = strlen(lineBuf);
WiredHome 39:21fc7a4b6927 70 strncpy(lineBuf + lbLen, pStart, (pEOL - pStart));
WiredHome 39:21fc7a4b6927 71 lineBuf[lbLen + (pEOL - pStart) + 1] = '\0';
WiredHome 39:21fc7a4b6927 72 if (lineBuf[pEOL - pStart + lbLen - 1] == '\r')
WiredHome 39:21fc7a4b6927 73 lineBuf[pEOL - pStart + lbLen - 1] = '\0';
WiredHome 40:bcb19f8dbba3 74 //printf("lineBuf:[%s]\r\n", lineBuf);
WiredHome 39:21fc7a4b6927 75 ParseICalStream(lineBuf, gridStartTime, gridEndTime, -300);
WiredHome 39:21fc7a4b6927 76 //INFO("");
WiredHome 39:21fc7a4b6927 77 lineBuf[0] = '\0';
WiredHome 39:21fc7a4b6927 78 len -= (pEOL - pStart);
WiredHome 39:21fc7a4b6927 79 pStart = pEOL + 1;
WiredHome 39:21fc7a4b6927 80 while (pStart && *pStart && *pStart <= ' ') {
WiredHome 39:21fc7a4b6927 81 pStart++;
WiredHome 39:21fc7a4b6927 82 len--;
WiredHome 39:21fc7a4b6927 83 }
WiredHome 39:21fc7a4b6927 84 if (*pStart)
WiredHome 39:21fc7a4b6927 85 pEOL = strchr(pStart, '\n');
WiredHome 39:21fc7a4b6927 86 else
WiredHome 39:21fc7a4b6927 87 pEOL = NULL;
WiredHome 39:21fc7a4b6927 88 }
WiredHome 39:21fc7a4b6927 89 if (len) {
WiredHome 39:21fc7a4b6927 90 strncpy(lineBuf, pStart, len);
WiredHome 39:21fc7a4b6927 91 lineBuf[len] = '\0';
WiredHome 39:21fc7a4b6927 92 //INFO("fragment:[%s]", lineBuf);
WiredHome 39:21fc7a4b6927 93 }
WiredHome 39:21fc7a4b6927 94 //INFO("write returns %d", origLen);
WiredHome 39:21fc7a4b6927 95 return origLen;
WiredHome 39:21fc7a4b6927 96 }
WiredHome 39:21fc7a4b6927 97
WiredHome 39:21fc7a4b6927 98 void HTTPiCal::setDataType(const char* type) {
WiredHome 39:21fc7a4b6927 99 //INFO("setDataType(%s)", type);
WiredHome 39:21fc7a4b6927 100 }
WiredHome 39:21fc7a4b6927 101
WiredHome 39:21fc7a4b6927 102 //void HTTPiCal::setLocation(const char * location) {
WiredHome 39:21fc7a4b6927 103 //
WiredHome 39:21fc7a4b6927 104 //}
WiredHome 39:21fc7a4b6927 105
WiredHome 39:21fc7a4b6927 106 void HTTPiCal::setIsChunked(bool chunked) {
WiredHome 39:21fc7a4b6927 107 INFO("setIsChunked(%d)", chunked);
WiredHome 39:21fc7a4b6927 108 m_chunked = chunked;
WiredHome 39:21fc7a4b6927 109 }
WiredHome 39:21fc7a4b6927 110
WiredHome 39:21fc7a4b6927 111 void HTTPiCal::setDataLen(size_t len) {
WiredHome 39:21fc7a4b6927 112 //INFO("setDataLen(%d)", len);
WiredHome 39:21fc7a4b6927 113 }
WiredHome 39:21fc7a4b6927 114
WiredHome 39:21fc7a4b6927 115
WiredHome 45:accd09953fae 116 static const char * RPT_DAYS[] = { "SU", "MO", "TU", "WE", "TH", "FR", "SA", "" };
WiredHome 39:21fc7a4b6927 117
WiredHome 39:21fc7a4b6927 118
WiredHome 39:21fc7a4b6927 119 const char * HTTPiCal::RepeatDayAbbrev(int i)
WiredHome 39:21fc7a4b6927 120 {
WiredHome 39:21fc7a4b6927 121 if (i < 7)
WiredHome 39:21fc7a4b6927 122 return RPT_DAYS[i];
WiredHome 39:21fc7a4b6927 123 else
WiredHome 39:21fc7a4b6927 124 return RPT_DAYS[7];
WiredHome 39:21fc7a4b6927 125 }
WiredHome 39:21fc7a4b6927 126
WiredHome 39:21fc7a4b6927 127 void HTTPiCal::SortEvents()
WiredHome 39:21fc7a4b6927 128 {
WiredHome 39:21fc7a4b6927 129 bool swapped;
WiredHome 39:21fc7a4b6927 130 int e;
WiredHome 39:21fc7a4b6927 131 Event_T Event;
WiredHome 39:21fc7a4b6927 132
WiredHome 39:21fc7a4b6927 133 do {
WiredHome 39:21fc7a4b6927 134 swapped = false;
WiredHome 39:21fc7a4b6927 135 for (e=0; e<EventCount-1; e++) {
WiredHome 39:21fc7a4b6927 136 if (EventList[e].Start > EventList[e+1].Start) {
WiredHome 39:21fc7a4b6927 137 Event = EventList[e];
WiredHome 39:21fc7a4b6927 138 EventList[e] = EventList[e+1];
WiredHome 39:21fc7a4b6927 139 EventList[e+1] = Event;
WiredHome 39:21fc7a4b6927 140 swapped = true;
WiredHome 39:21fc7a4b6927 141 }
WiredHome 39:21fc7a4b6927 142 }
WiredHome 39:21fc7a4b6927 143 } while (swapped);
WiredHome 39:21fc7a4b6927 144 }
WiredHome 39:21fc7a4b6927 145
WiredHome 39:21fc7a4b6927 146 uint16_t HTTPiCal::AtoIxN(const char * p, int n)
WiredHome 39:21fc7a4b6927 147 {
WiredHome 39:21fc7a4b6927 148 uint16_t res = 0;
WiredHome 39:21fc7a4b6927 149
WiredHome 39:21fc7a4b6927 150 while (n--) {
WiredHome 39:21fc7a4b6927 151 res = (res * 10) + (*p - '0');
WiredHome 39:21fc7a4b6927 152 p++;
WiredHome 39:21fc7a4b6927 153 }
WiredHome 39:21fc7a4b6927 154 return res;
WiredHome 39:21fc7a4b6927 155 }
WiredHome 39:21fc7a4b6927 156
WiredHome 39:21fc7a4b6927 157 // YYYYMMDD[THHMMSS[Z]]
WiredHome 39:21fc7a4b6927 158 // VALUE=DATE:YYYYMMDD
WiredHome 39:21fc7a4b6927 159 time_t HTTPiCal::ParseDateStamp(const char * string, tz_sec_t tzoSec)
WiredHome 39:21fc7a4b6927 160 {
WiredHome 39:21fc7a4b6927 161 time_t tStamp;
WiredHome 39:21fc7a4b6927 162 struct tm t;
WiredHome 39:21fc7a4b6927 163 struct tm * tnow;
WiredHome 39:21fc7a4b6927 164
WiredHome 39:21fc7a4b6927 165 time(&tStamp);
WiredHome 39:21fc7a4b6927 166 tnow = localtime(&tStamp);
WiredHome 39:21fc7a4b6927 167 if (strncmp(string, "VALUE=DATE:", 11) == 0) {
WiredHome 39:21fc7a4b6927 168 string += 11;
WiredHome 39:21fc7a4b6927 169 }
WiredHome 39:21fc7a4b6927 170 //INFO("ParseDateStamp(%s,%d)\n", string, tzoSec);
WiredHome 39:21fc7a4b6927 171 t.tm_year = AtoIxN(string, 4) - 1900;
WiredHome 39:21fc7a4b6927 172 t.tm_mon = AtoIxN(string+4, 2) - 1;
WiredHome 39:21fc7a4b6927 173 t.tm_mday = AtoIxN(string+6, 2);
WiredHome 39:21fc7a4b6927 174 if (strlen(string) > 8) {
WiredHome 39:21fc7a4b6927 175 t.tm_hour = AtoIxN(string+9, 2);
WiredHome 39:21fc7a4b6927 176 t.tm_min = AtoIxN(string+11, 2);
WiredHome 39:21fc7a4b6927 177 t.tm_sec = AtoIxN(string+13, 2);
WiredHome 39:21fc7a4b6927 178 t.tm_isdst = tnow->tm_isdst;
WiredHome 39:21fc7a4b6927 179 } else {
WiredHome 39:21fc7a4b6927 180 t.tm_hour = 0;
WiredHome 39:21fc7a4b6927 181 t.tm_min = 0;
WiredHome 39:21fc7a4b6927 182 t.tm_sec = 0;
WiredHome 39:21fc7a4b6927 183 t.tm_isdst = tnow->tm_isdst;
WiredHome 39:21fc7a4b6927 184 }
WiredHome 39:21fc7a4b6927 185 tStamp = mktime(&t);
WiredHome 39:21fc7a4b6927 186 if (string[strlen(string)-1] == 'Z') {
WiredHome 39:21fc7a4b6927 187 //INFO("Applying tzoSec %d", tzoSec);
WiredHome 39:21fc7a4b6927 188 tStamp = tStamp + tzoTZIDSec;
WiredHome 39:21fc7a4b6927 189 } else {
WiredHome 39:21fc7a4b6927 190 tStamp = tStamp + tzoSec;
WiredHome 39:21fc7a4b6927 191 }
WiredHome 39:21fc7a4b6927 192 return tStamp;
WiredHome 39:21fc7a4b6927 193 }
WiredHome 39:21fc7a4b6927 194
WiredHome 43:12a6ae712bcd 195 // since this returns the string from a static buffer, and unknowing users
WiredHome 43:12a6ae712bcd 196 // might call this twice in a single command (e.g. printf(..., FormatCTime(time1), FormatCTime(time2));
WiredHome 43:12a6ae712bcd 197 // this define controls how many of these can execute.
WiredHome 43:12a6ae712bcd 198 #define NumCallsPerArgList 2
WiredHome 39:21fc7a4b6927 199 char * HTTPiCal::FormatCTime(time_t t)
WiredHome 39:21fc7a4b6927 200 {
WiredHome 44:0e3b0849b2c7 201 static char temp[NumCallsPerArgList][30];
WiredHome 39:21fc7a4b6927 202 static int i = 0;
WiredHome 39:21fc7a4b6927 203
WiredHome 43:12a6ae712bcd 204 i %= NumCallsPerArgList;
WiredHome 39:21fc7a4b6927 205 strcpy(temp[i], ctime(&t));
WiredHome 39:21fc7a4b6927 206 temp[i][strlen(temp[i])-1] = '\0';
WiredHome 39:21fc7a4b6927 207 return temp[i++];
WiredHome 39:21fc7a4b6927 208 }
WiredHome 39:21fc7a4b6927 209
WiredHome 39:21fc7a4b6927 210
WiredHome 39:21fc7a4b6927 211 void HTTPiCal::ShowEventInfo(Event_T & Event)
WiredHome 39:21fc7a4b6927 212 {
WiredHome 39:21fc7a4b6927 213 char scratch[80];
WiredHome 39:21fc7a4b6927 214 #define LF "\r\n"
WiredHome 39:21fc7a4b6927 215
WiredHome 39:21fc7a4b6927 216 printf("******* Summary: %s" LF, Event.Summary);
WiredHome 39:21fc7a4b6927 217 printf(" Location: %s" LF, Event.Location);
WiredHome 39:21fc7a4b6927 218 printf(" Category: %s" LF, Event.Category);
WiredHome 39:21fc7a4b6927 219 printf(" Priority: %d" LF, Event.Priority);
WiredHome 39:21fc7a4b6927 220 sprintf(scratch, "%lu ", Event.Start);
WiredHome 39:21fc7a4b6927 221 sprintf(scratch + strlen(scratch), "%s", (Event.Start == 0) ? "" : ctime(&Event.Start));
WiredHome 39:21fc7a4b6927 222 scratch[strlen(scratch)-1] = '\0';
WiredHome 39:21fc7a4b6927 223 printf(" Start: %s" LF, scratch);
WiredHome 39:21fc7a4b6927 224 sprintf(scratch, "%lu ", Event.End);
WiredHome 39:21fc7a4b6927 225 sprintf(scratch + strlen(scratch), "%s", (Event.End == 0) ? "" : ctime(&Event.End));
WiredHome 39:21fc7a4b6927 226 scratch[strlen(scratch)-1] = '\0';
WiredHome 39:21fc7a4b6927 227 printf(" End: %s" LF, scratch);
WiredHome 39:21fc7a4b6927 228 printf(" Count: %d" LF, Event.Count);
WiredHome 39:21fc7a4b6927 229 printf(" Interval: %d" LF, Event.Interval);
WiredHome 39:21fc7a4b6927 230 printf(" RepeatFrq: %d" LF, Event.RepeatFreq);
WiredHome 39:21fc7a4b6927 231 printf(" RepeatDay: %02X" LF, Event.RepeatDays);
WiredHome 39:21fc7a4b6927 232 printf(" RepeatMonthDay: %08X" LF, Event.RepeatMonthDay);
WiredHome 39:21fc7a4b6927 233 printf(" RepeatMonthDayRev: %08X" LF, Event.RepeatMonthDayRev);
WiredHome 39:21fc7a4b6927 234 printf(" RepeatMonth: %04X" LF, Event.RepeatMonths);
WiredHome 39:21fc7a4b6927 235 sprintf(scratch, "%lu ", Event.Until);
WiredHome 39:21fc7a4b6927 236 sprintf(scratch + strlen(scratch), "%s", (Event.Until == 0) ? "" : ctime(&Event.Until));
WiredHome 39:21fc7a4b6927 237 scratch[strlen(scratch)-1] = '\0';
WiredHome 39:21fc7a4b6927 238 printf(" Until: %s" LF, scratch);
WiredHome 39:21fc7a4b6927 239 printf("" LF);
WiredHome 39:21fc7a4b6927 240 }
WiredHome 39:21fc7a4b6927 241
WiredHome 39:21fc7a4b6927 242
WiredHome 39:21fc7a4b6927 243 /// Computes the intersection of time1 and time2 ranges, and modifies time1
WiredHome 39:21fc7a4b6927 244 /// range to represent the intersection.
WiredHome 39:21fc7a4b6927 245 ///
WiredHome 39:21fc7a4b6927 246 /// start1 is input as the start of the time1 range, and is written
WiredHome 39:21fc7a4b6927 247 /// to represent the intersection of the two ranges.
WiredHome 39:21fc7a4b6927 248 /// end1 is input as the end of the time1 range and is written to
WiredHome 39:21fc7a4b6927 249 /// represent the intersection of the two ranges.
WiredHome 39:21fc7a4b6927 250 /// start2 is the start of the time2 range.
WiredHome 39:21fc7a4b6927 251 /// end2 is the end of the time2 range.
WiredHome 39:21fc7a4b6927 252 /// returns true if the ranges have an intersection, and the time1 range
WiredHome 39:21fc7a4b6927 253 /// values have been modified.
WiredHome 39:21fc7a4b6927 254 ///
WiredHome 39:21fc7a4b6927 255 bool HTTPiCal::TimeIntersects(time_t * start1, time_t * end1, time_t * start2, time_t * end2)
WiredHome 39:21fc7a4b6927 256 {
WiredHome 39:21fc7a4b6927 257 // |----Time1----|
WiredHome 39:21fc7a4b6927 258 // |--Time2--| false
WiredHome 39:21fc7a4b6927 259 //
WiredHome 39:21fc7a4b6927 260 // |----Time1----|
WiredHome 39:21fc7a4b6927 261 // |--Time2--| false
WiredHome 39:21fc7a4b6927 262 //
WiredHome 39:21fc7a4b6927 263 // |----Time1----|
WiredHome 39:21fc7a4b6927 264 // |----Time2----|
WiredHome 39:21fc7a4b6927 265 // |-Time1-| true
WiredHome 39:21fc7a4b6927 266 //
WiredHome 39:21fc7a4b6927 267 // |----Time1----|
WiredHome 39:21fc7a4b6927 268 // |----Time2----|
WiredHome 39:21fc7a4b6927 269 // |-Time1-| true
WiredHome 39:21fc7a4b6927 270 //
WiredHome 39:21fc7a4b6927 271 // |----Time1-------|
WiredHome 39:21fc7a4b6927 272 // |-Time2-|
WiredHome 39:21fc7a4b6927 273 // |-Time1-| true
WiredHome 39:21fc7a4b6927 274 //
WiredHome 39:21fc7a4b6927 275 // | Time1 (end1 == 0)
WiredHome 39:21fc7a4b6927 276 // | Time2 (end2 == 0) true
WiredHome 39:21fc7a4b6927 277 //
WiredHome 39:21fc7a4b6927 278 if (*start1 == *start2 && *end1 == 0 && *end2 == 0)
WiredHome 39:21fc7a4b6927 279 return true;
WiredHome 39:21fc7a4b6927 280 if (*end1 < *start2 || *end2 < *start1)
WiredHome 39:21fc7a4b6927 281 return false;
WiredHome 39:21fc7a4b6927 282 if (max(*start1,*start2) < min(*end1,*end2)) {
WiredHome 39:21fc7a4b6927 283 *start1 = max(*start1,*start2);
WiredHome 39:21fc7a4b6927 284 *end1 = min(*end1,*end2);
WiredHome 39:21fc7a4b6927 285 return true;
WiredHome 39:21fc7a4b6927 286 } else {
WiredHome 39:21fc7a4b6927 287 return false;
WiredHome 39:21fc7a4b6927 288 }
WiredHome 39:21fc7a4b6927 289 }
WiredHome 39:21fc7a4b6927 290
WiredHome 39:21fc7a4b6927 291 bool HTTPiCal::isLeapYear(time_t t)
WiredHome 39:21fc7a4b6927 292 {
WiredHome 39:21fc7a4b6927 293 int year;
WiredHome 39:21fc7a4b6927 294 struct tm * ts;
WiredHome 39:21fc7a4b6927 295 ts = localtime(&t);
WiredHome 39:21fc7a4b6927 296
WiredHome 39:21fc7a4b6927 297 year = 1900 + ts->tm_year + 1;
WiredHome 39:21fc7a4b6927 298 if ((((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0))
WiredHome 39:21fc7a4b6927 299 return true;
WiredHome 39:21fc7a4b6927 300 else
WiredHome 39:21fc7a4b6927 301 return false;
WiredHome 39:21fc7a4b6927 302 }
WiredHome 39:21fc7a4b6927 303
WiredHome 39:21fc7a4b6927 304 time_t HTTPiCal::NextInterval(time_t curTime, int repeatFreq, int interval)
WiredHome 39:21fc7a4b6927 305 {
WiredHome 39:21fc7a4b6927 306 const time_t secperday = 60*60*24;
WiredHome 39:21fc7a4b6927 307 const int repeatFactor[] = {0, 1, 7, 30, 365};
WiredHome 39:21fc7a4b6927 308 int delta = repeatFactor[repeatFreq];
WiredHome 39:21fc7a4b6927 309 if (repeatFreq == 4 && isLeapYear(curTime))
WiredHome 39:21fc7a4b6927 310 delta += 1;
WiredHome 39:21fc7a4b6927 311 //INFO("freq %d, interval %d, delta %d", repeatFreq, interval, delta);
WiredHome 39:21fc7a4b6927 312 return delta * interval * secperday;
WiredHome 39:21fc7a4b6927 313 }
WiredHome 39:21fc7a4b6927 314
WiredHome 39:21fc7a4b6927 315
WiredHome 39:21fc7a4b6927 316 // start1,end1 is the time range representing the visible grid
WiredHome 39:21fc7a4b6927 317 // start2,end2 is the time range of the event being tested
WiredHome 39:21fc7a4b6927 318 // Event is also the event being tested and permits testing the repeat information.
WiredHome 39:21fc7a4b6927 319 //
WiredHome 39:21fc7a4b6927 320 // If the event repeat pattern intersects with the display pattern, indicate this as "true"
WiredHome 39:21fc7a4b6927 321 //
WiredHome 39:21fc7a4b6927 322 bool HTTPiCal::RepeatMaskIntersects(time_t * start1, time_t * end1, time_t * start2, time_t * end2, Event_T * Event)
WiredHome 39:21fc7a4b6927 323 {
WiredHome 39:21fc7a4b6927 324 bool intersects = false;
WiredHome 39:21fc7a4b6927 325
WiredHome 39:21fc7a4b6927 326 //INFO("RepeatFreq: %d", Event->RepeatFreq);
WiredHome 39:21fc7a4b6927 327 if (Event->RepeatFreq == rptfDaily) {
WiredHome 39:21fc7a4b6927 328 //INFO("rptfDaily is not handled");
WiredHome 39:21fc7a4b6927 329 } else if (Event->RepeatFreq == rptfWeekly) {
WiredHome 39:21fc7a4b6927 330 struct tm * timeinfo;
WiredHome 39:21fc7a4b6927 331 timeinfo = localtime(start1);
WiredHome 39:21fc7a4b6927 332 uint8_t daymask = Event->RepeatDays;
WiredHome 39:21fc7a4b6927 333 // now, check the tm_wday (0=Sunday, 1=Monday, ...) and see if we intersect with the event time
WiredHome 39:21fc7a4b6927 334 uint8_t testmask = 1 << timeinfo->tm_wday;
WiredHome 39:21fc7a4b6927 335 //INFO("Mask: Event mask: %02X, test mask: %02X", daymask, testmask);
WiredHome 39:21fc7a4b6927 336 if (daymask & testmask)
WiredHome 39:21fc7a4b6927 337 intersects = true;
WiredHome 39:21fc7a4b6927 338 else
WiredHome 39:21fc7a4b6927 339 intersects = false;
WiredHome 39:21fc7a4b6927 340 //INFO(" intersects: %02X", daymask & testmask);
WiredHome 39:21fc7a4b6927 341 return intersects;
WiredHome 39:21fc7a4b6927 342 } else if (Event->RepeatFreq == rptfYearly) {
WiredHome 39:21fc7a4b6927 343 //struct tm * timeinfo;
WiredHome 39:21fc7a4b6927 344 //timeinfo = localtime(start1);
WiredHome 39:21fc7a4b6927 345 //INFO("rptfYearly is not handled well yet");
WiredHome 39:21fc7a4b6927 346 }
WiredHome 39:21fc7a4b6927 347 //INFO("Mask: no handler, returning true");
WiredHome 39:21fc7a4b6927 348 return true;
WiredHome 39:21fc7a4b6927 349 }
WiredHome 39:21fc7a4b6927 350
WiredHome 39:21fc7a4b6927 351 bool HTTPiCal::RepeatIntersects(time_t * start1, time_t * end1, time_t * start2, time_t * end2, Event_T * Event)
WiredHome 39:21fc7a4b6927 352 {
WiredHome 39:21fc7a4b6927 353 INFO("** 1: (%s, %s)", FormatCTime(*start1), *end1 ? FormatCTime(*end1) : "");
WiredHome 39:21fc7a4b6927 354 INFO(" 2: (%s, %s)", FormatCTime(*start2), *end2 ? FormatCTime(*end2) : "");
WiredHome 39:21fc7a4b6927 355 INFO(" ev: (%s, %s)", FormatCTime(Event->Start), Event->End ? FormatCTime(Event->End) : "");
WiredHome 39:21fc7a4b6927 356 if (TimeIntersects(start1, end1, start2, end2))
WiredHome 39:21fc7a4b6927 357 return true;
WiredHome 39:21fc7a4b6927 358 if (Event && Event->RepeatFreq) {
WiredHome 39:21fc7a4b6927 359 INFO("RepeatFreq: %d", Event->RepeatFreq);
WiredHome 39:21fc7a4b6927 360 if (Event->Start < *start2 && Event->Until > *start2 ) { // Until=....
WiredHome 39:21fc7a4b6927 361 INFO("Repeat until: %d", Event->Until);
WiredHome 39:21fc7a4b6927 362 do {
WiredHome 39:21fc7a4b6927 363 time_t interval = NextInterval(*start1, Event->RepeatFreq, (Event->Interval == 0) ? 1 : Event->Interval);
WiredHome 39:21fc7a4b6927 364 *start1 = *start1 + interval;
WiredHome 39:21fc7a4b6927 365 if (*end1)
WiredHome 39:21fc7a4b6927 366 *end1 = *end1 + interval;
WiredHome 39:21fc7a4b6927 367 INFO("** 1: (%s, %s)", FormatCTime(*start1), *end1 ? FormatCTime(*end1) : "");
WiredHome 39:21fc7a4b6927 368 INFO("until (%24s, %s)", " ", FormatCTime(Event->Until));
WiredHome 39:21fc7a4b6927 369 INFO(" 2: (%s, %s)", FormatCTime(*start2), *end2 ? FormatCTime(*end2) : "");
WiredHome 39:21fc7a4b6927 370 if (!RepeatMaskIntersects(start1, end1, start2, end2, Event)) {
WiredHome 39:21fc7a4b6927 371 continue; // we're not on a repeat cycle (e.g. wrong day of the week)
WiredHome 39:21fc7a4b6927 372 }
WiredHome 39:21fc7a4b6927 373 if (TimeIntersects(start1, end1, start2, end2)) {
WiredHome 39:21fc7a4b6927 374 return true;
WiredHome 39:21fc7a4b6927 375 }
WiredHome 39:21fc7a4b6927 376 } while ((*end2 == 0 || *start1 < *end2) && *start1 < Event->Until);
WiredHome 39:21fc7a4b6927 377 } else if (Event->Start < *start2 && Event->Count) { // Count=
WiredHome 39:21fc7a4b6927 378 INFO("Repeat count %d", Event->Count);
WiredHome 39:21fc7a4b6927 379 int count = Event->Count - 1;
WiredHome 39:21fc7a4b6927 380 do {
WiredHome 39:21fc7a4b6927 381 time_t interval = NextInterval(*start1, Event->RepeatFreq, (Event->Interval == 0) ? 1 : Event->Interval);
WiredHome 39:21fc7a4b6927 382 *start1 = *start1 + interval;
WiredHome 39:21fc7a4b6927 383 if (*end1)
WiredHome 39:21fc7a4b6927 384 *end1 = *end1 + interval;
WiredHome 39:21fc7a4b6927 385 INFO("** 1: (%s, %s) - %d", FormatCTime(*start1), *end1 ? FormatCTime(*end1) : "", count);
WiredHome 39:21fc7a4b6927 386 INFO(" 2: (%s, %s)", FormatCTime(*start2), *end2 ? FormatCTime(*end2) : "");
WiredHome 39:21fc7a4b6927 387 if (!RepeatMaskIntersects(start1, end1, start2, end2, Event)) {
WiredHome 39:21fc7a4b6927 388 continue; // we're not on a repeat cycle (e.g. wrong day of the week)
WiredHome 39:21fc7a4b6927 389 }
WiredHome 39:21fc7a4b6927 390 if (TimeIntersects(start1, end1, start2, end2)) {
WiredHome 39:21fc7a4b6927 391 return true;
WiredHome 39:21fc7a4b6927 392 }
WiredHome 39:21fc7a4b6927 393 } while (--count && *end1 < *start2);
WiredHome 39:21fc7a4b6927 394 } else if (Event->Start < *start2) { // no Count= and no Until=
WiredHome 39:21fc7a4b6927 395 INFO(" no Repeat end");
WiredHome 39:21fc7a4b6927 396 do {
WiredHome 39:21fc7a4b6927 397 int rptFreq = Event->RepeatFreq;
WiredHome 39:21fc7a4b6927 398 if (Event->RepeatFreq == 2 && Event->RepeatDays != 0)
WiredHome 39:21fc7a4b6927 399 rptFreq--;
WiredHome 39:21fc7a4b6927 400 time_t interval = NextInterval(*start1, rptFreq, (Event->Interval == 0) ? 1 : Event->Interval);
WiredHome 39:21fc7a4b6927 401 *start1 = *start1 + interval;
WiredHome 39:21fc7a4b6927 402 if (*end1)
WiredHome 39:21fc7a4b6927 403 *end1 = *end1 + interval;
WiredHome 39:21fc7a4b6927 404 INFO("== 1: (%s, %s)", FormatCTime(*start1), *end1 ? FormatCTime(*end1) : "");
WiredHome 39:21fc7a4b6927 405 INFO(" 2: (%s, %s)", FormatCTime(*start2), *end2 ? FormatCTime(*end2) : "");
WiredHome 39:21fc7a4b6927 406 if (!RepeatMaskIntersects(start1, end1, start2, end2, Event)) {
WiredHome 39:21fc7a4b6927 407 continue; // we're not on a repeat cycle (e.g. wrong day of the week)
WiredHome 39:21fc7a4b6927 408 }
WiredHome 39:21fc7a4b6927 409 if (TimeIntersects(start1, end1, start2, end2)) {
WiredHome 39:21fc7a4b6927 410 return true;
WiredHome 39:21fc7a4b6927 411 }
WiredHome 39:21fc7a4b6927 412 } while (*start1 < *end2 || (*end2 == 0 && *start1 < *start2));
WiredHome 39:21fc7a4b6927 413 } else {
WiredHome 39:21fc7a4b6927 414 INFO("falling out");
WiredHome 39:21fc7a4b6927 415 }
WiredHome 39:21fc7a4b6927 416 }
WiredHome 39:21fc7a4b6927 417 INFO(" no intersection");
WiredHome 39:21fc7a4b6927 418 return false;
WiredHome 39:21fc7a4b6927 419 }
WiredHome 39:21fc7a4b6927 420
WiredHome 39:21fc7a4b6927 421 // All the stuff between
WiredHome 39:21fc7a4b6927 422 // BEGIN:VEVENT
WiredHome 39:21fc7a4b6927 423 // ...
WiredHome 39:21fc7a4b6927 424 // END:VEVENT
WiredHome 39:21fc7a4b6927 425 //
WiredHome 39:21fc7a4b6927 426 void HTTPiCal::ParseEvent(Event_T * Event, const char * pStart, tz_sec_t tzoSec)
WiredHome 39:21fc7a4b6927 427 {
WiredHome 39:21fc7a4b6927 428 INFO("ParseEvent(...,'%s',%d)", pStart, tzoSec);
WiredHome 39:21fc7a4b6927 429 if (strncmp(pStart, "DTSTART:", 8) == 0) {
WiredHome 39:21fc7a4b6927 430 Event->Start = ParseDateStamp(pStart+8, tzoSec);
WiredHome 39:21fc7a4b6927 431 INFO(" Start: %s\n", ctime(&Event->Start));
WiredHome 39:21fc7a4b6927 432 } else if (strncmp(pStart, "DTSTART;", 8) == 0) {
WiredHome 39:21fc7a4b6927 433 const char * p = pStart + 8;
WiredHome 39:21fc7a4b6927 434 tzoSec = ParseTZID(p);
WiredHome 39:21fc7a4b6927 435 p = strrchr(pStart, ':');
WiredHome 39:21fc7a4b6927 436 if (p) {
WiredHome 39:21fc7a4b6927 437 Event->Start = ParseDateStamp(p+1, 0); // example was localtime with GMT -06:00 tzoSec);
WiredHome 39:21fc7a4b6927 438 INFO(" Start: %s", ctime(&Event->Start));
WiredHome 39:21fc7a4b6927 439 }
WiredHome 39:21fc7a4b6927 440 } else if (strncmp(pStart, "DTEND:", 6) == 0) {
WiredHome 39:21fc7a4b6927 441 Event->End = ParseDateStamp(pStart+6, tzoSec);
WiredHome 39:21fc7a4b6927 442 //INFO(" End: %d\n", mktime(&Event->eventEnd));
WiredHome 39:21fc7a4b6927 443 } else if (strncmp(pStart, "DTEND;", 6) == 0) {
WiredHome 39:21fc7a4b6927 444 const char * p = pStart + 6;
WiredHome 39:21fc7a4b6927 445 tzoSec = ParseTZID(p);
WiredHome 39:21fc7a4b6927 446 p = strrchr(pStart, ':');
WiredHome 39:21fc7a4b6927 447 if (p) {
WiredHome 39:21fc7a4b6927 448 Event->End = ParseDateStamp(p+1, 0); // example was localtime with GMT -06:00 tzoSec);
WiredHome 39:21fc7a4b6927 449 INFO(" End: %s", ctime(&Event->End));
WiredHome 39:21fc7a4b6927 450 }
WiredHome 39:21fc7a4b6927 451 } else if (strncmp(pStart, "SUMMARY:", 8) == 0) {
WiredHome 39:21fc7a4b6927 452 strncpy(Event->Summary, pStart+8, SUMMARY_CHARS-1);
WiredHome 39:21fc7a4b6927 453 Event->Summary[SUMMARY_CHARS-1] = '\0';
WiredHome 39:21fc7a4b6927 454 //INFO(" Summary: %s\n", Event->Summary);
WiredHome 39:21fc7a4b6927 455 } else if (strncmp(pStart, "LOCATION:", 9) == 0) {
WiredHome 39:21fc7a4b6927 456 strncpy(Event->Location, pStart+9, LOCATION_CHARS-1);
WiredHome 39:21fc7a4b6927 457 Event->Location[LOCATION_CHARS-1] = '\0';
WiredHome 39:21fc7a4b6927 458 //INFO(" Location: %s\n", Event->Location);
WiredHome 39:21fc7a4b6927 459 } else if (strncmp(pStart, "PRIORITY:", 9) == 0) {
WiredHome 39:21fc7a4b6927 460 Event->Priority = *(pStart+9) - '0';
WiredHome 39:21fc7a4b6927 461 //INFO(" Priority: %d\n", Event->Priority);
WiredHome 39:21fc7a4b6927 462 } else if (strncmp(pStart, "CATEGORIES:", 11) == 0) {
WiredHome 39:21fc7a4b6927 463 strncpy(Event->Category, pStart+11, CATEGORY_CHARS-1);
WiredHome 39:21fc7a4b6927 464 Event->Category[CATEGORY_CHARS-1] = '\0';
WiredHome 39:21fc7a4b6927 465 //INFO(" Category: %s\n", Event->Category);
WiredHome 39:21fc7a4b6927 466 } else if (strncmp(pStart, "RRULE:", 6) == 0) {
WiredHome 39:21fc7a4b6927 467 //RRULE:FREQ=WEEKLY;UNTIL=20140502T180000;BYDAY=MO,TU,WE,TH,FR
WiredHome 39:21fc7a4b6927 468 const char * p1, *p2;
WiredHome 39:21fc7a4b6927 469 //INFO("%s", pStart);
WiredHome 39:21fc7a4b6927 470 p1 = pStart + 6; // p1 = FREQ=WEEKLY;UNTIL=20140502T180000;BYDAY=MO,TU,WE,TH,FR
WiredHome 39:21fc7a4b6927 471 p2 = strchr(p1, ';');
WiredHome 39:21fc7a4b6927 472 //if (p2)
WiredHome 39:21fc7a4b6927 473 // *p2++ = '\0';
WiredHome 39:21fc7a4b6927 474 while (*p1) {
WiredHome 39:21fc7a4b6927 475 INFO("%s", p1);
WiredHome 39:21fc7a4b6927 476 if (strncmp(p1, "FREQ=", 5) == 0) {
WiredHome 39:21fc7a4b6927 477 //INFO("%s", p1);
WiredHome 39:21fc7a4b6927 478 p1 += 5; // p1 = WEEKLY;UNTIL=20140502T180000;BYDAY=MO,TU,WE,TH,FR
WiredHome 39:21fc7a4b6927 479 if (strncmp(p1, "WEEKLY", 6) == 0) {
WiredHome 39:21fc7a4b6927 480 //INFO(" %s", p1);
WiredHome 39:21fc7a4b6927 481 Event->RepeatFreq = rptfWeekly;
WiredHome 39:21fc7a4b6927 482 p1 += 6;
WiredHome 39:21fc7a4b6927 483 } else if (strncmp(p1, "DAILY", 5) == 0) {
WiredHome 39:21fc7a4b6927 484 //INFO(" %s", p1);
WiredHome 39:21fc7a4b6927 485 Event->RepeatFreq = rptfDaily;
WiredHome 39:21fc7a4b6927 486 p1 += 5;
WiredHome 39:21fc7a4b6927 487 } else if (strncmp(p1, "MONTHLY", 7) == 0) {
WiredHome 39:21fc7a4b6927 488 //INFO(" %s", p1);
WiredHome 39:21fc7a4b6927 489 Event->RepeatFreq = rptfMonthly;
WiredHome 39:21fc7a4b6927 490 p1 += 7;
WiredHome 39:21fc7a4b6927 491 } else if (strncmp(p1, "YEARLY", 6) == 0) {
WiredHome 39:21fc7a4b6927 492 //INFO(" %s", p1);
WiredHome 39:21fc7a4b6927 493 Event->RepeatFreq = rptfYearly;
WiredHome 39:21fc7a4b6927 494 p1 += 6;
WiredHome 39:21fc7a4b6927 495 }
WiredHome 39:21fc7a4b6927 496 } else if (strncmp(p1, "INTERVAL=", 9) == 0) { // INTERVAL=2
WiredHome 39:21fc7a4b6927 497 //INFO("%s", p1);
WiredHome 39:21fc7a4b6927 498 p1 += 9;
WiredHome 39:21fc7a4b6927 499 Event->Interval = atoi(p1);
WiredHome 39:21fc7a4b6927 500 } else if (strncmp(p1, "COUNT=", 6) == 0) { // COUNT=12;
WiredHome 39:21fc7a4b6927 501 //INFO("%s", p1);
WiredHome 39:21fc7a4b6927 502 p1 += 6; // p1 =
WiredHome 39:21fc7a4b6927 503 Event->Count = atoi(p1);
WiredHome 39:21fc7a4b6927 504 } else if (strncmp(p1, "UNTIL=", 6) == 0) {
WiredHome 39:21fc7a4b6927 505 //INFO("%s", p1);
WiredHome 39:21fc7a4b6927 506 p1 += 6; // p1 = 20140502T180000;BYDAY=MO,TU,WE,TH,FR
WiredHome 39:21fc7a4b6927 507 //printf("UNTIL= {%s}\n", p1);
WiredHome 39:21fc7a4b6927 508 Event->Until = ParseDateStamp(p1, tzoSec);
WiredHome 39:21fc7a4b6927 509 //printf("UNTIL:: %d: %d\n", Event->Until, tzoSec);
WiredHome 39:21fc7a4b6927 510 } else if (strncmp(p1, "BYDAY=", 6) == 0) {
WiredHome 39:21fc7a4b6927 511 //INFO("%s", p1);
WiredHome 39:21fc7a4b6927 512 p1 += 6; // p1 = MO,TU,WE,TH,FR
WiredHome 39:21fc7a4b6927 513 while (*p1 >= ' ') {
WiredHome 39:21fc7a4b6927 514 //INFO(" %s", p1);
WiredHome 39:21fc7a4b6927 515 for (int d=0; d<7; d++) {
WiredHome 39:21fc7a4b6927 516 if (strncmp(p1,RepeatDayAbbrev(d),2) == 0) {
WiredHome 39:21fc7a4b6927 517 Event->RepeatDays |= (1 << d);
WiredHome 39:21fc7a4b6927 518 //INFO(" %s %02X", RepeatDayAbbrev(d), Event->RepeatDays);
WiredHome 39:21fc7a4b6927 519 break;
WiredHome 39:21fc7a4b6927 520 }
WiredHome 39:21fc7a4b6927 521 }
WiredHome 39:21fc7a4b6927 522 p1 += 3;
WiredHome 39:21fc7a4b6927 523 }
WiredHome 39:21fc7a4b6927 524 //INFO(" RepeatDay: %02X", Event->RepeatDays);
WiredHome 39:21fc7a4b6927 525 } else if (strncmp(p1, "BYMONTHDAY=", 11) == 0) {
WiredHome 39:21fc7a4b6927 526 // RRULE:FREQ=MONTHLY;COUNT=10;BYMONTHDAY=2,15
WiredHome 39:21fc7a4b6927 527 p1 += 11;
WiredHome 39:21fc7a4b6927 528 while (*p1 >= ' ') {
WiredHome 39:21fc7a4b6927 529 const char * px = p1;
WiredHome 39:21fc7a4b6927 530 while (*px >= ' ' && *px != ',') { // find , or ; or <nul>
WiredHome 39:21fc7a4b6927 531 px++;
WiredHome 39:21fc7a4b6927 532 }
WiredHome 39:21fc7a4b6927 533 //if (*px)
WiredHome 39:21fc7a4b6927 534 // *px++ = '\0';
WiredHome 39:21fc7a4b6927 535 int num = atoi(p1);
WiredHome 39:21fc7a4b6927 536 if (num >= 0)
WiredHome 39:21fc7a4b6927 537 Event->RepeatMonthDay |= (1 << num);
WiredHome 39:21fc7a4b6927 538 else
WiredHome 39:21fc7a4b6927 539 Event->RepeatMonthDayRev |= (1 << -num);
WiredHome 39:21fc7a4b6927 540 p1 = px;
WiredHome 39:21fc7a4b6927 541 }
WiredHome 39:21fc7a4b6927 542 INFO(" RepeatMonthDay: %08X", Event->RepeatMonthDay);
WiredHome 39:21fc7a4b6927 543 } else if (strncmp(p1, "BYMONTH=", 8) == 0) {
WiredHome 39:21fc7a4b6927 544 // RRULE:FREQ=YEARLY;INTERVAL=2;COUNT=10;BYMONTH=1,2,3
WiredHome 39:21fc7a4b6927 545 p1 += 8;
WiredHome 39:21fc7a4b6927 546 while (*p1 >= ' ') {
WiredHome 39:21fc7a4b6927 547 const char * px = p1;
WiredHome 39:21fc7a4b6927 548 while (*px >= ' ' && *px != ',') { // find , or ; or <nul>
WiredHome 39:21fc7a4b6927 549 px++;
WiredHome 39:21fc7a4b6927 550 }
WiredHome 39:21fc7a4b6927 551 //if (*px)
WiredHome 39:21fc7a4b6927 552 // *px++ = '\0';
WiredHome 39:21fc7a4b6927 553 int num = atoi(p1);
WiredHome 39:21fc7a4b6927 554 if (num >= 0)
WiredHome 39:21fc7a4b6927 555 Event->RepeatMonths |= (1 << num);
WiredHome 39:21fc7a4b6927 556 //else
WiredHome 39:21fc7a4b6927 557 // ; // Event->RepeatMonthsRev |= (1 << -num);
WiredHome 39:21fc7a4b6927 558 p1 = px;
WiredHome 39:21fc7a4b6927 559 }
WiredHome 39:21fc7a4b6927 560 INFO(" RepeatMonths: %04X", Event->RepeatMonths);
WiredHome 39:21fc7a4b6927 561 }
WiredHome 39:21fc7a4b6927 562 if (!p2)
WiredHome 39:21fc7a4b6927 563 break;
WiredHome 39:21fc7a4b6927 564 p1 = p2 + 1;
WiredHome 39:21fc7a4b6927 565 p2 = strchr(p1, ';');
WiredHome 39:21fc7a4b6927 566 //if (p2)
WiredHome 39:21fc7a4b6927 567 // *p2++ = '\0';
WiredHome 39:21fc7a4b6927 568 }
WiredHome 39:21fc7a4b6927 569 }
WiredHome 39:21fc7a4b6927 570 }
WiredHome 39:21fc7a4b6927 571
WiredHome 39:21fc7a4b6927 572
WiredHome 39:21fc7a4b6927 573 // TZID="(GMT -06:00)":20140519T063000
WiredHome 39:21fc7a4b6927 574 // TZID:(UTC-06:00) Central Time (US & Canada)
WiredHome 39:21fc7a4b6927 575 // TZID:(GMT -06:00)
WiredHome 39:21fc7a4b6927 576 HTTPiCal::tz_sec_t HTTPiCal::ParseTZID(const char * string)
WiredHome 39:21fc7a4b6927 577 {
WiredHome 39:21fc7a4b6927 578 tz_sec_t tzo = 0;
WiredHome 39:21fc7a4b6927 579 bool sign = false;
WiredHome 39:21fc7a4b6927 580
WiredHome 39:21fc7a4b6927 581 INFO("ParseTZID(%s)", string); // TZID="(GMT -06:00)":20140519T063000
WiredHome 39:21fc7a4b6927 582 string += 5; // "(GMT -06:00)":20140519T063000
WiredHome 39:21fc7a4b6927 583 if (*string == '"')
WiredHome 39:21fc7a4b6927 584 string++; // (GMT -06:00)":20140519T063000
WiredHome 39:21fc7a4b6927 585 if ((strncmp(string, "(UTC", 4) == 0)
WiredHome 39:21fc7a4b6927 586 || (strncmp(string, "(GMT", 4) == 0) ){
WiredHome 39:21fc7a4b6927 587 string += 4;
WiredHome 39:21fc7a4b6927 588 if (*string == ' ')
WiredHome 39:21fc7a4b6927 589 string++;
WiredHome 39:21fc7a4b6927 590 if (*string == '-') {
WiredHome 39:21fc7a4b6927 591 sign = true;
WiredHome 39:21fc7a4b6927 592 string++;
WiredHome 39:21fc7a4b6927 593 }
WiredHome 39:21fc7a4b6927 594 tzo = atoi(string) * 3600;
WiredHome 39:21fc7a4b6927 595 string = strchr(string, ':');
WiredHome 39:21fc7a4b6927 596 if (string) {
WiredHome 39:21fc7a4b6927 597 string++;
WiredHome 39:21fc7a4b6927 598 tzo += atoi(string) * 60;
WiredHome 39:21fc7a4b6927 599 }
WiredHome 39:21fc7a4b6927 600 if (sign)
WiredHome 39:21fc7a4b6927 601 tzo = -tzo;
WiredHome 39:21fc7a4b6927 602 INFO(" tzo = %d", tzo);
WiredHome 39:21fc7a4b6927 603 } else {
WiredHome 39:21fc7a4b6927 604 ERR("Unhandled TZID(%s)", string);
WiredHome 39:21fc7a4b6927 605 }
WiredHome 39:21fc7a4b6927 606 return tzo;
WiredHome 39:21fc7a4b6927 607 }
WiredHome 39:21fc7a4b6927 608
WiredHome 39:21fc7a4b6927 609 int HTTPiCal::ParseICalStream(const char * pStart, time_t gridStartTime, time_t gridEndTime, tz_min_t tzoMin, bool showEvents)
WiredHome 39:21fc7a4b6927 610 {
WiredHome 39:21fc7a4b6927 611 INFO("Parse(%s)", pStart);
WiredHome 39:21fc7a4b6927 612 //INFO("EventCount: %d, EventSpaceCount: %d, seeking: %d", EventCount, EventSpaceCount, seeking);
WiredHome 39:21fc7a4b6927 613 if (pStart && *pStart && EventCount < EventSpaceCount) {
WiredHome 39:21fc7a4b6927 614 switch (seeking) {
WiredHome 39:21fc7a4b6927 615 case idle:
WiredHome 39:21fc7a4b6927 616 if (strncmp(pStart, "BEGIN:VTIMEZONE", 15) == 0) {
WiredHome 39:21fc7a4b6927 617 //INFO("begin:timezone");
WiredHome 39:21fc7a4b6927 618 seeking = inTimeZone;
WiredHome 39:21fc7a4b6927 619 } else if (strncmp(pStart, "BEGIN:VEVENT", 12) == 0) {
WiredHome 39:21fc7a4b6927 620 //INFO("begin:vevent");
WiredHome 39:21fc7a4b6927 621 seeking = inEvent;
WiredHome 39:21fc7a4b6927 622 EventList[EventCount].Start = 0;
WiredHome 39:21fc7a4b6927 623 EventList[EventCount].End = 0;
WiredHome 39:21fc7a4b6927 624 EventList[EventCount].Until = 0;
WiredHome 39:21fc7a4b6927 625 EventList[EventCount].Summary[0] = '\0';
WiredHome 39:21fc7a4b6927 626 EventList[EventCount].Location[0] = '\0';
WiredHome 39:21fc7a4b6927 627 EventList[EventCount].Category[0] = '\0';
WiredHome 39:21fc7a4b6927 628 EventList[EventCount].Count = 0;
WiredHome 39:21fc7a4b6927 629 EventList[EventCount].Interval = 0;
WiredHome 39:21fc7a4b6927 630 EventList[EventCount].RepeatFreq = rptfNone;
WiredHome 39:21fc7a4b6927 631 EventList[EventCount].RepeatDays = 0;
WiredHome 39:21fc7a4b6927 632 EventList[EventCount].RepeatMonthDay = 0;
WiredHome 39:21fc7a4b6927 633 EventList[EventCount].RepeatMonthDayRev = 0;
WiredHome 39:21fc7a4b6927 634 EventList[EventCount].RepeatMonths = 0;
WiredHome 39:21fc7a4b6927 635 EventList[EventCount].Priority = 5; // 5 is Normal
WiredHome 39:21fc7a4b6927 636 }
WiredHome 39:21fc7a4b6927 637 break;
WiredHome 39:21fc7a4b6927 638 case inTimeZone:
WiredHome 39:21fc7a4b6927 639 //INFO("inTimeZone:");
WiredHome 39:21fc7a4b6927 640 // Can also pick up daylight savings time
WiredHome 39:21fc7a4b6927 641 if (strncmp(pStart, "END:VTIMEZONE", 13) == 0) {
WiredHome 39:21fc7a4b6927 642 seeking = idle;
WiredHome 39:21fc7a4b6927 643 } else if ((strncmp(pStart, "TZID:", 5) == 0)
WiredHome 39:21fc7a4b6927 644 || (strncmp(pStart, "TZID=", 5) == 0) ) {
WiredHome 39:21fc7a4b6927 645 tzoTZIDSec = ParseTZID(pStart);
WiredHome 39:21fc7a4b6927 646 tzAdjusted = true;
WiredHome 39:21fc7a4b6927 647 pStart += 5;
WiredHome 39:21fc7a4b6927 648 } else if (strncmp(pStart, "BEGIN:STANDARD", 14) == 0) {
WiredHome 39:21fc7a4b6927 649
WiredHome 39:21fc7a4b6927 650 } else if (strncmp(pStart, "BEGIN:DAYLIGHT", 14) == 0) {
WiredHome 39:21fc7a4b6927 651
WiredHome 39:21fc7a4b6927 652 }
WiredHome 39:21fc7a4b6927 653 break;
WiredHome 39:21fc7a4b6927 654 case inEvent:
WiredHome 39:21fc7a4b6927 655 //INFO("inEvent:");
WiredHome 39:21fc7a4b6927 656 // inEvent
WiredHome 39:21fc7a4b6927 657 if (strncmp(pStart, "END:VEVENT", 10) == 0) {
WiredHome 39:21fc7a4b6927 658 // Timezone offset
WiredHome 39:21fc7a4b6927 659 if (!tzAdjusted) {
WiredHome 39:21fc7a4b6927 660 EventList[EventCount].Start += (60 * tzoMin);
WiredHome 39:21fc7a4b6927 661 if (EventList[EventCount].End)
WiredHome 39:21fc7a4b6927 662 EventList[EventCount].End += (60 * tzoMin);
WiredHome 39:21fc7a4b6927 663 }
WiredHome 39:21fc7a4b6927 664 // Process it
WiredHome 40:bcb19f8dbba3 665 if (showEvents) {
WiredHome 40:bcb19f8dbba3 666 //printf("ev: %d\r\n", EventCount);
WiredHome 39:21fc7a4b6927 667 ShowEventInfo(EventList[EventCount]);
WiredHome 40:bcb19f8dbba3 668 }
WiredHome 39:21fc7a4b6927 669 // Force to ALWAYS
WiredHome 39:21fc7a4b6927 670 time_t aStart = EventList[EventCount].Start;
WiredHome 39:21fc7a4b6927 671 time_t aEnd = EventList[EventCount].End;
WiredHome 39:21fc7a4b6927 672 if (gridStartTime
WiredHome 39:21fc7a4b6927 673 && RepeatIntersects(&aStart, &aEnd, &gridStartTime, &gridEndTime, &EventList[EventCount])) {
WiredHome 39:21fc7a4b6927 674 EventCount++;
WiredHome 39:21fc7a4b6927 675 if (showEvents) {
WiredHome 39:21fc7a4b6927 676 INFO(" +++++ Added Event %d", EventCount);//, EventList[EventCount].Summary);
WiredHome 39:21fc7a4b6927 677 }
WiredHome 39:21fc7a4b6927 678 }
WiredHome 39:21fc7a4b6927 679 seeking = idle;
WiredHome 39:21fc7a4b6927 680 } else {
WiredHome 39:21fc7a4b6927 681 //INFO("parse event data");
WiredHome 39:21fc7a4b6927 682 ParseEvent(&EventList[EventCount], pStart, 60 * tzoMin);
WiredHome 39:21fc7a4b6927 683 }
WiredHome 39:21fc7a4b6927 684 // End of inEvent
WiredHome 39:21fc7a4b6927 685 break;
WiredHome 39:21fc7a4b6927 686 default:
WiredHome 39:21fc7a4b6927 687 INFO("default:");
WiredHome 39:21fc7a4b6927 688 seeking = idle;
WiredHome 39:21fc7a4b6927 689 break;
WiredHome 39:21fc7a4b6927 690 }
WiredHome 39:21fc7a4b6927 691 } // while
WiredHome 39:21fc7a4b6927 692 return EventCount;
WiredHome 39:21fc7a4b6927 693 }