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