this will take a image from C328 serial camera and store those images in mbed flash as html and this html page is uploaded into the server at ip:192.168.1.2

Dependencies:   mbed

Committer:
mitesh2patel
Date:
Wed Dec 15 15:01:56 2010 +0000
Revision:
0:e1a0471e5ffb

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mitesh2patel 0:e1a0471e5ffb 1 /*
mitesh2patel 0:e1a0471e5ffb 2 * SNTPClient.cpp
mitesh2patel 0:e1a0471e5ffb 3 * SNTP (Simple NTP) client
mitesh2patel 0:e1a0471e5ffb 4 * Written by iva2k
mitesh2patel 0:e1a0471e5ffb 5 *
mitesh2patel 0:e1a0471e5ffb 6 * Wrapper around LWIP/sntp for MBED, with DST rules.
mitesh2patel 0:e1a0471e5ffb 7 * This implementation relies on:
mitesh2patel 0:e1a0471e5ffb 8 * 1. LWIP (http://www.sics.se/~adam/lwip/) adopted for MBED
mitesh2patel 0:e1a0471e5ffb 9 * http://mbed.org/projects/cookbook/svn/EMAC/lwip/trunk
mitesh2patel 0:e1a0471e5ffb 10 * 2. LWIP's contributed SNTP client (sntp.c and sntp.h) from
mitesh2patel 0:e1a0471e5ffb 11 * http://cvs.savannah.gnu.org/viewvc/contrib/apps/sntp/?root=lwip
mitesh2patel 0:e1a0471e5ffb 12 * (used version 1.8)
mitesh2patel 0:e1a0471e5ffb 13 *
mitesh2patel 0:e1a0471e5ffb 14 * Changes needed in LWIP/sntp:
mitesh2patel 0:e1a0471e5ffb 15 * - pointer typecast (line 594) - fixes mbed compiler problem
mitesh2patel 0:e1a0471e5ffb 16 * - #include "sntp.h" moved after lwip/opt.h et.al - for re-defines.
mitesh2patel 0:e1a0471e5ffb 17 * - pbuf_free(p) in sntp_send_request() (line 602) - fixes memory leak BUG.
mitesh2patel 0:e1a0471e5ffb 18 * - changing sntp_dns_found() to delayed sntp_try_next_server() - to unblock if network is disconnected.
mitesh2patel 0:e1a0471e5ffb 19 *
mitesh2patel 0:e1a0471e5ffb 20 * Changes in MBED's LWIP:
mitesh2patel 0:e1a0471e5ffb 21 * - modified lwipopts.h (this file is automatically included into sntp.c)
mitesh2patel 0:e1a0471e5ffb 22 *
mitesh2patel 0:e1a0471e5ffb 23 * Requirements:
mitesh2patel 0:e1a0471e5ffb 24 * + direct RTC update from receiving the NTP time packet
mitesh2patel 0:e1a0471e5ffb 25 * + optionally support more than one NTP server
mitesh2patel 0:e1a0471e5ffb 26 * + the IP address of the NTP server(s) stored in a local file
mitesh2patel 0:e1a0471e5ffb 27 * + timeout error recovery should the NTP server(s) not be available. No RTC update should the NTP access fail
mitesh2patel 0:e1a0471e5ffb 28 * + allow for a UTC offset, also stored in the local file
mitesh2patel 0:e1a0471e5ffb 29 * + DST correction
mitesh2patel 0:e1a0471e5ffb 30 * + use DNS for NTP servers IP address resolution
mitesh2patel 0:e1a0471e5ffb 31 * + periodic updates at specified time intervals
mitesh2patel 0:e1a0471e5ffb 32 *
mitesh2patel 0:e1a0471e5ffb 33 * TODO:
mitesh2patel 0:e1a0471e5ffb 34 * . DST correction
mitesh2patel 0:e1a0471e5ffb 35 * - record metrics (count of updates, failed tries?, correction more than epsilon, etc.?)
mitesh2patel 0:e1a0471e5ffb 36 */
mitesh2patel 0:e1a0471e5ffb 37
mitesh2patel 0:e1a0471e5ffb 38 #include "mbed.h"
mitesh2patel 0:e1a0471e5ffb 39 #include "lwip/opt.h"
mitesh2patel 0:e1a0471e5ffb 40 #include "SNTPClient.h"
mitesh2patel 0:e1a0471e5ffb 41
mitesh2patel 0:e1a0471e5ffb 42 #define SNTP_EPSILON 10 // time difference noticed as big update (in seconds).
mitesh2patel 0:e1a0471e5ffb 43
mitesh2patel 0:e1a0471e5ffb 44 //#define SNTP_DST_TESTS // Define this to run DST algorithms tests
mitesh2patel 0:e1a0471e5ffb 45
mitesh2patel 0:e1a0471e5ffb 46 typedef struct DST_ZONE_DESCR {
mitesh2patel 0:e1a0471e5ffb 47 tDST_ZONE zone;
mitesh2patel 0:e1a0471e5ffb 48 const char *name;
mitesh2patel 0:e1a0471e5ffb 49 int gmt;
mitesh2patel 0:e1a0471e5ffb 50 int dst;
mitesh2patel 0:e1a0471e5ffb 51 int hr1;
mitesh2patel 0:e1a0471e5ffb 52 int wk1;
mitesh2patel 0:e1a0471e5ffb 53 int wday1;
mitesh2patel 0:e1a0471e5ffb 54 int mon1;
mitesh2patel 0:e1a0471e5ffb 55 int hr2;
mitesh2patel 0:e1a0471e5ffb 56 int wk2;
mitesh2patel 0:e1a0471e5ffb 57 int wday2;
mitesh2patel 0:e1a0471e5ffb 58 int mon2;
mitesh2patel 0:e1a0471e5ffb 59 pFncDstCalc fnc;
mitesh2patel 0:e1a0471e5ffb 60 } tDST_ZONE_DESR;
mitesh2patel 0:e1a0471e5ffb 61
mitesh2patel 0:e1a0471e5ffb 62 static tDST_ZONE_DESR gSntpDstZones[] = {
mitesh2patel 0:e1a0471e5ffb 63 #define _(z, fnc, gmt, dst, hr1,wk1,wday1,mon1, hr2,wk2,wday2,mon2) \
mitesh2patel 0:e1a0471e5ffb 64 { z, #z, gmt, dst, hr1,wk1,wday1,mon1, hr2,wk2,wday2,mon2, fnc },
mitesh2patel 0:e1a0471e5ffb 65 #include "DstZones.h"
mitesh2patel 0:e1a0471e5ffb 66 };
mitesh2patel 0:e1a0471e5ffb 67 #define DST_ZONE_DESCR_CNT (sizeof(gSntpDstZones)/sizeof(gSntpDstZones[0]))
mitesh2patel 0:e1a0471e5ffb 68
mitesh2patel 0:e1a0471e5ffb 69 const char *SNTPDstZoneName(tDST_ZONE zone) {
mitesh2patel 0:e1a0471e5ffb 70 if (zone >= DST_ZONE_DESCR_CNT)
mitesh2patel 0:e1a0471e5ffb 71 return "";
mitesh2patel 0:e1a0471e5ffb 72 return gSntpDstZones[zone].name;
mitesh2patel 0:e1a0471e5ffb 73 }
mitesh2patel 0:e1a0471e5ffb 74
mitesh2patel 0:e1a0471e5ffb 75 #ifdef __cplusplus
mitesh2patel 0:e1a0471e5ffb 76 extern "C" {
mitesh2patel 0:e1a0471e5ffb 77 #endif
mitesh2patel 0:e1a0471e5ffb 78 tDST_ZONE gSntpDstZone = DST_NONE; // DST zone - rule selector
mitesh2patel 0:e1a0471e5ffb 79 unsigned int gSntpRecvTimeout_s = 3; // 3 sec; SNTP_RECV_TIMEOUT
mitesh2patel 0:e1a0471e5ffb 80 unsigned int gSntpUpdateDelay_s = 3600; // 1 hour; SNTP_UPDATE_DELAY
mitesh2patel 0:e1a0471e5ffb 81 signed int gSntpTimezone = 0*3600; // seconds from UTC to local time
mitesh2patel 0:e1a0471e5ffb 82 signed int gSntpDST = 0*3600; // seconds from UTC to local time
mitesh2patel 0:e1a0471e5ffb 83 bool gSntpRtcUtc = false; // true to keep RTC in UTC, false to keep in local time
mitesh2patel 0:e1a0471e5ffb 84 unsigned int gSntpUpdates = 0; // Track number of all clock NTP updates
mitesh2patel 0:e1a0471e5ffb 85 unsigned int gSntpUpdatesBig = 0; // Track number of significant clock NTP updates
mitesh2patel 0:e1a0471e5ffb 86 bool gSntpRunning = false; // true if SNTP service is running
mitesh2patel 0:e1a0471e5ffb 87 Timeout gSntpDelay; // For async calls.
mitesh2patel 0:e1a0471e5ffb 88 Ticker gSntpTicker; // There is no RTC interrupt on MBED (yet). Use (more wastefull) timer.
mitesh2patel 0:e1a0471e5ffb 89 time_t gSntpRtcTCR = 0; // Timer Capture Register equivalent (in RTC time - either local or UTC depending on gSntpRtcUtc)
mitesh2patel 0:e1a0471e5ffb 90 signed int gSntpRtcTCRDST = 0; // New DST value for when RTC crosses gSntpRtcTCR
mitesh2patel 0:e1a0471e5ffb 91
mitesh2patel 0:e1a0471e5ffb 92 static void SNTPSetDSTEx(unsigned int dst, bool adjust_clock) {
mitesh2patel 0:e1a0471e5ffb 93 if (adjust_clock && !gSntpRtcUtc && gSntpDST != dst) {
mitesh2patel 0:e1a0471e5ffb 94 time_t seconds = time(NULL);
mitesh2patel 0:e1a0471e5ffb 95 seconds -= gSntpDST; // Convert from old local time
mitesh2patel 0:e1a0471e5ffb 96 seconds += dst; // Convert to new local time
mitesh2patel 0:e1a0471e5ffb 97 set_time(seconds);
mitesh2patel 0:e1a0471e5ffb 98 if (gSntpRtcTCR) {
mitesh2patel 0:e1a0471e5ffb 99 // Adjust our alarm clock
mitesh2patel 0:e1a0471e5ffb 100 gSntpRtcTCR -= gSntpDST;
mitesh2patel 0:e1a0471e5ffb 101 gSntpRtcTCR += dst;
mitesh2patel 0:e1a0471e5ffb 102 }
mitesh2patel 0:e1a0471e5ffb 103 }
mitesh2patel 0:e1a0471e5ffb 104 gSntpDST = dst;
mitesh2patel 0:e1a0471e5ffb 105 }
mitesh2patel 0:e1a0471e5ffb 106
mitesh2patel 0:e1a0471e5ffb 107 #if 0
mitesh2patel 0:e1a0471e5ffb 108 // Custom DST zone function example
mitesh2patel 0:e1a0471e5ffb 109 // USA (since 2007)
mitesh2patel 0:e1a0471e5ffb 110 // Calculate start or stop DST point for given year based on rules
mitesh2patel 0:e1a0471e5ffb 111 // tz - Timezone
mitesh2patel 0:e1a0471e5ffb 112 // year - current year. DST changes well away from year end, so does not matter what timezone.
mitesh2patel 0:e1a0471e5ffb 113 // start - DST_START for start, DST_STOP for stop
mitesh2patel 0:e1a0471e5ffb 114 // Returns DST point (in local time). DST_STOP time is in DST
mitesh2patel 0:e1a0471e5ffb 115 static tDstPoint _sntp_dst_calc_custom(int tz, int year, tDST_START start) {
mitesh2patel 0:e1a0471e5ffb 116 tDstPoint ret;
mitesh2patel 0:e1a0471e5ffb 117 struct tm t;
mitesh2patel 0:e1a0471e5ffb 118
mitesh2patel 0:e1a0471e5ffb 119 // USA: 3600; 2, Second SUN, March; 2, First SUN, November
mitesh2patel 0:e1a0471e5ffb 120 int dst = 3600; // DST shift (seconds)
mitesh2patel 0:e1a0471e5ffb 121 int hour; // Hour of the change
mitesh2patel 0:e1a0471e5ffb 122 int N; // Week in the month
mitesh2patel 0:e1a0471e5ffb 123 int wday; // Day of the week
mitesh2patel 0:e1a0471e5ffb 124 int month;
mitesh2patel 0:e1a0471e5ffb 125 if (start == DST_START) {
mitesh2patel 0:e1a0471e5ffb 126 hour = 2; // (0-23) Hour of the change
mitesh2patel 0:e1a0471e5ffb 127 N = 2-1; // 2nd in the month
mitesh2patel 0:e1a0471e5ffb 128 wday = 0; // Sunday
mitesh2patel 0:e1a0471e5ffb 129 month = 2; // March
mitesh2patel 0:e1a0471e5ffb 130 } else { // DST_STOP
mitesh2patel 0:e1a0471e5ffb 131 hour = 2; // (0-23) Hour of the change
mitesh2patel 0:e1a0471e5ffb 132 N = 1-1; // 1st in the month
mitesh2patel 0:e1a0471e5ffb 133 wday = 0; // Sunday
mitesh2patel 0:e1a0471e5ffb 134 month = 10; // November
mitesh2patel 0:e1a0471e5ffb 135 }
mitesh2patel 0:e1a0471e5ffb 136
mitesh2patel 0:e1a0471e5ffb 137 t.tm_sec = 0; // 0-59
mitesh2patel 0:e1a0471e5ffb 138 t.tm_min = 0; // 0-59
mitesh2patel 0:e1a0471e5ffb 139 t.tm_hour = hour; // 0-23
mitesh2patel 0:e1a0471e5ffb 140 t.tm_year = year - 1900; //
mitesh2patel 0:e1a0471e5ffb 141 t.tm_mon = month; // 0-11
mitesh2patel 0:e1a0471e5ffb 142 t.tm_mday = 1+N*7; // 1-31, first possible date for Nth given weekday
mitesh2patel 0:e1a0471e5ffb 143 mktime(&t); // Calculate tm_wday
mitesh2patel 0:e1a0471e5ffb 144 t.tm_mday += (wday-t.tm_wday+14)%7; // Shift to wday
mitesh2patel 0:e1a0471e5ffb 145 ret.t = mktime(&t);
mitesh2patel 0:e1a0471e5ffb 146 ret.dst = (start == DST_START) ? dst : 0;
mitesh2patel 0:e1a0471e5ffb 147 ret.dstshift = dst;
mitesh2patel 0:e1a0471e5ffb 148 return ret;
mitesh2patel 0:e1a0471e5ffb 149 }
mitesh2patel 0:e1a0471e5ffb 150 #endif
mitesh2patel 0:e1a0471e5ffb 151
mitesh2patel 0:e1a0471e5ffb 152 // Calculate start or stop DST point for given year based on rules for the DST zone
mitesh2patel 0:e1a0471e5ffb 153 // tz - Timezone
mitesh2patel 0:e1a0471e5ffb 154 // zone - DST zone
mitesh2patel 0:e1a0471e5ffb 155 // year - current year. DST changes well away from year end, so does not matter timezone.
mitesh2patel 0:e1a0471e5ffb 156 // start - DST_START for start, DST_STOP for stop
mitesh2patel 0:e1a0471e5ffb 157 // Returns DST point (in standard local time). DST_STOP time is in NOT IN DST
mitesh2patel 0:e1a0471e5ffb 158 static tDstPoint _sntp_dst_calc(int tz, tDST_ZONE zone, int year, tDST_START start) {
mitesh2patel 0:e1a0471e5ffb 159 tDstPoint ret;
mitesh2patel 0:e1a0471e5ffb 160
mitesh2patel 0:e1a0471e5ffb 161 ret.t = 0;
mitesh2patel 0:e1a0471e5ffb 162 ret.dst = 0;
mitesh2patel 0:e1a0471e5ffb 163 ret.dstshift = 0;
mitesh2patel 0:e1a0471e5ffb 164 if (zone == DST_NONE || zone >= DST_ZONE_DESCR_CNT)
mitesh2patel 0:e1a0471e5ffb 165 return ret;
mitesh2patel 0:e1a0471e5ffb 166
mitesh2patel 0:e1a0471e5ffb 167 tDST_ZONE_DESR *descr = &gSntpDstZones[zone];
mitesh2patel 0:e1a0471e5ffb 168 if (descr->fnc) {
mitesh2patel 0:e1a0471e5ffb 169 // Use custom function
mitesh2patel 0:e1a0471e5ffb 170 ret = descr->fnc(tz, year, start);
mitesh2patel 0:e1a0471e5ffb 171 } else {
mitesh2patel 0:e1a0471e5ffb 172 // Use rules
mitesh2patel 0:e1a0471e5ffb 173 struct tm t;
mitesh2patel 0:e1a0471e5ffb 174 t.tm_sec = 0; // 0-59
mitesh2patel 0:e1a0471e5ffb 175 t.tm_min = 0; // 0-59
mitesh2patel 0:e1a0471e5ffb 176 t.tm_hour = (start == DST_START) ? descr->hr1 : descr->hr2;
mitesh2patel 0:e1a0471e5ffb 177 t.tm_year = year - 1900; //
mitesh2patel 0:e1a0471e5ffb 178 t.tm_mon = (start == DST_START) ? descr->mon1 : descr->mon2; // 0-11
mitesh2patel 0:e1a0471e5ffb 179 int wk =((start == DST_START) ? descr->wk1 : descr->wk2) -1;
mitesh2patel 0:e1a0471e5ffb 180 int wday = (start == DST_START) ? descr->wday1: descr->wday2;
mitesh2patel 0:e1a0471e5ffb 181 if (wk < 0) {
mitesh2patel 0:e1a0471e5ffb 182 // For "Last in the month" - we go to next month, then move back by one week
mitesh2patel 0:e1a0471e5ffb 183 t.tm_mon += 1; // 0-11
mitesh2patel 0:e1a0471e5ffb 184 if (t.tm_mon > 11) {
mitesh2patel 0:e1a0471e5ffb 185 t.tm_mon -= 12;
mitesh2patel 0:e1a0471e5ffb 186 t.tm_year += 1;
mitesh2patel 0:e1a0471e5ffb 187 }
mitesh2patel 0:e1a0471e5ffb 188 t.tm_mday = 1+0*7; // 1-31, first possible date for Nth given weekday
mitesh2patel 0:e1a0471e5ffb 189 } else {
mitesh2patel 0:e1a0471e5ffb 190 t.tm_mday = 1+wk*7; // 1-31, first possible date for Nth given weekday
mitesh2patel 0:e1a0471e5ffb 191 }
mitesh2patel 0:e1a0471e5ffb 192 mktime(&t); // Calculate tm_wday
mitesh2patel 0:e1a0471e5ffb 193 t.tm_mday += (wday-t.tm_wday+14)%7; // Shift to wday
mitesh2patel 0:e1a0471e5ffb 194 ret.t = mktime(&t);
mitesh2patel 0:e1a0471e5ffb 195 if (wk < 0) {
mitesh2patel 0:e1a0471e5ffb 196 ret.t -= 7 * 24 * 3600;
mitesh2patel 0:e1a0471e5ffb 197 }
mitesh2patel 0:e1a0471e5ffb 198 if (descr->gmt) {
mitesh2patel 0:e1a0471e5ffb 199 ret.t += tz;
mitesh2patel 0:e1a0471e5ffb 200 }
mitesh2patel 0:e1a0471e5ffb 201 ret.dst = (start == DST_START) ? descr->dst : 0;
mitesh2patel 0:e1a0471e5ffb 202 ret.dstshift = descr->dst;
mitesh2patel 0:e1a0471e5ffb 203 }
mitesh2patel 0:e1a0471e5ffb 204 if (start == DST_STOP) {
mitesh2patel 0:e1a0471e5ffb 205 ret.t -= ret.dstshift;
mitesh2patel 0:e1a0471e5ffb 206 // this correction is due to the fact that rules are given in local time with DST,
mitesh2patel 0:e1a0471e5ffb 207 // but calculations are made in standard local time (without DST adjustment)
mitesh2patel 0:e1a0471e5ffb 208 }
mitesh2patel 0:e1a0471e5ffb 209 return ret;
mitesh2patel 0:e1a0471e5ffb 210 }
mitesh2patel 0:e1a0471e5ffb 211
mitesh2patel 0:e1a0471e5ffb 212 // Calculate desired DST point relative to now based on rules for the DST zone
mitesh2patel 0:e1a0471e5ffb 213 // tz - timezone
mitesh2patel 0:e1a0471e5ffb 214 // zone - DST zone
mitesh2patel 0:e1a0471e5ffb 215 // now - current time (standard local time = excluding DST).
mitesh2patel 0:e1a0471e5ffb 216 // index - 0 for immediate next, +1 for second next, -1 for immediate previous
mitesh2patel 0:e1a0471e5ffb 217 // Returns DST point (in standard local time)
mitesh2patel 0:e1a0471e5ffb 218 static tDstPoint _sntp_dst_point(int tz, tDST_ZONE zone, time_t now, int index) {
mitesh2patel 0:e1a0471e5ffb 219 tDstPoint ret;
mitesh2patel 0:e1a0471e5ffb 220 int year;
mitesh2patel 0:e1a0471e5ffb 221 tDST_START type;
mitesh2patel 0:e1a0471e5ffb 222 struct tm *pt = localtime(&now);
mitesh2patel 0:e1a0471e5ffb 223
mitesh2patel 0:e1a0471e5ffb 224 ret.t = 0;
mitesh2patel 0:e1a0471e5ffb 225 ret.dst = 0;
mitesh2patel 0:e1a0471e5ffb 226 ret.dstshift = 0;
mitesh2patel 0:e1a0471e5ffb 227 if (zone == DST_NONE || zone >= DST_ZONE_DESCR_CNT)
mitesh2patel 0:e1a0471e5ffb 228 return ret;
mitesh2patel 0:e1a0471e5ffb 229
mitesh2patel 0:e1a0471e5ffb 230 // Algorithm
mitesh2patel 0:e1a0471e5ffb 231 // 1. Determine where now is in respect to current year DST points (find for index=0)
mitesh2patel 0:e1a0471e5ffb 232 // 2. Use index to shift year and type
mitesh2patel 0:e1a0471e5ffb 233 // 3. return the point
mitesh2patel 0:e1a0471e5ffb 234 // This algorithm relies on DST start date being before DST stop date in the year.
mitesh2patel 0:e1a0471e5ffb 235
mitesh2patel 0:e1a0471e5ffb 236 year = pt->tm_year + 1900;
mitesh2patel 0:e1a0471e5ffb 237 type = DST_START;
mitesh2patel 0:e1a0471e5ffb 238 ret = _sntp_dst_calc(tz, zone, year, type);
mitesh2patel 0:e1a0471e5ffb 239 if (now > ret.t) {
mitesh2patel 0:e1a0471e5ffb 240 type = DST_STOP;
mitesh2patel 0:e1a0471e5ffb 241 ret = _sntp_dst_calc(tz, zone, year, type);
mitesh2patel 0:e1a0471e5ffb 242 if (now > ret.t) {
mitesh2patel 0:e1a0471e5ffb 243 // It is next year's start point
mitesh2patel 0:e1a0471e5ffb 244 type = DST_START;
mitesh2patel 0:e1a0471e5ffb 245 year += 1;
mitesh2patel 0:e1a0471e5ffb 246 }
mitesh2patel 0:e1a0471e5ffb 247 }
mitesh2patel 0:e1a0471e5ffb 248 // Now year and type are right for index=0
mitesh2patel 0:e1a0471e5ffb 249
mitesh2patel 0:e1a0471e5ffb 250 // Calculate where index points to - shift year and type
mitesh2patel 0:e1a0471e5ffb 251 int norm = (index > 0) ? (int)(index/2) : (int)((index-1)/2);
mitesh2patel 0:e1a0471e5ffb 252 year += norm;
mitesh2patel 0:e1a0471e5ffb 253 index -= norm*2; // Now index is (0,1)
mitesh2patel 0:e1a0471e5ffb 254 if (index) {
mitesh2patel 0:e1a0471e5ffb 255 // Flip the type
mitesh2patel 0:e1a0471e5ffb 256 type = (type == DST_START) ? DST_STOP : DST_START;
mitesh2patel 0:e1a0471e5ffb 257 }
mitesh2patel 0:e1a0471e5ffb 258
mitesh2patel 0:e1a0471e5ffb 259 ret = _sntp_dst_calc(tz, zone, year, type);
mitesh2patel 0:e1a0471e5ffb 260 return ret;
mitesh2patel 0:e1a0471e5ffb 261
mitesh2patel 0:e1a0471e5ffb 262 // struct tm t;
mitesh2patel 0:e1a0471e5ffb 263 // t.tm_sec = 0; // 0-59
mitesh2patel 0:e1a0471e5ffb 264 // t.tm_min = 0; // 0-59
mitesh2patel 0:e1a0471e5ffb 265 // t.tm_hour = 0; // 0-23
mitesh2patel 0:e1a0471e5ffb 266 // t.tm_mday = 0; // 1-31
mitesh2patel 0:e1a0471e5ffb 267 // t.tm_mon = 0; // 0-11
mitesh2patel 0:e1a0471e5ffb 268 // t.tm_year = 2005-1900; // year since 1900
mitesh2patel 0:e1a0471e5ffb 269 // t.tm_wday = 0; // 0-6 Day of week (Sunday = 0)
mitesh2patel 0:e1a0471e5ffb 270 // t.tm_yday = 0; // Day of year (0 - 365)
mitesh2patel 0:e1a0471e5ffb 271 // t.tm_isdst = -1; // Nonzero = Daylight saving time
mitesh2patel 0:e1a0471e5ffb 272 }
mitesh2patel 0:e1a0471e5ffb 273
mitesh2patel 0:e1a0471e5ffb 274 #if defined(LWIP_DEBUG)
mitesh2patel 0:e1a0471e5ffb 275 // Print DST dates report
mitesh2patel 0:e1a0471e5ffb 276 static void _sntp_dst_dates(int tz, tDST_ZONE zone, int year) {
mitesh2patel 0:e1a0471e5ffb 277 char _buffer[64];
mitesh2patel 0:e1a0471e5ffb 278 tDstPoint r;
mitesh2patel 0:e1a0471e5ffb 279 printf("\r\nDST DATES for zone %d/%s:\r\n", (int)zone, SNTPDstZoneName(zone));
mitesh2patel 0:e1a0471e5ffb 280
mitesh2patel 0:e1a0471e5ffb 281 r = _sntp_dst_calc(tz, zone, year, DST_START);
mitesh2patel 0:e1a0471e5ffb 282 strftime(_buffer, sizeof(_buffer), "%A %m/%d/%Y %H:%M:%S", localtime(&r.t));
mitesh2patel 0:e1a0471e5ffb 283 printf(" %d DST BEGINS (+%04d sec) %s\r\n", year, r.dst, _buffer);
mitesh2patel 0:e1a0471e5ffb 284
mitesh2patel 0:e1a0471e5ffb 285 r = _sntp_dst_calc(tz, zone, year, DST_STOP);
mitesh2patel 0:e1a0471e5ffb 286 strftime(_buffer, sizeof(_buffer), "%A %m/%d/%Y %H:%M:%S", localtime(&r.t));
mitesh2patel 0:e1a0471e5ffb 287 printf(" %d DST ENDS (+%04d sec) %s\r\n", year, r.dst, _buffer);
mitesh2patel 0:e1a0471e5ffb 288 }
mitesh2patel 0:e1a0471e5ffb 289 #endif
mitesh2patel 0:e1a0471e5ffb 290
mitesh2patel 0:e1a0471e5ffb 291 #ifdef SNTP_DST_TESTS
mitesh2patel 0:e1a0471e5ffb 292 static void test_sntp_dst_calc(int tz, tDST_ZONE zone) {
mitesh2patel 0:e1a0471e5ffb 293 char _buffer[64];
mitesh2patel 0:e1a0471e5ffb 294 tDstPoint r;
mitesh2patel 0:e1a0471e5ffb 295 int year;
mitesh2patel 0:e1a0471e5ffb 296
mitesh2patel 0:e1a0471e5ffb 297 printf("\r\nTEST: _sntp_dst_calc(tz=%d, zone=%d/%s)\r\n", tz, (int)zone, SNTPDstZoneName(zone));
mitesh2patel 0:e1a0471e5ffb 298
mitesh2patel 0:e1a0471e5ffb 299 for (year = 1999; year < 2016; year++) {
mitesh2patel 0:e1a0471e5ffb 300 r = _sntp_dst_calc(tz, zone, year, DST_START);
mitesh2patel 0:e1a0471e5ffb 301 strftime(_buffer, sizeof(_buffer), "%A %m/%d/%Y %H:%M:%S", localtime(&r.t));
mitesh2patel 0:e1a0471e5ffb 302 printf(" (0,%d,start) %s %d\r\n", year, _buffer, r.dst);
mitesh2patel 0:e1a0471e5ffb 303
mitesh2patel 0:e1a0471e5ffb 304 r = _sntp_dst_calc(tz, zone, year, DST_STOP);
mitesh2patel 0:e1a0471e5ffb 305 strftime(_buffer, sizeof(_buffer), "%A %m/%d/%Y %H:%M:%S", localtime(&r.t));
mitesh2patel 0:e1a0471e5ffb 306 printf(" (0,%d,stop ) %s %d\r\n", year, _buffer, r.dst);
mitesh2patel 0:e1a0471e5ffb 307 }
mitesh2patel 0:e1a0471e5ffb 308 }
mitesh2patel 0:e1a0471e5ffb 309
mitesh2patel 0:e1a0471e5ffb 310 static void test_sntp_dst_point(int index) {
mitesh2patel 0:e1a0471e5ffb 311 char _buffer[64];
mitesh2patel 0:e1a0471e5ffb 312 struct tm t;
mitesh2patel 0:e1a0471e5ffb 313 tDstPoint r;
mitesh2patel 0:e1a0471e5ffb 314 int tz=gSntpTimezone;
mitesh2patel 0:e1a0471e5ffb 315 tDST_ZONE zone=gSntpDstZone;
mitesh2patel 0:e1a0471e5ffb 316 int year = 2009, day, month;
mitesh2patel 0:e1a0471e5ffb 317
mitesh2patel 0:e1a0471e5ffb 318 int norm = (index > 0) ? (int)(index/2) : (int)((index-1)/2);
mitesh2patel 0:e1a0471e5ffb 319 printf("\r\nTEST: _sntp_dst_point(%d) norm=%d\r\n", index, norm);
mitesh2patel 0:e1a0471e5ffb 320
mitesh2patel 0:e1a0471e5ffb 321 t.tm_sec = 0; // 0-59
mitesh2patel 0:e1a0471e5ffb 322 t.tm_min = 0; // 0-59
mitesh2patel 0:e1a0471e5ffb 323 t.tm_hour = 9; // 0-23
mitesh2patel 0:e1a0471e5ffb 324 t.tm_year = year-1900;
mitesh2patel 0:e1a0471e5ffb 325
mitesh2patel 0:e1a0471e5ffb 326 day = 1;
mitesh2patel 0:e1a0471e5ffb 327 for (month = 0; month < 2; month++) {
mitesh2patel 0:e1a0471e5ffb 328 t.tm_mon = month;
mitesh2patel 0:e1a0471e5ffb 329 t.tm_mday = day;
mitesh2patel 0:e1a0471e5ffb 330 t.tm_year = year-1900;
mitesh2patel 0:e1a0471e5ffb 331 r = _sntp_dst_point(tz, zone, mktime(&t), index);
mitesh2patel 0:e1a0471e5ffb 332 strftime(_buffer, sizeof(_buffer), "%A %m/%d/%Y %H:%M:%S", localtime(&r.t));
mitesh2patel 0:e1a0471e5ffb 333 printf(" (0,%02d/%02d/%d,%d) %s %d\r\n", month+1, day, year, index, _buffer, r.dst);
mitesh2patel 0:e1a0471e5ffb 334 }
mitesh2patel 0:e1a0471e5ffb 335
mitesh2patel 0:e1a0471e5ffb 336 for (day = 1; day < 32; day++) {
mitesh2patel 0:e1a0471e5ffb 337 t.tm_mon = month;
mitesh2patel 0:e1a0471e5ffb 338 t.tm_mday = day;
mitesh2patel 0:e1a0471e5ffb 339 t.tm_year = year-1900;
mitesh2patel 0:e1a0471e5ffb 340 r = _sntp_dst_point(tz, zone, mktime(&t), index);
mitesh2patel 0:e1a0471e5ffb 341 strftime(_buffer, sizeof(_buffer), "%A %m/%d/%Y %H:%M:%S", localtime(&r.t));
mitesh2patel 0:e1a0471e5ffb 342 printf(" (0,%02d/%02d/%d,%d) %s %d\r\n", month+1, day, year, index, _buffer, r.dst);
mitesh2patel 0:e1a0471e5ffb 343 }
mitesh2patel 0:e1a0471e5ffb 344
mitesh2patel 0:e1a0471e5ffb 345 day = 30;
mitesh2patel 0:e1a0471e5ffb 346 for (; month < 10; month++) {
mitesh2patel 0:e1a0471e5ffb 347 t.tm_mon = month;
mitesh2patel 0:e1a0471e5ffb 348 t.tm_mday = day;
mitesh2patel 0:e1a0471e5ffb 349 t.tm_year = year-1900;
mitesh2patel 0:e1a0471e5ffb 350 r = _sntp_dst_point(tz, zone, mktime(&t), index);
mitesh2patel 0:e1a0471e5ffb 351 strftime(_buffer, sizeof(_buffer), "%A %m/%d/%Y %H:%M:%S", localtime(&r.t));
mitesh2patel 0:e1a0471e5ffb 352 printf(" (0,%02d/%02d/%d,%d) %s %d\r\n", month+1, day, year, index, _buffer, r.dst);
mitesh2patel 0:e1a0471e5ffb 353 }
mitesh2patel 0:e1a0471e5ffb 354
mitesh2patel 0:e1a0471e5ffb 355 for (day = 1; day < 32; day++) {
mitesh2patel 0:e1a0471e5ffb 356 t.tm_mon = month;
mitesh2patel 0:e1a0471e5ffb 357 t.tm_mday = day;
mitesh2patel 0:e1a0471e5ffb 358 t.tm_year = year-1900;
mitesh2patel 0:e1a0471e5ffb 359 r = _sntp_dst_point(tz, zone, mktime(&t), index);
mitesh2patel 0:e1a0471e5ffb 360 strftime(_buffer, sizeof(_buffer), "%A %m/%d/%Y %H:%M:%S", localtime(&r.t));
mitesh2patel 0:e1a0471e5ffb 361 printf(" (0,%02d/%02d/%d,%d) %s %d\r\n", month+1, day, year, index, _buffer, r.dst);
mitesh2patel 0:e1a0471e5ffb 362 }
mitesh2patel 0:e1a0471e5ffb 363
mitesh2patel 0:e1a0471e5ffb 364 }
mitesh2patel 0:e1a0471e5ffb 365 #endif // SNTP_DST_TESTS
mitesh2patel 0:e1a0471e5ffb 366
mitesh2patel 0:e1a0471e5ffb 367 // Set current DST
mitesh2patel 0:e1a0471e5ffb 368 static void _sntp_dst_now(void) {
mitesh2patel 0:e1a0471e5ffb 369 time_t now = time(NULL);
mitesh2patel 0:e1a0471e5ffb 370 // Convert to standart local time (no DST)
mitesh2patel 0:e1a0471e5ffb 371 now = gSntpRtcUtc ? (now + gSntpTimezone) : (now - gSntpDST);
mitesh2patel 0:e1a0471e5ffb 372
mitesh2patel 0:e1a0471e5ffb 373 // Check DST setting for now
mitesh2patel 0:e1a0471e5ffb 374 tDstPoint dst = _sntp_dst_point(gSntpTimezone, gSntpDstZone, now, -1);
mitesh2patel 0:e1a0471e5ffb 375
mitesh2patel 0:e1a0471e5ffb 376 #ifdef LWIP_DEBUG
mitesh2patel 0:e1a0471e5ffb 377 char _buffer[64];
mitesh2patel 0:e1a0471e5ffb 378 strftime(_buffer, sizeof(_buffer), "%A %m/%d/%Y %H:%M:%S", localtime(&dst.t));
mitesh2patel 0:e1a0471e5ffb 379 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
mitesh2patel 0:e1a0471e5ffb 380 "DEBUG: _sntp_dst_now(%d) based on last DST change on (%d) %s to (+%04d sec)\r\n",
mitesh2patel 0:e1a0471e5ffb 381 now, dst.t, _buffer, dst.dst));
mitesh2patel 0:e1a0471e5ffb 382 #endif
mitesh2patel 0:e1a0471e5ffb 383
mitesh2patel 0:e1a0471e5ffb 384 // Change RTC
mitesh2patel 0:e1a0471e5ffb 385 SNTPSetDSTEx(dst.dst, true);
mitesh2patel 0:e1a0471e5ffb 386 }
mitesh2patel 0:e1a0471e5ffb 387
mitesh2patel 0:e1a0471e5ffb 388 // Plan for next DST change
mitesh2patel 0:e1a0471e5ffb 389 static void _sntp_dst_schedule(void) {
mitesh2patel 0:e1a0471e5ffb 390 time_t now = time(NULL);
mitesh2patel 0:e1a0471e5ffb 391 // Convert to standart local time (no DST)
mitesh2patel 0:e1a0471e5ffb 392 now = gSntpRtcUtc ? (now + gSntpTimezone) : (now - gSntpDST);
mitesh2patel 0:e1a0471e5ffb 393
mitesh2patel 0:e1a0471e5ffb 394 // Check next DST change point
mitesh2patel 0:e1a0471e5ffb 395 tDstPoint dst = _sntp_dst_point(gSntpTimezone, gSntpDstZone, now, 0);
mitesh2patel 0:e1a0471e5ffb 396
mitesh2patel 0:e1a0471e5ffb 397 if (dst.t) {
mitesh2patel 0:e1a0471e5ffb 398
mitesh2patel 0:e1a0471e5ffb 399 #ifdef LWIP_DEBUG
mitesh2patel 0:e1a0471e5ffb 400 char _buffer[64];
mitesh2patel 0:e1a0471e5ffb 401 strftime(_buffer, sizeof(_buffer), "%A %m/%d/%Y %H:%M:%S", localtime(&dst.t));
mitesh2patel 0:e1a0471e5ffb 402 #endif
mitesh2patel 0:e1a0471e5ffb 403
mitesh2patel 0:e1a0471e5ffb 404 // Set our alarm clock
mitesh2patel 0:e1a0471e5ffb 405 // Convert from standard local to UTC time or local time
mitesh2patel 0:e1a0471e5ffb 406 dst.t = gSntpRtcUtc ? (dst.t - gSntpTimezone) : (dst.t + gSntpDST);
mitesh2patel 0:e1a0471e5ffb 407
mitesh2patel 0:e1a0471e5ffb 408 #ifdef LWIP_DEBUG
mitesh2patel 0:e1a0471e5ffb 409 if (time(NULL) > dst.t) {
mitesh2patel 0:e1a0471e5ffb 410 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
mitesh2patel 0:e1a0471e5ffb 411 "DEBUG: _sntp_dst_schedule() ASSERTION FAILED !(%d<%d) trying to schedule for the past: %s (+%04d sec)\r\n",
mitesh2patel 0:e1a0471e5ffb 412 time(NULL), dst.t, _buffer, dst.dst));
mitesh2patel 0:e1a0471e5ffb 413 } else {
mitesh2patel 0:e1a0471e5ffb 414 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
mitesh2patel 0:e1a0471e5ffb 415 "DEBUG: _sntp_dst_schedule() scheduled in %d seconds, set for %s (+%04d sec)\r\n",
mitesh2patel 0:e1a0471e5ffb 416 dst.t-time(NULL), _buffer, dst.dst));
mitesh2patel 0:e1a0471e5ffb 417 }
mitesh2patel 0:e1a0471e5ffb 418 #endif
mitesh2patel 0:e1a0471e5ffb 419 }
mitesh2patel 0:e1a0471e5ffb 420 gSntpRtcTCR = dst.t;
mitesh2patel 0:e1a0471e5ffb 421 gSntpRtcTCRDST = dst.dst;
mitesh2patel 0:e1a0471e5ffb 422 }
mitesh2patel 0:e1a0471e5ffb 423
mitesh2patel 0:e1a0471e5ffb 424 // RTC ISR - called upon each RTC tick
mitesh2patel 0:e1a0471e5ffb 425 static void _sntp_isr(void) {
mitesh2patel 0:e1a0471e5ffb 426 time_t seconds = time(NULL);
mitesh2patel 0:e1a0471e5ffb 427 if (gSntpRtcTCR && seconds > gSntpRtcTCR ) {
mitesh2patel 0:e1a0471e5ffb 428 // DST change has arrived
mitesh2patel 0:e1a0471e5ffb 429 gSntpRtcTCR = 0;
mitesh2patel 0:e1a0471e5ffb 430 // Disable ISR and avoid extra calcs in SNTPSetDSTEx()
mitesh2patel 0:e1a0471e5ffb 431
mitesh2patel 0:e1a0471e5ffb 432 //if (gSntpRtcTCRDST != gSntpDST) {
mitesh2patel 0:e1a0471e5ffb 433 // Change to/from DST
mitesh2patel 0:e1a0471e5ffb 434 SNTPSetDSTEx(gSntpRtcTCRDST, true);
mitesh2patel 0:e1a0471e5ffb 435 gSntpRtcTCRDST = 0;
mitesh2patel 0:e1a0471e5ffb 436
mitesh2patel 0:e1a0471e5ffb 437 // Schedule callback to plan for next DST change (take it out of ISR context)
mitesh2patel 0:e1a0471e5ffb 438 gSntpDelay.attach(_sntp_dst_schedule, 1.0);
mitesh2patel 0:e1a0471e5ffb 439
mitesh2patel 0:e1a0471e5ffb 440 #ifdef LWIP_DEBUG
mitesh2patel 0:e1a0471e5ffb 441 char _buffer[64];
mitesh2patel 0:e1a0471e5ffb 442 if (gSntpRtcUtc) {
mitesh2patel 0:e1a0471e5ffb 443 seconds += gSntpTimezone + gSntpDST; // Convert to local time
mitesh2patel 0:e1a0471e5ffb 444 }
mitesh2patel 0:e1a0471e5ffb 445 strftime(_buffer, sizeof(_buffer), "%A %m/%d/%Y %H:%M:%S", localtime(&seconds));
mitesh2patel 0:e1a0471e5ffb 446 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
mitesh2patel 0:e1a0471e5ffb 447 "DEBUG: _sntp_isr() changed DST. datetime=%s\r\n", _buffer));
mitesh2patel 0:e1a0471e5ffb 448 #endif
mitesh2patel 0:e1a0471e5ffb 449
mitesh2patel 0:e1a0471e5ffb 450 //}
mitesh2patel 0:e1a0471e5ffb 451
mitesh2patel 0:e1a0471e5ffb 452 }
mitesh2patel 0:e1a0471e5ffb 453 }
mitesh2patel 0:e1a0471e5ffb 454
mitesh2patel 0:e1a0471e5ffb 455 // NTP Callback - timestamp from NTP server arrives here
mitesh2patel 0:e1a0471e5ffb 456 void SntpClientSet(time_t seconds) {
mitesh2patel 0:e1a0471e5ffb 457 time_t old_seconds = time(NULL);
mitesh2patel 0:e1a0471e5ffb 458 if (!gSntpRtcUtc) {
mitesh2patel 0:e1a0471e5ffb 459 seconds += gSntpTimezone + gSntpDST; // Convert to local time
mitesh2patel 0:e1a0471e5ffb 460 }
mitesh2patel 0:e1a0471e5ffb 461 set_time(seconds);
mitesh2patel 0:e1a0471e5ffb 462
mitesh2patel 0:e1a0471e5ffb 463 // Special tasks for the very first NTP updates
mitesh2patel 0:e1a0471e5ffb 464 if (!gSntpUpdates) {
mitesh2patel 0:e1a0471e5ffb 465
mitesh2patel 0:e1a0471e5ffb 466 #if defined(LWIP_DEBUG)
mitesh2patel 0:e1a0471e5ffb 467 // Report DST dates for the zone
mitesh2patel 0:e1a0471e5ffb 468 struct tm *pt = localtime(&seconds);
mitesh2patel 0:e1a0471e5ffb 469 _sntp_dst_dates(gSntpTimezone, gSntpDstZone, pt->tm_year+1900);
mitesh2patel 0:e1a0471e5ffb 470 #endif
mitesh2patel 0:e1a0471e5ffb 471
mitesh2patel 0:e1a0471e5ffb 472 // DST scheduler
mitesh2patel 0:e1a0471e5ffb 473 _sntp_dst_now();
mitesh2patel 0:e1a0471e5ffb 474 _sntp_dst_schedule();
mitesh2patel 0:e1a0471e5ffb 475
mitesh2patel 0:e1a0471e5ffb 476 // Enable RTC ISR
mitesh2patel 0:e1a0471e5ffb 477 gSntpTicker.attach(_sntp_isr, 1.0);
mitesh2patel 0:e1a0471e5ffb 478 }
mitesh2patel 0:e1a0471e5ffb 479
mitesh2patel 0:e1a0471e5ffb 480 if (gSntpUpdates && abs((int)(old_seconds - seconds)) > SNTP_EPSILON) {
mitesh2patel 0:e1a0471e5ffb 481 printf("SNTP settime() corrected big difference: (%d) seconds, more than %d. Big updates count=%d.\r\n",
mitesh2patel 0:e1a0471e5ffb 482 old_seconds-seconds, SNTP_EPSILON, gSntpUpdatesBig);
mitesh2patel 0:e1a0471e5ffb 483 gSntpUpdatesBig ++;
mitesh2patel 0:e1a0471e5ffb 484 }
mitesh2patel 0:e1a0471e5ffb 485
mitesh2patel 0:e1a0471e5ffb 486 gSntpUpdates++;
mitesh2patel 0:e1a0471e5ffb 487
mitesh2patel 0:e1a0471e5ffb 488 if (1) {
mitesh2patel 0:e1a0471e5ffb 489 char _buffer[64];
mitesh2patel 0:e1a0471e5ffb 490 if (gSntpRtcUtc) {
mitesh2patel 0:e1a0471e5ffb 491 seconds += gSntpTimezone + gSntpDST; // Convert to local time
mitesh2patel 0:e1a0471e5ffb 492 }
mitesh2patel 0:e1a0471e5ffb 493 strftime(_buffer, sizeof(_buffer), "%A %m/%d/%Y %H:%M:%S", localtime(&seconds));
mitesh2patel 0:e1a0471e5ffb 494 printf("SNTP settime() #%d seconds=%d TZ=%0.1f datetime=%s\r\n",
mitesh2patel 0:e1a0471e5ffb 495 gSntpUpdates, seconds, gSntpTimezone/3600.0, _buffer);
mitesh2patel 0:e1a0471e5ffb 496 }
mitesh2patel 0:e1a0471e5ffb 497 }
mitesh2patel 0:e1a0471e5ffb 498 #ifdef __cplusplus
mitesh2patel 0:e1a0471e5ffb 499 };
mitesh2patel 0:e1a0471e5ffb 500 #endif
mitesh2patel 0:e1a0471e5ffb 501
mitesh2patel 0:e1a0471e5ffb 502 #ifdef __cplusplus
mitesh2patel 0:e1a0471e5ffb 503 extern "C" {
mitesh2patel 0:e1a0471e5ffb 504 #endif
mitesh2patel 0:e1a0471e5ffb 505
mitesh2patel 0:e1a0471e5ffb 506 #include "lwip/def.h"
mitesh2patel 0:e1a0471e5ffb 507 #include "lwip/pbuf.h"
mitesh2patel 0:e1a0471e5ffb 508 #include "lwip/sys.h"
mitesh2patel 0:e1a0471e5ffb 509 #include "lwip/stats.h"
mitesh2patel 0:e1a0471e5ffb 510 #include "netif/etharp.h"
mitesh2patel 0:e1a0471e5ffb 511 #include "string.h"
mitesh2patel 0:e1a0471e5ffb 512
mitesh2patel 0:e1a0471e5ffb 513 #ifdef __cplusplus
mitesh2patel 0:e1a0471e5ffb 514 };
mitesh2patel 0:e1a0471e5ffb 515 #endif
mitesh2patel 0:e1a0471e5ffb 516
mitesh2patel 0:e1a0471e5ffb 517 // Accomodating sntp timeout functions
mitesh2patel 0:e1a0471e5ffb 518 #if NO_SYS
mitesh2patel 0:e1a0471e5ffb 519 #include "sntp.h"
mitesh2patel 0:e1a0471e5ffb 520 extern void sntp_request(void *arg); // this is dirty hack around "static" function. Some linkers may revolt!
mitesh2patel 0:e1a0471e5ffb 521 extern void sntp_try_next_server(void *arg);
mitesh2patel 0:e1a0471e5ffb 522 extern char* sntp_server_addresses[];
mitesh2patel 0:e1a0471e5ffb 523 extern u8_t sntp_current_server;
mitesh2patel 0:e1a0471e5ffb 524 extern u8_t sntp_num_servers;
mitesh2patel 0:e1a0471e5ffb 525 static void (*sntp_addresses_free)(void*) = NULL;
mitesh2patel 0:e1a0471e5ffb 526 static Timeout _sntp_timer1;
mitesh2patel 0:e1a0471e5ffb 527 static Timeout _sntp_timer2;
mitesh2patel 0:e1a0471e5ffb 528 void sntp_sys_timeout(u32_t timeout_s, void (*func)(void *arg), void *arg) {
mitesh2patel 0:e1a0471e5ffb 529 // all we really need to track is only 2 functions: sntp_request, sntp_try_next_server
mitesh2patel 0:e1a0471e5ffb 530 Timeout *t = NULL;
mitesh2patel 0:e1a0471e5ffb 531 if (func == &sntp_request) {
mitesh2patel 0:e1a0471e5ffb 532 t = &_sntp_timer1;
mitesh2patel 0:e1a0471e5ffb 533 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("DEBUG: IN sntp_sys_timeout(), func=sntp_request\r\n"));
mitesh2patel 0:e1a0471e5ffb 534 } else if (func == &sntp_try_next_server) {
mitesh2patel 0:e1a0471e5ffb 535 t = &_sntp_timer2;
mitesh2patel 0:e1a0471e5ffb 536 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("DEBUG: IN sntp_sys_timeout(), func=sntp_try_next_server\r\n"));
mitesh2patel 0:e1a0471e5ffb 537 }
mitesh2patel 0:e1a0471e5ffb 538 if (t) {
mitesh2patel 0:e1a0471e5ffb 539 t->detach();
mitesh2patel 0:e1a0471e5ffb 540 t->attach((void(*)(void))func, 1.0*timeout_s);
mitesh2patel 0:e1a0471e5ffb 541 // Another shortcut - we have no arg to pass, so just typecast the func.
mitesh2patel 0:e1a0471e5ffb 542 }
mitesh2patel 0:e1a0471e5ffb 543 }
mitesh2patel 0:e1a0471e5ffb 544
mitesh2patel 0:e1a0471e5ffb 545 void sntp_sys_untimeout(void (*func)(void *arg), void *arg) {
mitesh2patel 0:e1a0471e5ffb 546 Timeout *t = NULL;
mitesh2patel 0:e1a0471e5ffb 547 if (func == &sntp_request) {
mitesh2patel 0:e1a0471e5ffb 548 t = &_sntp_timer1;
mitesh2patel 0:e1a0471e5ffb 549 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("DEBUG: IN sntp_sys_untimeout(), func=sntp_request\r\n"));
mitesh2patel 0:e1a0471e5ffb 550 } else if (func == &sntp_try_next_server) {
mitesh2patel 0:e1a0471e5ffb 551 t = &_sntp_timer2;
mitesh2patel 0:e1a0471e5ffb 552 LWIP_DEBUGF(SNTP_DEBUG_STATE, ("DEBUG: IN sntp_sys_untimeout(), func=sntp_try_next_server\r\n"));
mitesh2patel 0:e1a0471e5ffb 553 }
mitesh2patel 0:e1a0471e5ffb 554 if (t) {
mitesh2patel 0:e1a0471e5ffb 555 t->detach();
mitesh2patel 0:e1a0471e5ffb 556 }
mitesh2patel 0:e1a0471e5ffb 557 }
mitesh2patel 0:e1a0471e5ffb 558
mitesh2patel 0:e1a0471e5ffb 559 #else // NO_SYS
mitesh2patel 0:e1a0471e5ffb 560 #error "I don't know how to compile LWIP/SNTP with NO_SYS=0"
mitesh2patel 0:e1a0471e5ffb 561 #endif // NO_SYS
mitesh2patel 0:e1a0471e5ffb 562
mitesh2patel 0:e1a0471e5ffb 563 // Can be called when already running
mitesh2patel 0:e1a0471e5ffb 564 void SNTPSetDstZone(tDST_ZONE zone) {
mitesh2patel 0:e1a0471e5ffb 565 if (zone >= DST_ZONE_DESCR_CNT)
mitesh2patel 0:e1a0471e5ffb 566 return; // ERR_INVALID_ARG
mitesh2patel 0:e1a0471e5ffb 567
mitesh2patel 0:e1a0471e5ffb 568 gSntpDstZone = zone;
mitesh2patel 0:e1a0471e5ffb 569
mitesh2patel 0:e1a0471e5ffb 570 if (gSntpRunning) {
mitesh2patel 0:e1a0471e5ffb 571 // DST scheduler
mitesh2patel 0:e1a0471e5ffb 572 _sntp_dst_now();
mitesh2patel 0:e1a0471e5ffb 573 _sntp_dst_schedule();
mitesh2patel 0:e1a0471e5ffb 574 }
mitesh2patel 0:e1a0471e5ffb 575 }
mitesh2patel 0:e1a0471e5ffb 576
mitesh2patel 0:e1a0471e5ffb 577 void SNTPSetRecvTimeout(unsigned int val_s) { gSntpRecvTimeout_s = val_s; }
mitesh2patel 0:e1a0471e5ffb 578 void SNTPSetUpdateDelay(unsigned int val_s) { gSntpUpdateDelay_s = val_s; }
mitesh2patel 0:e1a0471e5ffb 579 void SNTPSetTimezone(float hours_from_utc, bool adjust_clock) {
mitesh2patel 0:e1a0471e5ffb 580 if (adjust_clock && !gSntpRtcUtc) {
mitesh2patel 0:e1a0471e5ffb 581 time_t seconds = time(NULL);
mitesh2patel 0:e1a0471e5ffb 582 seconds -= gSntpTimezone; // Convert from old local time
mitesh2patel 0:e1a0471e5ffb 583 seconds += hours_from_utc * 3600; // Convert to new local time
mitesh2patel 0:e1a0471e5ffb 584 set_time(seconds);
mitesh2patel 0:e1a0471e5ffb 585 if (gSntpRtcTCR) {
mitesh2patel 0:e1a0471e5ffb 586 // Adjust our alarm clock
mitesh2patel 0:e1a0471e5ffb 587 gSntpRtcTCR -= gSntpTimezone;
mitesh2patel 0:e1a0471e5ffb 588 gSntpRtcTCR += hours_from_utc * 3600;
mitesh2patel 0:e1a0471e5ffb 589 }
mitesh2patel 0:e1a0471e5ffb 590 }
mitesh2patel 0:e1a0471e5ffb 591 gSntpTimezone = hours_from_utc * 3600;
mitesh2patel 0:e1a0471e5ffb 592 }
mitesh2patel 0:e1a0471e5ffb 593 void SNTPSetDST(float hours_from_utc, bool adjust_clock) {
mitesh2patel 0:e1a0471e5ffb 594 SNTPSetDSTEx(hours_from_utc * 3600, adjust_clock);
mitesh2patel 0:e1a0471e5ffb 595 }
mitesh2patel 0:e1a0471e5ffb 596
mitesh2patel 0:e1a0471e5ffb 597 static int sntp_num_servers_alloc = 0;
mitesh2patel 0:e1a0471e5ffb 598 static void _SNTPClrAddresses(void) {
mitesh2patel 0:e1a0471e5ffb 599 if (!sntp_num_servers_alloc) sntp_num_servers_alloc = sntp_num_servers;
mitesh2patel 0:e1a0471e5ffb 600 // Here we save the original size of the sntp_server_addresses[] array.
mitesh2patel 0:e1a0471e5ffb 601
mitesh2patel 0:e1a0471e5ffb 602 if (sntp_addresses_free) {
mitesh2patel 0:e1a0471e5ffb 603 for (int i=0; i<sntp_num_servers; i++) {
mitesh2patel 0:e1a0471e5ffb 604 sntp_addresses_free(sntp_server_addresses[i]);
mitesh2patel 0:e1a0471e5ffb 605 }
mitesh2patel 0:e1a0471e5ffb 606 }
mitesh2patel 0:e1a0471e5ffb 607 sntp_current_server = 0;
mitesh2patel 0:e1a0471e5ffb 608 sntp_num_servers = 0;
mitesh2patel 0:e1a0471e5ffb 609 sntp_addresses_free = NULL;
mitesh2patel 0:e1a0471e5ffb 610 }
mitesh2patel 0:e1a0471e5ffb 611 static int _SNTPAddAddress(const char* server_address) {
mitesh2patel 0:e1a0471e5ffb 612 if (sntp_num_servers+1 > sntp_num_servers_alloc)
mitesh2patel 0:e1a0471e5ffb 613 return -1;
mitesh2patel 0:e1a0471e5ffb 614 sntp_server_addresses[sntp_num_servers] = (char*)malloc(strlen(server_address)+1);
mitesh2patel 0:e1a0471e5ffb 615 if (sntp_server_addresses[sntp_num_servers] == NULL) return -1; // Out of memory
mitesh2patel 0:e1a0471e5ffb 616 strcpy(sntp_server_addresses[sntp_num_servers], server_address);
mitesh2patel 0:e1a0471e5ffb 617 sntp_num_servers++;
mitesh2patel 0:e1a0471e5ffb 618 return 0;
mitesh2patel 0:e1a0471e5ffb 619 }
mitesh2patel 0:e1a0471e5ffb 620
mitesh2patel 0:e1a0471e5ffb 621 // Override default servers list.
mitesh2patel 0:e1a0471e5ffb 622 // For no-copy, pass pointer to free() in p_free.
mitesh2patel 0:e1a0471e5ffb 623 // Returns: actual number of servers set (limited by allocated buffer size)
mitesh2patel 0:e1a0471e5ffb 624 // WARNING! There is no interlock to ensure that SNTP service does not read its data while we are updating it.
mitesh2patel 0:e1a0471e5ffb 625 // This function is intended to be called only before SNTPClientInit().
mitesh2patel 0:e1a0471e5ffb 626 int SNTPSetAddresses(const char* server_addresses[], int count, void (*p_free)(void*)) {
mitesh2patel 0:e1a0471e5ffb 627 // In order to use sntp.c as-is, we hack into its static variables.
mitesh2patel 0:e1a0471e5ffb 628 // Not all compilers/linkers will support that.
mitesh2patel 0:e1a0471e5ffb 629
mitesh2patel 0:e1a0471e5ffb 630 _SNTPClrAddresses();
mitesh2patel 0:e1a0471e5ffb 631 if (count > sntp_num_servers_alloc)
mitesh2patel 0:e1a0471e5ffb 632 count = sntp_num_servers_alloc;
mitesh2patel 0:e1a0471e5ffb 633 for (int i=0; i<count; i++) {
mitesh2patel 0:e1a0471e5ffb 634 if (p_free) {
mitesh2patel 0:e1a0471e5ffb 635 sntp_server_addresses[i] = (char *)server_addresses[i];
mitesh2patel 0:e1a0471e5ffb 636 } else {
mitesh2patel 0:e1a0471e5ffb 637 _SNTPAddAddress(server_addresses[i]);
mitesh2patel 0:e1a0471e5ffb 638 }
mitesh2patel 0:e1a0471e5ffb 639 }
mitesh2patel 0:e1a0471e5ffb 640 sntp_num_servers = count;
mitesh2patel 0:e1a0471e5ffb 641 sntp_current_server = 0;
mitesh2patel 0:e1a0471e5ffb 642 sntp_addresses_free = p_free ? p_free : &free;
mitesh2patel 0:e1a0471e5ffb 643 return count;
mitesh2patel 0:e1a0471e5ffb 644 }
mitesh2patel 0:e1a0471e5ffb 645
mitesh2patel 0:e1a0471e5ffb 646 // Trim whitespace/CRLFs from both ends of a given string
mitesh2patel 0:e1a0471e5ffb 647 char * str_cleanup(char *in) {
mitesh2patel 0:e1a0471e5ffb 648 char * out = in;
mitesh2patel 0:e1a0471e5ffb 649 // Trim leading spaces and CR/LF
mitesh2patel 0:e1a0471e5ffb 650 while (*out == ' ' || *out == '\t' || *out == '\r' || *out == '\n')
mitesh2patel 0:e1a0471e5ffb 651 out ++;
mitesh2patel 0:e1a0471e5ffb 652 // Trim trailing spaces and CR/LF
mitesh2patel 0:e1a0471e5ffb 653 int len = strlen(out)-1;
mitesh2patel 0:e1a0471e5ffb 654 while (out[len] == ' ' || out[len] == '\t' || out[len] == '\r' || out[len] == '\n') {
mitesh2patel 0:e1a0471e5ffb 655 out[len] = '\0';
mitesh2patel 0:e1a0471e5ffb 656 len--;
mitesh2patel 0:e1a0471e5ffb 657 }
mitesh2patel 0:e1a0471e5ffb 658 return out;
mitesh2patel 0:e1a0471e5ffb 659 }
mitesh2patel 0:e1a0471e5ffb 660
mitesh2patel 0:e1a0471e5ffb 661 #ifndef CRLF
mitesh2patel 0:e1a0471e5ffb 662 #define CRLF "\r\n"
mitesh2patel 0:e1a0471e5ffb 663 #endif
mitesh2patel 0:e1a0471e5ffb 664 void SNTPWriteIniFile(FILE * f) {
mitesh2patel 0:e1a0471e5ffb 665 fprintf(f, "# SNTP Configuration file" CRLF);
mitesh2patel 0:e1a0471e5ffb 666 fprintf(f, CRLF "[Servers]" CRLF);
mitesh2patel 0:e1a0471e5ffb 667 for (int i=0; i<sntp_num_servers; i++) {
mitesh2patel 0:e1a0471e5ffb 668 fprintf(f, "%s" CRLF, sntp_server_addresses[i]);
mitesh2patel 0:e1a0471e5ffb 669 }
mitesh2patel 0:e1a0471e5ffb 670 fprintf(f, CRLF "[Global]" CRLF);
mitesh2patel 0:e1a0471e5ffb 671 fprintf(f, "RtcUtc=%d" CRLF, (int)gSntpRtcUtc);
mitesh2patel 0:e1a0471e5ffb 672 fprintf(f, "Timezone=%0.1f" CRLF, gSntpTimezone / 3600.0);
mitesh2patel 0:e1a0471e5ffb 673 fprintf(f, "DstZone=%d" CRLF, gSntpDstZone);
mitesh2patel 0:e1a0471e5ffb 674 fprintf(f, "# %s" CRLF, SNTPDstZoneName(gSntpDstZone));
mitesh2patel 0:e1a0471e5ffb 675 fprintf(f, "UpdateDelay=%d" CRLF, gSntpUpdateDelay_s);
mitesh2patel 0:e1a0471e5ffb 676 fprintf(f, "RecvTimeout=%d" CRLF, gSntpRecvTimeout_s);
mitesh2patel 0:e1a0471e5ffb 677 fprintf(f, CRLF "##END" CRLF);
mitesh2patel 0:e1a0471e5ffb 678 }
mitesh2patel 0:e1a0471e5ffb 679
mitesh2patel 0:e1a0471e5ffb 680 // Simple ini file parser for SNTP configuration (Case-sensitive!)
mitesh2patel 0:e1a0471e5ffb 681 // This function is intended to be called only before SNTPClientInit().
mitesh2patel 0:e1a0471e5ffb 682 // Returns: 0 if OK, errno otherwise
mitesh2patel 0:e1a0471e5ffb 683 enum {
mitesh2patel 0:e1a0471e5ffb 684 SECT_NONE,
mitesh2patel 0:e1a0471e5ffb 685 SECT_SERVERS,
mitesh2patel 0:e1a0471e5ffb 686 SECT_GLOBAL,
mitesh2patel 0:e1a0471e5ffb 687 };
mitesh2patel 0:e1a0471e5ffb 688 int SNTPReadIniFile(const char* filename) {
mitesh2patel 0:e1a0471e5ffb 689 FILE *f;
mitesh2patel 0:e1a0471e5ffb 690 char buf[512];
mitesh2patel 0:e1a0471e5ffb 691 bool addresses_cleared = false;
mitesh2patel 0:e1a0471e5ffb 692
mitesh2patel 0:e1a0471e5ffb 693 f = fopen(filename, "r");
mitesh2patel 0:e1a0471e5ffb 694 if (!f)
mitesh2patel 0:e1a0471e5ffb 695 return -1; // errno not used?
mitesh2patel 0:e1a0471e5ffb 696
mitesh2patel 0:e1a0471e5ffb 697 char *buf1, *buf2;
mitesh2patel 0:e1a0471e5ffb 698 int section=SECT_NONE;
mitesh2patel 0:e1a0471e5ffb 699 int line = 0;
mitesh2patel 0:e1a0471e5ffb 700 while (fgets(buf, sizeof(buf)/sizeof(buf[0]), f)) {
mitesh2patel 0:e1a0471e5ffb 701 line++;
mitesh2patel 0:e1a0471e5ffb 702 buf1 = str_cleanup(buf);
mitesh2patel 0:e1a0471e5ffb 703 if (*buf1 == '#' || *buf1 == '\0')
mitesh2patel 0:e1a0471e5ffb 704 continue; // Comment line or empty line - skip
mitesh2patel 0:e1a0471e5ffb 705 if (*buf1 == '[') {
mitesh2patel 0:e1a0471e5ffb 706 // New section
mitesh2patel 0:e1a0471e5ffb 707 if (0 == strncmp(buf1,"[Servers]", sizeof("[Servers]")-1)) {
mitesh2patel 0:e1a0471e5ffb 708 section=SECT_SERVERS;
mitesh2patel 0:e1a0471e5ffb 709 if (!addresses_cleared) {
mitesh2patel 0:e1a0471e5ffb 710 // Clear addresses only once.
mitesh2patel 0:e1a0471e5ffb 711 _SNTPClrAddresses();
mitesh2patel 0:e1a0471e5ffb 712 addresses_cleared = true;
mitesh2patel 0:e1a0471e5ffb 713 }
mitesh2patel 0:e1a0471e5ffb 714 } else if (0 == strncmp(buf1,"[Global]", sizeof("[Global]")-1)) {
mitesh2patel 0:e1a0471e5ffb 715 section=SECT_GLOBAL;
mitesh2patel 0:e1a0471e5ffb 716 } else {
mitesh2patel 0:e1a0471e5ffb 717 section=SECT_NONE;
mitesh2patel 0:e1a0471e5ffb 718 fprintf(stderr, "File \"%s\", line %d - section \"%s\" is not understood.\r\n", filename, line, buf1);
mitesh2patel 0:e1a0471e5ffb 719 }
mitesh2patel 0:e1a0471e5ffb 720 } else {
mitesh2patel 0:e1a0471e5ffb 721 // Section values
mitesh2patel 0:e1a0471e5ffb 722 switch (section) {
mitesh2patel 0:e1a0471e5ffb 723 case SECT_SERVERS:
mitesh2patel 0:e1a0471e5ffb 724 if (_SNTPAddAddress(buf1)) {
mitesh2patel 0:e1a0471e5ffb 725 fprintf(stderr, "File \"%s\", line %d - cannot add server \"%s\" - exceeded allocated slots.\r\n", filename, line, buf1);
mitesh2patel 0:e1a0471e5ffb 726 }
mitesh2patel 0:e1a0471e5ffb 727 break;
mitesh2patel 0:e1a0471e5ffb 728 case SECT_GLOBAL:
mitesh2patel 0:e1a0471e5ffb 729 buf2 = strchr(buf1, '=');
mitesh2patel 0:e1a0471e5ffb 730 if (buf2) {
mitesh2patel 0:e1a0471e5ffb 731 *buf2++ = '\0'; // Now buf1 has variable name, buf2 has value
mitesh2patel 0:e1a0471e5ffb 732 buf2 = str_cleanup(buf2);
mitesh2patel 0:e1a0471e5ffb 733 if (0 == strncmp(buf1, "Timezone", sizeof("Timezone")-1)) {
mitesh2patel 0:e1a0471e5ffb 734 gSntpTimezone = strtod(buf2, &buf2) * 3600;
mitesh2patel 0:e1a0471e5ffb 735 } else if (0 == strncmp(buf1, "UpdateDelay", sizeof("UpdateDelay")-1)) {
mitesh2patel 0:e1a0471e5ffb 736 gSntpUpdateDelay_s = strtoul(buf2, &buf2, 10);
mitesh2patel 0:e1a0471e5ffb 737 } else if (0 == strncmp(buf1, "RecvTimeout", sizeof("RecvTimeout")-1)) {
mitesh2patel 0:e1a0471e5ffb 738 gSntpRecvTimeout_s = strtoul(buf2, &buf2, 10);
mitesh2patel 0:e1a0471e5ffb 739 } else if (0 == strncmp(buf1, "RtcUtc", sizeof("RtcUtc")-1)) {
mitesh2patel 0:e1a0471e5ffb 740 gSntpRtcUtc = (bool)strtol(buf2, &buf2, 10);
mitesh2patel 0:e1a0471e5ffb 741 } else if (0 == strncmp(buf1, "DstZone", sizeof("DstZone")-1)) {
mitesh2patel 0:e1a0471e5ffb 742 // FIXME: It would be nice to allow human-readable string here.
mitesh2patel 0:e1a0471e5ffb 743 gSntpDstZone = (tDST_ZONE)strtol(buf2, &buf2, 10);
mitesh2patel 0:e1a0471e5ffb 744 } else {
mitesh2patel 0:e1a0471e5ffb 745 fprintf(stderr, "File \"%s\", line %d - unrecognized variable \"%s\" in section [Global]\r\n", filename, line, buf1);
mitesh2patel 0:e1a0471e5ffb 746 }
mitesh2patel 0:e1a0471e5ffb 747 } else {
mitesh2patel 0:e1a0471e5ffb 748 fprintf(stderr, "File \"%s\", line %d - unrecognized statement in section [Global]: %s\r\n", filename, line, buf1);
mitesh2patel 0:e1a0471e5ffb 749 }
mitesh2patel 0:e1a0471e5ffb 750 break;
mitesh2patel 0:e1a0471e5ffb 751 default:
mitesh2patel 0:e1a0471e5ffb 752 fprintf(stderr, "File \"%s\", line %d - unrecognized statement / no section: %s\r\n", filename, line, buf1);
mitesh2patel 0:e1a0471e5ffb 753 }
mitesh2patel 0:e1a0471e5ffb 754 }
mitesh2patel 0:e1a0471e5ffb 755 }
mitesh2patel 0:e1a0471e5ffb 756 fclose(f);
mitesh2patel 0:e1a0471e5ffb 757 printf("SNTP configuration read from file \"%s\", %d lines.\r\n", filename, line);
mitesh2patel 0:e1a0471e5ffb 758 return 0;
mitesh2patel 0:e1a0471e5ffb 759 }
mitesh2patel 0:e1a0471e5ffb 760
mitesh2patel 0:e1a0471e5ffb 761 // Start the SNTP client
mitesh2patel 0:e1a0471e5ffb 762 void SNTPClientInit(void) {
mitesh2patel 0:e1a0471e5ffb 763
mitesh2patel 0:e1a0471e5ffb 764 #ifdef SNTP_DST_TESTS
mitesh2patel 0:e1a0471e5ffb 765 // Test our DST algorithms
mitesh2patel 0:e1a0471e5ffb 766 test_sntp_dst_calc(gSntpTimezone, gSntpDstZone);
mitesh2patel 0:e1a0471e5ffb 767 test_sntp_dst_point(-2);
mitesh2patel 0:e1a0471e5ffb 768 test_sntp_dst_point(-1);
mitesh2patel 0:e1a0471e5ffb 769 test_sntp_dst_point(0);
mitesh2patel 0:e1a0471e5ffb 770 test_sntp_dst_point(1);
mitesh2patel 0:e1a0471e5ffb 771 test_sntp_dst_point(2);
mitesh2patel 0:e1a0471e5ffb 772 #endif
mitesh2patel 0:e1a0471e5ffb 773
mitesh2patel 0:e1a0471e5ffb 774 // SNTPv4 RFC 4330 enforces a minimum update time of 15 seconds
mitesh2patel 0:e1a0471e5ffb 775 if (gSntpUpdateDelay_s < 15) {
mitesh2patel 0:e1a0471e5ffb 776 gSntpUpdateDelay_s = 15;
mitesh2patel 0:e1a0471e5ffb 777 }
mitesh2patel 0:e1a0471e5ffb 778
mitesh2patel 0:e1a0471e5ffb 779 gSntpRunning = true;
mitesh2patel 0:e1a0471e5ffb 780
mitesh2patel 0:e1a0471e5ffb 781 // Just call this to start SNTP client:
mitesh2patel 0:e1a0471e5ffb 782 sntp_init();
mitesh2patel 0:e1a0471e5ffb 783
mitesh2patel 0:e1a0471e5ffb 784 // // Enable RTC ISR
mitesh2patel 0:e1a0471e5ffb 785 // gSntpTicker.attach(_sntp_isr, 1);
mitesh2patel 0:e1a0471e5ffb 786 // We do it from first NTP response
mitesh2patel 0:e1a0471e5ffb 787 }
mitesh2patel 0:e1a0471e5ffb 788
mitesh2patel 0:e1a0471e5ffb 789 // Use instead of system time()
mitesh2patel 0:e1a0471e5ffb 790 // Returns local time
mitesh2patel 0:e1a0471e5ffb 791 time_t SNTPTime(void) {
mitesh2patel 0:e1a0471e5ffb 792 time_t seconds = time(NULL);
mitesh2patel 0:e1a0471e5ffb 793 if (gSntpRtcUtc) {
mitesh2patel 0:e1a0471e5ffb 794 seconds += gSntpTimezone + gSntpDST; // Convert to local time
mitesh2patel 0:e1a0471e5ffb 795 }
mitesh2patel 0:e1a0471e5ffb 796 return seconds;
mitesh2patel 0:e1a0471e5ffb 797 }
mitesh2patel 0:e1a0471e5ffb 798
mitesh2patel 0:e1a0471e5ffb 799 // Use instead of system set_time()
mitesh2patel 0:e1a0471e5ffb 800 // seconds - local time
mitesh2patel 0:e1a0471e5ffb 801 void SNTPSetTime(time_t seconds) {
mitesh2patel 0:e1a0471e5ffb 802 if (gSntpRtcUtc) {
mitesh2patel 0:e1a0471e5ffb 803 seconds -= gSntpTimezone + gSntpDST; // Convert from local time
mitesh2patel 0:e1a0471e5ffb 804 }
mitesh2patel 0:e1a0471e5ffb 805 set_time(seconds);
mitesh2patel 0:e1a0471e5ffb 806 }
mitesh2patel 0:e1a0471e5ffb 807
mitesh2patel 0:e1a0471e5ffb 808 // Use instead of system time()
mitesh2patel 0:e1a0471e5ffb 809 // Returns UTC time
mitesh2patel 0:e1a0471e5ffb 810 time_t SNTPTimeUTC(void) {
mitesh2patel 0:e1a0471e5ffb 811 time_t seconds = time(NULL);
mitesh2patel 0:e1a0471e5ffb 812 if (!gSntpRtcUtc) {
mitesh2patel 0:e1a0471e5ffb 813 seconds -= gSntpTimezone + gSntpDST; // Convert from local time
mitesh2patel 0:e1a0471e5ffb 814 }
mitesh2patel 0:e1a0471e5ffb 815 return seconds;
mitesh2patel 0:e1a0471e5ffb 816 }
mitesh2patel 0:e1a0471e5ffb 817
mitesh2patel 0:e1a0471e5ffb 818 // Use instead of system set_time()
mitesh2patel 0:e1a0471e5ffb 819 // seconds - UTC time
mitesh2patel 0:e1a0471e5ffb 820 void SNTPSetTimeUTC(time_t seconds) {
mitesh2patel 0:e1a0471e5ffb 821 if (!gSntpRtcUtc) {
mitesh2patel 0:e1a0471e5ffb 822 seconds += gSntpTimezone + gSntpDST; // Convert to local time
mitesh2patel 0:e1a0471e5ffb 823 }
mitesh2patel 0:e1a0471e5ffb 824 set_time(seconds);
mitesh2patel 0:e1a0471e5ffb 825 }
mitesh2patel 0:e1a0471e5ffb 826
mitesh2patel 0:e1a0471e5ffb 827 //END