mirror of
https://github.com/cesanta/mongoose.git
synced 2024-11-27 20:59:00 +08:00
Add mg_now() to sntp.c
This commit is contained in:
parent
6357b30712
commit
22de1dc0f2
@ -26,12 +26,6 @@ static struct settings s_settings = {true, 1, 57, NULL};
|
|||||||
static const char *s_json_header =
|
static const char *s_json_header =
|
||||||
"Content-Type: application/json\r\n"
|
"Content-Type: application/json\r\n"
|
||||||
"Cache-Control: no-cache\r\n";
|
"Cache-Control: no-cache\r\n";
|
||||||
static uint64_t s_boot_timestamp = 0; // Updated by SNTP
|
|
||||||
|
|
||||||
// This is for newlib and TLS (mbedTLS)
|
|
||||||
uint64_t mg_now(void) {
|
|
||||||
return mg_millis() + s_boot_timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ui_event_next(int no, struct ui_event *e) {
|
int ui_event_next(int no, struct ui_event *e) {
|
||||||
if (no < 0 || no >= MAX_EVENTS_NO) return 0;
|
if (no < 0 || no >= MAX_EVENTS_NO) return 0;
|
||||||
@ -49,23 +43,8 @@ int ui_event_next(int no, struct ui_event *e) {
|
|||||||
return no + 1;
|
return no + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SNTP connection event handler. When we get a response from an SNTP server,
|
|
||||||
// adjust s_boot_timestamp. We'll get a valid time from that point on
|
|
||||||
static void sfn(struct mg_connection *c, int ev, void *ev_data) {
|
|
||||||
uint64_t *expiration_time = (uint64_t *) c->data;
|
|
||||||
if (ev == MG_EV_OPEN) {
|
|
||||||
*expiration_time = mg_millis() + 3000; // Store expiration time in 3s
|
|
||||||
} else if (ev == MG_EV_SNTP_TIME) {
|
|
||||||
uint64_t t = *(uint64_t *) ev_data;
|
|
||||||
s_boot_timestamp = t - mg_millis();
|
|
||||||
c->is_closing = 1;
|
|
||||||
} else if (ev == MG_EV_POLL) {
|
|
||||||
if (mg_millis() > *expiration_time) c->is_closing = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timer_sntp_fn(void *param) { // SNTP timer function. Sync up time
|
static void timer_sntp_fn(void *param) { // SNTP timer function. Sync up time
|
||||||
mg_sntp_connect(param, "udp://time.google.com:123", sfn, NULL);
|
mg_sntp_connect(param, "udp://time.google.com:123", NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse HTTP requests, return authenticated user or NULL
|
// Parse HTTP requests, return authenticated user or NULL
|
||||||
|
@ -22,7 +22,6 @@ static struct device_settings s_settings;
|
|||||||
static const char *s_json_header =
|
static const char *s_json_header =
|
||||||
"Content-Type: application/json\r\n"
|
"Content-Type: application/json\r\n"
|
||||||
"Cache-Control: no-cache\r\n";
|
"Cache-Control: no-cache\r\n";
|
||||||
static uint64_t s_boot_timestamp = 0; // Updated by SNTP
|
|
||||||
|
|
||||||
static void set_default_settings(struct device_settings *s) {
|
static void set_default_settings(struct device_settings *s) {
|
||||||
s->magic = SETTINGS_MAGIC;
|
s->magic = SETTINGS_MAGIC;
|
||||||
@ -33,29 +32,9 @@ static void set_default_settings(struct device_settings *s) {
|
|||||||
mg_snprintf(s->mqtt_topic_rx, sizeof(s->mqtt_topic_rx), "%s", "modbus1/rx");
|
mg_snprintf(s->mqtt_topic_rx, sizeof(s->mqtt_topic_rx), "%s", "modbus1/rx");
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is for newlib and TLS (mbedTLS)
|
|
||||||
uint64_t mg_now(void) {
|
|
||||||
return mg_millis() + s_boot_timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SNTP connection event handler. When we get a response from an SNTP server,
|
|
||||||
// adjust s_boot_timestamp. We'll get a valid time from that point on
|
|
||||||
static void sfn(struct mg_connection *c, int ev, void *ev_data) {
|
|
||||||
uint64_t *expiration_time = (uint64_t *) c->data;
|
|
||||||
if (ev == MG_EV_OPEN) {
|
|
||||||
*expiration_time = mg_millis() + 3000; // Store expiration time in 3s
|
|
||||||
} else if (ev == MG_EV_SNTP_TIME) {
|
|
||||||
uint64_t t = *(uint64_t *) ev_data;
|
|
||||||
s_boot_timestamp = t - mg_millis();
|
|
||||||
c->is_closing = 1;
|
|
||||||
} else if (ev == MG_EV_POLL) {
|
|
||||||
if (mg_millis() > *expiration_time) c->is_closing = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SNTP timer function. Sync up time
|
// SNTP timer function. Sync up time
|
||||||
static void timer_sntp_fn(void *param) {
|
static void timer_sntp_fn(void *param) {
|
||||||
mg_sntp_connect(param, "udp://time.google.com:123", sfn, NULL);
|
mg_sntp_connect(param, "udp://time.google.com:123", NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setfromjson(struct mg_str json, const char *jsonpath, char *buf,
|
static void setfromjson(struct mg_str json, const char *jsonpath, char *buf,
|
||||||
|
@ -20,11 +20,6 @@ struct device_config {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct device_config s_device_config;
|
static struct device_config s_device_config;
|
||||||
static uint64_t s_boot_timestamp = 0; // Updated by SNTP
|
|
||||||
|
|
||||||
uint64_t mg_now(void) {
|
|
||||||
return mg_millis() + s_boot_timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Device ID generation function. Create an ID that is unique
|
// Device ID generation function. Create an ID that is unique
|
||||||
// for a given device, and does not change between device restarts.
|
// for a given device, and does not change between device restarts.
|
||||||
@ -277,26 +272,11 @@ static void timer_ping(void *arg) {
|
|||||||
(void) arg;
|
(void) arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SNTP connection event handler. When we get a response from an SNTP server,
|
|
||||||
// adjust s_boot_timestamp. We'll get a valid time from that point on
|
|
||||||
static void sntp_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
|
||||||
uint64_t *expiration_time = (uint64_t *) c->data;
|
|
||||||
if (ev == MG_EV_OPEN) {
|
|
||||||
*expiration_time = mg_millis() + 3000; // Store expiration time in 3s
|
|
||||||
} else if (ev == MG_EV_SNTP_TIME) {
|
|
||||||
uint64_t t = *(uint64_t *) ev_data;
|
|
||||||
s_boot_timestamp = t - mg_millis();
|
|
||||||
c->is_closing = 1;
|
|
||||||
} else if (ev == MG_EV_POLL) {
|
|
||||||
if (mg_millis() > *expiration_time) c->is_closing = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timer_sntp(void *param) { // SNTP timer function. Sync up time
|
static void timer_sntp(void *param) { // SNTP timer function. Sync up time
|
||||||
static uint64_t hourly_timer = 0;
|
static uint64_t hourly_timer = 0;
|
||||||
if (s_boot_timestamp == 0 ||
|
uint64_t t1 = mg_now(), t2 = mg_millis();
|
||||||
mg_timer_expired(&hourly_timer, 3600000, mg_millis())) {
|
if (t1 < t2 + 3600 || mg_timer_expired(&hourly_timer, 3600000, t2)) {
|
||||||
mg_sntp_connect(param, "udp://time.google.com:123", sntp_ev_handler, NULL);
|
mg_sntp_connect(param, "udp://time.google.com:123", NULL, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
40
mongoose.c
40
mongoose.c
@ -7145,6 +7145,12 @@ void mg_hmac_sha256(uint8_t dst[32], uint8_t *key, size_t keysz, uint8_t *data,
|
|||||||
#define SNTP_TIME_OFFSET 2208988800U // (1970 - 1900) in seconds
|
#define SNTP_TIME_OFFSET 2208988800U // (1970 - 1900) in seconds
|
||||||
#define SNTP_MAX_FRAC 4294967295.0 // 2 ** 32 - 1
|
#define SNTP_MAX_FRAC 4294967295.0 // 2 ** 32 - 1
|
||||||
|
|
||||||
|
static uint64_t s_boot_timestamp = 0; // Updated by SNTP
|
||||||
|
|
||||||
|
uint64_t mg_now(void) {
|
||||||
|
return mg_millis() + s_boot_timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
static int64_t gettimestamp(const uint32_t *data) {
|
static int64_t gettimestamp(const uint32_t *data) {
|
||||||
uint32_t sec = mg_ntohl(data[0]), frac = mg_ntohl(data[1]);
|
uint32_t sec = mg_ntohl(data[0]), frac = mg_ntohl(data[1]);
|
||||||
if (sec) sec -= SNTP_TIME_OFFSET;
|
if (sec) sec -= SNTP_TIME_OFFSET;
|
||||||
@ -7167,9 +7173,9 @@ int64_t mg_sntp_parse(const unsigned char *buf, size_t len) {
|
|||||||
int64_t receive_time = gettimestamp((uint32_t *) &buf[32]);
|
int64_t receive_time = gettimestamp((uint32_t *) &buf[32]);
|
||||||
int64_t transmit_time = gettimestamp((uint32_t *) &buf[40]);
|
int64_t transmit_time = gettimestamp((uint32_t *) &buf[40]);
|
||||||
int64_t now = (int64_t) mg_millis();
|
int64_t now = (int64_t) mg_millis();
|
||||||
int64_t travel_time = (now - origin_time) - (transmit_time - receive_time);
|
int64_t latency = (now - origin_time) - (transmit_time - receive_time);
|
||||||
MG_INFO(("%lld %lld", transmit_time, travel_time));
|
epoch_milliseconds = transmit_time + latency / 2;
|
||||||
epoch_milliseconds = transmit_time + travel_time / 2;
|
s_boot_timestamp = (uint64_t) (epoch_milliseconds - now);
|
||||||
} else {
|
} else {
|
||||||
MG_ERROR(("unexpected version: %d", version));
|
MG_ERROR(("unexpected version: %d", version));
|
||||||
}
|
}
|
||||||
@ -7177,17 +7183,22 @@ int64_t mg_sntp_parse(const unsigned char *buf, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void sntp_cb(struct mg_connection *c, int ev, void *ev_data) {
|
static void sntp_cb(struct mg_connection *c, int ev, void *ev_data) {
|
||||||
if (ev == MG_EV_READ) {
|
uint64_t *expiration_time = (uint64_t *) c->data;
|
||||||
int64_t milliseconds = mg_sntp_parse(c->recv.buf, c->recv.len);
|
if (ev == MG_EV_OPEN) {
|
||||||
if (milliseconds > 0) {
|
*expiration_time = mg_millis() + 3000; // Store expiration time in 3s
|
||||||
MG_DEBUG(("%lu got time: %lld ms from epoch", c->id, milliseconds));
|
|
||||||
mg_call(c, MG_EV_SNTP_TIME, (uint64_t *) &milliseconds);
|
|
||||||
MG_VERBOSE(("%u.%u", (unsigned) (milliseconds / 1000),
|
|
||||||
(unsigned) (milliseconds % 1000)));
|
|
||||||
}
|
|
||||||
mg_iobuf_del(&c->recv, 0, c->recv.len); // Free receive buffer
|
|
||||||
} else if (ev == MG_EV_CONNECT) {
|
} else if (ev == MG_EV_CONNECT) {
|
||||||
mg_sntp_request(c);
|
mg_sntp_request(c);
|
||||||
|
} else if (ev == MG_EV_READ) {
|
||||||
|
int64_t milliseconds = mg_sntp_parse(c->recv.buf, c->recv.len);
|
||||||
|
if (milliseconds > 0) {
|
||||||
|
s_boot_timestamp = (uint64_t) milliseconds - mg_millis();
|
||||||
|
mg_call(c, MG_EV_SNTP_TIME, (uint64_t *) &milliseconds);
|
||||||
|
MG_DEBUG(("%lu got time: %lld ms from epoch", c->id, milliseconds));
|
||||||
|
}
|
||||||
|
// mg_iobuf_del(&c->recv, 0, c->recv.len); // Free receive buffer
|
||||||
|
c->is_closing = 1;
|
||||||
|
} else if (ev == MG_EV_POLL) {
|
||||||
|
if (mg_millis() > *expiration_time) c->is_closing = 1;
|
||||||
} else if (ev == MG_EV_CLOSE) {
|
} else if (ev == MG_EV_CLOSE) {
|
||||||
}
|
}
|
||||||
(void) ev_data;
|
(void) ev_data;
|
||||||
@ -7212,7 +7223,10 @@ struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
|
|||||||
mg_event_handler_t fn, void *fnd) {
|
mg_event_handler_t fn, void *fnd) {
|
||||||
struct mg_connection *c = NULL;
|
struct mg_connection *c = NULL;
|
||||||
if (url == NULL) url = "udp://time.google.com:123";
|
if (url == NULL) url = "udp://time.google.com:123";
|
||||||
if ((c = mg_connect(mgr, url, fn, fnd)) != NULL) c->pfn = sntp_cb;
|
if ((c = mg_connect(mgr, url, fn, fnd)) != NULL) {
|
||||||
|
c->pfn = sntp_cb;
|
||||||
|
sntp_cb(c, MG_EV_OPEN, (void *) url);
|
||||||
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,12 +27,6 @@ static struct settings s_settings = {true, 1, 57, NULL};
|
|||||||
static const char *s_json_header =
|
static const char *s_json_header =
|
||||||
"Content-Type: application/json\r\n"
|
"Content-Type: application/json\r\n"
|
||||||
"Cache-Control: no-cache\r\n";
|
"Cache-Control: no-cache\r\n";
|
||||||
static uint64_t s_boot_timestamp = 0; // Updated by SNTP
|
|
||||||
|
|
||||||
// This is for newlib and TLS (mbedTLS)
|
|
||||||
uint64_t mg_now(void) {
|
|
||||||
return mg_millis() + s_boot_timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ui_event_next(int no, struct ui_event *e) {
|
int ui_event_next(int no, struct ui_event *e) {
|
||||||
if (no < 0 || no >= MAX_EVENTS_NO) return 0;
|
if (no < 0 || no >= MAX_EVENTS_NO) return 0;
|
||||||
@ -50,23 +44,8 @@ int ui_event_next(int no, struct ui_event *e) {
|
|||||||
return no + 1;
|
return no + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SNTP connection event handler. When we get a response from an SNTP server,
|
|
||||||
// adjust s_boot_timestamp. We'll get a valid time from that point on
|
|
||||||
static void sfn(struct mg_connection *c, int ev, void *ev_data) {
|
|
||||||
uint64_t *expiration_time = (uint64_t *) c->data;
|
|
||||||
if (ev == MG_EV_OPEN) {
|
|
||||||
*expiration_time = mg_millis() + 3000; // Store expiration time in 3s
|
|
||||||
} else if (ev == MG_EV_SNTP_TIME) {
|
|
||||||
uint64_t t = *(uint64_t *) ev_data;
|
|
||||||
s_boot_timestamp = t - mg_millis();
|
|
||||||
c->is_closing = 1;
|
|
||||||
} else if (ev == MG_EV_POLL) {
|
|
||||||
if (mg_millis() > *expiration_time) c->is_closing = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timer_sntp_fn(void *param) { // SNTP timer function. Sync up time
|
static void timer_sntp_fn(void *param) { // SNTP timer function. Sync up time
|
||||||
mg_sntp_connect(param, "udp://time.google.com:123", sfn, NULL);
|
mg_sntp_connect(param, "udp://time.google.com:123", NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse HTTP requests, return authenticated user or NULL
|
// Parse HTTP requests, return authenticated user or NULL
|
||||||
|
39
src/sntp.c
39
src/sntp.c
@ -7,6 +7,12 @@
|
|||||||
#define SNTP_TIME_OFFSET 2208988800U // (1970 - 1900) in seconds
|
#define SNTP_TIME_OFFSET 2208988800U // (1970 - 1900) in seconds
|
||||||
#define SNTP_MAX_FRAC 4294967295.0 // 2 ** 32 - 1
|
#define SNTP_MAX_FRAC 4294967295.0 // 2 ** 32 - 1
|
||||||
|
|
||||||
|
static uint64_t s_boot_timestamp = 0; // Updated by SNTP
|
||||||
|
|
||||||
|
uint64_t mg_now(void) {
|
||||||
|
return mg_millis() + s_boot_timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
static int64_t gettimestamp(const uint32_t *data) {
|
static int64_t gettimestamp(const uint32_t *data) {
|
||||||
uint32_t sec = mg_ntohl(data[0]), frac = mg_ntohl(data[1]);
|
uint32_t sec = mg_ntohl(data[0]), frac = mg_ntohl(data[1]);
|
||||||
if (sec) sec -= SNTP_TIME_OFFSET;
|
if (sec) sec -= SNTP_TIME_OFFSET;
|
||||||
@ -29,8 +35,9 @@ int64_t mg_sntp_parse(const unsigned char *buf, size_t len) {
|
|||||||
int64_t receive_time = gettimestamp((uint32_t *) &buf[32]);
|
int64_t receive_time = gettimestamp((uint32_t *) &buf[32]);
|
||||||
int64_t transmit_time = gettimestamp((uint32_t *) &buf[40]);
|
int64_t transmit_time = gettimestamp((uint32_t *) &buf[40]);
|
||||||
int64_t now = (int64_t) mg_millis();
|
int64_t now = (int64_t) mg_millis();
|
||||||
int64_t travel_time = (now - origin_time) - (transmit_time - receive_time);
|
int64_t latency = (now - origin_time) - (transmit_time - receive_time);
|
||||||
epoch_milliseconds = transmit_time + travel_time / 2;
|
epoch_milliseconds = transmit_time + latency / 2;
|
||||||
|
s_boot_timestamp = (uint64_t) (epoch_milliseconds - now);
|
||||||
} else {
|
} else {
|
||||||
MG_ERROR(("unexpected version: %d", version));
|
MG_ERROR(("unexpected version: %d", version));
|
||||||
}
|
}
|
||||||
@ -38,17 +45,22 @@ int64_t mg_sntp_parse(const unsigned char *buf, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void sntp_cb(struct mg_connection *c, int ev, void *ev_data) {
|
static void sntp_cb(struct mg_connection *c, int ev, void *ev_data) {
|
||||||
if (ev == MG_EV_READ) {
|
uint64_t *expiration_time = (uint64_t *) c->data;
|
||||||
int64_t milliseconds = mg_sntp_parse(c->recv.buf, c->recv.len);
|
if (ev == MG_EV_OPEN) {
|
||||||
if (milliseconds > 0) {
|
*expiration_time = mg_millis() + 3000; // Store expiration time in 3s
|
||||||
MG_DEBUG(("%lu got time: %lld ms from epoch", c->id, milliseconds));
|
|
||||||
mg_call(c, MG_EV_SNTP_TIME, (uint64_t *) &milliseconds);
|
|
||||||
MG_VERBOSE(("%u.%u", (unsigned) (milliseconds / 1000),
|
|
||||||
(unsigned) (milliseconds % 1000)));
|
|
||||||
}
|
|
||||||
mg_iobuf_del(&c->recv, 0, c->recv.len); // Free receive buffer
|
|
||||||
} else if (ev == MG_EV_CONNECT) {
|
} else if (ev == MG_EV_CONNECT) {
|
||||||
mg_sntp_request(c);
|
mg_sntp_request(c);
|
||||||
|
} else if (ev == MG_EV_READ) {
|
||||||
|
int64_t milliseconds = mg_sntp_parse(c->recv.buf, c->recv.len);
|
||||||
|
if (milliseconds > 0) {
|
||||||
|
s_boot_timestamp = (uint64_t) milliseconds - mg_millis();
|
||||||
|
mg_call(c, MG_EV_SNTP_TIME, (uint64_t *) &milliseconds);
|
||||||
|
MG_DEBUG(("%lu got time: %lld ms from epoch", c->id, milliseconds));
|
||||||
|
}
|
||||||
|
// mg_iobuf_del(&c->recv, 0, c->recv.len); // Free receive buffer
|
||||||
|
c->is_closing = 1;
|
||||||
|
} else if (ev == MG_EV_POLL) {
|
||||||
|
if (mg_millis() > *expiration_time) c->is_closing = 1;
|
||||||
} else if (ev == MG_EV_CLOSE) {
|
} else if (ev == MG_EV_CLOSE) {
|
||||||
}
|
}
|
||||||
(void) ev_data;
|
(void) ev_data;
|
||||||
@ -73,6 +85,9 @@ struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
|
|||||||
mg_event_handler_t fn, void *fnd) {
|
mg_event_handler_t fn, void *fnd) {
|
||||||
struct mg_connection *c = NULL;
|
struct mg_connection *c = NULL;
|
||||||
if (url == NULL) url = "udp://time.google.com:123";
|
if (url == NULL) url = "udp://time.google.com:123";
|
||||||
if ((c = mg_connect(mgr, url, fn, fnd)) != NULL) c->pfn = sntp_cb;
|
if ((c = mg_connect(mgr, url, fn, fnd)) != NULL) {
|
||||||
|
c->pfn = sntp_cb;
|
||||||
|
sntp_cb(c, MG_EV_OPEN, (void *) url);
|
||||||
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user