Hi Heinrich, On 6/2/25 23:23, Heinrich Schuchardt wrote: > Am 21. Mai 2025 17:14:42 MESZ schrieb Jerome Forissier > <jerome.foriss...@linaro.org>: >> Implement the sntp command when NET_LWIP=y. >> >> Signed-off-by: Jerome Forissier <jerome.foriss...@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; >> +} >