From 9913e5210779d2f3c4197760d6813270dbba6232 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 24 Dec 2017 21:48:25 +0100 Subject: [PATCH] handle tv.tv_usec in settimeofday() (#4001) optional settimeofday()'s callback fix #1679 --- cores/esp8266/coredecls.h | 13 +++++++++- cores/esp8266/sntp-lwip2.c | 21 ++++++++++++---- cores/esp8266/time.c | 24 +++++++------------ .../examples/NTP-TZ-DST/NTP-TZ-DST.ino | 14 ++++++++++- 4 files changed, 49 insertions(+), 23 deletions(-) diff --git a/cores/esp8266/coredecls.h b/cores/esp8266/coredecls.h index 809b1b2f6f..9e06419ca4 100644 --- a/cores/esp8266/coredecls.h +++ b/cores/esp8266/coredecls.h @@ -2,8 +2,19 @@ #ifndef __COREDECLS_H #define __COREDECLS_H -extern bool s_bootTimeSet; +#ifdef __cplusplus +extern "C" { +#endif // TODO: put declarations here, get rid of -Wno-implicit-function-declaration +extern bool timeshift64_is_set; + +void tune_timeshift64 (uint64_t now_us); +void settimeofday_cb (void (*cb)(void)); + +#ifdef __cplusplus +} +#endif + #endif // __COREDECLS_H diff --git a/cores/esp8266/sntp-lwip2.c b/cores/esp8266/sntp-lwip2.c index 0cb1a71657..2eabf12412 100644 --- a/cores/esp8266/sntp-lwip2.c +++ b/cores/esp8266/sntp-lwip2.c @@ -34,6 +34,7 @@ * TODOs: * settimeofday(): handle tv->tv_usec * sntp_mktm_r(): review, fix DST handling (this one is currently untouched from lwip-1.4) + * implement adjtime() */ #include @@ -42,6 +43,13 @@ #include #include "coredecls.h" +static void (*_settimeofday_cb)(void) = NULL; + +void settimeofday_cb (void (*cb)(void)) +{ + _settimeofday_cb = cb; +} + #if LWIP_VERSION_MAJOR == 1 #include @@ -58,10 +66,11 @@ int settimeofday(const struct timeval* tv, const struct timezone* tz) } if (tv) /* after*/ { + // can't call lwip1.4's static sntp_set_system_time() os_printf(stod14); // reset time subsystem - s_bootTimeSet = false; + timeshift64_is_set = false; return -1; } @@ -440,11 +449,13 @@ int settimeofday(const struct timeval* tv, const struct timezone* tz) } if (tv) /* after*/ { - sntp_set_system_time(tv->tv_sec); - // XXX FIXME TODO: efficiently use provided tv->tv_sec - // reset time subsystem - s_bootTimeSet = false; + tune_timeshift64(tv->tv_sec * 1000000ULL + tv->tv_usec); + + sntp_set_system_time(tv->tv_sec); + + if (_settimeofday_cb) + _settimeofday_cb(); } return 0; } diff --git a/cores/esp8266/time.c b/cores/esp8266/time.c index ab3fdfecaf..19b0dee522 100644 --- a/cores/esp8266/time.c +++ b/cores/esp8266/time.c @@ -37,22 +37,13 @@ extern uint64_t micros64(); // time gap in seconds from 01.01.1900 (NTP time) to 01.01.1970 (UNIX time) #define DIFF1900TO1970 2208988800UL -bool s_bootTimeSet = false; -static uint64_t s_bootTime_us = 0; +bool timeshift64_is_set = false; +static uint64_t timeshift64 = 0; -// calculate offset used in gettimeofday -static void ensureBootTimeIsSet() +void tune_timeshift64 (uint64_t now_us) { - // Check just a bool flag instead of the full 64-bit s_bootTime for zero. - if (!s_bootTimeSet) - { - time_t now_s = sntp_get_current_timestamp(); - if (now_s) - { - s_bootTime_us = now_s * 1000000ULL - micros64(); - s_bootTimeSet = true; - } - } + timeshift64 = now_us - micros64(); + timeshift64_is_set = true; } static void setServer(int id, const char* name_or_ip) @@ -102,8 +93,9 @@ int _gettimeofday_r(struct _reent* unused, struct timeval *tp, void *tzp) (void) tzp; if (tp) { - ensureBootTimeIsSet(); - uint64_t currentTime_us = s_bootTime_us + micros64(); + if (!timeshift64_is_set) + tune_timeshift64(sntp_get_current_timestamp() * 1000000ULL); + uint64_t currentTime_us = timeshift64 + micros64(); tp->tv_sec = currentTime_us / 1000000ULL; tp->tv_usec = currentTime_us % 1000000ULL; } diff --git a/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino b/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino index 254eb65fee..ebcbd59f20 100644 --- a/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino +++ b/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino @@ -12,9 +12,10 @@ This example code is in the public domain. */ +#include #include // time() ctime() #include // struct timeval -#include +#include // settimeofday_cb() //////////////////////////////////////////////////////// @@ -32,8 +33,19 @@ #define TZ_SEC ((TZ)*3600) #define DST_SEC ((DST_MN)*60) +timeval cbtime; // time set in callback +bool cbtime_set = false; + +void time_is_set (void) +{ + gettimeofday(&cbtime, NULL); + cbtime_set = true; + Serial.println("------------------ settimeofday() was called ------------------"); +} + void setup() { Serial.begin(115200); + settimeofday_cb(time_is_set); #if NTP0_OR_LOCAL1 // local