Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions include/zephyr/net/sntp_server.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2025 Lothar Felten <lothar.felten@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @file
* @brief SNTP (Simple Network Time Protocol, RFC5905) Server
*/

#ifndef ZEPHYR_INCLUDE_NET_SNTP_SERVER_H_
#define ZEPHYR_INCLUDE_NET_SNTP_SERVER_H_

#include <zephyr/posix/time.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Simple Network Time Protocol Server API
* @defgroup sntp SNTP
* @since 4.3
* @version 0.1.0
* @ingroup networking
* @{
*/

/**
* @brief Set SNTP time source id and stratum
* @param refid the reference ID (RFC5905, Fig.12)
* @param stratum indicating the stratum of the clock source
* @param precision an exponent of two, where the resulting value is the precision
* of the system clock in seconds.
*
* @return 0 if ok, <0 if error.
*/
int sntp_server_clock_source(unsigned char *refid, unsigned char stratum, char precision);

#ifdef __cplusplus
}
#endif

/**
* @}
*/

#endif /* ZEPHYR_INCLUDE_NET_SNTP_SERVER_H_ */
1 change: 1 addition & 0 deletions samples/net/cloud/aws_iot_mqtt/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ CONFIG_NET_DHCPV4=y

# SNTP
CONFIG_SNTP=y
CONFIG_SNTP_CLIENT=y
CONFIG_NET_CONFIG_CLOCK_SNTP_INIT=y
CONFIG_NET_CONFIG_SNTP_INIT_SERVER="0.pool.ntp.org"

Expand Down
10 changes: 10 additions & 0 deletions samples/net/sockets/sntp_server/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(sntp_server)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

include(${ZEPHYR_BASE}/samples/net/common/common.cmake)
3 changes: 3 additions & 0 deletions samples/net/sockets/sntp_server/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Copyright (c) 2025 Lothar Felten <lothar.felten@gmail.com>

source "Kconfig.zephyr"
33 changes: 33 additions & 0 deletions samples/net/sockets/sntp_server/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.. zephyr:code-sample:: sntp-server
:name: SNTP server
:relevant-api: bsd_sockets sntp

SNTP to get the current time from the host.

Overview
********

This sample is a simple SNTP server implementation.
The demo will query a SNTP server and set the system time and date.
When the local clock is set, the system will respond to SNTP queries
on port 123, the default SNTP port.
You can query the server using a SNTP client, such as ntpdig or sntp.

This demo assumes that the platform of choice has networking support,
some adjustments to the configuration may be needed.

Building and Running
********************

See the `net-tools`_ project for more details.

This sample can be built and executed on QEMU or native_sim board as
described in :ref:`networking_with_qemu`.

.. _`net-tools`: https://github.com/zephyrproject-rtos/net-tools

Wi-Fi
=====

The IPv4 Wi-Fi support can be enabled in the sample with
:ref:`Wi-Fi snippet <snippet-wifi-ipv4>`.
11 changes: 11 additions & 0 deletions samples/net/sockets/sntp_server/overlay-nsos.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright (c) 2025 Embeint Inc

CONFIG_ETH_NATIVE_TAP=n
CONFIG_NET_DRIVERS=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_OFFLOAD=y
CONFIG_NET_NATIVE_OFFLOADED_SOCKETS=y
CONFIG_HEAP_MEM_POOL_SIZE=4096

# IPv6 DAD requires lower level network interface access, below exposed socket-level access
CONFIG_NET_IPV6_DAD=n
35 changes: 35 additions & 0 deletions samples/net/sockets/sntp_server/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# General config
CONFIG_REQUIRES_FULL_LIBC=y
CONFIG_POSIX_API=y

# Networking config
CONFIG_NETWORKING=y
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=y
CONFIG_NET_UDP=y
CONFIG_NET_SHELL=y

# Sockets
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_SERVICE=y

# Network driver config
CONFIG_TEST_RANDOM_GENERATOR=y

# Network address config
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_CONFIG_NEED_IPV4=y
CONFIG_NET_DHCPV4=y
CONFIG_NET_CONFIG_NEED_IPV6=y

# SNTP
CONFIG_SNTP=y
CONFIG_DNS_RESOLVER=y
CONFIG_SNTP_CLIENT=y
CONFIG_SNTP_SERVER=y

CONFIG_MAIN_STACK_SIZE=2048
# Network debug config
CONFIG_LOG=y
CONFIG_NET_LOG=y
CONFIG_SNTP_LOG_LEVEL_DBG=y
20 changes: 20 additions & 0 deletions samples/net/sockets/sntp_server/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
sample:
description: SNTP server sample
name: sntp_server
common:
harness: net
tags: net
tests:
sample.net.sockets.sntp_server:
platform_allow:
- qemu_x86
- native_sim
sample.net.sockets.sntp_server.native:
platform_allow:
- native_sim
integration_platforms:
- native_sim
extra_configs:
- CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME=y
extra_args:
- EXTRA_CONF_FILE="overlay-nsos.conf"
37 changes: 37 additions & 0 deletions samples/net/sockets/sntp_server/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2025 Lothar Felten <lothar.felten@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(sntp_demo, LOG_LEVEL_DBG);

#include <zephyr/net/sntp_server.h>
#include <zephyr/net/sntp.h>
#include "net_sample_common.h"

