diff --git a/doc/prusa_printer_settings.ini b/doc/prusa_printer_settings.ini index 6717ec16d1..18c17e0514 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 of Czech CESNET NTP server tak.cesnet.cz +ntp4=195.113.144.238 [eth::ipv4] # Type could be DHCP, STATIC or OFF. diff --git a/include/buddy/lwipopts.h b/include/buddy/lwipopts.h index f90af900d5..6dd207f667 100644 --- a/include/buddy/lwipopts.h +++ b/include/buddy/lwipopts.h @@ -9,15 +9,16 @@ 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 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_GET_SERVERS_FROM_DHCP 1 #define TCP_MSS 1024 #define TCP_WND (8 * TCP_MSS) diff --git a/lib/WUI/netif_settings.h b/lib/WUI/netif_settings.h index b729eccfdb..b297a9ed30 100644 --- a/lib/WUI/netif_settings.h +++ b/lib/WUI/netif_settings.h @@ -33,6 +33,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 + ip_addr_t ntp_ip4; // 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..c2a77ec8d2 100644 --- a/lib/WUI/sntp/sntp_client.c +++ b/lib/WUI/sntp/sntp_client.c @@ -1,30 +1,47 @@ #include "sntp.h" #include "sntp_client.h" #include "netdev.h" +#include "netif.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(ip4_addr_t *ntp_ipv4_address) { sntp_setoperatingmode(SNTP_OPMODE_POLL); + sntp_servermode_dhcp(0); +#if LWIP_IPV4 + sntp_setserver(0, ntp_ipv4_address); +#endif /* LWIP_IPV4 */ + 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); - } +void sntp_client_dhcp_init(ip4_addr_t *ntp_ipv4_address) { + sntp_setoperatingmode(SNTP_OPMODE_POLL); + sntp_servermode_dhcp(1); +#if LWIP_IPV4 + sntp_setserver(0, ntp_ipv4_address); +#endif /* LWIP_IPV4 */ sntp_init(); } -void sntp_client_step(void) { +void sntp_client_step(bool ntp_via_dhcp, ip4_addr_t *ntp_ipv4_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_ipv4_address); + } else { + sntp_client_static_init(ntp_ipv4_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..f82a807771 100644 --- a/lib/WUI/sntp/sntp_client.h +++ b/lib/WUI/sntp/sntp_client.h @@ -5,8 +5,10 @@ extern "C" { #endif -void sntp_client_init(void); -void sntp_client_step(void); +void sntp_client_static_init(ip4_addr_t *ntp_ipv4_address); +void sntp_client_dhcp_init(ip4_addr_t *ntp_ipv4_address); +void sntp_client_step(bool ntp_via_dhcp, ip4_addr_t *ntp_ipv4_address); +void sntp_client_stop(void); #ifdef __cplusplus } diff --git a/lib/WUI/wui.cpp b/lib/WUI/wui.cpp index 78fec7170f..a3babeccfc 100644 --- a/lib/WUI/wui.cpp +++ b/lib/WUI/wui.cpp @@ -29,7 +29,7 @@ #include "main.h" #include #include "tasks.hpp" - +#include "sntp_client.h" #include "netdev.h" #include "otp.hpp" @@ -244,6 +244,8 @@ class NetworkState { // selected interface? dns_setserver(0, &cfg.dns1_ip4); dns_setserver(1, &cfg.dns2_ip4); + ip4_addr_t ntp_ipv4 { .addr = cfg.ntp_ip4.addr }; + sntp_client_static_init(&ntp_ipv4); 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,8 @@ 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(); + ip4_addr_t ntp_ipv4 = { .addr = config_store().lan_ntp_ip4_addr.get() }; + sntp_client_step(config_store().lan_ntp_via_dhcp.get(), &ntp_ipv4); } if (events & HealthCheck) { diff --git a/lib/WUI/wui_api.cpp b/lib/WUI/wui_api.cpp index 3498bf2183..8b35e4cdbd 100644 --- a/lib/WUI/wui_api.cpp +++ b/lib/WUI/wui_api.cpp @@ -80,6 +80,10 @@ 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, "ntp4")) { + if (ip4addr_aton(value, &tmp_config->ntp_ip4)) { + tmp_config->var_mask |= ETHVAR_MSK(ETHVAR_NTP_ADDR_IP4); + } } else if (ini_string_match(section, "network", name, "dns4")) { if (NULL != strchr(value, ';')) { @@ -169,7 +173,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_ADDR_IP4)) { + config_store().lan_ntp_ip4_addr.set(ethconfig->ntp_ip4.addr); + } if (ap != NULL) { assert(netdev_id == NETDEV_ESP_ID); static_assert(SSID_MAX_LEN == config_store_ns::wifi_max_ssid_len); @@ -194,6 +200,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(); + ethconfig->ntp_ip4.addr = config_store().lan_ntp_ip4_addr.get(); 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 +209,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(); + ethconfig->ntp_ip4.addr = config_store().lan_ntp_ip4_addr.get(); 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..1a100bd732 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_ADDR_IP4, // ip_addr_t, ntp_ip4 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..7829f6e2fb 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_IP4_ADDR::MI_NTP_IP4_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().lan_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().lan_ntp_via_dhcp.get(); + config_store().lan_ntp_via_dhcp.set(!enabled); + notify_reconfigure(); +} diff --git a/src/gui/MItem_lan.hpp b/src/gui/MItem_lan.hpp index 08509c220a..530884ddcf 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_IP4_ADDR : public WiInfo { + static constexpr const char *const label = GuiDefaults::ScreenWidth > 240 ? N_("NTP IPv4 Address") : N_("NTP IP"); + +public: + MI_NTP_IP4_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..2724cb034e 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..aa925ab292 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_IP4_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/defaults.hpp b/src/persistent_stores/store_instances/config_store/defaults.hpp index 2c9ecf4814..2419654358 100644 --- a/src/persistent_stores/store_instances/config_store/defaults.hpp +++ b/src/persistent_stores/store_instances/config_store/defaults.hpp @@ -78,6 +78,9 @@ namespace defaults { inline constexpr std::array wifi_ap_ssid { "" }; inline constexpr std::array wifi_ap_password { "" }; + // default ntp server: ip of Czech CESNET NTP server tak.cesnet.cz, until user changable + inline constexpr uint32_t ntp_server { 4002443715 }; // 4002443715 = rev32(3278999790) => "195.113.144.238" + 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 bc35d13d4f..3db3a862f9 100644 --- a/src/persistent_stores/store_instances/config_store/store_definition.hpp +++ b/src/persistent_stores/store_instances/config_store/store_definition.hpp @@ -58,10 +58,13 @@ struct CurrentStore : public journal::CurrentStoreConfig lan_ip4_gateway; // X.X.X.X address encoded StoreItem lan_ip4_dns1; // X.X.X.X address encoded StoreItem lan_ip4_dns2; // X.X.X.X address encoded + StoreItem lan_ntp_ip4_addr; // X.X.X.X address encoded StoreItem, defaults::net_hostname, journal::hash("LAN Hostname")> lan_hostname; StoreItem timezone; // hour difference from UTC + StoreItem lan_ntp_via_dhcp; // use dhcp server for ntp + // 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;