DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
ntp_server.h File Reference

NTP/SNTP time server (RFC 5905 / RFC 4330 server mode) on UDP/123. More...

#include <stddef.h>
#include <stdint.h>

Go to the source code of this file.

Macros

#define NTP_PACKET_LEN   48u
 One NTP packet on the wire is exactly 48 octets (no extension/auth fields).
 
#define NTP_UNIX_OFFSET   2208988800u
 Seconds between the NTP epoch (1900-01-01) and the Unix epoch (1970-01-01).
 
#define NTP_REFID_LOCL   0x4C4F434Cu
 Reference ID "LOCL" - an undisciplined local clock (RFC 5905 sec 7.3).
 
#define NTP_REFID_GPS   0x47505320u
 Reference ID "GPS " - a GPS-disciplined reference clock (use with stratum 1).
 

Functions

size_t ntp_server_build_response (const uint8_t *req, size_t req_len, uint8_t stratum, uint32_t refid, uint32_t ntp_secs, uint32_t ntp_frac, uint8_t *out, size_t out_cap)
 Build a server (mode 4) reply to a client NTP request. Pure - no clock, no I/O.
 
bool ntp_server_begin (uint8_t stratum, uint32_t refid=NTP_REFID_LOCL)
 Start answering NTP requests on UDP/123 from the device's own clock.
 

Detailed Description

NTP/SNTP time server (RFC 5905 / RFC 4330 server mode) on UDP/123.

The device answers client NTP requests from its own clock, so a LAN with no path to the public NTP pool (offline, air-gapped, or behind a strict firewall) can still keep its devices in sync against this one. It is a stateless request/response: a client sends a 48-octet packet, the server fills in the reference/receive/transmit timestamps (echoing the client's transmit stamp as the origin so the client can compute round-trip delay) and sends it back. Zero heap; gated by DETWS_ENABLE_NTP_SERVER (default off).

The response builder (ntp_server_build_response) is pure - it takes the request bytes and the current NTP-epoch time and writes the reply - so it is fully host-tested with no lwIP. ntp_server_begin() binds UDP/123 via the transport UDP service and drives it from detws_time_now() (seconds) plus a detws_millis()-derived sub-second fraction.

Author
Douglas Quigg (dstroy0)
Date
2026

Definition in file ntp_server.h.

Macro Definition Documentation

◆ NTP_PACKET_LEN

#define NTP_PACKET_LEN   48u

One NTP packet on the wire is exactly 48 octets (no extension/auth fields).

Definition at line 31 of file ntp_server.h.

◆ NTP_UNIX_OFFSET

#define NTP_UNIX_OFFSET   2208988800u

Seconds between the NTP epoch (1900-01-01) and the Unix epoch (1970-01-01).

Definition at line 34 of file ntp_server.h.

◆ NTP_REFID_LOCL

#define NTP_REFID_LOCL   0x4C4F434Cu

Reference ID "LOCL" - an undisciplined local clock (RFC 5905 sec 7.3).

Definition at line 37 of file ntp_server.h.

◆ NTP_REFID_GPS

#define NTP_REFID_GPS   0x47505320u

Reference ID "GPS " - a GPS-disciplined reference clock (use with stratum 1).

Definition at line 40 of file ntp_server.h.

Function Documentation

◆ ntp_server_build_response()

size_t ntp_server_build_response ( const uint8_t *  req,
size_t  req_len,
uint8_t  stratum,
uint32_t  refid,
uint32_t  ntp_secs,
uint32_t  ntp_frac,
uint8_t *  out,
size_t  out_cap 
)

Build a server (mode 4) reply to a client NTP request. Pure - no clock, no I/O.

Echoes the request's protocol version, copies the client's transmit timestamp into the response's origin field, and stamps the reference / receive / transmit times with (ntp_secs, ntp_frac). Leap indicator 0, root dispersion ~1 s (a coarse clock).

Parameters
reqthe received request bytes.
req_lenlength of req (must be >= NTP_PACKET_LEN).
stratumstratum to advertise (1-15).
refidreference identifier (e.g. NTP_REFID_LOCL).
ntp_secscurrent time, seconds since the NTP epoch (Unix seconds + NTP_UNIX_OFFSET).
ntp_fracsub-second fraction as a 32-bit binary fraction of a second.
outoutput buffer.
out_capcapacity of out (must be >= NTP_PACKET_LEN).
Returns
NTP_PACKET_LEN on success, or 0 if a length is too small.

◆ ntp_server_begin()

bool ntp_server_begin ( uint8_t  stratum,
uint32_t  refid = NTP_REFID_LOCL 
)

Start answering NTP requests on UDP/123 from the device's own clock.

Uses detws_time_now() for the seconds and detws_millis() for the sub-second fraction. While the device has no time (detws_time_now() returns 0) the server does not reply, so a client falls through to its next configured source rather than trusting an unset clock.

Parameters
stratumthe stratum to advertise (1 for a GPS/reference clock, 2-15 for a relay).
refidthe reference identifier to advertise (NTP_REFID_LOCL, NTP_REFID_GPS, ...).
Returns
true if the UDP listener bound; false on a host build or if the port is taken.