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.

>@@ -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;
>+}

Reply via email to