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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HTTPiCal.h Source File

HTTPiCal.h

00001 #ifndef HTTPICAL_H
00002 #define HTTPICAL_H
00003 #include <mbed.h>
00004 #include "../IHTTPData.h"
00005 
00006 
00007 /// An iCal handling mechanism - downloads and parses calendar events
00008 class HTTPiCal : public IHTTPDataIn {
00009     
00010     public:
00011         #define SUMMARY_CHARS 100
00012         #define LOCATION_CHARS 100
00013         #define CATEGORY_CHARS 20
00014         #define LINEBUFLEN 200
00015         
00016         /// The repeat attribute for an event
00017         typedef enum {
00018             rptfNone,                       ///< no repeat for this event
00019             rptfDaily,                      ///< daily repeat
00020             rptfWeekly,                     ///< weekly repeat
00021             rptfMonthly,                    ///< monthly repeat
00022             rptfYearly                      ///< yearly repeat
00023         } RepeatFreq_t;
00024 
00025         typedef int32_t tz_sec_t;
00026         typedef int16_t tz_min_t;
00027 
00028         /// A single event consists of quite a number of attributes.
00029         typedef struct {
00030             time_t Start;
00031             time_t End;
00032             time_t Until;
00033             uint16_t Count;
00034             uint16_t Interval;
00035             RepeatFreq_t RepeatFreq;
00036             uint8_t RepeatDays;             // bit mapped (bit 0 = sunday, bit 1=monday, ...)
00037             uint16_t RepeatMonths;          // bit mapped (bit 0 = jan, 1=feb, ...)
00038             uint32_t RepeatMonthDay;        // bit mapped (bit 1 = 1st, 2=2nd, ...)
00039             uint32_t RepeatMonthDayRev;     // reverse -1 = last day = bit 1, -2=bit 2, ...
00040             char Summary[SUMMARY_CHARS];
00041             char Location[LOCATION_CHARS];
00042             char Category[CATEGORY_CHARS];  // "Green", ...
00043             int Priority;                   // 1 == High, 5 == Normal, 9 == Low
00044         } Event_T;
00045         
00046 
00047         /// Instantiate HTTPiCal 
00048         ///
00049         /// @code
00050         /// HTTPClient http;
00051         /// HTTPiCal iCal(10);      // define a limit of 10 events to be held
00052         ///
00053         /// http.basicAuth(calInfo.user, calInfo.pass);
00054         ///
00055         /// time_t now = t.timelocal();     // Set a 4-hour window from now
00056         /// time_t nxt = now + 4 * 3600;
00057         /// ical.SetTimeWindow(now, nxt);
00058         /// HTTPErrorCode = http.get(calInfo.url, &iCal);
00059         /// if (HTTPErrorCode == HTTP_OK) {
00060         ///     // calendar successfully downloaded
00061         ///     for (int i=0; i<iCal.GetEventCount(); i++) {
00062         ///        HTTPiCal::Event_T event;
00063         ///        if (ical.GetEvent(i, &event)) {
00064         ///            printf("Event %d\r\n", i);
00065         ///            printf("Summary : %s\r\n", event.Summary);
00066         ///            printf("Location: %s\r\n", event.Location);
00067         ///            printf("Category: %s\r\n", event.Category);
00068         ///        }
00069         ///     }
00070         /// }
00071         /// @endcode
00072         ///
00073         /// @param count is the number of Event_T entries to reserve space for.
00074         ///
00075         HTTPiCal(int count);
00076         
00077         /// Destructor to free memory
00078         ~HTTPiCal();
00079         
00080         /// Set the time window of interest, for which to retain events.
00081         ///
00082         /// This sets the time window of interest. Any event, whether directly 
00083         /// scheduled in this window, or indirectly via repeat attributes, will
00084         /// be retained in the list of available events. Any event not in this
00085         /// window will be ignored.
00086         ///
00087         /// @param StartTime is the optional time value for the beginning of 
00088         ///         interest. If gridStartTime is zero, no filtering is performed.
00089         /// @param EndTime is the optional time value ending the period of interest.
00090         ///
00091         void SetTimeWindow(time_t StartTime = 0, time_t EndTime = 0);
00092  
00093         /// Get the count of Events currently available.
00094         ///
00095         /// @returns the count of events.
00096         ///
00097         int GetEventCount(void) { return EventCount; }
00098         
00099         /// Get a copy of the specified event.
00100         ///
00101         /// @param i is the event number, ranging from 0 to GetEventCount()
00102         /// @param event is a pointer to where the event will be copied.
00103         /// @returns true if the event was available and copied.
00104         ///
00105         bool GetEvent(unsigned int i, Event_T * event);
00106 
00107 
00108         /// Compute the intersection of two time ranges, and evaluate the recurringing events.
00109         ///
00110         /// This compares a pair of time ranges, each by a start and end time. If they overlap
00111         /// it then computes the intersection of those two ranges. Additionally, for a 
00112         /// specified Event, it will evaluate the recurring events that may also fall into
00113         /// the target time range.
00114         ///
00115         /// @note This is usually the only API you need, as this will first call
00116         ///     the TimeIntersects function, and if that fails, then it will evaluate
00117         ///     repeat information.
00118         ///
00119         /// @param[in,out] start1 is the starting time of range 1.
00120         /// @param[in,out] end1 is the ending time of range 1.
00121         /// @param[in] start2 is the starting time of range 2.
00122         /// @param[in] end2 is the ending time of range 2.
00123         /// @param[in] Event is a pointer to the event of interest that may have recurring series.
00124         /// @returns true if the ranges overlap, and then start1 and end1 are set to the
00125         ///     intersection.
00126         ///
00127         bool RepeatIntersects(time_t * start1, time_t * end1, time_t * start2, time_t * end2, Event_T * Event = NULL);
00128         
00129         
00130         /// Compute the intersection of two time ranges, and returns that intersection.
00131         ///
00132         /// This compares a pair of time ranges, each by a start and end time. If they overlap
00133         /// it then computes the intersection of those two ranges.
00134         ///
00135         /// @param[in,out] start1 is the starting time of range 1.
00136         /// @param[in,out] end1 is the ending time of range 1.
00137         /// @param[in] start2 is the starting time of range 2.
00138         /// @param[in] end2 is the ending time of range 2.
00139         /// @returns true if the ranges overlap, and then start1 and end1 are set to the
00140         ///     intersection.
00141         ///
00142         bool TimeIntersects(time_t * start1, time_t * end1, time_t * start2, time_t * end2);
00143 
00144 
00145     protected:     
00146        
00147         friend class HTTPClient;
00148     
00149         /** Reset stream to its beginning 
00150         * Called by the HTTPClient on each new request
00151         */
00152         virtual void writeReset();
00153         
00154         /** Write a piece of data transmitted by the server
00155         * @param[in] buf Pointer to the buffer from which to copy the data
00156         * @param[in] len Length of the buffer
00157         * @returns number of bytes written.
00158         */
00159         virtual int write(const char* buf, size_t len);
00160         
00161         /** Set MIME type
00162         * @param[in] type Internet media type from Content-Type header
00163         */
00164         virtual void setDataType(const char* type);
00165         
00166         /** Determine whether the data is chunked
00167         *  Recovered from Transfer-Encoding header
00168         * @param[in] chunked indicates the transfer is chunked.
00169         */
00170         virtual void setIsChunked(bool chunked);
00171         
00172         /** If the data is not chunked, set its size
00173         * From Content-Length header
00174         * @param[in] len defines the size of the non-chunked transfer.
00175         */
00176         virtual void setDataLen(size_t len);
00177 
00178     private:
00179         char lineBuf[LINEBUFLEN];      ///< workspace to copy [partial] lines into
00180     
00181         Event_T * EventList;    ///< Pointer to the array of events
00182         int EventSpaceCount;    ///< Maximum number of events that can be tracked
00183         int EventCount;         ///< Current Count of events 
00184 
00185         time_t gridStartTime;   ///< defines the start of the time window of interest
00186         time_t gridEndTime;     ///< defines the end of the time winedow of interest
00187 
00188         int32_t tzoTZIDSec;
00189         bool tzAdjusted;
00190         
00191         typedef enum { 
00192             idle, 
00193             inTimeZone, 
00194             inEvent 
00195         } seekstate_t;
00196         seekstate_t seeking;
00197 
00198         #if !defined(min) && !defined(max)
00199         #define min(a,b) (((a)<(b))?(a):(b))
00200         #define max(a,b) (((a)>(b))?(a):(b))
00201         #endif
00202         
00203         /// Determine if a specific timestamp is in a leap year
00204         ///
00205         /// @param[in] t is the timestamp to evaluate
00206         /// @returns true if the specified timestamp is within a leap year
00207         ///
00208         bool isLeapYear(time_t t);
00209 
00210         /// Inspect the event to determine if its repeat attribute places it in the specified time window
00211         ///
00212         /// @param[in] start1 represents the start of the timerange of interest.
00213         /// @param[in] end1 is the time range representing the end of the range of interest
00214         /// @param[in] start2 is the time range of the event being tested
00215         /// @param[in] end2 is the time range of the event being tested
00216         /// @param[in] Event is a pointer to the event being tested and permits testing the repeat information.
00217         /// @returns true if the event repeat pattern intersects with the display pattern
00218         ///
00219         bool RepeatMaskIntersects(time_t * start1, time_t * end1, time_t * start2, time_t * end2, Event_T * Event);
00220 
00221         /// Convert 'n' characters in a string to an unsigned integer.
00222         ///
00223         /// @param[in] p is a pointer to the string.
00224         /// @param[in] n is the number of characters to convert.
00225         /// @returns an unsigned integer of the converted value.
00226         ///
00227         uint16_t AtoIxN(const char * p, int n);
00228 
00229         /// Parse some information from the stream and extract event information.
00230         ///
00231         /// @param[in] Event is a pointer to the current event to populate.
00232         /// @param[in] pStart is a pointer to the start of a text stream to evaluate.
00233         /// @param[in] tzoSec is the time zone offset in seconds.
00234         ///
00235         void ParseEvent(Event_T * Event, const char * pStart, tz_sec_t tzoSec);
00236         
00237         
00238         /// Prepare to start processing an iCal stream
00239         ///
00240         /// This initializes the data structures for parsing.
00241         ///
00242         /// @code
00243         /// ParseICalStart();
00244         /// while (receive(buf, ... ))
00245         ///     ParseICalStream(buf, ...);
00246         /// count = ParseICalClose();
00247         /// @endcode
00248         ///
00249         void ParseICalStart(void);
00250         
00251         
00252         /// End processing an iCal stream and return the number of events
00253         ///
00254         /// @returns number of events in range
00255         ///
00256         int ParseICalClose(void);
00257         
00258         
00259         /// Parse an iCal stream, and extract everything useful.
00260         ///
00261         /// This accepts a pointer to a [large] buffer, which is the contents
00262         /// of an iCal stream. It walked through all of the available
00263         /// information to extract the Event list. 
00264         ///
00265         /// @param[in] pStart is a pointer to the start of the stream.
00266         /// @param[in] gridStartTime is a time value representing the start of the time-window of interest.
00267         /// @param[in] gridEndTime is a time value representing the end of the time-window of interest.
00268         /// @param[in] tzoMin is the time-zone offset in minutes.
00269         /// @param[in] showEvents when true causes it to print the events as parsed.
00270         /// @returns number of events in range.
00271         ///
00272         int ParseICalStream(const char * pStart, time_t gridStartTime, time_t gridEndTime, tz_min_t tzoMin, bool showEvents = true);
00273 
00274 
00275         /// Compute if the referenced event occurs within the specified time window.
00276         ///
00277         /// @param[in] startWindow is the starting timestamp.
00278         /// @param[in] endWindow is the ending timestamp.
00279         /// @param[in] Event is a pointer to the event, which can have repeat rules.
00280         /// @returns true if the event laps into the current time window.
00281         ///
00282 //        bool EventIntersects(time_t startWindow, time_t endWindow, Event_T * Event);
00283 
00284 
00285         // Private Functions - no real value external to the iCal public interface
00286         // other than for test code.
00287         
00288         /// Computes the next interval for iCal events that have recurrence.
00289         /// 
00290         /// @param[in] baseT is the base time value which is a factor only in leap-year.
00291         /// @param[in] repeatFreq is a value representing the frequency of recurrence - 
00292         ///     0=none, 1=daily, 2=weekly, 3=monthly, 4=yearly
00293         /// @param[in] interval is the multiplier of that repeat frequency to the next
00294         ///     event.
00295         /// @returns a time_t value which is the incremental interval, and would be added
00296         ///     to a reference time.
00297         ///
00298         time_t NextInterval(time_t baseT, int repeatFreq, int interval);
00299         
00300         
00301         /// Format a ctime value as a string, without the trailing <cr>
00302         ///
00303         /// This uses the normal ctime function, which appends a <cr>, but
00304         /// it then removes that trailing line ending character. Additionally,
00305         /// this keeps a few local static buffers to return the time string in
00306         /// which permits a printf (for example) to call this api a few times
00307         /// and get the proper representation of each.
00308         ///
00309         /// @param[in] t is a time value;
00310         /// @returns a pointer to a static buffer containing the converted time.
00311         ///
00312         char * FormatCTime(time_t t);
00313         
00314         /// Sort the Events that have been extracted from the iCal results.
00315         ///
00316         void SortEvents();
00317         
00318         /// Show the details for a specific Event, on the specified serial stream.
00319         ///
00320         /// Most useful during development, and perhaps no value after that.
00321         ///
00322         /// @param[in] Event is the event of interest.
00323         ///
00324         void ShowEventInfo(Event_T & Event);
00325         
00326         /// Access the 2-letter abbreviation for the day of the week.
00327         /// 
00328         /// @param[in] i is the day of the week, where 0 = sunday
00329         /// @returns a pointer to the 2-letter abbreviation.
00330         ///
00331         const char * RepeatDayAbbrev(int i);
00332         
00333         /// Parse a Datestamp string into a time value.
00334         ///
00335         /// Parses a string which can look like this: 20140505T200000
00336         /// into a time_t value.
00337         ///
00338         /// @param[in] string is the string to parse.
00339         /// @param[in] tzoSec is the time-zone offset in seconds.
00340         /// @returns time_t value.
00341         ///
00342         time_t ParseDateStamp(const char * string, tz_sec_t tzoSec);
00343         
00344         /// Parse a Time Zone ID value from the front-end of a Datestamp
00345         ///
00346         /// Parses a string which can look like one of these:
00347         /// @li TZID="(GMT -06:00)":20140519T063000
00348         /// @li TZID:(UTC-06:00) Central Time (US & Canada)
00349         /// @li TZID:(GMT -06:00)
00350         ///
00351         /// @param[in] string to be parsed.
00352         /// @returns time zone offset in seconds.
00353         ///
00354         tz_sec_t ParseTZID(const char * string);
00355 
00356 
00357         bool m_chunked;
00358 };
00359 #endif  // HTTPICAL_H