]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
lwip: add sntp command
authorJerome Forissier <jerome.forissier@linaro.org>
Wed, 25 Jun 2025 13:19:19 +0000 (15:19 +0200)
committerJerome Forissier <jerome.forissier@linaro.org>
Tue, 8 Jul 2025 09:07:37 +0000 (11:07 +0200)
Implement the sntp command when NET_LWIP=y.

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
cmd/Kconfig
cmd/lwip/Makefile
cmd/lwip/sntp.c [new file with mode: 0644]
include/net-common.h
lib/lwip/Makefile
lib/lwip/u-boot/arch/cc.h
lib/lwip/u-boot/lwipopts.h

index 1ba3cfcb28a785f7c8b5bdc3814be38200102a38..ca7ed58c06257eff3c884e2a562de91ffcc36c58 100644 (file)
@@ -2074,12 +2074,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)
@@ -2157,6 +2151,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
index 4c28d2b28e5bc5edb986a3ecf568378aba0f64c4..a7f8976af3fb7cb2d41344f9f22a5d820c5ebc7e 100644 (file)
@@ -1,5 +1,6 @@
 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_CMD_WGET) += wget.o
diff --git a/cmd/lwip/sntp.c b/cmd/lwip/sntp.c
new file mode 100644 (file)
index 0000000..ae02bb1
--- /dev/null
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (C) 2025 Linaro Ltd. */
+
+#include <command.h>
+#include <console.h>
+#include <dm/device.h>
+#include <env.h>
+#include <lwip/apps/sntp.h>
+#include <lwip/timeouts.h>
+#include <net.h>
+
+U_BOOT_CMD(sntp, 2, 1, do_sntp, "synchronize RTC via network",
+          "[NTPServerNameOrIp]");
+
+#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;
+       char *server;
+       ip_addr_t ipaddr;
+
+       switch (argc) {
+       case 1:
+               srvip = NULL;
+               server = env_get("ntpserverip");
+               if (server) {
+                       if (!ipaddr_aton(server, &ipaddr)) {
+                               printf("ntpserverip is invalid\n");
+                               return CMD_RET_FAILURE;
+                       }
+                       srvip = &ipaddr;
+               }
+               break;
+       case 2:
+               if (net_lwip_dns_resolve(argv[1], &ipaddr))
+                       return CMD_RET_FAILURE;
+               srvip = &ipaddr;
+               break;
+       default:
+               return CMD_RET_USAGE;
+       }
+
+       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;
+}
index d4512c3a4d19fc7c84b009b4945acd2fd99ead18..1112af381a9842c46bd8a926ecf4e93a682621ca 100644 (file)
@@ -491,6 +491,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
  *
index e9e8caee93a8d21386056c1e603e954328691d28..c3f0e916f665a7490b70a8a236a9cbadbe3679fe 100644 (file)
@@ -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 \
index 6104c296f6fce5a0dbd2a16505172c5a1cb30923..f91127ac56581204bed49b4c04e3951e8ffa79c3 100644 (file)
@@ -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 */
index 1818a445dc5e220a9086f0e8efa24f4f5d154d3d..46af91f94108cba774f20a46470541b67278f9b0 100644 (file)
 #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 */