sntp.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185
  1. /**
  2. * @file
  3. * SNTP client module
  4. *
  5. * This is simple "SNTP" client for the lwIP raw API.
  6. * It is a minimal implementation of SNTPv4 as specified in RFC 4330.
  7. *
  8. * For a list of some public NTP servers, see this link :
  9. * http://support.ntp.org/bin/view/Servers/NTPPoolServers
  10. *
  11. * @todo:
  12. * - set/change servers at runtime
  13. * - complete SNTP_CHECK_RESPONSE checks 3 and 4
  14. * - support broadcast/multicast mode?
  15. */
  16. /*
  17. * Redistribution and use in source and binary forms, with or without modification,
  18. * are permitted provided that the following conditions are met:
  19. *
  20. * 1. Redistributions of source code must retain the above copyright notice,
  21. * this list of conditions and the following disclaimer.
  22. * 2. Redistributions in binary form must reproduce the above copyright notice,
  23. * this list of conditions and the following disclaimer in the documentation
  24. * and/or other materials provided with the distribution.
  25. * 3. The name of the author may not be used to endorse or promote products
  26. * derived from this software without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  29. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  30. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  31. * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  32. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  33. * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  34. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  35. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  36. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  37. * OF SUCH DAMAGE.
  38. *
  39. * This file is part of the lwIP TCP/IP stack.
  40. *
  41. * Author: Simon Goldschmidt (lwIP raw API part)
  42. */
  43. #include "lwip/sntp.h"
  44. #include "osapi.h"
  45. #include "os_type.h"
  46. #include "lwip/opt.h"
  47. #include "lwip/timers.h"
  48. #include "lwip/udp.h"
  49. #include "lwip/dns.h"
  50. #include "lwip/ip_addr.h"
  51. #include "lwip/pbuf.h"
  52. #include "lwip/app/time.h"
  53. //#include <string.h>
  54. #if LWIP_UDP
  55. /**
  56. * SNTP_DEBUG: Enable debugging for SNTP.
  57. */
  58. #ifndef SNTP_DEBUG
  59. #define SNTP_DEBUG LWIP_DBG_ON
  60. #endif
  61. /** SNTP server port */
  62. #ifndef SNTP_PORT
  63. #define SNTP_PORT 123
  64. #endif
  65. /** Set this to 1 to allow config of SNTP server(s) by DNS name */
  66. #ifndef SNTP_SERVER_DNS
  67. #define SNTP_SERVER_DNS 0
  68. #endif
  69. /** Handle support for more than one server via NTP_MAX_SERVERS,
  70. * but catch legacy style of setting SNTP_SUPPORT_MULTIPLE_SERVERS, probably outside of this file
  71. */
  72. #ifndef SNTP_SUPPORT_MULTIPLE_SERVERS
  73. #if SNTP_MAX_SERVERS > 1
  74. #define SNTP_SUPPORT_MULTIPLE_SERVERS 1
  75. #else /* NTP_MAX_SERVERS > 1 */
  76. #define SNTP_SUPPORT_MULTIPLE_SERVERS 0
  77. #endif /* NTP_MAX_SERVERS > 1 */
  78. #else /* SNTP_SUPPORT_MULTIPLE_SERVERS */
  79. /* The developer has defined SNTP_SUPPORT_MULTIPLE_SERVERS, probably from old code */
  80. #if SNTP_MAX_SERVERS <= 1
  81. #error "SNTP_MAX_SERVERS needs to be defined to the max amount of servers if SNTP_SUPPORT_MULTIPLE_SERVERS is defined"
  82. #endif /* SNTP_MAX_SERVERS <= 1 */
  83. #endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */
  84. /** Sanity check:
  85. * Define this to
  86. * - 0 to turn off sanity checks (default; smaller code)
  87. * - >= 1 to check address and port of the response packet to ensure the
  88. * response comes from the server we sent the request to.
  89. * - >= 2 to check returned Originate Timestamp against Transmit Timestamp
  90. * sent to the server (to ensure response to older request).
  91. * - >= 3 @todo: discard reply if any of the LI, Stratum, or Transmit Timestamp
  92. * fields is 0 or the Mode field is not 4 (unicast) or 5 (broadcast).
  93. * - >= 4 @todo: to check that the Root Delay and Root Dispersion fields are each
  94. * greater than or equal to 0 and less than infinity, where infinity is
  95. * currently a cozy number like one second. This check avoids using a
  96. * server whose synchronization source has expired for a very long time.
  97. */
  98. #ifndef SNTP_CHECK_RESPONSE
  99. #define SNTP_CHECK_RESPONSE 0
  100. #endif
  101. /** According to the RFC, this shall be a random delay
  102. * between 1 and 5 minutes (in milliseconds) to prevent load peaks.
  103. * This can be defined to a random generation function,
  104. * which must return the delay in milliseconds as u32_t.
  105. * Turned off by default.
  106. */
  107. #ifndef SNTP_STARTUP_DELAY
  108. #define SNTP_STARTUP_DELAY 0
  109. #endif
  110. /** If you want the startup delay to be a function, define this
  111. * to a function (including the brackets) and define SNTP_STARTUP_DELAY to 1.
  112. */
  113. #ifndef SNTP_STARTUP_DELAY_FUNC
  114. #define SNTP_STARTUP_DELAY_FUNC SNTP_STARTUP_DELAY
  115. #endif
  116. /** SNTP receive timeout - in milliseconds
  117. * Also used as retry timeout - this shouldn't be too low.
  118. * Default is 3 seconds.
  119. */
  120. #ifndef SNTP_RECV_TIMEOUT
  121. #define SNTP_RECV_TIMEOUT 3000
  122. #endif
  123. /** SNTP update delay - in milliseconds
  124. * Default is 1 hour.
  125. */
  126. #ifndef SNTP_UPDATE_DELAY
  127. #define SNTP_UPDATE_DELAY 3600000
  128. #endif
  129. #if (SNTP_UPDATE_DELAY < 15000) && !SNTP_SUPPRESS_DELAY_CHECK
  130. #error "SNTPv4 RFC 4330 enforces a minimum update time of 15 seconds!"
  131. #endif
  132. /** SNTP macro to change system time and/or the update the RTC clock */
  133. #ifndef SNTP_SET_SYSTEM_TIME
  134. #define SNTP_SET_SYSTEM_TIME(sec) ((void)sec)
  135. #endif
  136. /** SNTP macro to change system time including microseconds */
  137. uint8 sntp_receive_time_size = 1;
  138. #define SNTP_RECEIVE_TIME_SIZE sntp_receive_time_size
  139. #define SNTP_SET_SYSTEM_TIME_US(sec, us) sntp_update_rtc(sec, us)
  140. //#ifdef SNTP_SET_SYSTEM_TIME_US
  141. //#define SNTP_SET_SYSTEM_TIME_US(sec, us) sntp_update_rtc(sec, us)
  142. //#define SNTP_CALC_TIME_US 1
  143. //#define SNTP_RECEIVE_TIME_SIZE 2
  144. //#else
  145. //#define SNTP_SET_SYSTEM_TIME_US(sec, us)
  146. //#define SNTP_CALC_TIME_US 0
  147. //#define SNTP_RECEIVE_TIME_SIZE sntp_receive_time_size
  148. //#endif
  149. /** SNTP macro to get system time, used with SNTP_CHECK_RESPONSE >= 2
  150. * to send in request and compare in response.
  151. */
  152. #ifndef SNTP_GET_SYSTEM_TIME
  153. #define SNTP_GET_SYSTEM_TIME(sec, us) do { (sec) = 0; (us) = 0; } while(0)
  154. #endif
  155. /** Default retry timeout (in milliseconds) if the response
  156. * received is invalid.
  157. * This is doubled with each retry until SNTP_RETRY_TIMEOUT_MAX is reached.
  158. */
  159. #ifndef SNTP_RETRY_TIMEOUT
  160. #define SNTP_RETRY_TIMEOUT SNTP_RECV_TIMEOUT
  161. #endif
  162. /** Maximum retry timeout (in milliseconds). */
  163. #ifndef SNTP_RETRY_TIMEOUT_MAX
  164. #define SNTP_RETRY_TIMEOUT_MAX (SNTP_RETRY_TIMEOUT * 10)
  165. #endif
  166. /** Increase retry timeout with every retry sent
  167. * Default is on to conform to RFC.
  168. */
  169. #ifndef SNTP_RETRY_TIMEOUT_EXP
  170. #define SNTP_RETRY_TIMEOUT_EXP 1
  171. #endif
  172. /* the various debug levels for this file */
  173. #define SNTP_DEBUG_TRACE (SNTP_DEBUG | LWIP_DBG_TRACE)
  174. #define SNTP_DEBUG_STATE (SNTP_DEBUG | LWIP_DBG_STATE)
  175. #define SNTP_DEBUG_WARN (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING)
  176. #define SNTP_DEBUG_WARN_STATE (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE)
  177. #define SNTP_DEBUG_SERIOUS (SNTP_DEBUG | LWIP_DBG_LEVEL_SERIOUS)
  178. #define SNTP_ERR_KOD 1
  179. /* SNTP protocol defines */
  180. #define SNTP_MSG_LEN 48
  181. #define SNTP_OFFSET_LI_VN_MODE 0
  182. #define SNTP_LI_MASK 0xC0
  183. #define SNTP_LI_NO_WARNING 0x00
  184. #define SNTP_LI_LAST_MINUTE_61_SEC 0x01
  185. #define SNTP_LI_LAST_MINUTE_59_SEC 0x02
  186. #define SNTP_LI_ALARM_CONDITION 0x03 /* (clock not synchronized) */
  187. #define SNTP_VERSION_MASK 0x38
  188. #define SNTP_VERSION (4/* NTP Version 4*/<<3)
  189. #define SNTP_MODE_MASK 0x07
  190. #define SNTP_MODE_CLIENT 0x03
  191. #define SNTP_MODE_SERVER 0x04
  192. #define SNTP_MODE_BROADCAST 0x05
  193. #define SNTP_OFFSET_STRATUM 1
  194. #define SNTP_STRATUM_KOD 0x00
  195. #define SNTP_OFFSET_ORIGINATE_TIME 24
  196. #define SNTP_OFFSET_RECEIVE_TIME 32
  197. #define SNTP_OFFSET_TRANSMIT_TIME 40
  198. /* number of seconds between 1900 and 1970 */
  199. #define DIFF_SEC_1900_1970 (2208988800UL)
  200. /**
  201. * SNTP packet format (without optional fields)
  202. * Timestamps are coded as 64 bits:
  203. * - 32 bits seconds since Jan 01, 1970, 00:00
  204. * - 32 bits seconds fraction (0-padded)
  205. * For future use, if the MSB in the seconds part is set, seconds are based
  206. * on Feb 07, 2036, 06:28:16.
  207. */
  208. #ifdef PACK_STRUCT_USE_INCLUDES
  209. # include "arch/bpstruct.h"
  210. #endif
  211. PACK_STRUCT_BEGIN
  212. #define PACK_STRUCT_FLD_8 PACK_STRUCT_FIELD
  213. struct sntp_msg {
  214. PACK_STRUCT_FLD_8(u8_t li_vn_mode);
  215. PACK_STRUCT_FLD_8(u8_t stratum);
  216. PACK_STRUCT_FLD_8(u8_t poll);
  217. PACK_STRUCT_FLD_8(u8_t precision);
  218. PACK_STRUCT_FIELD(u32_t root_delay);
  219. PACK_STRUCT_FIELD(u32_t root_dispersion);
  220. PACK_STRUCT_FIELD(u32_t reference_identifier);
  221. PACK_STRUCT_FIELD(u32_t reference_timestamp[2]);
  222. PACK_STRUCT_FIELD(u32_t originate_timestamp[2]);
  223. PACK_STRUCT_FIELD(u32_t receive_timestamp[2]);
  224. PACK_STRUCT_FIELD(u32_t transmit_timestamp[2]);
  225. } PACK_STRUCT_STRUCT;
  226. PACK_STRUCT_END
  227. #ifdef PACK_STRUCT_USE_INCLUDES
  228. # include "arch/epstruct.h"
  229. #endif
  230. /* function prototypes */
  231. static void sntp_request(void *arg);
  232. /** The UDP pcb used by the SNTP client */
  233. static struct udp_pcb* sntp_pcb;
  234. sint8 time_zone = 8;
  235. /** Names/Addresses of servers */
  236. struct sntp_server {
  237. #if SNTP_SERVER_DNS
  238. char* name;
  239. #endif /* SNTP_SERVER_DNS */
  240. ip_addr_t addr;
  241. };
  242. static struct sntp_server sntp_servers[SNTP_MAX_SERVERS];
  243. static u8_t sntp_set_servers_from_dhcp;
  244. #if SNTP_SUPPORT_MULTIPLE_SERVERS
  245. /** The currently used server (initialized to 0) */
  246. static u8_t sntp_current_server;
  247. #else /* SNTP_SUPPORT_MULTIPLE_SERVERS */
  248. #define sntp_current_server 0
  249. #endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */
  250. #if SNTP_RETRY_TIMEOUT_EXP
  251. #define SNTP_RESET_RETRY_TIMEOUT() sntp_retry_timeout = SNTP_RETRY_TIMEOUT
  252. /** Retry time, initialized with SNTP_RETRY_TIMEOUT and doubled with each retry. */
  253. static u32_t sntp_retry_timeout;
  254. #else /* SNTP_RETRY_TIMEOUT_EXP */
  255. #define SNTP_RESET_RETRY_TIMEOUT()
  256. #define sntp_retry_timeout SNTP_RETRY_TIMEOUT
  257. #endif /* SNTP_RETRY_TIMEOUT_EXP */
  258. #if SNTP_CHECK_RESPONSE >= 1
  259. /** Saves the last server address to compare with response */
  260. static ip_addr_t sntp_last_server_address;
  261. #endif /* SNTP_CHECK_RESPONSE >= 1 */
  262. #if SNTP_CHECK_RESPONSE >= 2
  263. /** Saves the last timestamp sent (which is sent back by the server)
  264. * to compare against in response */
  265. static u32_t sntp_last_timestamp_sent[2];
  266. #endif /* SNTP_CHECK_RESPONSE >= 2 */
  267. //uint32 current_stamp_1 = 0;
  268. //uint32 current_stamp_2 = 0;
  269. static bool sntp_time_flag = false;
  270. static uint32 sntp_update_delay = SNTP_UPDATE_DELAY;
  271. static uint32 realtime_stamp = 0;
  272. LOCAL os_timer_t sntp_timer;
  273. /*****************************************/
  274. #define SECSPERMIN 60L
  275. #define MINSPERHOUR 60L
  276. #define HOURSPERDAY 24L
  277. #define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
  278. #define SECSPERDAY (SECSPERHOUR * HOURSPERDAY)
  279. #define DAYSPERWEEK 7
  280. #define MONSPERYEAR 12
  281. #define YEAR_BASE 1900
  282. #define EPOCH_YEAR 1970
  283. #define EPOCH_WDAY 4
  284. #define EPOCH_YEARS_SINCE_LEAP 2
  285. #define EPOCH_YEARS_SINCE_CENTURY 70
  286. #define EPOCH_YEARS_SINCE_LEAP_CENTURY 370
  287. #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
  288. int __tznorth;
  289. int __tzyear;
  290. char reult[100];
  291. static const int mon_lengths[2][12] = {
  292. {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
  293. {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
  294. } ;
  295. static const int year_lengths[2] = {
  296. 365,
  297. 366
  298. } ;
  299. struct tm
  300. {
  301. int tm_sec;
  302. int tm_min;
  303. int tm_hour;
  304. int tm_mday;
  305. int tm_mon;
  306. int tm_year;
  307. int tm_wday;
  308. int tm_yday;
  309. int tm_isdst;
  310. };
  311. struct tm res_buf;
  312. typedef struct __tzrule_struct
  313. {
  314. char ch;
  315. int m;
  316. int n;
  317. int d;
  318. int s;
  319. time_t change;
  320. int offset;
  321. } __tzrule_type;
  322. __tzrule_type sntp__tzrule[2];
  323. struct tm * ICACHE_FLASH_ATTR
  324. sntp_mktm_r(const time_t * tim_p ,struct tm *res ,int is_gmtime)
  325. {
  326. long days, rem;
  327. time_t lcltime;
  328. int i;
  329. int y;
  330. int yleap;
  331. const int *ip;
  332. /* base decision about std/dst time on current time */
  333. lcltime = *tim_p;
  334. days = ((long)lcltime) / SECSPERDAY;
  335. rem = ((long)lcltime) % SECSPERDAY;
  336. while (rem < 0)
  337. {
  338. rem += SECSPERDAY;
  339. --days;
  340. }
  341. while (rem >= SECSPERDAY)
  342. {
  343. rem -= SECSPERDAY;
  344. ++days;
  345. }
  346. /* compute hour, min, and sec */
  347. res->tm_hour = (int) (rem / SECSPERHOUR);
  348. rem %= SECSPERHOUR;
  349. res->tm_min = (int) (rem / SECSPERMIN);
  350. res->tm_sec = (int) (rem % SECSPERMIN);
  351. /* compute day of week */
  352. if ((res->tm_wday = ((EPOCH_WDAY + days) % DAYSPERWEEK)) < 0)
  353. res->tm_wday += DAYSPERWEEK;
  354. /* compute year & day of year */
  355. y = EPOCH_YEAR;
  356. if (days >= 0)
  357. {
  358. for (;;)
  359. {
  360. yleap = isleap(y);
  361. if (days < year_lengths[yleap])
  362. break;
  363. y++;
  364. days -= year_lengths[yleap];
  365. }
  366. }
  367. else
  368. {
  369. do
  370. {
  371. --y;
  372. yleap = isleap(y);
  373. days += year_lengths[yleap];
  374. } while (days < 0);
  375. }
  376. res->tm_year = y - YEAR_BASE;
  377. res->tm_yday = days;
  378. ip = mon_lengths[yleap];
  379. for (res->tm_mon = 0; days >= ip[res->tm_mon]; ++res->tm_mon)
  380. days -= ip[res->tm_mon];
  381. res->tm_mday = days + 1;
  382. if (!is_gmtime)
  383. {
  384. int offset;
  385. int hours, mins, secs;
  386. // TZ_LOCK;
  387. // if (_daylight)
  388. // {
  389. // if (y == __tzyear || __tzcalc_limits (y))
  390. // res->tm_isdst = (__tznorth
  391. // ? (*tim_p >= __tzrule[0].change && *tim_p < __tzrule[1].change)
  392. // : (*tim_p >= __tzrule[0].change || *tim_p < __tzrule[1].change));
  393. // else
  394. // res->tm_isdst = -1;
  395. // }
  396. // else
  397. res->tm_isdst = 0;
  398. offset = (res->tm_isdst == 1 ? sntp__tzrule[1].offset : sntp__tzrule[0].offset);
  399. hours = offset / SECSPERHOUR;
  400. offset = offset % SECSPERHOUR;
  401. mins = offset / SECSPERMIN;
  402. secs = offset % SECSPERMIN;
  403. res->tm_sec -= secs;
  404. res->tm_min -= mins;
  405. res->tm_hour -= hours;
  406. if (res->tm_sec >= SECSPERMIN)
  407. {
  408. res->tm_min += 1;
  409. res->tm_sec -= SECSPERMIN;
  410. }
  411. else if (res->tm_sec < 0)
  412. {
  413. res->tm_min -= 1;
  414. res->tm_sec += SECSPERMIN;
  415. }
  416. if (res->tm_min >= MINSPERHOUR)
  417. {
  418. res->tm_hour += 1;
  419. res->tm_min -= MINSPERHOUR;
  420. }
  421. else if (res->tm_min < 0)
  422. {
  423. res->tm_hour -= 1;
  424. res->tm_min += MINSPERHOUR;
  425. }
  426. if (res->tm_hour >= HOURSPERDAY)
  427. {
  428. ++res->tm_yday;
  429. ++res->tm_wday;
  430. if (res->tm_wday > 6)
  431. res->tm_wday = 0;
  432. ++res->tm_mday;
  433. res->tm_hour -= HOURSPERDAY;
  434. if (res->tm_mday > ip[res->tm_mon])
  435. {
  436. res->tm_mday -= ip[res->tm_mon];
  437. res->tm_mon += 1;
  438. if (res->tm_mon == 12)
  439. {
  440. res->tm_mon = 0;
  441. res->tm_year += 1;
  442. res->tm_yday = 0;
  443. }
  444. }
  445. }
  446. else if (res->tm_hour < 0)
  447. {
  448. res->tm_yday -= 1;
  449. res->tm_wday -= 1;
  450. if (res->tm_wday < 0)
  451. res->tm_wday = 6;
  452. res->tm_mday -= 1;
  453. res->tm_hour += 24;
  454. if (res->tm_mday == 0)
  455. {
  456. res->tm_mon -= 1;
  457. if (res->tm_mon < 0)
  458. {
  459. res->tm_mon = 11;
  460. res->tm_year -= 1;
  461. res->tm_yday = 365 + isleap(res->tm_year);
  462. }
  463. res->tm_mday = ip[res->tm_mon];
  464. }
  465. }
  466. // TZ_UNLOCK;
  467. }
  468. else
  469. res->tm_isdst = 0;
  470. // os_printf("res %d %d %d %d %d\n",res->tm_year,res->tm_mon,res->tm_mday,res->tm_yday,res->tm_hour);
  471. return (res);
  472. }
  473. struct tm * ICACHE_FLASH_ATTR
  474. sntp_localtime_r(const time_t * tim_p ,
  475. struct tm *res)
  476. {
  477. return sntp_mktm_r (tim_p, res, 0);
  478. }
  479. struct tm * ICACHE_FLASH_ATTR
  480. sntp_localtime(const time_t * tim_p)
  481. {
  482. return sntp_localtime_r (tim_p, &res_buf);
  483. }
  484. int ICACHE_FLASH_ATTR
  485. sntp__tzcalc_limits(int year)
  486. {
  487. int days, year_days, years;
  488. int i, j;
  489. if (year < EPOCH_YEAR)
  490. return 0;
  491. __tzyear = year;
  492. years = (year - EPOCH_YEAR);
  493. year_days = years * 365 +
  494. (years - 1 + EPOCH_YEARS_SINCE_LEAP) / 4 - (years - 1 + EPOCH_YEARS_SINCE_CENTURY) / 100 +
  495. (years - 1 + EPOCH_YEARS_SINCE_LEAP_CENTURY) / 400;
  496. for (i = 0; i < 2; ++i)
  497. {
  498. if (sntp__tzrule[i].ch == 'J')
  499. days = year_days + sntp__tzrule[i].d + (isleap(year) && sntp__tzrule[i].d >= 60);
  500. else if (sntp__tzrule[i].ch == 'D')
  501. days = year_days + sntp__tzrule[i].d;
  502. else
  503. {
  504. int yleap = isleap(year);
  505. int m_day, m_wday, wday_diff;
  506. const int *ip = mon_lengths[yleap];
  507. days = year_days;
  508. for (j = 1; j < sntp__tzrule[i].m; ++j)
  509. days += ip[j-1];
  510. m_wday = (EPOCH_WDAY + days) % DAYSPERWEEK;
  511. wday_diff = sntp__tzrule[i].d - m_wday;
  512. if (wday_diff < 0)
  513. wday_diff += DAYSPERWEEK;
  514. m_day = (sntp__tzrule[i].n - 1) * DAYSPERWEEK + wday_diff;
  515. while (m_day >= ip[j-1])
  516. m_day -= DAYSPERWEEK;
  517. days += m_day;
  518. }
  519. /* store the change-over time in GMT form by adding offset */
  520. sntp__tzrule[i].change = days * SECSPERDAY + sntp__tzrule[i].s + sntp__tzrule[i].offset;
  521. }
  522. __tznorth = (sntp__tzrule[0].change < sntp__tzrule[1].change);
  523. return 1;
  524. }
  525. char * ICACHE_FLASH_ATTR
  526. sntp_asctime_r(struct tm *tim_p ,char *result)
  527. {
  528. static const char day_name[7][4] = {
  529. "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  530. };
  531. static const char mon_name[12][4] = {
  532. "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  533. "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  534. };
  535. os_sprintf (result, "%s %s %02d %02d:%02d:%02d %02d\n",
  536. day_name[tim_p->tm_wday],
  537. mon_name[tim_p->tm_mon],
  538. tim_p->tm_mday, tim_p->tm_hour, tim_p->tm_min,
  539. tim_p->tm_sec, 1900 + tim_p->tm_year);
  540. return result;
  541. }
  542. char *ICACHE_FLASH_ATTR
  543. sntp_asctime(struct tm *tim_p)
  544. {
  545. return sntp_asctime_r (tim_p, reult);
  546. }
  547. uint32 sntp_get_current_timestamp()
  548. {
  549. if(realtime_stamp == 0){
  550. os_printf("please start sntp first !\n");
  551. return 0;
  552. } else {
  553. return realtime_stamp;
  554. }
  555. }
  556. char* sntp_get_real_time(time_t t)
  557. {
  558. return sntp_asctime(sntp_localtime (&t));
  559. }
  560. /**
  561. * SNTP get time_zone default GMT + 8
  562. */
  563. sint8 ICACHE_FLASH_ATTR
  564. sntp_get_timezone(void)
  565. {
  566. return time_zone;
  567. }
  568. /**
  569. * SNTP set time_zone default GMT + 8
  570. */
  571. bool ICACHE_FLASH_ATTR
  572. sntp_set_timezone(sint8 timezone)
  573. {
  574. if(timezone >= -11 || timezone <= 13) {
  575. if (sntp_get_timetype()){
  576. RTC_TZ_SET(time_zone);
  577. } else
  578. time_zone = timezone;
  579. return true;
  580. } else {
  581. return false;
  582. }
  583. }
  584. void ICACHE_FLASH_ATTR sntp_set_daylight(int daylight)
  585. {
  586. if (sntp_get_timetype()){
  587. RTC_DST_SET(daylight);
  588. }
  589. }
  590. void ICACHE_FLASH_ATTR
  591. sntp_time_inc(void)
  592. {
  593. realtime_stamp++;
  594. }
  595. /**
  596. * SNTP processing of received timestamp
  597. */
  598. static void ICACHE_FLASH_ATTR
  599. sntp_process(u32_t *receive_timestamp)
  600. {
  601. /* convert SNTP time (1900-based) to unix GMT time (1970-based)
  602. * @todo: if MSB is 1, SNTP time is 2036-based!
  603. */
  604. time_t t = (ntohl(receive_timestamp[0]) - DIFF_SEC_1900_1970);
  605. if (sntp_get_timetype()){
  606. u32_t us = ntohl(receive_timestamp[1]) / 4295;
  607. SNTP_SET_SYSTEM_TIME_US(t, us);
  608. /* display local time from GMT time */
  609. LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s, %"U32_F" us", ctime(&t), us));
  610. } else{
  611. /* change system time and/or the update the RTC clock */
  612. SNTP_SET_SYSTEM_TIME(t);
  613. /* display local time from GMT time */
  614. t += time_zone * 60 * 60;// format GMT + time_zone TIME ZONE
  615. realtime_stamp = t;
  616. os_timer_disarm(&sntp_timer);
  617. os_timer_setfn(&sntp_timer, (os_timer_func_t *)sntp_time_inc, NULL);
  618. os_timer_arm(&sntp_timer, 1000, 1);
  619. }
  620. #if 0
  621. #if SNTP_CALC_TIME_US
  622. u32_t us = ntohl(receive_timestamp[1]) / 4295;
  623. SNTP_SET_SYSTEM_TIME_US(t, us);
  624. /* display local time from GMT time */
  625. LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s, %"U32_F" us", ctime(&t), us));
  626. #else /* SNTP_CALC_TIME_US */
  627. /* change system time and/or the update the RTC clock */
  628. SNTP_SET_SYSTEM_TIME(t);
  629. /* display local time from GMT time */
  630. t += time_zone * 60 * 60;// format GMT + time_zone TIME ZONE
  631. realtime_stamp = t;
  632. os_timer_disarm(&sntp_timer);
  633. os_timer_setfn(&sntp_timer, (os_timer_func_t *)sntp_time_inc, NULL);
  634. os_timer_arm(&sntp_timer, 1000, 1);
  635. #endif /* SNTP_CALC_TIME_US */
  636. #endif
  637. }
  638. /**
  639. * Initialize request struct to be sent to server.
  640. */
  641. static void ICACHE_FLASH_ATTR
  642. sntp_initialize_request(struct sntp_msg *req)
  643. {
  644. os_memset(req, 0, SNTP_MSG_LEN);
  645. req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT;
  646. #if SNTP_CHECK_RESPONSE >= 2
  647. {
  648. u32_t sntp_time_sec, sntp_time_us;
  649. /* fill in transmit timestamp and save it in 'sntp_last_timestamp_sent' */
  650. SNTP_GET_SYSTEM_TIME(sntp_time_sec, sntp_time_us);
  651. sntp_last_timestamp_sent[0] = htonl(sntp_time_sec + DIFF_SEC_1900_1970);
  652. req->transmit_timestamp[0] = sntp_last_timestamp_sent[0];
  653. /* we send/save us instead of fraction to be faster... */
  654. sntp_last_timestamp_sent[1] = htonl(sntp_time_us);
  655. req->transmit_timestamp[1] = sntp_last_timestamp_sent[1];
  656. }
  657. #endif /* SNTP_CHECK_RESPONSE >= 2 */
  658. }
  659. /**
  660. * Retry: send a new request (and increase retry timeout).
  661. *
  662. * @param arg is unused (only necessary to conform to sys_timeout)
  663. */
  664. static void ICACHE_FLASH_ATTR
  665. sntp_retry(void* arg)
  666. {
  667. LWIP_UNUSED_ARG(arg);
  668. LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_retry: Next request will be sent in %"U32_F" ms\n",
  669. sntp_retry_timeout));
  670. /* set up a timer to send a retry and increase the retry delay */
  671. sys_timeout(sntp_retry_timeout, sntp_request, NULL);
  672. #if SNTP_RETRY_TIMEOUT_EXP
  673. {
  674. u32_t new_retry_timeout;
  675. /* increase the timeout for next retry */
  676. new_retry_timeout = sntp_retry_timeout << 1;
  677. /* limit to maximum timeout and prevent overflow */
  678. if ((new_retry_timeout <= SNTP_RETRY_TIMEOUT_MAX) &&
  679. (new_retry_timeout > sntp_retry_timeout)) {
  680. sntp_retry_timeout = new_retry_timeout;
  681. }
  682. }
  683. #endif /* SNTP_RETRY_TIMEOUT_EXP */
  684. }
  685. #if SNTP_SUPPORT_MULTIPLE_SERVERS
  686. /**
  687. * If Kiss-of-Death is received (or another packet parsing error),
  688. * try the next server or retry the current server and increase the retry
  689. * timeout if only one server is available.
  690. * (implicitly, SNTP_MAX_SERVERS > 1)
  691. *
  692. * @param arg is unused (only necessary to conform to sys_timeout)
  693. */
  694. static void
  695. sntp_try_next_server(void* arg)
  696. {
  697. u8_t old_server, i;
  698. LWIP_UNUSED_ARG(arg);
  699. old_server = sntp_current_server;
  700. for (i = 0; i < SNTP_MAX_SERVERS - 1; i++) {
  701. sntp_current_server++;
  702. if (sntp_current_server >= SNTP_MAX_SERVERS) {
  703. sntp_current_server = 0;
  704. }
  705. if (!ip_addr_isany(&sntp_servers[sntp_current_server].addr)
  706. #if SNTP_SERVER_DNS
  707. || (sntp_servers[sntp_current_server].name != NULL)
  708. #endif
  709. ) {
  710. LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_try_next_server: Sending request to server %"U16_F"\n",
  711. (u16_t)sntp_current_server));
  712. /* new server: reset retry timeout */
  713. SNTP_RESET_RETRY_TIMEOUT();
  714. /* instantly send a request to the next server */
  715. sntp_request(NULL);
  716. return;
  717. }
  718. }
  719. /* no other valid server found */
  720. sntp_current_server = old_server;
  721. sntp_retry(NULL);
  722. }
  723. #else /* SNTP_SUPPORT_MULTIPLE_SERVERS */
  724. /* Always retry on error if only one server is supported */
  725. #define sntp_try_next_server sntp_retry
  726. #endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */
  727. /** UDP recv callback for the sntp pcb */
  728. static void ICACHE_FLASH_ATTR
  729. sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
  730. {
  731. u8_t mode;
  732. u8_t stratum;
  733. u32_t receive_timestamp[SNTP_RECEIVE_TIME_SIZE];
  734. err_t err;
  735. //os_printf("sntp_recv\n");
  736. LWIP_UNUSED_ARG(arg);
  737. LWIP_UNUSED_ARG(pcb);
  738. /* packet received: stop retry timeout */
  739. sys_untimeout(sntp_try_next_server, NULL);
  740. sys_untimeout(sntp_request, NULL);
  741. err = ERR_ARG;
  742. #if SNTP_CHECK_RESPONSE >= 1
  743. /* check server address and port */
  744. if (ip_addr_cmp(addr, &sntp_last_server_address) &&
  745. (port == SNTP_PORT))
  746. #else /* SNTP_CHECK_RESPONSE >= 1 */
  747. LWIP_UNUSED_ARG(addr);
  748. LWIP_UNUSED_ARG(port);
  749. #endif /* SNTP_CHECK_RESPONSE >= 1 */
  750. {
  751. /* process the response */
  752. if (p->tot_len == SNTP_MSG_LEN) {
  753. pbuf_copy_partial(p, &mode, 1, SNTP_OFFSET_LI_VN_MODE);
  754. mode &= SNTP_MODE_MASK;
  755. /* if this is a SNTP response... */
  756. if ((mode == SNTP_MODE_SERVER) ||
  757. (mode == SNTP_MODE_BROADCAST)) {
  758. pbuf_copy_partial(p, &stratum, 1, SNTP_OFFSET_STRATUM);
  759. if (stratum == SNTP_STRATUM_KOD) {
  760. /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
  761. err = SNTP_ERR_KOD;
  762. LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Received Kiss-of-Death\n"));
  763. } else {
  764. #if SNTP_CHECK_RESPONSE >= 2
  765. /* check originate_timetamp against sntp_last_timestamp_sent */
  766. u32_t originate_timestamp[2];
  767. pbuf_copy_partial(p, &originate_timestamp, 8, SNTP_OFFSET_ORIGINATE_TIME);
  768. if ((originate_timestamp[0] != sntp_last_timestamp_sent[0]) ||
  769. (originate_timestamp[1] != sntp_last_timestamp_sent[1]))
  770. {
  771. LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid originate timestamp in response\n"));
  772. } else
  773. #endif /* SNTP_CHECK_RESPONSE >= 2 */
  774. /* @todo: add code for SNTP_CHECK_RESPONSE >= 3 and >= 4 here */
  775. {
  776. /* correct answer */
  777. err = ERR_OK;
  778. pbuf_copy_partial(p, &receive_timestamp, SNTP_RECEIVE_TIME_SIZE * 4, SNTP_OFFSET_RECEIVE_TIME);
  779. }
  780. }
  781. } else {
  782. LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid mode in response: %"U16_F"\n", (u16_t)mode));
  783. }
  784. } else {
  785. LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid packet length: %"U16_F"\n", p->tot_len));
  786. }
  787. }
  788. pbuf_free(p);
  789. if (err == ERR_OK) {
  790. /* Correct response, reset retry timeout */
  791. SNTP_RESET_RETRY_TIMEOUT();
  792. sntp_process(receive_timestamp);
  793. /* Set up timeout for next request */
  794. sys_timeout((u32_t)sntp_update_delay, sntp_request, NULL);
  795. LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Scheduled next time request: %"U32_F" ms\n",
  796. (u32_t)sntp_update_delay));
  797. } else if (err == SNTP_ERR_KOD) {
  798. /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
  799. sntp_try_next_server(NULL);
  800. } else {
  801. /* another error, try the same server again */
  802. sntp_retry(NULL);
  803. }
  804. }
  805. /** Actually send an sntp request to a server.
  806. *
  807. * @param server_addr resolved IP address of the SNTP server
  808. */
  809. static void ICACHE_FLASH_ATTR
  810. sntp_send_request(ip_addr_t *server_addr)
  811. {
  812. struct pbuf* p;
  813. // os_printf("sntp_send_request\n");
  814. p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM);
  815. if (p != NULL) {
  816. struct sntp_msg *sntpmsg = (struct sntp_msg *)p->payload;
  817. LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_send_request: Sending request to server\n"));
  818. /* initialize request message */
  819. sntp_initialize_request(sntpmsg);
  820. /* send request */
  821. udp_sendto(sntp_pcb, p, server_addr, SNTP_PORT);
  822. /* free the pbuf after sending it */
  823. pbuf_free(p);
  824. /* set up receive timeout: try next server or retry on timeout */
  825. sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL);
  826. #if SNTP_CHECK_RESPONSE >= 1
  827. /* save server address to verify it in sntp_recv */
  828. ip_addr_set(&sntp_last_server_address, server_addr);
  829. #endif /* SNTP_CHECK_RESPONSE >= 1 */
  830. } else {
  831. LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n",
  832. (u32_t)SNTP_RETRY_TIMEOUT));
  833. /* out of memory: set up a timer to send a retry */
  834. sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL);
  835. }
  836. }
  837. #if SNTP_SERVER_DNS
  838. /**
  839. * DNS found callback when using DNS names as server address.
  840. */
  841. static void
  842. sntp_dns_found(const char* hostname, ip_addr_t *ipaddr, void *arg)
  843. {
  844. LWIP_UNUSED_ARG(hostname);
  845. LWIP_UNUSED_ARG(arg);
  846. if (ipaddr != NULL) {
  847. /* Address resolved, send request */
  848. LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_dns_found: Server address resolved, sending request\n"));
  849. sntp_send_request(ipaddr);
  850. } else {
  851. /* DNS resolving failed -> try another server */
  852. LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_dns_found: Failed to resolve server address resolved, trying next server\n"));
  853. sntp_try_next_server(NULL);
  854. }
  855. }
  856. #endif /* SNTP_SERVER_DNS */
  857. /**
  858. * Send out an sntp request.
  859. *
  860. * @param arg is unused (only necessary to conform to sys_timeout)
  861. */
  862. static void ICACHE_FLASH_ATTR
  863. sntp_request(void *arg)
  864. {
  865. ip_addr_t sntp_server_address;
  866. err_t err;
  867. LWIP_UNUSED_ARG(arg);
  868. /* initialize SNTP server address */
  869. #if SNTP_SERVER_DNS
  870. if (sntp_servers[sntp_current_server].name) {
  871. /* always resolve the name and rely on dns-internal caching & timeout */
  872. ip_addr_set_any(&sntp_servers[sntp_current_server].addr);
  873. err = dns_gethostbyname(sntp_servers[sntp_current_server].name, &sntp_server_address,
  874. sntp_dns_found, NULL);
  875. if (err == ERR_INPROGRESS) {
  876. /* DNS request sent, wait for sntp_dns_found being called */
  877. LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_request: Waiting for server address to be resolved.\n"));
  878. return;
  879. } else if (err == ERR_OK) {
  880. sntp_servers[sntp_current_server].addr = sntp_server_address;
  881. }
  882. } else
  883. #endif /* SNTP_SERVER_DNS */
  884. {
  885. sntp_server_address = sntp_servers[sntp_current_server].addr;
  886. // os_printf("sntp_server_address ip %d\n",sntp_server_address.addr);
  887. err = (ip_addr_isany(&sntp_server_address)) ? ERR_ARG : ERR_OK;
  888. }
  889. if (err == ERR_OK) {
  890. LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_request: current server address is %u.%u.%u.%u\n",
  891. ip4_addr1(&sntp_server_address), ip4_addr2(&sntp_server_address), ip4_addr3(&sntp_server_address), ip4_addr4(&sntp_server_address)));
  892. sntp_send_request(&sntp_server_address);
  893. } else {
  894. /* address conversion failed, try another server */
  895. LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_request: Invalid server address, trying next server.\n"));
  896. sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_try_next_server, NULL);
  897. }
  898. }
  899. /**
  900. * Initialize this module.
  901. * Send out request instantly or after SNTP_STARTUP_DELAY(_FUNC).
  902. */
  903. void ICACHE_FLASH_ATTR
  904. sntp_init(void)
  905. {
  906. #ifdef SNTP_SERVER_ADDRESS
  907. #if SNTP_SERVER_DNS
  908. sntp_setservername(0, SNTP_SERVER_ADDRESS);
  909. #else
  910. #error SNTP_SERVER_ADDRESS string not supported SNTP_SERVER_DNS==0
  911. #endif
  912. #endif /* SNTP_SERVER_ADDRESS */
  913. if (sntp_pcb == NULL) {
  914. SNTP_RESET_RETRY_TIMEOUT();
  915. sntp_pcb = udp_new();
  916. LWIP_ASSERT("Failed to allocate udp pcb for sntp client", sntp_pcb != NULL);
  917. if (sntp_pcb != NULL) {
  918. udp_recv(sntp_pcb, sntp_recv, NULL);
  919. #if SNTP_STARTUP_DELAY
  920. sys_timeout((u32_t)SNTP_STARTUP_DELAY_FUNC, sntp_request, NULL);
  921. #else
  922. sntp_request(NULL);
  923. #endif
  924. }
  925. }
  926. }
  927. /**
  928. * Stop this module.
  929. */
  930. void ICACHE_FLASH_ATTR
  931. sntp_stop(void)
  932. {
  933. if (sntp_pcb != NULL) {
  934. sys_untimeout(sntp_request, NULL);
  935. udp_remove(sntp_pcb);
  936. sntp_pcb = NULL;
  937. }
  938. os_timer_disarm(&sntp_timer);
  939. realtime_stamp = 0;
  940. }
  941. #if SNTP_GET_SERVERS_FROM_DHCP
  942. /**
  943. * Config SNTP server handling by IP address, name, or DHCP; clear table
  944. * @param set_servers_from_dhcp enable or disable getting server addresses from dhcp
  945. */
  946. void
  947. sntp_servermode_dhcp(int set_servers_from_dhcp)
  948. {
  949. u8_t new_mode = set_servers_from_dhcp ? 1 : 0;
  950. if (sntp_set_servers_from_dhcp != new_mode) {
  951. sntp_set_servers_from_dhcp = new_mode;
  952. }
  953. }
  954. #endif /* SNTP_GET_SERVERS_FROM_DHCP */
  955. /**
  956. * Initialize one of the NTP servers by IP address
  957. *
  958. * @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS
  959. * @param dnsserver IP address of the NTP server to set
  960. */
  961. void ICACHE_FLASH_ATTR
  962. sntp_setserver(u8_t idx, ip_addr_t *server)
  963. {
  964. if (idx < SNTP_MAX_SERVERS) {
  965. if (server != NULL) {
  966. sntp_servers[idx].addr = (*server);
  967. // os_printf("server ip %d\n",server->addr);
  968. } else {
  969. ip_addr_set_any(&sntp_servers[idx].addr);
  970. }
  971. #if SNTP_SERVER_DNS
  972. sntp_servers[idx].name = NULL;
  973. #endif
  974. }
  975. }
  976. #if LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP
  977. /**
  978. * Initialize one of the NTP servers by IP address, required by DHCP
  979. *
  980. * @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS
  981. * @param dnsserver IP address of the NTP server to set
  982. */
  983. void
  984. dhcp_set_ntp_servers(u8_t num, ip_addr_t *server)
  985. {
  986. LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: %s %u.%u.%u.%u as NTP server #%u via DHCP\n",
  987. (sntp_set_servers_from_dhcp ? "Got" : "Rejected"),
  988. ip4_addr1(server), ip4_addr2(server), ip4_addr3(server), ip4_addr4(server), num));
  989. if (sntp_set_servers_from_dhcp && num) {
  990. u8_t i;
  991. for (i = 0; (i < num) && (i < SNTP_MAX_SERVERS); i++) {
  992. sntp_setserver(i, &server[i]);
  993. }
  994. for (i = num; i < SNTP_MAX_SERVERS; i++) {
  995. sntp_setserver(i, NULL);
  996. }
  997. }
  998. }
  999. #endif /* LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP */
  1000. /**
  1001. * Obtain one of the currently configured by IP address (or DHCP) NTP servers
  1002. *
  1003. * @param numdns the index of the NTP server
  1004. * @return IP address of the indexed NTP server or "ip_addr_any" if the NTP
  1005. * server has not been configured by address (or at all).
  1006. */
  1007. ip_addr_t ICACHE_FLASH_ATTR
  1008. sntp_getserver(u8_t idx)
  1009. {
  1010. if (idx < SNTP_MAX_SERVERS) {
  1011. return sntp_servers[idx].addr;
  1012. }
  1013. return *IP_ADDR_ANY;
  1014. }
  1015. #if SNTP_SERVER_DNS
  1016. /**
  1017. * Initialize one of the NTP servers by name
  1018. *
  1019. * @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS
  1020. * @param dnsserver DNS name of the NTP server to set, to be resolved at contact time
  1021. */
  1022. void ICACHE_FLASH_ATTR
  1023. sntp_setservername(u8_t idx, char *server)
  1024. {
  1025. if (idx < SNTP_MAX_SERVERS) {
  1026. sntp_servers[idx].name = server;
  1027. }
  1028. }
  1029. /**
  1030. * Obtain one of the currently configured by name NTP servers.
  1031. *
  1032. * @param numdns the index of the NTP server
  1033. * @return IP address of the indexed NTP server or NULL if the NTP
  1034. * server has not been configured by name (or at all)
  1035. */
  1036. char * ICACHE_FLASH_ATTR
  1037. sntp_getservername(u8_t idx)
  1038. {
  1039. if (idx < SNTP_MAX_SERVERS) {
  1040. return sntp_servers[idx].name;
  1041. }
  1042. return NULL;
  1043. }
  1044. #endif /* SNTP_SERVER_DNS */
  1045. void ICACHE_FLASH_ATTR
  1046. sntp_set_update_delay(uint32 ms)
  1047. {
  1048. sntp_update_delay = ms > 15000?ms:15000;
  1049. }
  1050. void ICACHE_FLASH_ATTR
  1051. sntp_set_timetype(bool type)
  1052. {
  1053. sntp_time_flag = type;
  1054. }
  1055. bool sntp_get_timetype(void)
  1056. {
  1057. return sntp_time_flag;
  1058. }
  1059. void ICACHE_FLASH_ATTR
  1060. sntp_set_receive_time_size(void)
  1061. {
  1062. if (sntp_get_timetype()){
  1063. sntp_receive_time_size = 2;
  1064. } else{
  1065. sntp_receive_time_size = 1;
  1066. }
  1067. }
  1068. #endif /* LWIP_UDP */