From 89cea59c554449ea44f677fff796e040211a3985 Mon Sep 17 00:00:00 2001 From: Bjoern Kerler Date: Sat, 13 Jan 2024 15:14:43 +0100 Subject: [PATCH] Add ntp server address to settings menu and ntp via dhcp support. Prepare manual ntp server ip entry. Add support for setting ntp ip addr manually via prusa_printer_settings.ini. Add ntp pool support. --- doc/prusa_printer_settings.ini | 2 + include/buddy/lwipopts.h | 44 ++++++++++--------- lib/WUI/netif_settings.h | 2 +- lib/WUI/sntp/sntp_client.c | 34 +++++++++----- lib/WUI/sntp/sntp_client.h | 5 ++- lib/WUI/sntp/sntp_opts.h | 2 +- lib/WUI/wui.cpp | 6 ++- lib/WUI/wui_api.cpp | 9 +++- lib/WUI/wui_api.h | 1 + src/gui/MItem_lan.cpp | 18 ++++++++ src/gui/MItem_lan.hpp | 15 +++++++ src/gui/screen_menu_network.cpp | 4 ++ src/gui/screen_menu_network.hpp | 2 +- .../config_store/constants.hpp | 1 - .../store_instances/config_store/defaults.hpp | 3 ++ .../config_store/store_definition.hpp | 3 ++ 16 files changed, 112 insertions(+), 39 deletions(-) diff --git a/doc/prusa_printer_settings.ini b/doc/prusa_printer_settings.ini index 6717ec16d1..cf9ad41f34 100644 --- a/doc/prusa_printer_settings.ini +++ b/doc/prusa_printer_settings.ini @@ -5,6 +5,8 @@ hostname=prusa # Printer support two dns servers. If variables are not empty, they will be used # even is DHCP pr AUTO type is set. dns4=192.168.0.1;192.168.0.2 +# ip or dns name for NTP server +ntp=pool.ntp.org [eth::ipv4] # Type could be DHCP, STATIC or OFF. diff --git a/include/buddy/lwipopts.h b/include/buddy/lwipopts.h index f90af900d5..583ca98c88 100644 --- a/include/buddy/lwipopts.h +++ b/include/buddy/lwipopts.h @@ -9,26 +9,30 @@ extern "C" { #include -#define WITH_RTOS 1 -#define MEM_LIBC_MALLOC 0 -#define CHECKSUM_BY_HARDWARE 0 -#define LWIP_DHCP 1 -#define MEM_ALIGNMENT 4 -#define MEMP_NUM_SYS_TIMEOUT 8 -#define LWIP_ETHERNET 1 -#define LWIP_DNS_SECURE 7 -#define DNS_MAX_NAME_LENGTH 128 - -#define TCP_MSS 1024 -#define TCP_WND (8 * TCP_MSS) -#define TCP_SND_BUF (2 * TCP_MSS) -#define LWIP_WND_SCALE 0 -#define TCP_RCV_SCALE 0 -#define PBUF_POOL_SIZE 10 -#define PBUF_POOL_SMALL_SIZE 12 -#define IP_REASS_MAX_PBUFS 15 -#define TCPIP_THREAD_STACKSIZE 1248 -#define TCPIP_MBOX_SIZE PBUF_POOL_SIZE + PBUF_POOL_SMALL_SIZE +#define WITH_RTOS 1 +#define MEM_LIBC_MALLOC 0 +#define CHECKSUM_BY_HARDWARE 0 +#define LWIP_DHCP 1 +#define MEM_ALIGNMENT 4 +#define MEMP_NUM_SYS_TIMEOUT 8 +#define LWIP_ETHERNET 1 +#define LWIP_DNS_SECURE 7 +#define DNS_MAX_NAME_LENGTH 128 +#define SNTP_SERVER_DNS 1 +#define SNTP_GET_SERVERS_FROM_DHCP 1 +#define SNTP_GET_SERVERS_FROM_DHCPV6 1 +#define LWIP_DHCP_GET_NTP_SRV 1 +#define SNTP_MAX_SERVERS 2 +#define TCP_MSS 1024 +#define TCP_WND (8 * TCP_MSS) +#define TCP_SND_BUF (2 * TCP_MSS) +#define LWIP_WND_SCALE 0 +#define TCP_RCV_SCALE 0 +#define PBUF_POOL_SIZE 10 +#define PBUF_POOL_SMALL_SIZE 12 +#define IP_REASS_MAX_PBUFS 15 +#define TCPIP_THREAD_STACKSIZE 1248 +#define TCPIP_MBOX_SIZE PBUF_POOL_SIZE + PBUF_POOL_SMALL_SIZE #define DEFAULT_UDP_RECVMBOX_SIZE TCPIP_MBOX_SIZE #define DEFAULT_TCP_RECVMBOX_SIZE TCPIP_MBOX_SIZE diff --git a/lib/WUI/netif_settings.h b/lib/WUI/netif_settings.h index b729eccfdb..1eb9b83472 100644 --- a/lib/WUI/netif_settings.h +++ b/lib/WUI/netif_settings.h @@ -1,7 +1,6 @@ #pragma once #include "lwip/ip_addr.h" - #define LAN_FLAG_ONOFF_POS (1 << 0) // position of ONOFF switch in lan.flag #define LAN_FLAG_TYPE_POS (1 << 1) // position of DHCP/STATIC switch in lan.flag @@ -33,6 +32,7 @@ typedef struct { ip_addr_t dns2_ip4; // user defined DNS #2 lan_t lan; // user defined LAN configurations uint32_t var_mask; // mask for setting ethvars + char ntp[DNS_MAX_NAME_LENGTH - 68 + 1]; // user defined NTP } ETH_config_t; // those bits were previously assigned to distinguish WPA/WEP/none diff --git a/lib/WUI/sntp/sntp_client.c b/lib/WUI/sntp/sntp_client.c index fbd4e1cf17..9c1add618e 100644 --- a/lib/WUI/sntp/sntp_client.c +++ b/lib/WUI/sntp/sntp_client.c @@ -1,30 +1,44 @@ #include "sntp.h" #include "sntp_client.h" #include "netdev.h" +#include "netif.h" +#include "netdb.h" -static ip_addr_t ntp_server; // testing ntp server located in Prague static uint32_t sntp_running = 0; // describes if sntp is currently running or not -void sntp_client_init(void) { +void sntp_client_static_init(const char *ntp_address) { sntp_setoperatingmode(SNTP_OPMODE_POLL); + sntp_servermode_dhcp(0); + sntp_setservername(0, ntp_address); + sntp_init(); +} - /* TODO: enable DNS for ntp.pool.org as default sntp server*/ - - // TMP: ip of Czech CESNET NTP server tak.cesnet.cz - if (ipaddr_aton("195.113.144.238", &ntp_server)) { - sntp_setserver(0, &ntp_server); - } +static void sntp_client_dhcp_init(const char *ntp_address) { + sntp_setoperatingmode(SNTP_OPMODE_POLL); + sntp_servermode_dhcp(1); + sntp_setservername(1, ntp_address); sntp_init(); } -void sntp_client_step(void) { +void sntp_client_step(bool ntp_via_dhcp, const char *ntp_address) { netdev_status_t eth = netdev_get_status(NETDEV_ETH_ID); netdev_status_t wifi = netdev_get_status(NETDEV_ESP_ID); if (!sntp_running && (eth == NETDEV_NETIF_UP || wifi == NETDEV_NETIF_UP)) { - sntp_client_init(); + if (ntp_via_dhcp) { + sntp_client_dhcp_init(ntp_address); + } else { + sntp_client_static_init(ntp_address); + } sntp_running = 1; } else if (sntp_running && eth != NETDEV_NETIF_UP && wifi != NETDEV_NETIF_UP) { sntp_stop(); sntp_running = 0; } } + +void sntp_client_stop() { + if (sntp_running) { + sntp_stop(); + sntp_running = 0; + } +} diff --git a/lib/WUI/sntp/sntp_client.h b/lib/WUI/sntp/sntp_client.h index 1d0b545afd..a44bb51064 100644 --- a/lib/WUI/sntp/sntp_client.h +++ b/lib/WUI/sntp/sntp_client.h @@ -5,8 +5,9 @@ extern "C" { #endif -void sntp_client_init(void); -void sntp_client_step(void); +void sntp_client_static_init(const char *ntp_address); +void sntp_client_step(bool ntp_via_dhcp, const char *ntp_ipv4_address); +void sntp_client_stop(void); #ifdef __cplusplus } diff --git a/lib/WUI/sntp/sntp_opts.h b/lib/WUI/sntp/sntp_opts.h index 74e582f33f..ebe500016e 100644 --- a/lib/WUI/sntp/sntp_opts.h +++ b/lib/WUI/sntp/sntp_opts.h @@ -78,7 +78,7 @@ * \#define SNTP_SERVER_ADDRESS "pool.ntp.org" */ #if !defined SNTP_SERVER_DNS || defined __DOXYGEN__ - #define SNTP_SERVER_DNS 0 + #define SNTP_SERVER_DNS 1 #endif /** diff --git a/lib/WUI/wui.cpp b/lib/WUI/wui.cpp index 78fec7170f..7844c35645 100644 --- a/lib/WUI/wui.cpp +++ b/lib/WUI/wui.cpp @@ -1,4 +1,5 @@ #include "wui.h" +#include "netdb.h" #include "netif_settings.h" #include "marlin_client.hpp" @@ -29,7 +30,7 @@ #include "main.h" #include #include "tasks.hpp" - +#include "sntp_client.h" #include "netdev.h" #include "otp.hpp" @@ -244,6 +245,7 @@ class NetworkState { // selected interface? dns_setserver(0, &cfg.dns1_ip4); dns_setserver(1, &cfg.dns2_ip4); + sntp_client_static_init((const char *)&cfg.ntp); netifapi_netif_set_addr(&iface.dev, &cfg.lan.addr_ip4, &cfg.lan.msk_ip4, &cfg.lan.gw_ip4); netifapi_dhcp_inform(&iface.dev); break; @@ -408,7 +410,7 @@ class NetworkState { // TODO: This does some code gymnastics inside to track changes // of network configuration. Consider cleaning that up and // integrating into some kind of up/down mechanism. - sntp_client_step(); + sntp_client_step(config_store().ntp_via_dhcp.get(), config_store().ntp_addr.get_c_str()); } if (events & HealthCheck) { diff --git a/lib/WUI/wui_api.cpp b/lib/WUI/wui_api.cpp index 3498bf2183..6bc076b5f4 100644 --- a/lib/WUI/wui_api.cpp +++ b/lib/WUI/wui_api.cpp @@ -80,6 +80,9 @@ static int ini_handler_func(void *user, const char *section, const char *name, c if (ip4addr_aton(value, &tmp_config->lan.gw_ip4)) { tmp_config->var_mask |= ETHVAR_MSK(ETHVAR_LAN_GW_IP4); } + } else if (ini_string_match(section, "network", name, "ntp")) { + strlcpy(tmp_config->ntp, value, DNS_MAX_NAME_LENGTH - 68 + 1); + tmp_config->var_mask |= ETHVAR_MSK(ETHVAR_NTP_ADDRESS); } else if (ini_string_match(section, "network", name, "dns4")) { if (NULL != strchr(value, ';')) { @@ -169,7 +172,9 @@ void save_net_params(ETH_config_t *ethconfig, ap_entry_t *ap, uint32_t netdev_id netdev_id == NETDEV_ETH_ID ? config_store().lan_hostname.set(ethconfig->hostname) : config_store().wifi_hostname.set(ethconfig->hostname); } - + if (ethconfig->var_mask & ETHVAR_MSK(ETHVAR_NTP_ADDRESS)) { + config_store().ntp_addr.set(ethconfig->ntp); + } if (ap != NULL) { assert(netdev_id == NETDEV_ESP_ID); static_assert(SSID_MAX_LEN == config_store_ns::wifi_max_ssid_len); @@ -194,6 +199,7 @@ void load_net_params(ETH_config_t *ethconfig, ap_entry_t *ap, uint32_t netdev_id ethconfig->dns2_ip4.addr = config_store().lan_ip4_dns2.get(); ethconfig->lan.msk_ip4.addr = config_store().lan_ip4_mask.get(); ethconfig->lan.gw_ip4.addr = config_store().lan_ip4_gateway.get(); + strlcpy(ethconfig->ntp, config_store().ntp_addr.get_c_str(), DNS_MAX_NAME_LENGTH - 68 + 1); strlcpy(ethconfig->hostname, config_store().lan_hostname.get_c_str(), ETH_HOSTNAME_LEN + 1); } else { ethconfig->lan.flag = config_store().wifi_flag.get() & ~RESERVED_MASK; @@ -202,6 +208,7 @@ void load_net_params(ETH_config_t *ethconfig, ap_entry_t *ap, uint32_t netdev_id ethconfig->dns2_ip4.addr = config_store().wifi_ip4_dns2.get(); ethconfig->lan.msk_ip4.addr = config_store().wifi_ip4_mask.get(); ethconfig->lan.gw_ip4.addr = config_store().wifi_ip4_gateway.get(); + strlcpy(ethconfig->ntp, config_store().ntp_addr.get_c_str(), DNS_MAX_NAME_LENGTH - 68 + 1); strlcpy(ethconfig->hostname, config_store().wifi_hostname.get_c_str(), ETH_HOSTNAME_LEN + 1); } diff --git a/lib/WUI/wui_api.h b/lib/WUI/wui_api.h index 195423c398..315e0a3851 100644 --- a/lib/WUI/wui_api.h +++ b/lib/WUI/wui_api.h @@ -48,6 +48,7 @@ typedef enum { ETHVAR_DNS1_IP4, // ip_addr_t, dns1_ip4 ETHVAR_DNS2_IP4, // ip_addr_t, dns2_ip4 ETHVAR_MAC_ADDRESS, // is not included in ethconfig (used in stringifying for screen) + ETHVAR_NTP_ADDRESS, // char[60+1], hostname or ip APVAR_SSID, // char[32 + 1], ap_entry_t::ssid APVAR_PASS, // char[64 + 1], ap_entry_t::pass diff --git a/src/gui/MItem_lan.cpp b/src/gui/MItem_lan.cpp index 8f89d2f8aa..5d10fc7b64 100644 --- a/src/gui/MItem_lan.cpp +++ b/src/gui/MItem_lan.cpp @@ -6,9 +6,12 @@ #include "MItem_lan.hpp" #include "wui_api.h" +#include "wui.h" #include "netdev.h" #include "ScreenHandler.hpp" #include "marlin_client.hpp" +#include "sntp.h" +#include "sntp_client.h" MI_WIFI_STATUS_t::MI_WIFI_STATUS_t() : WI_INFO_t(_(label), nullptr, is_enabled_t::yes, is_hidden_t::dev) { @@ -83,3 +86,18 @@ MI_IP4_GWAY::MI_IP4_GWAY() MI_MAC_ADDR::MI_MAC_ADDR() : WiInfo(_(label), nullptr, is_enabled_t::yes, is_hidden_t::no) { } + +MI_NTP_ADDR::MI_NTP_ADDR() + : WiInfo(_(label), nullptr, is_enabled_t::yes, is_hidden_t::no) { +} + +/*****************************************************************************/ +// MI_NTP_VIA_DHCP +MI_NTP_VIA_DHCP::MI_NTP_VIA_DHCP() + : WI_ICON_SWITCH_OFF_ON_t(bool(config_store().ntp_via_dhcp.get()), _(label), nullptr, is_enabled_t::yes, is_hidden_t::no) {} + +void MI_NTP_VIA_DHCP::OnChange(size_t /*old_index*/) { + bool enabled = config_store().ntp_via_dhcp.get(); + config_store().ntp_via_dhcp.set(!enabled); + notify_reconfigure(); +} diff --git a/src/gui/MItem_lan.hpp b/src/gui/MItem_lan.hpp index 08509c220a..8d245e202b 100644 --- a/src/gui/MItem_lan.hpp +++ b/src/gui/MItem_lan.hpp @@ -117,3 +117,18 @@ class MI_MAC_ADDR : public WiInfo { public: MI_MAC_ADDR(); }; + +class MI_NTP_ADDR : public WiInfo { + static constexpr const char *const label = GuiDefaults::ScreenWidth > 240 ? N_("NTP Address") : N_("NTP"); + +public: + MI_NTP_ADDR(); +}; + +class MI_NTP_VIA_DHCP : public WI_ICON_SWITCH_OFF_ON_t { + constexpr static const char *const label = N_("NTP via DHCP"); + +public: + MI_NTP_VIA_DHCP(); + virtual void OnChange(size_t old_index) override; +}; diff --git a/src/gui/screen_menu_network.cpp b/src/gui/screen_menu_network.cpp index bed6d0fb69..b9c58fc012 100644 --- a/src/gui/screen_menu_network.cpp +++ b/src/gui/screen_menu_network.cpp @@ -8,6 +8,7 @@ #include "netdev.h" #include "network_gui_tools.hpp" #include +#include ScreenMenuNetwork::ScreenMenuNetwork() : ScreenMenuNetwork__(_(label)) { @@ -27,8 +28,11 @@ void ScreenMenuNetwork::refresh_address() { netdev_get_ipv4_addresses(active_netdev, ðconfig); stringify_address_for_screen(str, sizeof(str), ethconfig, ETHVAR_MSK(ETHVAR_LAN_ADDR_IP4)); Item().ChangeInformation(str); + const ip_addr_t *ntp_server = sntp_getserver(0); + Item().ChangeInformation(ipaddr_ntoa(ntp_server)); } else { Item().ChangeInformation(UNKNOWN_ADDR); + Item().ChangeInformation(UNKNOWN_ADDR); } } diff --git a/src/gui/screen_menu_network.hpp b/src/gui/screen_menu_network.hpp index d4f23cbfe1..9b04bcaaed 100644 --- a/src/gui/screen_menu_network.hpp +++ b/src/gui/screen_menu_network.hpp @@ -15,7 +15,7 @@ using ScreenMenuNetwork__ = ScreenMenu; + MI_NET_INTERFACE_t, MI_IP4_ADDR, MI_MAC_ADDR, MI_NTP_VIA_DHCP, MI_NTP_ADDR, MI_METRICS_SETTINGS, MI_ETH_SETTINGS, MI_WIFI_SETTINGS>; class ScreenMenuNetwork : public ScreenMenuNetwork__ { public: diff --git a/src/persistent_stores/store_instances/config_store/constants.hpp b/src/persistent_stores/store_instances/config_store/constants.hpp index 6f2dd246a3..8373bf5d90 100644 --- a/src/persistent_stores/store_instances/config_store/constants.hpp +++ b/src/persistent_stores/store_instances/config_store/constants.hpp @@ -37,7 +37,6 @@ inline constexpr size_t connect_token_size { old_eeprom::CONNECT_TOKEN_SIZE }; inline constexpr size_t pl_password_size { old_eeprom::PL_PASSWORD_SIZE }; inline constexpr size_t wifi_max_ssid_len { old_eeprom::WIFI_MAX_SSID_LEN }; inline constexpr size_t wifi_max_passwd_len { old_eeprom::WIFI_MAX_PASSWD_LEN }; - inline constexpr size_t metrics_host_size { connect_host_size }; ///< Size of metrics host string inline constexpr int16_t stallguard_sensitivity_unset { std::numeric_limits::max() }; } // namespace config_store_ns diff --git a/src/persistent_stores/store_instances/config_store/defaults.hpp b/src/persistent_stores/store_instances/config_store/defaults.hpp index 996715290b..3d3f4ca8d1 100644 --- a/src/persistent_stores/store_instances/config_store/defaults.hpp +++ b/src/persistent_stores/store_instances/config_store/defaults.hpp @@ -12,6 +12,7 @@ #include #include #include +#include "lwipopts.h" namespace config_store_ns { @@ -80,6 +81,8 @@ namespace defaults { inline constexpr std::array wifi_ap_ssid { "" }; inline constexpr std::array wifi_ap_password { "" }; + inline constexpr std::array ntp_server { "pool.ntp.org" }; + inline constexpr eSOUND_MODE sound_mode { eSOUND_MODE::_undef }; inline constexpr uint8_t sound_volume { 5 }; inline constexpr uint16_t language { 0xffff }; diff --git a/src/persistent_stores/store_instances/config_store/store_definition.hpp b/src/persistent_stores/store_instances/config_store/store_definition.hpp index e3e97d32cb..39fc7fe2cb 100644 --- a/src/persistent_stores/store_instances/config_store/store_definition.hpp +++ b/src/persistent_stores/store_instances/config_store/store_definition.hpp @@ -64,6 +64,9 @@ struct CurrentStore : public journal::CurrentStoreConfig timezone_minutes; // minutes offset for hour difference from UTC StoreItem timezone_summer; // Summertime hour offset + StoreItem ntp_via_dhcp; // use dhcp server for ntp + StoreItem, defaults::ntp_server, journal::hash("NTP Address")> ntp_addr; // X.X.X.X address encoded or string + // WIFI settings // wifi_flag & 1 -> On = 0/off = 1, lan_flag & 2 -> dhcp = 0/static = 1, wifi_flag & 0b1100 -> reserved, previously ap_sec_t security StoreItem wifi_flag;