Files
RTLPlayground/ntp_cli.c
T
DrDoof 3cd6d60e0b ntp: keep the time from an NTP server
The switch has no battery backed clock, only a seconds counter that starts
at zero on every boot. An SNTP client keeps UTC as the time of the last
answer plus the seconds counted since: "ntp server <name|ip>", "ntp interval
<minutes>", "ntp timezone <+hh:mm>", "ntp dst off|eu|us", "ntp on|off",
"ntp" and "time". A server given by name goes through the DNS resolver, an
answer from an unsynchronised server is ignored, and a failed attempt is
repeated after 30 seconds.

The local time adds the time zone offset and, while the European or United
States rule says so, one hour. The date is split with a shift and subtract
division and a walk over the years, so no 32-bit division from the library
ends up in the common area.

The System page gets the NTP settings and shows the local time.
2026-09-29 22:40:59 +02:00

120 lines
2.5 KiB
C

/*
* Command line interface of the NTP client for the RTL837x platform
* This code is in the Public Domain
*/
#include <stdint.h>
#include "rtl837x_common.h"
#include "cmd_parser.h"
#include "ntp.h"
#pragma codeseg BANK2
#pragma constseg BANK2
extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
extern __xdata uint8_t cmd_words_len;
extern __xdata uint8_t cmd_words_b[15];
extern __xdata uint16_t atoi_results_short;
uint8_t cmd_compare(uint8_t start, __code const uint8_t * cmd);
uint8_t atoi_short(uint8_t idx);
static uint8_t ntp_cli_server(void) __reentrant
{
__xdata uint8_t *s = &cmd_buffer[cmd_words_b[2]];
uint8_t n;
for (n = 0; s[n] && s[n] != ' '; n++)
if (n == DNS_NAME_LEN - 1)
return 0;
memcpy(ntp_state.server, s, n);
ntp_state.server[n] = 0;
return n;
}
static uint8_t ntp_cli_timezone(void) __reentrant
{
__xdata uint8_t *s = &cmd_buffer[cmd_words_b[2]];
uint8_t neg = 0, h = 0, m = 0, n = 0;
uint16_t v;
if (*s == '+' || *s == '-')
neg = *s++ == '-';
while (*s >= '0' && *s <= '9') {
h = h * 10 + (*s++ - '0');
if (++n > 2)
return 0;
}
if (!n)
return 0;
if (*s == ':') {
s++;
if (s[0] < '0' || s[0] > '9' || s[1] < '0' || s[1] > '9')
return 0;
m = (s[0] - '0') * 10 + s[1] - '0';
s += 2;
}
if ((*s && *s != ' ') || (m && m != 30 && m != 45))
return 0;
v = (uint16_t)h * 60 + m;
if (v > (neg ? 720 : 840))
return 0;
ntp_state.offset = neg ? -(int16_t)v : (int16_t)v;
return 1;
}
void ntp_parse(void) __banked __reentrant
{
if (cmd_compare(0, "time")) {
ntp_show_time();
return;
}
if (cmd_words_len < 2) {
ntp_show();
return;
}
if (cmd_compare(1, "on")) {
ntp_start();
return;
}
if (cmd_compare(1, "off")) {
ntp_stop();
return;
}
if (cmd_words_len < 3)
goto err;
if (cmd_compare(1, "server")) {
if (!ntp_cli_server())
goto err;
if (ntp_state.enabled)
ntp_start();
return;
}
if (cmd_compare(1, "interval")) {
if (!atoi_short(cmd_words_b[2]) || !atoi_results_short || atoi_results_short > 1440)
goto err;
ntp_state.interval = atoi_results_short;
return;
}
if (cmd_compare(1, "timezone")) {
if (!ntp_cli_timezone())
goto err;
return;
}
if (cmd_compare(1, "dst")) {
if (cmd_compare(2, "off"))
ntp_state.dst = NTP_DST_OFF;
else if (cmd_compare(2, "eu"))
ntp_state.dst = NTP_DST_EU;
else if (cmd_compare(2, "us"))
ntp_state.dst = NTP_DST_US;
else
goto err;
return;
}
err:
print_string("Error: ntp [on|off|server <name>|interval <1-1440>|timezone <+hh:mm>|dst off|eu|us]\n");
}