The ISO C function time() should not depend on POSIX and this was corrected recently via the common libc time() implementation. Remove this dependency from the network subsystem where it has been unduly needed for some time. Similarly, XSI_SINGLE_PROCESS was a dependency for time() via picolibc, because the time() implementation in picolibc relies on the POSIX gettimeofday() call. However, since Zephyr's common libc time() implementation no longer depends on that, it can be removed as a dependency in the network subsystem as well. Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
110 lines
3.1 KiB
C
110 lines
3.1 KiB
C
/*
|
|
* Copyright (c) 2019 Linaro Limited
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/kernel.h>
|
|
#include <zephyr/logging/log.h>
|
|
LOG_MODULE_DECLARE(net_config, CONFIG_NET_CONFIG_LOG_LEVEL);
|
|
|
|
#include <errno.h>
|
|
#include <zephyr/net/net_if.h>
|
|
#include <zephyr/net/net_mgmt.h>
|
|
#include <zephyr/net/sntp.h>
|
|
|
|
#ifdef CONFIG_NET_CONFIG_SNTP_INIT_RESYNC
|
|
static void sntp_resync_handler(struct k_work *work);
|
|
static K_WORK_DELAYABLE_DEFINE(sntp_resync_work_handle, sntp_resync_handler);
|
|
#endif
|
|
|
|
BUILD_ASSERT(
|
|
IS_ENABLED(CONFIG_NET_CONFIG_SNTP_INIT_SERVER_USE_DHCPV4_OPTION) ||
|
|
(sizeof(CONFIG_NET_CONFIG_SNTP_INIT_SERVER) != 1),
|
|
"SNTP server has to be configured, unless DHCPv4 is used to set it");
|
|
|
|
static int sntp_init_helper(struct sntp_time *tm)
|
|
{
|
|
#ifdef CONFIG_NET_CONFIG_SNTP_INIT_SERVER_USE_DHCPV4_OPTION
|
|
struct net_if *iface = net_if_get_default();
|
|
|
|
if (!net_ipv4_is_addr_unspecified(&iface->config.dhcpv4.ntp_addr)) {
|
|
struct sockaddr_in sntp_addr = {0};
|
|
|
|
sntp_addr.sin_family = AF_INET;
|
|
sntp_addr.sin_addr.s_addr = iface->config.dhcpv4.ntp_addr.s_addr;
|
|
return sntp_simple_addr((struct sockaddr *)&sntp_addr, sizeof(sntp_addr),
|
|
CONFIG_NET_CONFIG_SNTP_INIT_TIMEOUT, tm);
|
|
}
|
|
if (sizeof(CONFIG_NET_CONFIG_SNTP_INIT_SERVER) == 1) {
|
|
/* Empty address, skip using SNTP via Kconfig defaults */
|
|
return -EINVAL;
|
|
}
|
|
LOG_INF("SNTP address not set by DHCPv4, using Kconfig defaults");
|
|
#endif /* NET_CONFIG_SNTP_INIT_SERVER_USE_DHCPV4_OPTION */
|
|
return sntp_simple(CONFIG_NET_CONFIG_SNTP_INIT_SERVER,
|
|
CONFIG_NET_CONFIG_SNTP_INIT_TIMEOUT, tm);
|
|
}
|
|
|
|
int net_init_clock_via_sntp(void)
|
|
{
|
|
struct sntp_time ts;
|
|
struct timespec tspec;
|
|
int res = sntp_init_helper(&ts);
|
|
|
|
if (res < 0) {
|
|
LOG_ERR("Cannot set time using SNTP");
|
|
goto end;
|
|
}
|
|
|
|
tspec.tv_sec = ts.seconds;
|
|
tspec.tv_nsec = ((uint64_t)ts.fraction * (1000 * 1000 * 1000)) >> 32;
|
|
res = sys_clock_settime(SYS_CLOCK_REALTIME, &tspec);
|
|
|
|
end:
|
|
#ifdef CONFIG_NET_CONFIG_SNTP_INIT_RESYNC
|
|
k_work_reschedule(
|
|
&sntp_resync_work_handle,
|
|
(res < 0) ? K_SECONDS(CONFIG_NET_CONFIG_SNTP_INIT_RESYNC_ON_FAILURE_INTERVAL)
|
|
: K_SECONDS(CONFIG_NET_CONFIG_SNTP_INIT_RESYNC_INTERVAL));
|
|
#endif
|
|
return res;
|
|
}
|
|
|
|
#ifdef CONFIG_NET_CONFIG_SNTP_INIT_RESYNC
|
|
static void sntp_resync_handler(struct k_work *work)
|
|
{
|
|
int res;
|
|
|
|
ARG_UNUSED(work);
|
|
|
|
res = net_init_clock_via_sntp();
|
|
if (res < 0) {
|
|
LOG_ERR("Cannot resync time using SNTP");
|
|
return;
|
|
}
|
|
LOG_DBG("Time resynced using SNTP");
|
|
}
|
|
#endif /* CONFIG_NET_CONFIG_SNTP_INIT_RESYNC */
|
|
|
|
#ifdef CONFIG_NET_CONFIG_SNTP_INIT_USE_CONNECTION_MANAGER
|
|
static void l4_event_handler(uint64_t mgmt_event, struct net_if *iface, void *info,
|
|
size_t info_length, void *user_data)
|
|
{
|
|
ARG_UNUSED(iface);
|
|
ARG_UNUSED(info);
|
|
ARG_UNUSED(info_length);
|
|
ARG_UNUSED(user_data);
|
|
|
|
if (mgmt_event == NET_EVENT_L4_CONNECTED) {
|
|
k_work_reschedule(&sntp_resync_work_handle, K_NO_WAIT);
|
|
} else if (mgmt_event == NET_EVENT_L4_DISCONNECTED) {
|
|
k_work_cancel_delayable(&sntp_resync_work_handle);
|
|
}
|
|
}
|
|
|
|
NET_MGMT_REGISTER_EVENT_HANDLER(sntp_init_event_handler,
|
|
NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED,
|
|
&l4_event_handler, NULL);
|
|
#endif /* CONFIG_LOG_BACKEND_NET_USE_CONNECTION_MANAGER */
|