Message ID | 20250521151516.16729-3-jerome.forissier@linaro.org |
---|---|
State | New |
Headers | show |
Series | sntp for NET_LWIP | expand |
Am 21. Mai 2025 17:14:42 MESZ schrieb Jerome Forissier <jerome.forissier@linaro.org>: >Implement the sntp command when NET_LWIP=y. > >Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> >--- > > cmd/Kconfig | 13 ++-- > cmd/net-lwip.c | 5 ++ > include/net-common.h | 11 ++++ > lib/lwip/Makefile | 1 + > lib/lwip/u-boot/arch/cc.h | 4 ++ > lib/lwip/u-boot/lwipopts.h | 4 ++ > net/lwip/Makefile | 1 + > net/lwip/sntp.c | 128 +++++++++++++++++++++++++++++++++++++ > 8 files changed, 161 insertions(+), 6 deletions(-) > create mode 100644 net/lwip/sntp.c > >diff --git a/cmd/Kconfig b/cmd/Kconfig >index f21d27cb27f..58f629e1c34 100644 >--- a/cmd/Kconfig >+++ b/cmd/Kconfig >@@ -2061,12 +2061,6 @@ config CMD_CDP > and to retrieve configuration data including the VLAN id using the > proprietary Cisco Discovery Protocol (CDP). > >-config CMD_SNTP >- bool "sntp" >- select PROT_UDP >- help >- Synchronize RTC via network >- > config CMD_LINK_LOCAL > bool "linklocal" > depends on (LIB_RAND || LIB_HW_RAND) >@@ -2144,6 +2138,13 @@ config CMD_PING > help > Send ICMP ECHO_REQUEST to network host > >+config CMD_SNTP The command should depend on RTC support. >+ bool "sntp" >+ select PROT_UDP if NET >+ select PROT_UDP_LWIP if NET_LWIP >+ help >+ Synchronize RTC via network >+ > config CMD_TFTPBOOT > bool "tftp" > select PROT_UDP_LWIP if NET_LWIP >diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c >index cecf8d02555..2ffee64f97e 100644 >--- a/cmd/net-lwip.c >+++ b/cmd/net-lwip.c Please, put every command into a separate file instead of duplicating the #ifdef chaos of the old network stack. >@@ -21,6 +21,11 @@ U_BOOT_CMD(tftpboot, 3, 0, do_tftpb, > "[loadAddress] [[hostIPaddr:]bootfilename]"); > #endif > >+#if defined(CONFIG_CMD_SNTP) >+U_BOOT_CMD(sntp, 2, 1, do_sntp, "synchronize RTC via network", >+ "[NTP server IP]"); >+#endif Why wouldn't we support server names ( e.g. 0.de.pool.ntp.org) here if we have DNS enabled? Please, add the missing documentation change for the commands. Best regards Heinrich >+ > #if defined(CONFIG_CMD_DNS) > U_BOOT_CMD(dns, 3, 1, do_dns, "lookup the IP of a hostname", > "hostname [envvar]"); >diff --git a/include/net-common.h b/include/net-common.h >index a021bf503ff..b06cafb497e 100644 >--- a/include/net-common.h >+++ b/include/net-common.h >@@ -505,6 +505,17 @@ int dhcp_run(ulong addr, const char *fname, bool autoload); > */ > int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); > >+/** >+ * do_sntp - Run the sntp command >+ * >+ * @cmdtp: Unused >+ * @flag: Command flags (CMD_FLAG_...) >+ * @argc: Number of arguments >+ * @argv: List of arguments >+ * Return: result (see enum command_ret_t) >+ */ >+int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); >+ > /** > * do_tftpb - Run the tftpboot command > * >diff --git a/lib/lwip/Makefile b/lib/lwip/Makefile >index e9e8caee93a..c3f0e916f66 100644 >--- a/lib/lwip/Makefile >+++ b/lib/lwip/Makefile >@@ -13,6 +13,7 @@ obj-y += \ > lwip/src/api/sockets.o \ > lwip/src/api/tcpip.o \ > lwip/src/apps/http/http_client.o \ >+ lwip/src/apps/sntp/sntp.o \ > lwip/src/apps/tftp/tftp.o \ > lwip/src/core/altcp_alloc.o \ > lwip/src/core/altcp.o \ >diff --git a/lib/lwip/u-boot/arch/cc.h b/lib/lwip/u-boot/arch/cc.h >index 6104c296f6f..f91127ac565 100644 >--- a/lib/lwip/u-boot/arch/cc.h >+++ b/lib/lwip/u-boot/arch/cc.h >@@ -43,4 +43,8 @@ > #define BYTE_ORDER BIG_ENDIAN > #endif > >+#define SNTP_STARTUP_DELAY 0 >+void sntp_set_system_time(uint32_t sec); >+#define SNTP_SET_SYSTEM_TIME(sec) sntp_set_system_time(sec) >+ > #endif /* LWIP_ARCH_CC_H */ >diff --git a/lib/lwip/u-boot/lwipopts.h b/lib/lwip/u-boot/lwipopts.h >index edac74ff7a2..14ba7bd7ae2 100644 >--- a/lib/lwip/u-boot/lwipopts.h >+++ b/lib/lwip/u-boot/lwipopts.h >@@ -162,4 +162,8 @@ > #define LWIP_ALTCP_TLS_MBEDTLS 1 > #endif > >+#if defined(CONFIG_CMD_SNTP) >+#define LWIP_DHCP_GET_NTP_SRV 1 >+#endif >+ > #endif /* LWIP_UBOOT_LWIPOPTS_H */ >diff --git a/net/lwip/Makefile b/net/lwip/Makefile >index 5df222589b8..5bb98dc4d98 100644 >--- a/net/lwip/Makefile >+++ b/net/lwip/Makefile >@@ -4,6 +4,7 @@ obj-$(CONFIG_$(PHASE_)DM_ETH) += net-lwip.o > obj-$(CONFIG_CMD_DHCP) += dhcp.o > obj-$(CONFIG_CMD_DNS) += dns.o > obj-$(CONFIG_CMD_PING) += ping.o >+obj-$(CONFIG_CMD_SNTP) += sntp.o > obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o > obj-$(CONFIG_WGET) += wget.o > >diff --git a/net/lwip/sntp.c b/net/lwip/sntp.c >new file mode 100644 >index 00000000000..3b2bc3c679d >--- /dev/null >+++ b/net/lwip/sntp.c >@@ -0,0 +1,128 @@ >+// SPDX-License-Identifier: GPL-2.0+ >+/* Copyright (C) 2025 Linaro Ltd. */ >+ >+#include <command.h> >+#include <console.h> >+#include <dm/device.h> >+#include <lwip/apps/sntp.h> >+#include <lwip/timeouts.h> >+#include <net.h> >+ >+#define SNTP_TIMEOUT 10000 >+ >+static enum done_state { >+ NOT_DONE = 0, >+ SUCCESS, >+ ABORTED, >+ TIMED_OUT >+} sntp_state; >+ >+static void no_response(void *arg) >+{ >+ sntp_state = TIMED_OUT; >+} >+ >+/* Called by lwIP via the SNTP_SET_SYSTEM_TIME() macro */ >+void sntp_set_system_time(uint32_t seconds) >+{ >+ char *toff; >+ int net_ntp_time_offset = 0; >+ >+ toff = env_get("timeoffset"); >+ if (toff) >+ net_ntp_time_offset = simple_strtol(toff, NULL, 10); >+ >+ net_sntp_set_rtc(seconds + net_ntp_time_offset); >+ sntp_state = SUCCESS; >+} >+ >+static bool ntp_server_known(void) >+{ >+ int i; >+ >+ for (i = 0; i < SNTP_MAX_SERVERS; i++) { >+ const ip_addr_t *ip = sntp_getserver(i); >+ >+ if (ip && ip->addr) >+ return true; >+ } >+ >+ return false; >+} >+ >+static int sntp_loop(struct udevice *udev, ip_addr_t *srvip) >+{ >+ struct netif *netif; >+ >+ netif = net_lwip_new_netif(udev); >+ if (!netif) >+ return -1; >+ >+ sntp_state = NOT_DONE; >+ >+ sntp_setoperatingmode(SNTP_OPMODE_POLL); >+ sntp_servermode_dhcp(CONFIG_IS_ENABLED(CMD_DHCP)); >+ if (srvip) { >+ sntp_setserver(0, srvip); >+ } else { >+ if (!ntp_server_known()) { >+ log_err("error: ntpserverip not set\n"); >+ return -1; >+ } >+ } >+ sntp_init(); >+ >+ sys_timeout(SNTP_TIMEOUT, no_response, NULL); >+ while (sntp_state == NOT_DONE) { >+ net_lwip_rx(udev, netif); >+ sys_check_timeouts(); >+ if (ctrlc()) { >+ printf("\nAbort\n"); >+ sntp_state = ABORTED; >+ break; >+ } >+ } >+ sys_untimeout(no_response, NULL); >+ >+ sntp_stop(); >+ net_lwip_remove_netif(netif); >+ >+ if (sntp_state == SUCCESS) >+ return 0; >+ >+ return -1; >+} >+ >+int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) >+{ >+ ip_addr_t *srvip = NULL; >+ char *server_ip = NULL; >+ ip_addr_t ipaddr; >+ >+ switch (argc) { >+ case 1: >+ server_ip = env_get("ntpserverip"); >+ break; >+ case 2: >+ server_ip = argv[1]; >+ break; >+ default: >+ return CMD_RET_USAGE; >+ } >+ >+ if (server_ip) { >+ if (!ipaddr_aton(server_ip, &ipaddr)) { >+ log_err("error: ipaddr_aton\n"); >+ return CMD_RET_FAILURE; >+ } >+ srvip = &ipaddr; >+ } >+ >+ if (net_lwip_eth_start() < 0) >+ return CMD_RET_FAILURE; >+ >+ if (sntp_loop(eth_get_dev(), srvip) < 0) >+ return CMD_RET_FAILURE; >+ >+ return CMD_RET_SUCCESS; >+}
Am 2. Juni 2025 23:23:08 MESZ schrieb Heinrich Schuchardt <xypron.glpk@gmx.de>: >Am 21. Mai 2025 17:14:42 MESZ schrieb Jerome Forissier <jerome.forissier@linaro.org>: >>Implement the sntp command when NET_LWIP=y. https://datatracker.ietf.org/doc/rfc5905/ describes that on Feb 7th, 2036 the 32 bit seconds field wraps around and era 1 starts. Does our code consider this? Best regards Heinrich >> >>Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> >>--- >> >> cmd/Kconfig | 13 ++-- >> cmd/net-lwip.c | 5 ++ >> include/net-common.h | 11 ++++ >> lib/lwip/Makefile | 1 + >> lib/lwip/u-boot/arch/cc.h | 4 ++ >> lib/lwip/u-boot/lwipopts.h | 4 ++ >> net/lwip/Makefile | 1 + >> net/lwip/sntp.c | 128 +++++++++++++++++++++++++++++++++++++ >> 8 files changed, 161 insertions(+), 6 deletions(-) >> create mode 100644 net/lwip/sntp.c >> >>diff --git a/cmd/Kconfig b/cmd/Kconfig >>index f21d27cb27f..58f629e1c34 100644 >>--- a/cmd/Kconfig >>+++ b/cmd/Kconfig >>@@ -2061,12 +2061,6 @@ config CMD_CDP >> and to retrieve configuration data including the VLAN id using the >> proprietary Cisco Discovery Protocol (CDP). >> >>-config CMD_SNTP >>- bool "sntp" >>- select PROT_UDP >>- help >>- Synchronize RTC via network >>- >> config CMD_LINK_LOCAL >> bool "linklocal" >> depends on (LIB_RAND || LIB_HW_RAND) >>@@ -2144,6 +2138,13 @@ config CMD_PING >> help >> Send ICMP ECHO_REQUEST to network host >> >>+config CMD_SNTP > >The command should depend on RTC support. > >>+ bool "sntp" >>+ select PROT_UDP if NET >>+ select PROT_UDP_LWIP if NET_LWIP >>+ help >>+ Synchronize RTC via network >>+ >> config CMD_TFTPBOOT >> bool "tftp" >> select PROT_UDP_LWIP if NET_LWIP >>diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c >>index cecf8d02555..2ffee64f97e 100644 >>--- a/cmd/net-lwip.c >>+++ b/cmd/net-lwip.c > >Please, put every command into a separate file instead of duplicating the #ifdef chaos of the old network stack. > >>@@ -21,6 +21,11 @@ U_BOOT_CMD(tftpboot, 3, 0, do_tftpb, >> "[loadAddress] [[hostIPaddr:]bootfilename]"); >> #endif >> >>+#if defined(CONFIG_CMD_SNTP) >>+U_BOOT_CMD(sntp, 2, 1, do_sntp, "synchronize RTC via network", >>+ "[NTP server IP]"); >>+#endif > >Why wouldn't we support server names ( e.g. 0.de.pool.ntp.org) here if we have DNS enabled? > >Please, add the missing documentation change for the commands. > >Best regards > >Heinrich > > >>+ >> #if defined(CONFIG_CMD_DNS) >> U_BOOT_CMD(dns, 3, 1, do_dns, "lookup the IP of a hostname", >> "hostname [envvar]"); >>diff --git a/include/net-common.h b/include/net-common.h >>index a021bf503ff..b06cafb497e 100644 >>--- a/include/net-common.h >>+++ b/include/net-common.h >>@@ -505,6 +505,17 @@ int dhcp_run(ulong addr, const char *fname, bool autoload); >> */ >> int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); >> >>+/** >>+ * do_sntp - Run the sntp command >>+ * >>+ * @cmdtp: Unused >>+ * @flag: Command flags (CMD_FLAG_...) >>+ * @argc: Number of arguments >>+ * @argv: List of arguments >>+ * Return: result (see enum command_ret_t) >>+ */ >>+int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); >>+ >> /** >> * do_tftpb - Run the tftpboot command >> * >>diff --git a/lib/lwip/Makefile b/lib/lwip/Makefile >>index e9e8caee93a..c3f0e916f66 100644 >>--- a/lib/lwip/Makefile >>+++ b/lib/lwip/Makefile >>@@ -13,6 +13,7 @@ obj-y += \ >> lwip/src/api/sockets.o \ >> lwip/src/api/tcpip.o \ >> lwip/src/apps/http/http_client.o \ >>+ lwip/src/apps/sntp/sntp.o \ >> lwip/src/apps/tftp/tftp.o \ >> lwip/src/core/altcp_alloc.o \ >> lwip/src/core/altcp.o \ >>diff --git a/lib/lwip/u-boot/arch/cc.h b/lib/lwip/u-boot/arch/cc.h >>index 6104c296f6f..f91127ac565 100644 >>--- a/lib/lwip/u-boot/arch/cc.h >>+++ b/lib/lwip/u-boot/arch/cc.h >>@@ -43,4 +43,8 @@ >> #define BYTE_ORDER BIG_ENDIAN >> #endif >> >>+#define SNTP_STARTUP_DELAY 0 >>+void sntp_set_system_time(uint32_t sec); >>+#define SNTP_SET_SYSTEM_TIME(sec) sntp_set_system_time(sec) >>+ >> #endif /* LWIP_ARCH_CC_H */ >>diff --git a/lib/lwip/u-boot/lwipopts.h b/lib/lwip/u-boot/lwipopts.h >>index edac74ff7a2..14ba7bd7ae2 100644 >>--- a/lib/lwip/u-boot/lwipopts.h >>+++ b/lib/lwip/u-boot/lwipopts.h >>@@ -162,4 +162,8 @@ >> #define LWIP_ALTCP_TLS_MBEDTLS 1 >> #endif >> >>+#if defined(CONFIG_CMD_SNTP) >>+#define LWIP_DHCP_GET_NTP_SRV 1 >>+#endif >>+ >> #endif /* LWIP_UBOOT_LWIPOPTS_H */ >>diff --git a/net/lwip/Makefile b/net/lwip/Makefile >>index 5df222589b8..5bb98dc4d98 100644 >>--- a/net/lwip/Makefile >>+++ b/net/lwip/Makefile >>@@ -4,6 +4,7 @@ obj-$(CONFIG_$(PHASE_)DM_ETH) += net-lwip.o >> obj-$(CONFIG_CMD_DHCP) += dhcp.o >> obj-$(CONFIG_CMD_DNS) += dns.o >> obj-$(CONFIG_CMD_PING) += ping.o >>+obj-$(CONFIG_CMD_SNTP) += sntp.o >> obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o >> obj-$(CONFIG_WGET) += wget.o >> >>diff --git a/net/lwip/sntp.c b/net/lwip/sntp.c >>new file mode 100644 >>index 00000000000..3b2bc3c679d >>--- /dev/null >>+++ b/net/lwip/sntp.c >>@@ -0,0 +1,128 @@ >>+// SPDX-License-Identifier: GPL-2.0+ >>+/* Copyright (C) 2025 Linaro Ltd. */ >>+ >>+#include <command.h> >>+#include <console.h> >>+#include <dm/device.h> >>+#include <lwip/apps/sntp.h> >>+#include <lwip/timeouts.h> >>+#include <net.h> >>+ >>+#define SNTP_TIMEOUT 10000 >>+ >>+static enum done_state { >>+ NOT_DONE = 0, >>+ SUCCESS, >>+ ABORTED, >>+ TIMED_OUT >>+} sntp_state; >>+ >>+static void no_response(void *arg) >>+{ >>+ sntp_state = TIMED_OUT; >>+} >>+ >>+/* Called by lwIP via the SNTP_SET_SYSTEM_TIME() macro */ >>+void sntp_set_system_time(uint32_t seconds) >>+{ >>+ char *toff; >>+ int net_ntp_time_offset = 0; >>+ >>+ toff = env_get("timeoffset"); >>+ if (toff) >>+ net_ntp_time_offset = simple_strtol(toff, NULL, 10); >>+ >>+ net_sntp_set_rtc(seconds + net_ntp_time_offset); >>+ sntp_state = SUCCESS; >>+} >>+ >>+static bool ntp_server_known(void) >>+{ >>+ int i; >>+ >>+ for (i = 0; i < SNTP_MAX_SERVERS; i++) { >>+ const ip_addr_t *ip = sntp_getserver(i); >>+ >>+ if (ip && ip->addr) >>+ return true; >>+ } >>+ >>+ return false; >>+} >>+ >>+static int sntp_loop(struct udevice *udev, ip_addr_t *srvip) >>+{ >>+ struct netif *netif; >>+ >>+ netif = net_lwip_new_netif(udev); >>+ if (!netif) >>+ return -1; >>+ >>+ sntp_state = NOT_DONE; >>+ >>+ sntp_setoperatingmode(SNTP_OPMODE_POLL); >>+ sntp_servermode_dhcp(CONFIG_IS_ENABLED(CMD_DHCP)); >>+ if (srvip) { >>+ sntp_setserver(0, srvip); >>+ } else { >>+ if (!ntp_server_known()) { >>+ log_err("error: ntpserverip not set\n"); >>+ return -1; >>+ } >>+ } >>+ sntp_init(); >>+ >>+ sys_timeout(SNTP_TIMEOUT, no_response, NULL); >>+ while (sntp_state == NOT_DONE) { >>+ net_lwip_rx(udev, netif); >>+ sys_check_timeouts(); >>+ if (ctrlc()) { >>+ printf("\nAbort\n"); >>+ sntp_state = ABORTED; >>+ break; >>+ } >>+ } >>+ sys_untimeout(no_response, NULL); >>+ >>+ sntp_stop(); >>+ net_lwip_remove_netif(netif); >>+ >>+ if (sntp_state == SUCCESS) >>+ return 0; >>+ >>+ return -1; >>+} >>+ >>+int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) >>+{ >>+ ip_addr_t *srvip = NULL; >>+ char *server_ip = NULL; >>+ ip_addr_t ipaddr; >>+ >>+ switch (argc) { >>+ case 1: >>+ server_ip = env_get("ntpserverip"); >>+ break; >>+ case 2: >>+ server_ip = argv[1]; >>+ break; >>+ default: >>+ return CMD_RET_USAGE; >>+ } >>+ >>+ if (server_ip) { >>+ if (!ipaddr_aton(server_ip, &ipaddr)) { >>+ log_err("error: ipaddr_aton\n"); >>+ return CMD_RET_FAILURE; >>+ } >>+ srvip = &ipaddr; >>+ } >>+ >>+ if (net_lwip_eth_start() < 0) >>+ return CMD_RET_FAILURE; >>+ >>+ if (sntp_loop(eth_get_dev(), srvip) < 0) >>+ return CMD_RET_FAILURE; >>+ >>+ return CMD_RET_SUCCESS; >>+} >
Hi Heinrich, On 6/2/25 23:23, Heinrich Schuchardt wrote: > Am 21. Mai 2025 17:14:42 MESZ schrieb Jerome Forissier <jerome.forissier@linaro.org>: >> Implement the sntp command when NET_LWIP=y. >> >> Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> >> --- >> >> cmd/Kconfig | 13 ++-- >> cmd/net-lwip.c | 5 ++ >> include/net-common.h | 11 ++++ >> lib/lwip/Makefile | 1 + >> lib/lwip/u-boot/arch/cc.h | 4 ++ >> lib/lwip/u-boot/lwipopts.h | 4 ++ >> net/lwip/Makefile | 1 + >> net/lwip/sntp.c | 128 +++++++++++++++++++++++++++++++++++++ >> 8 files changed, 161 insertions(+), 6 deletions(-) >> create mode 100644 net/lwip/sntp.c >> >> diff --git a/cmd/Kconfig b/cmd/Kconfig >> index f21d27cb27f..58f629e1c34 100644 >> --- a/cmd/Kconfig >> +++ b/cmd/Kconfig >> @@ -2061,12 +2061,6 @@ config CMD_CDP >> and to retrieve configuration data including the VLAN id using the >> proprietary Cisco Discovery Protocol (CDP). >> >> -config CMD_SNTP >> - bool "sntp" >> - select PROT_UDP >> - help >> - Synchronize RTC via network >> - >> config CMD_LINK_LOCAL >> bool "linklocal" >> depends on (LIB_RAND || LIB_HW_RAND) >> @@ -2144,6 +2138,13 @@ config CMD_PING >> help >> Send ICMP ECHO_REQUEST to network host >> >> +config CMD_SNTP > > The command should depend on RTC support. > >> + bool "sntp" >> + select PROT_UDP if NET >> + select PROT_UDP_LWIP if NET_LWIP >> + help >> + Synchronize RTC via network >> + >> config CMD_TFTPBOOT >> bool "tftp" >> select PROT_UDP_LWIP if NET_LWIP >> diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c >> index cecf8d02555..2ffee64f97e 100644 >> --- a/cmd/net-lwip.c >> +++ b/cmd/net-lwip.c > > Please, put every command into a separate file instead of duplicating the #ifdef chaos of the old network stack. While I agree that cmd/net.c is painful re. #ifdef's, I believe cmd/net-lwip.c is not bad at all. In fact I took care of having only the command wrappers in there (U_BOOT_CMD(...)), so it's just 55 lines at the moment. The implementations are in net/lwip/{dhcp,dns,ping,sntp,tftp,wget}.c. So I don't think there is a need to change that. Or I could move the U_BOOT_CMD(...) into net/lwip/*.c as well, leaving only the non-net commands under cmd/ (apart from the legacy NET stuff). Any opinions on that? > >> @@ -21,6 +21,11 @@ U_BOOT_CMD(tftpboot, 3, 0, do_tftpb, >> "[loadAddress] [[hostIPaddr:]bootfilename]"); >> #endif >> >> +#if defined(CONFIG_CMD_SNTP) >> +U_BOOT_CMD(sntp, 2, 1, do_sntp, "synchronize RTC via network", >> + "[NTP server IP]"); >> +#endif > > Why wouldn't we support server names ( e.g. 0.de.pool.ntp.org) here if we have DNS enabled? Good idea. I will add support for server names to v2. > > Please, add the missing documentation change for the commands. Sure. > Best regards > > Heinrich > > >> + >> #if defined(CONFIG_CMD_DNS) >> U_BOOT_CMD(dns, 3, 1, do_dns, "lookup the IP of a hostname", >> "hostname [envvar]"); >> diff --git a/include/net-common.h b/include/net-common.h >> index a021bf503ff..b06cafb497e 100644 >> --- a/include/net-common.h >> +++ b/include/net-common.h >> @@ -505,6 +505,17 @@ int dhcp_run(ulong addr, const char *fname, bool autoload); >> */ >> int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); >> >> +/** >> + * do_sntp - Run the sntp command >> + * >> + * @cmdtp: Unused >> + * @flag: Command flags (CMD_FLAG_...) >> + * @argc: Number of arguments >> + * @argv: List of arguments >> + * Return: result (see enum command_ret_t) >> + */ >> +int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); >> + >> /** >> * do_tftpb - Run the tftpboot command >> * >> diff --git a/lib/lwip/Makefile b/lib/lwip/Makefile >> index e9e8caee93a..c3f0e916f66 100644 >> --- a/lib/lwip/Makefile >> +++ b/lib/lwip/Makefile >> @@ -13,6 +13,7 @@ obj-y += \ >> lwip/src/api/sockets.o \ >> lwip/src/api/tcpip.o \ >> lwip/src/apps/http/http_client.o \ >> + lwip/src/apps/sntp/sntp.o \ >> lwip/src/apps/tftp/tftp.o \ >> lwip/src/core/altcp_alloc.o \ >> lwip/src/core/altcp.o \ >> diff --git a/lib/lwip/u-boot/arch/cc.h b/lib/lwip/u-boot/arch/cc.h >> index 6104c296f6f..f91127ac565 100644 >> --- a/lib/lwip/u-boot/arch/cc.h >> +++ b/lib/lwip/u-boot/arch/cc.h >> @@ -43,4 +43,8 @@ >> #define BYTE_ORDER BIG_ENDIAN >> #endif >> >> +#define SNTP_STARTUP_DELAY 0 >> +void sntp_set_system_time(uint32_t sec); >> +#define SNTP_SET_SYSTEM_TIME(sec) sntp_set_system_time(sec) >> + >> #endif /* LWIP_ARCH_CC_H */ >> diff --git a/lib/lwip/u-boot/lwipopts.h b/lib/lwip/u-boot/lwipopts.h >> index edac74ff7a2..14ba7bd7ae2 100644 >> --- a/lib/lwip/u-boot/lwipopts.h >> +++ b/lib/lwip/u-boot/lwipopts.h >> @@ -162,4 +162,8 @@ >> #define LWIP_ALTCP_TLS_MBEDTLS 1 >> #endif >> >> +#if defined(CONFIG_CMD_SNTP) >> +#define LWIP_DHCP_GET_NTP_SRV 1 >> +#endif >> + >> #endif /* LWIP_UBOOT_LWIPOPTS_H */ >> diff --git a/net/lwip/Makefile b/net/lwip/Makefile >> index 5df222589b8..5bb98dc4d98 100644 >> --- a/net/lwip/Makefile >> +++ b/net/lwip/Makefile >> @@ -4,6 +4,7 @@ obj-$(CONFIG_$(PHASE_)DM_ETH) += net-lwip.o >> obj-$(CONFIG_CMD_DHCP) += dhcp.o >> obj-$(CONFIG_CMD_DNS) += dns.o >> obj-$(CONFIG_CMD_PING) += ping.o >> +obj-$(CONFIG_CMD_SNTP) += sntp.o >> obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o >> obj-$(CONFIG_WGET) += wget.o >> >> diff --git a/net/lwip/sntp.c b/net/lwip/sntp.c >> new file mode 100644 >> index 00000000000..3b2bc3c679d >> --- /dev/null >> +++ b/net/lwip/sntp.c >> @@ -0,0 +1,128 @@ >> +// SPDX-License-Identifier: GPL-2.0+ >> +/* Copyright (C) 2025 Linaro Ltd. */ >> + >> +#include <command.h> >> +#include <console.h> >> +#include <dm/device.h> >> +#include <lwip/apps/sntp.h> >> +#include <lwip/timeouts.h> >> +#include <net.h> >> + >> +#define SNTP_TIMEOUT 10000 >> + >> +static enum done_state { >> + NOT_DONE = 0, >> + SUCCESS, >> + ABORTED, >> + TIMED_OUT >> +} sntp_state; >> + >> +static void no_response(void *arg) >> +{ >> + sntp_state = TIMED_OUT; >> +} >> + >> +/* Called by lwIP via the SNTP_SET_SYSTEM_TIME() macro */ >> +void sntp_set_system_time(uint32_t seconds) >> +{ >> + char *toff; >> + int net_ntp_time_offset = 0; >> + >> + toff = env_get("timeoffset"); >> + if (toff) >> + net_ntp_time_offset = simple_strtol(toff, NULL, 10); >> + >> + net_sntp_set_rtc(seconds + net_ntp_time_offset); >> + sntp_state = SUCCESS; >> +} >> + >> +static bool ntp_server_known(void) >> +{ >> + int i; >> + >> + for (i = 0; i < SNTP_MAX_SERVERS; i++) { >> + const ip_addr_t *ip = sntp_getserver(i); >> + >> + if (ip && ip->addr) >> + return true; >> + } >> + >> + return false; >> +} >> + >> +static int sntp_loop(struct udevice *udev, ip_addr_t *srvip) >> +{ >> + struct netif *netif; >> + >> + netif = net_lwip_new_netif(udev); >> + if (!netif) >> + return -1; >> + >> + sntp_state = NOT_DONE; >> + >> + sntp_setoperatingmode(SNTP_OPMODE_POLL); >> + sntp_servermode_dhcp(CONFIG_IS_ENABLED(CMD_DHCP)); >> + if (srvip) { >> + sntp_setserver(0, srvip); >> + } else { >> + if (!ntp_server_known()) { >> + log_err("error: ntpserverip not set\n"); >> + return -1; >> + } >> + } >> + sntp_init(); >> + >> + sys_timeout(SNTP_TIMEOUT, no_response, NULL); >> + while (sntp_state == NOT_DONE) { >> + net_lwip_rx(udev, netif); >> + sys_check_timeouts(); >> + if (ctrlc()) { >> + printf("\nAbort\n"); >> + sntp_state = ABORTED; >> + break; >> + } >> + } >> + sys_untimeout(no_response, NULL); >> + >> + sntp_stop(); >> + net_lwip_remove_netif(netif); >> + >> + if (sntp_state == SUCCESS) >> + return 0; >> + >> + return -1; >> +} >> + >> +int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) >> +{ >> + ip_addr_t *srvip = NULL; >> + char *server_ip = NULL; >> + ip_addr_t ipaddr; >> + >> + switch (argc) { >> + case 1: >> + server_ip = env_get("ntpserverip"); >> + break; >> + case 2: >> + server_ip = argv[1]; >> + break; >> + default: >> + return CMD_RET_USAGE; >> + } >> + >> + if (server_ip) { >> + if (!ipaddr_aton(server_ip, &ipaddr)) { >> + log_err("error: ipaddr_aton\n"); >> + return CMD_RET_FAILURE; >> + } >> + srvip = &ipaddr; >> + } >> + >> + if (net_lwip_eth_start() < 0) >> + return CMD_RET_FAILURE; >> + >> + if (sntp_loop(eth_get_dev(), srvip) < 0) >> + return CMD_RET_FAILURE; >> + >> + return CMD_RET_SUCCESS; >> +} >
On Tue, Jun 03, 2025 at 03:49:05PM +0200, Jerome Forissier wrote: > Hi Heinrich, > > On 6/2/25 23:23, Heinrich Schuchardt wrote: > > Am 21. Mai 2025 17:14:42 MESZ schrieb Jerome Forissier <jerome.forissier@linaro.org>: > >> Implement the sntp command when NET_LWIP=y. > >> > >> Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> > >> --- > >> > >> cmd/Kconfig | 13 ++-- > >> cmd/net-lwip.c | 5 ++ > >> include/net-common.h | 11 ++++ > >> lib/lwip/Makefile | 1 + > >> lib/lwip/u-boot/arch/cc.h | 4 ++ > >> lib/lwip/u-boot/lwipopts.h | 4 ++ > >> net/lwip/Makefile | 1 + > >> net/lwip/sntp.c | 128 +++++++++++++++++++++++++++++++++++++ > >> 8 files changed, 161 insertions(+), 6 deletions(-) > >> create mode 100644 net/lwip/sntp.c > >> > >> diff --git a/cmd/Kconfig b/cmd/Kconfig > >> index f21d27cb27f..58f629e1c34 100644 > >> --- a/cmd/Kconfig > >> +++ b/cmd/Kconfig > >> @@ -2061,12 +2061,6 @@ config CMD_CDP > >> and to retrieve configuration data including the VLAN id using the > >> proprietary Cisco Discovery Protocol (CDP). > >> > >> -config CMD_SNTP > >> - bool "sntp" > >> - select PROT_UDP > >> - help > >> - Synchronize RTC via network > >> - > >> config CMD_LINK_LOCAL > >> bool "linklocal" > >> depends on (LIB_RAND || LIB_HW_RAND) > >> @@ -2144,6 +2138,13 @@ config CMD_PING > >> help > >> Send ICMP ECHO_REQUEST to network host > >> > >> +config CMD_SNTP > > > > The command should depend on RTC support. > > > >> + bool "sntp" > >> + select PROT_UDP if NET > >> + select PROT_UDP_LWIP if NET_LWIP > >> + help > >> + Synchronize RTC via network > >> + > >> config CMD_TFTPBOOT > >> bool "tftp" > >> select PROT_UDP_LWIP if NET_LWIP > >> diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c > >> index cecf8d02555..2ffee64f97e 100644 > >> --- a/cmd/net-lwip.c > >> +++ b/cmd/net-lwip.c > > > > Please, put every command into a separate file instead of duplicating the #ifdef chaos of the old network stack. > > While I agree that cmd/net.c is painful re. #ifdef's, I believe > cmd/net-lwip.c is not bad at all. In fact I took care of having only the > command wrappers in there (U_BOOT_CMD(...)), so it's just 55 lines at > the moment. The implementations are in > net/lwip/{dhcp,dns,ping,sntp,tftp,wget}.c. So I don't think there is > a need to change that. Or I could move the U_BOOT_CMD(...) into > net/lwip/*.c as well, leaving only the non-net commands under cmd/ (apart > from the legacy NET stuff). > > Any opinions on that? While there are commands outside of cmd/ they are the exception (and generally ought to be moved) so if we go the route of breaking up cmd/net-lwip.c I'd rather see cmd/lwip/${cmd}.c instead.
On 6/3/25 16:06, Tom Rini wrote: > On Tue, Jun 03, 2025 at 03:49:05PM +0200, Jerome Forissier wrote: >> Hi Heinrich, >> >> On 6/2/25 23:23, Heinrich Schuchardt wrote: >>> Am 21. Mai 2025 17:14:42 MESZ schrieb Jerome Forissier <jerome.forissier@linaro.org>: >>>> Implement the sntp command when NET_LWIP=y. >>>> >>>> Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> >>>> --- >>>> >>>> cmd/Kconfig | 13 ++-- >>>> cmd/net-lwip.c | 5 ++ >>>> include/net-common.h | 11 ++++ >>>> lib/lwip/Makefile | 1 + >>>> lib/lwip/u-boot/arch/cc.h | 4 ++ >>>> lib/lwip/u-boot/lwipopts.h | 4 ++ >>>> net/lwip/Makefile | 1 + >>>> net/lwip/sntp.c | 128 +++++++++++++++++++++++++++++++++++++ >>>> 8 files changed, 161 insertions(+), 6 deletions(-) >>>> create mode 100644 net/lwip/sntp.c >>>> >>>> diff --git a/cmd/Kconfig b/cmd/Kconfig >>>> index f21d27cb27f..58f629e1c34 100644 >>>> --- a/cmd/Kconfig >>>> +++ b/cmd/Kconfig >>>> @@ -2061,12 +2061,6 @@ config CMD_CDP >>>> and to retrieve configuration data including the VLAN id using the >>>> proprietary Cisco Discovery Protocol (CDP). >>>> >>>> -config CMD_SNTP >>>> - bool "sntp" >>>> - select PROT_UDP >>>> - help >>>> - Synchronize RTC via network >>>> - >>>> config CMD_LINK_LOCAL >>>> bool "linklocal" >>>> depends on (LIB_RAND || LIB_HW_RAND) >>>> @@ -2144,6 +2138,13 @@ config CMD_PING >>>> help >>>> Send ICMP ECHO_REQUEST to network host >>>> >>>> +config CMD_SNTP >>> >>> The command should depend on RTC support. >>> >>>> + bool "sntp" >>>> + select PROT_UDP if NET >>>> + select PROT_UDP_LWIP if NET_LWIP >>>> + help >>>> + Synchronize RTC via network >>>> + >>>> config CMD_TFTPBOOT >>>> bool "tftp" >>>> select PROT_UDP_LWIP if NET_LWIP >>>> diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c >>>> index cecf8d02555..2ffee64f97e 100644 >>>> --- a/cmd/net-lwip.c >>>> +++ b/cmd/net-lwip.c >>> >>> Please, put every command into a separate file instead of duplicating the #ifdef chaos of the old network stack. >> >> While I agree that cmd/net.c is painful re. #ifdef's, I believe >> cmd/net-lwip.c is not bad at all. In fact I took care of having only the >> command wrappers in there (U_BOOT_CMD(...)), so it's just 55 lines at >> the moment. The implementations are in >> net/lwip/{dhcp,dns,ping,sntp,tftp,wget}.c. So I don't think there is >> a need to change that. Or I could move the U_BOOT_CMD(...) into >> net/lwip/*.c as well, leaving only the non-net commands under cmd/ (apart >> from the legacy NET stuff). >> >> Any opinions on that? > > While there are commands outside of cmd/ they are the exception (and > generally ought to be moved) so if we go the route of breaking up > cmd/net-lwip.c I'd rather see cmd/lwip/${cmd}.c instead. To be clear, you mean moving net/lwip/${cmd}.c into cmd/lwip/ in addition to splitting cmd/net-lwip.c? Thanks,
On Tue, Jun 03, 2025 at 04:13:32PM +0200, Jerome Forissier wrote: > > > On 6/3/25 16:06, Tom Rini wrote: > > On Tue, Jun 03, 2025 at 03:49:05PM +0200, Jerome Forissier wrote: > >> Hi Heinrich, > >> > >> On 6/2/25 23:23, Heinrich Schuchardt wrote: > >>> Am 21. Mai 2025 17:14:42 MESZ schrieb Jerome Forissier <jerome.forissier@linaro.org>: > >>>> Implement the sntp command when NET_LWIP=y. > >>>> > >>>> Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> > >>>> --- > >>>> > >>>> cmd/Kconfig | 13 ++-- > >>>> cmd/net-lwip.c | 5 ++ > >>>> include/net-common.h | 11 ++++ > >>>> lib/lwip/Makefile | 1 + > >>>> lib/lwip/u-boot/arch/cc.h | 4 ++ > >>>> lib/lwip/u-boot/lwipopts.h | 4 ++ > >>>> net/lwip/Makefile | 1 + > >>>> net/lwip/sntp.c | 128 +++++++++++++++++++++++++++++++++++++ > >>>> 8 files changed, 161 insertions(+), 6 deletions(-) > >>>> create mode 100644 net/lwip/sntp.c > >>>> > >>>> diff --git a/cmd/Kconfig b/cmd/Kconfig > >>>> index f21d27cb27f..58f629e1c34 100644 > >>>> --- a/cmd/Kconfig > >>>> +++ b/cmd/Kconfig > >>>> @@ -2061,12 +2061,6 @@ config CMD_CDP > >>>> and to retrieve configuration data including the VLAN id using the > >>>> proprietary Cisco Discovery Protocol (CDP). > >>>> > >>>> -config CMD_SNTP > >>>> - bool "sntp" > >>>> - select PROT_UDP > >>>> - help > >>>> - Synchronize RTC via network > >>>> - > >>>> config CMD_LINK_LOCAL > >>>> bool "linklocal" > >>>> depends on (LIB_RAND || LIB_HW_RAND) > >>>> @@ -2144,6 +2138,13 @@ config CMD_PING > >>>> help > >>>> Send ICMP ECHO_REQUEST to network host > >>>> > >>>> +config CMD_SNTP > >>> > >>> The command should depend on RTC support. > >>> > >>>> + bool "sntp" > >>>> + select PROT_UDP if NET > >>>> + select PROT_UDP_LWIP if NET_LWIP > >>>> + help > >>>> + Synchronize RTC via network > >>>> + > >>>> config CMD_TFTPBOOT > >>>> bool "tftp" > >>>> select PROT_UDP_LWIP if NET_LWIP > >>>> diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c > >>>> index cecf8d02555..2ffee64f97e 100644 > >>>> --- a/cmd/net-lwip.c > >>>> +++ b/cmd/net-lwip.c > >>> > >>> Please, put every command into a separate file instead of duplicating the #ifdef chaos of the old network stack. > >> > >> While I agree that cmd/net.c is painful re. #ifdef's, I believe > >> cmd/net-lwip.c is not bad at all. In fact I took care of having only the > >> command wrappers in there (U_BOOT_CMD(...)), so it's just 55 lines at > >> the moment. The implementations are in > >> net/lwip/{dhcp,dns,ping,sntp,tftp,wget}.c. So I don't think there is > >> a need to change that. Or I could move the U_BOOT_CMD(...) into > >> net/lwip/*.c as well, leaving only the non-net commands under cmd/ (apart > >> from the legacy NET stuff). > >> > >> Any opinions on that? > > > > While there are commands outside of cmd/ they are the exception (and > > generally ought to be moved) so if we go the route of breaking up > > cmd/net-lwip.c I'd rather see cmd/lwip/${cmd}.c instead. > > To be clear, you mean moving net/lwip/${cmd}.c into cmd/lwip/ in addition to > splitting cmd/net-lwip.c? Yes and I think that will make things clearer overall, thanks.
On 6/3/25 07:51, Heinrich Schuchardt wrote: > Am 2. Juni 2025 23:23:08 MESZ schrieb Heinrich Schuchardt <xypron.glpk@gmx.de>: >> Am 21. Mai 2025 17:14:42 MESZ schrieb Jerome Forissier <jerome.forissier@linaro.org>: >>> Implement the sntp command when NET_LWIP=y. > > https://datatracker.ietf.org/doc/rfc5905/ describes that on Feb 7th, 2036 the 32 bit seconds field wraps around and era 1 starts. > > Does our code consider this? I don't know. The lwIP code seems to somewhat take care of the year 2036 issue [1] but I need to spend more time understanding what's happening here to be certain. [1] https://github.com/u-boot/u-boot/blob/d1555de5fa21c06118540dcd4a627a1af29bbb40/lib/lwip/lwip/src/apps/sntp/sntp.c#L141 Thanks,
diff --git a/cmd/Kconfig b/cmd/Kconfig index f21d27cb27f..58f629e1c34 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2061,12 +2061,6 @@ config CMD_CDP and to retrieve configuration data including the VLAN id using the proprietary Cisco Discovery Protocol (CDP). -config CMD_SNTP - bool "sntp" - select PROT_UDP - help - Synchronize RTC via network - config CMD_LINK_LOCAL bool "linklocal" depends on (LIB_RAND || LIB_HW_RAND) @@ -2144,6 +2138,13 @@ config CMD_PING help Send ICMP ECHO_REQUEST to network host +config CMD_SNTP + bool "sntp" + select PROT_UDP if NET + select PROT_UDP_LWIP if NET_LWIP + help + Synchronize RTC via network + config CMD_TFTPBOOT bool "tftp" select PROT_UDP_LWIP if NET_LWIP diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c index cecf8d02555..2ffee64f97e 100644 --- a/cmd/net-lwip.c +++ b/cmd/net-lwip.c @@ -21,6 +21,11 @@ U_BOOT_CMD(tftpboot, 3, 0, do_tftpb, "[loadAddress] [[hostIPaddr:]bootfilename]"); #endif +#if defined(CONFIG_CMD_SNTP) +U_BOOT_CMD(sntp, 2, 1, do_sntp, "synchronize RTC via network", + "[NTP server IP]"); +#endif + #if defined(CONFIG_CMD_DNS) U_BOOT_CMD(dns, 3, 1, do_dns, "lookup the IP of a hostname", "hostname [envvar]"); diff --git a/include/net-common.h b/include/net-common.h index a021bf503ff..b06cafb497e 100644 --- a/include/net-common.h +++ b/include/net-common.h @@ -505,6 +505,17 @@ int dhcp_run(ulong addr, const char *fname, bool autoload); */ int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); +/** + * do_sntp - Run the sntp command + * + * @cmdtp: Unused + * @flag: Command flags (CMD_FLAG_...) + * @argc: Number of arguments + * @argv: List of arguments + * Return: result (see enum command_ret_t) + */ +int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); + /** * do_tftpb - Run the tftpboot command * diff --git a/lib/lwip/Makefile b/lib/lwip/Makefile index e9e8caee93a..c3f0e916f66 100644 --- a/lib/lwip/Makefile +++ b/lib/lwip/Makefile @@ -13,6 +13,7 @@ obj-y += \ lwip/src/api/sockets.o \ lwip/src/api/tcpip.o \ lwip/src/apps/http/http_client.o \ + lwip/src/apps/sntp/sntp.o \ lwip/src/apps/tftp/tftp.o \ lwip/src/core/altcp_alloc.o \ lwip/src/core/altcp.o \ diff --git a/lib/lwip/u-boot/arch/cc.h b/lib/lwip/u-boot/arch/cc.h index 6104c296f6f..f91127ac565 100644 --- a/lib/lwip/u-boot/arch/cc.h +++ b/lib/lwip/u-boot/arch/cc.h @@ -43,4 +43,8 @@ #define BYTE_ORDER BIG_ENDIAN #endif +#define SNTP_STARTUP_DELAY 0 +void sntp_set_system_time(uint32_t sec); +#define SNTP_SET_SYSTEM_TIME(sec) sntp_set_system_time(sec) + #endif /* LWIP_ARCH_CC_H */ diff --git a/lib/lwip/u-boot/lwipopts.h b/lib/lwip/u-boot/lwipopts.h index edac74ff7a2..14ba7bd7ae2 100644 --- a/lib/lwip/u-boot/lwipopts.h +++ b/lib/lwip/u-boot/lwipopts.h @@ -162,4 +162,8 @@ #define LWIP_ALTCP_TLS_MBEDTLS 1 #endif +#if defined(CONFIG_CMD_SNTP) +#define LWIP_DHCP_GET_NTP_SRV 1 +#endif + #endif /* LWIP_UBOOT_LWIPOPTS_H */ diff --git a/net/lwip/Makefile b/net/lwip/Makefile index 5df222589b8..5bb98dc4d98 100644 --- a/net/lwip/Makefile +++ b/net/lwip/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_$(PHASE_)DM_ETH) += net-lwip.o obj-$(CONFIG_CMD_DHCP) += dhcp.o obj-$(CONFIG_CMD_DNS) += dns.o obj-$(CONFIG_CMD_PING) += ping.o +obj-$(CONFIG_CMD_SNTP) += sntp.o obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o obj-$(CONFIG_WGET) += wget.o diff --git a/net/lwip/sntp.c b/net/lwip/sntp.c new file mode 100644 index 00000000000..3b2bc3c679d --- /dev/null +++ b/net/lwip/sntp.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright (C) 2025 Linaro Ltd. */ + +#include <command.h> +#include <console.h> +#include <dm/device.h> +#include <lwip/apps/sntp.h> +#include <lwip/timeouts.h> +#include <net.h> + +#define SNTP_TIMEOUT 10000 + +static enum done_state { + NOT_DONE = 0, + SUCCESS, + ABORTED, + TIMED_OUT +} sntp_state; + +static void no_response(void *arg) +{ + sntp_state = TIMED_OUT; +} + +/* Called by lwIP via the SNTP_SET_SYSTEM_TIME() macro */ +void sntp_set_system_time(uint32_t seconds) +{ + char *toff; + int net_ntp_time_offset = 0; + + toff = env_get("timeoffset"); + if (toff) + net_ntp_time_offset = simple_strtol(toff, NULL, 10); + + net_sntp_set_rtc(seconds + net_ntp_time_offset); + sntp_state = SUCCESS; +} + +static bool ntp_server_known(void) +{ + int i; + + for (i = 0; i < SNTP_MAX_SERVERS; i++) { + const ip_addr_t *ip = sntp_getserver(i); + + if (ip && ip->addr) + return true; + } + + return false; +} + +static int sntp_loop(struct udevice *udev, ip_addr_t *srvip) +{ + struct netif *netif; + + netif = net_lwip_new_netif(udev); + if (!netif) + return -1; + + sntp_state = NOT_DONE; + + sntp_setoperatingmode(SNTP_OPMODE_POLL); + sntp_servermode_dhcp(CONFIG_IS_ENABLED(CMD_DHCP)); + if (srvip) { + sntp_setserver(0, srvip); + } else { + if (!ntp_server_known()) { + log_err("error: ntpserverip not set\n"); + return -1; + } + } + sntp_init(); + + sys_timeout(SNTP_TIMEOUT, no_response, NULL); + while (sntp_state == NOT_DONE) { + net_lwip_rx(udev, netif); + sys_check_timeouts(); + if (ctrlc()) { + printf("\nAbort\n"); + sntp_state = ABORTED; + break; + } + } + sys_untimeout(no_response, NULL); + + sntp_stop(); + net_lwip_remove_netif(netif); + + if (sntp_state == SUCCESS) + return 0; + + return -1; +} + +int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + ip_addr_t *srvip = NULL; + char *server_ip = NULL; + ip_addr_t ipaddr; + + switch (argc) { + case 1: + server_ip = env_get("ntpserverip"); + break; + case 2: + server_ip = argv[1]; + break; + default: + return CMD_RET_USAGE; + } + + if (server_ip) { + if (!ipaddr_aton(server_ip, &ipaddr)) { + log_err("error: ipaddr_aton\n"); + return CMD_RET_FAILURE; + } + srvip = &ipaddr; + } + + if (net_lwip_eth_start() < 0) + return CMD_RET_FAILURE; + + if (sntp_loop(eth_get_dev(), srvip) < 0) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +}
Implement the sntp command when NET_LWIP=y. Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org> --- cmd/Kconfig | 13 ++-- cmd/net-lwip.c | 5 ++ include/net-common.h | 11 ++++ lib/lwip/Makefile | 1 + lib/lwip/u-boot/arch/cc.h | 4 ++ lib/lwip/u-boot/lwipopts.h | 4 ++ net/lwip/Makefile | 1 + net/lwip/sntp.c | 128 +++++++++++++++++++++++++++++++++++++ 8 files changed, 161 insertions(+), 6 deletions(-) create mode 100644 net/lwip/sntp.c