int main(void)
{
struct sntp_time t;
struct timespec tp;
int ret;

LOG_INF("waiting for network");
wait_for_network();
ret = sntp_simple("ptbtime1.ptb.de", SYS_FOREVER_MS, &t);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The address of the server should be set via kconfig option. The server sample can have its own Kconfig file where the server name can be stored (see examples how to do this in other network samples). Note that the server name should be empty by default so that user is forced to set it according to his/hers network setup.

if (ret < 0) {
LOG_ERR("SNTP client error (%d)", ret);
return 0;
}
tp.tv_sec = t.seconds;
tp.tv_nsec = t.fraction / 1000;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, wrong handling of the fractional part, I think

ret = sys_clock_settime(SYS_CLOCK_REALTIME, &tp);
if (ret < 0) {
LOG_ERR("SNTP unable to set system time (%d)", ret);
return 0;
}

sntp_server_clock_source("XDEV", 2, -6);
return 0;
}
9 changes: 8 additions & 1 deletion subsys/net/lib/sntp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_sources(
zephyr_sources_ifdef(CONFIG_SNTP
sntp.c
)

zephyr_sources_ifdef(CONFIG_SNTP_CLIENT
sntp_simple.c
)

zephyr_sources_ifdef(CONFIG_SNTP_SERVER
sntp_server.c
)
32 changes: 30 additions & 2 deletions subsys/net/lib/sntp/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@ menuconfig SNTP
bool "SNTP (Simple Network Time Protocol)"
depends on NET_SOCKETS
help
Enable SNTP client library
Enable SNTP support library

if SNTP

config SNTP_CLIENT
bool "SNTP client support"
help
This option enables SNTP client support

if SNTP_CLIENT

config SNTP_UNCERTAINTY
bool "Calculate SNTP uncertainty and set uptime timestamp"
help
Expand All @@ -19,10 +26,31 @@ config SNTP_UNCERTAINTY
Enabling this option uses more resources (memory) and is not normally
needed.

endif # SNTP client

config SNTP_SERVER
bool "SNTP client support"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bool "SNTP client support"
bool "SNTP server support"
help
This option enables SNTP server support

if SNTP_SERVER

config SNTP_SERVER_STACK_SIZE
int "Stack size of the SNTP server thread"
default 1024

config SNTP_SERVER_THREAD_PRIORITY
int "SNTP server thread priority"
default NUM_PREEMPT_PRIORITIES
help
Priority of SNTP server thread.

endif # SNTP server

module = SNTP
module-dep = NET_LOG
module-str = Log level for SNTP
module-help = Enable debug message of SNTP client library.
module-help = Enable debug message of SNTP library.
source "subsys/net/Kconfig.template.log_config.net"

endif # SNTP
9 changes: 1 addition & 8 deletions subsys/net/lib/sntp/sntp.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,7 @@ LOG_MODULE_REGISTER(net_sntp, CONFIG_SNTP_LOG_LEVEL);
#include "sntp_pkt.h"
#include <limits.h>

#define SNTP_LI_MAX 3
#define SNTP_VERSION_NUMBER 3
#define SNTP_MODE_CLIENT 3
#define SNTP_MODE_SERVER 4
#define SNTP_STRATUM_KOD 0 /* kiss-o'-death */
#define OFFSET_1970_JAN_1 2208988800

static void sntp_pkt_dump(struct sntp_pkt *pkt)
void sntp_pkt_dump(struct sntp_pkt *pkt)
{
if (!pkt) {
return;
Expand Down
23 changes: 17 additions & 6 deletions subsys/net/lib/sntp/sntp_pkt.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@

#include <zephyr/types.h>

#define SNTP_LI_MAX 3
#define SNTP_VERSION_NUMBER 3
#define SNTP_MODE_CLIENT 3
#define SNTP_MODE_SERVER 4
#define SNTP_LEAP_INDICATOR_NONE 0
#define SNTP_LEAP_INDICATOR_CLOCK_INVALID 3
#define SNTP_STRATUM_KOD 0 /* kiss-o'-death */
#define OFFSET_1970_JAN_1 2208988800

struct sntp_pkt {
#if defined(CONFIG_LITTLE_ENDIAN)
uint8_t mode: 3;
Expand All @@ -27,12 +36,14 @@ struct sntp_pkt {
uint32_t ref_id;
uint32_t ref_tm_s;
uint32_t ref_tm_f;
uint32_t orig_tm_s;/* Originate timestamp seconds */
uint32_t orig_tm_f;/* Originate timestamp seconds fraction */
uint32_t rx_tm_s;/* Receive timestamp seconds */
uint32_t rx_tm_f;/* Receive timestamp seconds fraction */
uint32_t tx_tm_s;/* Transmit timestamp seconds */
uint32_t tx_tm_f;/* Transmit timestamp seconds fraction */
uint32_t orig_tm_s; /* Originate timestamp seconds */
uint32_t orig_tm_f; /* Originate timestamp seconds fraction */
uint32_t rx_tm_s; /* Receive timestamp seconds */
uint32_t rx_tm_f; /* Receive timestamp seconds fraction */
uint32_t tx_tm_s; /* Transmit timestamp seconds */
uint32_t tx_tm_f; /* Transmit timestamp seconds fraction */
} __packed;

void sntp_pkt_dump(struct sntp_pkt *pkt);

#endif
Loading