70#if SNTP_MAX_SERVERS > 1
71#define SNTP_SUPPORT_MULTIPLE_SERVERS 1
73#define SNTP_SUPPORT_MULTIPLE_SERVERS 0
76#ifndef SNTP_SUPPRESS_DELAY_CHECK
77#if SNTP_UPDATE_DELAY < 15000
78#error "SNTPv4 RFC 4330 enforces a minimum update time of 15 seconds (define SNTP_SUPPRESS_DELAY_CHECK to disable this error)!"
83#define SNTP_DEBUG_TRACE (SNTP_DEBUG | LWIP_DBG_TRACE)
84#define SNTP_DEBUG_STATE (SNTP_DEBUG | LWIP_DBG_STATE)
85#define SNTP_DEBUG_WARN (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING)
86#define SNTP_DEBUG_WARN_STATE (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE)
87#define SNTP_DEBUG_SERIOUS (SNTP_DEBUG | LWIP_DBG_LEVEL_SERIOUS)
92#define SNTP_MSG_LEN 48
94#define SNTP_OFFSET_LI_VN_MODE 0
95#define SNTP_LI_MASK 0xC0
96#define SNTP_LI_NO_WARNING (0x00 << 6)
97#define SNTP_LI_LAST_MINUTE_61_SEC (0x01 << 6)
98#define SNTP_LI_LAST_MINUTE_59_SEC (0x02 << 6)
99#define SNTP_LI_ALARM_CONDITION (0x03 << 6)
101#define SNTP_VERSION_MASK 0x38
102#define SNTP_VERSION (4<<3)
104#define SNTP_MODE_MASK 0x07
105#define SNTP_MODE_CLIENT 0x03
106#define SNTP_MODE_SERVER 0x04
107#define SNTP_MODE_BROADCAST 0x05
109#define SNTP_OFFSET_STRATUM 1
110#define SNTP_STRATUM_KOD 0x00
112#define SNTP_OFFSET_ORIGINATE_TIME 24
113#define SNTP_OFFSET_RECEIVE_TIME 32
114#define SNTP_OFFSET_TRANSMIT_TIME 40
117#define DIFF_SEC_1970_2036 ((u32_t)2085978496L)
121#ifndef SNTP_FRAC_TO_US
123# define SNTP_FRAC_TO_US(f) ((u32_t)(((u64_t)(f) * 1000000UL) >> 32))
125# define SNTP_FRAC_TO_US(f) ((u32_t)(f) / 4295)
135#ifndef SNTP_SET_SYSTEM_TIME_NTP
136# ifdef SNTP_SET_SYSTEM_TIME_US
137# define SNTP_SET_SYSTEM_TIME_NTP(s, f) \
138 SNTP_SET_SYSTEM_TIME_US((u32_t)((s) + DIFF_SEC_1970_2036), SNTP_FRAC_TO_US(f))
140# define SNTP_SET_SYSTEM_TIME_NTP(s, f) \
141 SNTP_SET_SYSTEM_TIME((u32_t)((s) + DIFF_SEC_1970_2036))
151#ifndef SNTP_GET_SYSTEM_TIME_NTP
152# define SNTP_GET_SYSTEM_TIME_NTP(s, f) do { \
154 SNTP_GET_SYSTEM_TIME(sec_, usec_); \
155 (s) = (s32_t)(sec_ - DIFF_SEC_1970_2036); \
156 (f) = usec_ * 4295 - ((usec_ * 2143) >> 16) + 2147; \
161#define SNTP_OFFSET_TIMESTAMPS \
162 (SNTP_OFFSET_TRANSMIT_TIME + 8 - sizeof(struct sntp_timestamps))
165#if SNTP_COMP_ROUNDTRIP
167# error "SNTP round-trip delay compensation requires 64-bit arithmetic"
169# define SNTP_SEC_FRAC_TO_S64(s, f) \
170 ((s64_t)(((u64_t)(s) << 32) | (u32_t)(f)))
171# define SNTP_TIMESTAMP_TO_S64(t) \
172 SNTP_SEC_FRAC_TO_S64(lwip_ntohl((t).sec), lwip_ntohl((t).frac))
186struct sntp_timestamps {
187#if SNTP_COMP_ROUNDTRIP || SNTP_CHECK_RESPONSE >= 2
188 struct sntp_time orig;
189 struct sntp_time
recv;
191 struct sntp_time xmit;
200#ifdef PACK_STRUCT_USE_INCLUDES
218#ifdef PACK_STRUCT_USE_INCLUDES
223static void sntp_request(
void *
arg);
226static u8_t sntp_opmode;
229static struct udp_pcb *sntp_pcb;
236#if SNTP_MONITOR_SERVER_REACHABILITY
240#if SNTP_SUPPORT_MULTIPLE_SERVERS
246#if SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6
247static u8_t sntp_set_servers_from_dhcp;
249#if SNTP_SUPPORT_MULTIPLE_SERVERS
251static u8_t sntp_current_server;
253#define sntp_current_server 0
256#if SNTP_RETRY_TIMEOUT_EXP
257#define SNTP_RESET_RETRY_TIMEOUT() sntp_retry_timeout = SNTP_RETRY_TIMEOUT
259static u32_t sntp_retry_timeout;
261#define SNTP_RESET_RETRY_TIMEOUT()
262#define sntp_retry_timeout SNTP_RETRY_TIMEOUT
265#if SNTP_CHECK_RESPONSE >= 1
267static ip_addr_t sntp_last_server_address;
270#if SNTP_CHECK_RESPONSE >= 2
273static struct sntp_time sntp_last_timestamp_sent;
276#if defined(LWIP_DEBUG) && !defined(sntp_format_time)
279sntp_format_time(
s32_t sec)
282 ut = (
u32_t)((
u32_t)sec + DIFF_SEC_1970_2036);
291sntp_process(
const struct sntp_timestamps *timestamps)
299#if SNTP_COMP_ROUNDTRIP
300# if SNTP_CHECK_RESPONSE >= 2
301 if (timestamps->recv.sec != 0 || timestamps->recv.frac != 0)
309 SNTP_GET_SYSTEM_TIME_NTP(dest_sec, dest_frac);
311 step_sec = (dest_sec < sec) ? ((
u32_t)sec - (
u32_t)dest_sec)
315 if ((step_sec >> 30) == 0) {
316 s64_t t1, t2, t3, t4;
318 t4 = SNTP_SEC_FRAC_TO_S64(dest_sec, dest_frac);
319 t3 = SNTP_SEC_FRAC_TO_S64(sec,
frac);
320 t1 = SNTP_TIMESTAMP_TO_S64(timestamps->orig);
321 t2 = SNTP_TIMESTAMP_TO_S64(timestamps->recv);
323 t4 += ((t2 - t1) + (t3 - t4)) / 2;
325 sec = (
s32_t)((u64_t)t4 >> 32);
331 SNTP_SET_SYSTEM_TIME_NTP(sec,
frac);
334 sntp_format_time(sec), SNTP_FRAC_TO_US(
frac)));
341sntp_initialize_request(
struct sntp_msg *req)
343 memset(req, 0, SNTP_MSG_LEN);
344 req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT;
346#if SNTP_CHECK_RESPONSE >= 2 || SNTP_COMP_ROUNDTRIP
351 SNTP_GET_SYSTEM_TIME_NTP(secs,
frac);
355# if SNTP_CHECK_RESPONSE >= 2
356 sntp_last_timestamp_sent.sec = sec;
357 sntp_last_timestamp_sent.frac =
frac;
359 req->transmit_timestamp[0] = sec;
360 req->transmit_timestamp[1] =
frac;
375 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
"sntp_retry: Next request will be sent in %"U32_F" ms\n",
376 sntp_retry_timeout));
379 sys_untimeout(sntp_request,
NULL);
380 sys_timeout(sntp_retry_timeout, sntp_request,
NULL);
382#if SNTP_RETRY_TIMEOUT_EXP
384 u32_t new_retry_timeout;
386 new_retry_timeout = sntp_retry_timeout << 1;
389 (new_retry_timeout > sntp_retry_timeout)) {
390 sntp_retry_timeout = new_retry_timeout;
398#if SNTP_SUPPORT_MULTIPLE_SERVERS
408sntp_try_next_server(
void *
arg)
413 old_server = sntp_current_server;
415 sntp_current_server++;
417 sntp_current_server = 0;
419 if (sntp_servers[sntp_current_server].kod_received) {
425 || (sntp_servers[sntp_current_server].
name !=
NULL)
428 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
"sntp_try_next_server: Sending request to server %"U16_F"\n",
429 (
u16_t)sntp_current_server));
431 SNTP_RESET_RETRY_TIMEOUT();
438 sntp_current_server = old_server;
443sntp_kod_try_next_server(
void *
arg)
445 sntp_servers[sntp_current_server].kod_received = 1;
446 sntp_try_next_server(
arg);
451#define sntp_try_next_server sntp_retry
452#define sntp_kod_try_next_server sntp_retry
459 struct sntp_timestamps timestamps;
468#if SNTP_CHECK_RESPONSE >= 1
478 if (
p->tot_len == SNTP_MSG_LEN) {
485 if (stratum == SNTP_STRATUM_KOD) {
488 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
"sntp_recv: Received Kiss-of-Death\n"));
491#if SNTP_CHECK_RESPONSE >= 2
493 if (timestamps.orig.sec != sntp_last_timestamp_sent.sec ||
494 timestamps.orig.frac != sntp_last_timestamp_sent.frac) {
496 (
"sntp_recv: Invalid originate timestamp in response\n"));
511 LWIP_DEBUGF(SNTP_DEBUG_WARN, (
"sntp_recv: Invalid packet length: %"U16_F"\n",
p->tot_len));
514#if SNTP_CHECK_RESPONSE >= 1
525 sntp_process(×tamps);
527#if SNTP_MONITOR_SERVER_REACHABILITY
529 sntp_servers[sntp_current_server].reachability |= 1;
533 u32_t sntp_update_delay;
534 sys_untimeout(sntp_try_next_server,
NULL);
535 sys_untimeout(sntp_request,
NULL);
538 SNTP_RESET_RETRY_TIMEOUT();
541 sys_timeout(sntp_update_delay, sntp_request,
NULL);
542 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
"sntp_recv: Scheduled next time request: %"U32_F" ms\n",
545 }
else if (
err == SNTP_ERR_KOD) {
549 sntp_kod_try_next_server(
NULL);
561sntp_send_request(
const ip_addr_t *server_addr)
569 struct sntp_msg *sntpmsg = (
struct sntp_msg *)
p->payload;
570 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
"sntp_send_request: Sending request to server\n"));
572 sntp_initialize_request(sntpmsg);
574 udp_sendto(sntp_pcb,
p, server_addr,
SNTP_PORT);
577#if SNTP_MONITOR_SERVER_REACHABILITY
579 sntp_servers[sntp_current_server].reachability <<= 1;
582 sys_untimeout(sntp_try_next_server,
NULL);
584#if SNTP_CHECK_RESPONSE >= 1
589 LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, (
"sntp_send_request: Out of memory, trying again in %"U32_F" ms\n",
592 sys_untimeout(sntp_request,
NULL);
607 if (ipaddr !=
NULL) {
609 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
"sntp_dns_found: Server address resolved, sending request\n"));
610 sntp_servers[sntp_current_server].addr = *ipaddr;
611 sntp_send_request(ipaddr);
614 LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, (
"sntp_dns_found: Failed to resolve server address resolved, trying next server\n"));
615 sntp_try_next_server(
NULL);
626sntp_request(
void *
arg)
635 if (sntp_servers[sntp_current_server].
name) {
638 err = dns_gethostbyname(sntp_servers[sntp_current_server].
name, &sntp_server_address,
639 sntp_dns_found,
NULL);
642 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
"sntp_request: Waiting for server address to be resolved.\n"));
645 sntp_servers[sntp_current_server].addr = sntp_server_address;
650 sntp_server_address = sntp_servers[sntp_current_server].addr;
655 LWIP_DEBUGF(SNTP_DEBUG_TRACE, (
"sntp_request: current server address is %s\n",
657 sntp_send_request(&sntp_server_address);
660 LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, (
"sntp_request: Invalid server address, trying next server.\n"));
661 sys_untimeout(sntp_try_next_server,
NULL);
675 LWIP_DEBUGF(SNTP_DEBUG_TRACE, (
"sntp_init: SNTP initialised\n"));
677#ifdef SNTP_SERVER_ADDRESS
679 sntp_setservername(0, SNTP_SERVER_ADDRESS);
681#error SNTP_SERVER_ADDRESS string not supported SNTP_SERVER_DNS==0
685 if (sntp_pcb ==
NULL) {
687 LWIP_ASSERT(
"Failed to allocate udp pcb for sntp client", sntp_pcb !=
NULL);
688 if (sntp_pcb !=
NULL) {
689 udp_recv(sntp_pcb, sntp_recv,
NULL);
692 SNTP_RESET_RETRY_TIMEOUT();
693#if SNTP_STARTUP_DELAY
714 if (sntp_pcb !=
NULL) {
715#if SNTP_MONITOR_SERVER_REACHABILITY
718 sntp_servers[
i].reachability = 0;
721 sys_untimeout(sntp_request,
NULL);
722 sys_untimeout(sntp_try_next_server,
NULL);
723 udp_remove(sntp_pcb);
734 return (sntp_pcb !=
NULL) ? 1 : 0;
747 LWIP_ASSERT(
"Operating mode must not be set while SNTP client is running", sntp_pcb ==
NULL);
748 sntp_opmode = operating_mode;
761#if SNTP_MONITOR_SERVER_REACHABILITY
772 return sntp_servers[
idx].reachability;
778#if SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6
786 u8_t new_mode = set_servers_from_dhcp ? 1 : 0;
788 if (sntp_set_servers_from_dhcp != new_mode) {
789 sntp_set_servers_from_dhcp = new_mode;
807 sntp_servers[
idx].addr = (*server);
808#if SNTP_SUPPORT_MULTIPLE_SERVERS
809 sntp_servers[
idx].kod_received = 0;
820#if LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP
830 LWIP_DEBUGF(SNTP_DEBUG_TRACE, (
"sntp: %s %u.%u.%u.%u as NTP server #%u via DHCP\n",
831 (sntp_set_servers_from_dhcp ?
"Got" :
"Rejected"),
833 if (sntp_set_servers_from_dhcp &&
num) {
847#if LWIP_IPV6_DHCP6 && SNTP_GET_SERVERS_FROM_DHCPV6
855dhcp6_set_ntp_servers(
u8_t num_ntp_servers,
ip_addr_t* ntp_server_addrs)
857 LWIP_DEBUGF(SNTP_DEBUG_TRACE, (
"sntp: %s %u NTP server(s) via DHCPv6\n",
858 (sntp_set_servers_from_dhcp ?
"Got" :
"Rejected"),
860 if (sntp_set_servers_from_dhcp && num_ntp_servers) {
863 LWIP_DEBUGF(SNTP_DEBUG_TRACE, (
"sntp: NTP server %u: %s\n",
886 return &sntp_servers[
idx].addr;
902#if SNTP_SUPPORT_MULTIPLE_SERVERS
904 return sntp_servers[
idx].kod_received;
925#if SNTP_SUPPORT_MULTIPLE_SERVERS
926 sntp_servers[
idx].kod_received = 0;
942 return sntp_servers[
idx].name;
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
#define PACK_STRUCT_STRUCT
#define LWIP_DEBUGF(debug, message)
#define LWIP_ASSERT(message, assertion)
#define ip_set_option(pcb, opt)
GLenum const GLvoid * addr
GLenum GLint GLint * precision
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define LWIP_UNUSED_ARG(x)
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_FLD_8(x)
#define PACK_STRUCT_FIELD(x)
#define LWIP_ASSERT_CORE_LOCKED()
u8_t pbuf_get_at(const struct pbuf *p, u16_t offset)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u8_t pbuf_free(struct pbuf *p)
u16_t pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
#define SNTP_RECV_TIMEOUT
#define SNTP_RETRY_TIMEOUT
#define SNTP_UPDATE_DELAY
#define SNTP_STARTUP_DELAY_FUNC
#define SNTP_RETRY_TIMEOUT_MAX
#define ip_addr_isany(ipaddr)
#define ip_addr_eq(addr1, addr2)
#define ip_addr_copy(dest, src)
#define ip_addr_set_zero(ipaddr)
#define ip_addr_isany_val(ipaddr)
#define ipaddr_ntoa(ipaddr)
#define SNTP_OPMODE_LISTENONLY
u8_t sntp_getkodreceived(u8_t idx)
void sntp_setoperatingmode(u8_t operating_mode)
const ip_addr_t * sntp_getserver(u8_t idx)
void sntp_setserver(u8_t idx, const ip_addr_t *addr)
u8_t sntp_getoperatingmode(void)
#define sntp_servermode_dhcp(x)
static rfbScreenInfoPtr server