64 #if SNTP_MAX_SERVERS > 1 65 #define SNTP_SUPPORT_MULTIPLE_SERVERS 1 67 #define SNTP_SUPPORT_MULTIPLE_SERVERS 0 70 #if (SNTP_UPDATE_DELAY < 15000) && !defined(SNTP_SUPPRESS_DELAY_CHECK) 71 #error "SNTPv4 RFC 4330 enforces a minimum update time of 15 seconds (define SNTP_SUPPRESS_DELAY_CHECK to disable this error)!" 75 #ifdef SNTP_SET_SYSTEM_TIME_US 76 #define SNTP_CALC_TIME_US 1 77 #define SNTP_RECEIVE_TIME_SIZE 2 79 #define SNTP_SET_SYSTEM_TIME_US(sec, us) 80 #define SNTP_CALC_TIME_US 0 81 #define SNTP_RECEIVE_TIME_SIZE 1 86 #define SNTP_DEBUG_TRACE (SNTP_DEBUG | LWIP_DBG_TRACE) 87 #define SNTP_DEBUG_STATE (SNTP_DEBUG | LWIP_DBG_STATE) 88 #define SNTP_DEBUG_WARN (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING) 89 #define SNTP_DEBUG_WARN_STATE (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE) 90 #define SNTP_DEBUG_SERIOUS (SNTP_DEBUG | LWIP_DBG_LEVEL_SERIOUS) 92 #define SNTP_ERR_KOD 1 95 #define SNTP_MSG_LEN 48 97 #define SNTP_OFFSET_LI_VN_MODE 0 98 #define SNTP_LI_MASK 0xC0 99 #define SNTP_LI_NO_WARNING 0x00 100 #define SNTP_LI_LAST_MINUTE_61_SEC 0x01 101 #define SNTP_LI_LAST_MINUTE_59_SEC 0x02 102 #define SNTP_LI_ALARM_CONDITION 0x03 104 #define SNTP_VERSION_MASK 0x38 105 #define SNTP_VERSION (4<<3) 107 #define SNTP_MODE_MASK 0x07 108 #define SNTP_MODE_CLIENT 0x03 109 #define SNTP_MODE_SERVER 0x04 110 #define SNTP_MODE_BROADCAST 0x05 112 #define SNTP_OFFSET_STRATUM 1 113 #define SNTP_STRATUM_KOD 0x00 115 #define SNTP_OFFSET_ORIGINATE_TIME 24 116 #define SNTP_OFFSET_RECEIVE_TIME 32 117 #define SNTP_OFFSET_TRANSMIT_TIME 40 120 #define DIFF_SEC_1900_1970 (2208988800UL) 122 #define DIFF_SEC_1970_2036 (2085978496UL) 132 #ifdef PACK_STRUCT_USE_INCLUDES 150 #ifdef PACK_STRUCT_USE_INCLUDES 155 static void sntp_request(
void *arg);
158 static u8_t sntp_opmode;
161 static struct udp_pcb* sntp_pcb;
171 #if SNTP_GET_SERVERS_FROM_DHCP 172 static u8_t sntp_set_servers_from_dhcp;
174 #if SNTP_SUPPORT_MULTIPLE_SERVERS 176 static u8_t sntp_current_server;
178 #define sntp_current_server 0 181 #if SNTP_RETRY_TIMEOUT_EXP 182 #define SNTP_RESET_RETRY_TIMEOUT() sntp_retry_timeout = SNTP_RETRY_TIMEOUT 184 static u32_t sntp_retry_timeout;
186 #define SNTP_RESET_RETRY_TIMEOUT() 187 #define sntp_retry_timeout SNTP_RETRY_TIMEOUT 190 #if SNTP_CHECK_RESPONSE >= 1 192 static ip_addr_t sntp_last_server_address;
195 #if SNTP_CHECK_RESPONSE >= 2 198 static u32_t sntp_last_timestamp_sent[2];
205 sntp_process(
u32_t *receive_timestamp)
211 int is_1900_based = ((rx_secs & 0x80000000) != 0);
212 u32_t t = is_1900_based ? (rx_secs - DIFF_SEC_1900_1970) : (rx_secs + DIFF_SEC_1970_2036);
215 #if SNTP_CALC_TIME_US 216 u32_t us =
ntohl(receive_timestamp[1]) / 4295;
217 SNTP_SET_SYSTEM_TIME_US(t, us);
219 LWIP_DEBUGF(SNTP_DEBUG_TRACE, (
"sntp_process: %s, %"U32_F" us", ctime(&tim), us));
226 LWIP_DEBUGF(SNTP_DEBUG_TRACE, (
"sntp_process: %s", ctime(&tim)));
235 sntp_initialize_request(
struct sntp_msg *req)
237 memset(req, 0, SNTP_MSG_LEN);
238 req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT;
240 #if SNTP_CHECK_RESPONSE >= 2 242 u32_t sntp_time_sec, sntp_time_us;
245 sntp_last_timestamp_sent[0] =
htonl(sntp_time_sec + DIFF_SEC_1900_1970);
246 req->transmit_timestamp[0] = sntp_last_timestamp_sent[0];
248 sntp_last_timestamp_sent[1] =
htonl(sntp_time_us);
249 req->transmit_timestamp[1] = sntp_last_timestamp_sent[1];
260 sntp_retry(
void* arg)
264 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
"sntp_retry: Next request will be sent in %"U32_F" ms\n",
265 sntp_retry_timeout));
270 #if SNTP_RETRY_TIMEOUT_EXP 272 u32_t new_retry_timeout;
274 new_retry_timeout = sntp_retry_timeout << 1;
277 (new_retry_timeout > sntp_retry_timeout)) {
278 sntp_retry_timeout = new_retry_timeout;
284 #if SNTP_SUPPORT_MULTIPLE_SERVERS 294 sntp_try_next_server(
void* arg)
299 old_server = sntp_current_server;
301 sntp_current_server++;
302 if (sntp_current_server >= SNTP_MAX_SERVERS) {
303 sntp_current_server = 0;
307 || (sntp_servers[sntp_current_server].name !=
NULL)
310 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
"sntp_try_next_server: Sending request to server %"U16_F"\n",
311 (
u16_t)sntp_current_server));
313 SNTP_RESET_RETRY_TIMEOUT();
320 sntp_current_server = old_server;
325 #define sntp_try_next_server sntp_retry 330 sntp_recv(
void *arg,
struct udp_pcb* pcb,
struct pbuf *p,
const ip_addr_t *addr,
u16_t port)
334 u32_t receive_timestamp[SNTP_RECEIVE_TIME_SIZE];
345 #if SNTP_CHECK_RESPONSE >= 1 355 if (p->
tot_len == SNTP_MSG_LEN) {
357 mode &= SNTP_MODE_MASK;
362 if (stratum == SNTP_STRATUM_KOD) {
365 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
"sntp_recv: Received Kiss-of-Death\n"));
367 #if SNTP_CHECK_RESPONSE >= 2 369 u32_t originate_timestamp[2];
371 if ((originate_timestamp[0] != sntp_last_timestamp_sent[0]) ||
372 (originate_timestamp[1] != sntp_last_timestamp_sent[1]))
374 LWIP_DEBUGF(SNTP_DEBUG_WARN, (
"sntp_recv: Invalid originate timestamp in response\n"));
381 pbuf_copy_partial(p, &receive_timestamp, SNTP_RECEIVE_TIME_SIZE * 4, SNTP_OFFSET_TRANSMIT_TIME);
393 #if SNTP_CHECK_RESPONSE >= 1 401 sntp_process(receive_timestamp);
406 SNTP_RESET_RETRY_TIMEOUT();
409 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
"sntp_recv: Scheduled next time request: %"U32_F" ms\n",
415 if (err == SNTP_ERR_KOD) {
417 sntp_try_next_server(
NULL);
431 sntp_send_request(
ip_addr_t *server_addr)
436 struct sntp_msg *sntpmsg = (
struct sntp_msg *)p->
payload;
437 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
"sntp_send_request: Sending request to server\n"));
439 sntp_initialize_request(sntpmsg);
441 udp_sendto(sntp_pcb, p, server_addr,
SNTP_PORT);
446 #if SNTP_CHECK_RESPONSE >= 1 448 ip_addr_set(&sntp_last_server_address, server_addr);
451 LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, (
"sntp_send_request: Out of memory, trying again in %"U32_F" ms\n",
463 sntp_dns_found(
const char* hostname,
ip_addr_t *ipaddr,
void *arg)
468 if (ipaddr !=
NULL) {
470 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
"sntp_dns_found: Server address resolved, sending request\n"));
471 sntp_send_request(ipaddr);
474 LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, (
"sntp_dns_found: Failed to resolve server address resolved, trying next server\n"));
475 sntp_try_next_server(
NULL);
486 sntp_request(
void *arg)
495 if (sntp_servers[sntp_current_server].name) {
498 err = dns_gethostbyname(sntp_servers[sntp_current_server].name, &sntp_server_address,
499 sntp_dns_found,
NULL);
502 LWIP_DEBUGF(SNTP_DEBUG_STATE, (
"sntp_request: Waiting for server address to be resolved.\n"));
504 }
else if (err ==
ERR_OK) {
505 sntp_servers[sntp_current_server].addr = sntp_server_address;
510 sntp_server_address = sntp_servers[sntp_current_server].addr;
515 LWIP_DEBUGF(SNTP_DEBUG_TRACE, (
"sntp_request: current server address is %s\n",
517 sntp_send_request(&sntp_server_address);
520 LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, (
"sntp_request: Invalid server address, trying next server.\n"));
532 #ifdef SNTP_SERVER_ADDRESS 534 sntp_setservername(0, SNTP_SERVER_ADDRESS);
536 #error SNTP_SERVER_ADDRESS string not supported SNTP_SERVER_DNS==0 540 if (sntp_pcb ==
NULL) {
541 sntp_pcb = udp_new();
542 LWIP_ASSERT(
"Failed to allocate udp pcb for sntp client", sntp_pcb !=
NULL);
543 if (sntp_pcb !=
NULL) {
544 udp_recv(sntp_pcb, sntp_recv,
NULL);
547 SNTP_RESET_RETRY_TIMEOUT();
548 #if SNTP_STARTUP_DELAY 555 udp_bind(sntp_pcb, IP_ADDR_ANY,
SNTP_PORT);
567 if (sntp_pcb !=
NULL) {
569 udp_remove(sntp_pcb);
582 LWIP_ASSERT(
"Operating mode must not be set while SNTP client is running", sntp_pcb ==
NULL);
583 sntp_opmode = operating_mode;
595 #if SNTP_GET_SERVERS_FROM_DHCP 603 u8_t new_mode = set_servers_from_dhcp ? 1 : 0;
604 if (sntp_set_servers_from_dhcp != new_mode) {
605 sntp_set_servers_from_dhcp = new_mode;
619 if (idx < SNTP_MAX_SERVERS) {
620 if (server !=
NULL) {
621 sntp_servers[
idx].addr = (*server);
631 #if LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP 639 dhcp_set_ntp_servers(
u8_t num,
const ip4_addr_t *server)
641 LWIP_DEBUGF(SNTP_DEBUG_TRACE, (
"sntp: %s %u.%u.%u.%u as NTP server #%u via DHCP\n",
642 (sntp_set_servers_from_dhcp ?
"Got" :
"Rejected"),
643 ip4_addr1(server), ip4_addr2(server), ip4_addr3(server), ip4_addr4(server), num));
644 if (sntp_set_servers_from_dhcp && num) {
646 for (i = 0; (i < num) && (i < SNTP_MAX_SERVERS); i++) {
648 ip_addr_copy_from_ip4(addr, server[i]);
668 if (idx < SNTP_MAX_SERVERS) {
669 return sntp_servers[
idx].addr;
682 sntp_setservername(
u8_t idx,
char *server)
684 if (idx < SNTP_MAX_SERVERS) {
685 sntp_servers[
idx].name = server;
697 sntp_getservername(
u8_t idx)
699 if (idx < SNTP_MAX_SERVERS) {
700 return sntp_servers[
idx].name;
#define SNTP_RETRY_TIMEOUT_MAX
#define SNTP_UPDATE_DELAY
#define SNTP_OPMODE_LISTENONLY
#define ip_addr_isany(ipaddr)
#define PACK_STRUCT_STRUCT
#define ip_addr_isany_val(ipaddr)
ip_addr_t sntp_getserver(u8_t idx)
#define PACK_STRUCT_FLD_8(x)
void sntp_setserver(u8_t idx, const ip_addr_t *addr)
#define PACK_STRUCT_FIELD(x)
#define SNTP_RECV_TIMEOUT
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u8_t pbuf_free(struct pbuf *p)
#define sntp_servermode_dhcp(x)
void sntp_setoperatingmode(u8_t operating_mode)
void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg)
#define SNTP_SET_SYSTEM_TIME(sec)
#define ip_addr_cmp(addr1, addr2)
#define LWIP_ASSERT(message, assertion)
#define ip_addr_set(dest, src)
#define SNTP_GET_SYSTEM_TIME(sec, us)
#define PACK_STRUCT_BEGIN
#define ipaddr_ntoa(ipaddr)
u16_t pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
#define SNTP_RETRY_TIMEOUT
#define ip_addr_set_zero(ipaddr)
u8_t sntp_getoperatingmode(void)
#define LWIP_DEBUGF(debug, message)
#define ip_set_option(pcb, opt)
#define LWIP_UNUSED_ARG(x)
void sys_untimeout(sys_timeout_handler handler, void *arg)
#define SNTP_STARTUP_DELAY_FUNC