[Network] Fix import/export for WiFi STA and AP

This commit is contained in:
TD-er
2026-07-16 17:47:45 +02:00
parent aaf43fa423
commit 99b910b806
4 changed files with 116 additions and 96 deletions
@@ -44,6 +44,26 @@ The fallback order can be tweaked using the Delay Startup and Route Priority.
N.B. Network interfaces which should be started at boot, should not be marked as Fallback Interface.
Delay Startup
^^^^^^^^^^^^^
For various reasons, it can be useful to not immediately start a network interface at boot.
For example to reduce the power consumption as most network interfaces may draw significant more power for a short time when starting.
Another use case can be to check some sensor value before deciding to either start the network interface or enter deep sleep again.
The set value (in msec) is the delay from boot before starting the network interface.
Delay Startup for Fallback Interface
""""""""""""""""""""""""""""""""""""
A Fallback Interface is not started at boot.
The set Delay Startup is then used as delay to schedule starting the network interface.
See "Fallback Interface" for more information.
Append Name to Hostname
^^^^^^^^^^^^^^^^^^^^^^^
@@ -59,23 +79,6 @@ This will be used in for example DHCP requests and when using mDNS.
Default setting is to have it disabled for WiFi STA and enabled for all other network interfaces.
Delay Startup
^^^^^^^^^^^^^
For various reasons, it can be useful to not immediately start a network interface at boot.
For example to reduce the power consumption as most network interfaces may draw significant more power for a short time when starting.
Another use case can be to check some sensor value before deciding to either start the network interface or enter deep sleep again.
The set value (in msec) is the delay from boot before starting the network interface.
Delay Startup for Fallback Interface
""""""""""""""""""""""""""""""""""""
A Fallback Interface is not started at boot.
The set Delay Startup is then used as delay to schedule starting the network interface.
See "Fallback Interface" for more information.
Block Web Access
^^^^^^^^^^^^^^^^
@@ -116,20 +116,6 @@ String NWPlugin_import_export::exportConfig(
if (!nwpluginID.isValid()) { return F("KVS : Invalid NW-Plugin ID"); }
ESPEasy_key_value_store kvs;
if (!kvs.load(
SettingsType::Enum::NetworkInterfaceSettings_Type,
networkIndex,
0,
nwpluginID.value)) { return F("KVS : Failed loading"); }
auto labelFnc = getLabelFnc(nwpluginID);
auto nextKeyFnc = getNextKeyFnc(nwpluginID, includeCredentials);
if ((labelFnc == nullptr) || (nextKeyFnc == nullptr)) {
return F("KVS : NWPlugin ID does not support import/export");
}
auto child = writer->createChild();
if (child) {
@@ -139,22 +125,36 @@ String NWPlugin_import_export::exportConfig(
child->write({ F("fallback"), Settings.getNetworkInterface_isFallback(networkIndex) });
child->write({ F("sn_block"), Settings.getNetworkInterfaceSubnetBlockClientIP(networkIndex) });
child->write({ F("start_delay"), Settings.getNetworkInterfaceStartupDelay(networkIndex) });
#ifdef ESP32
# ifdef ESP32
child->write({ F("append_hostname"), Settings.getAppendNetworkAdapterNameToHostname(networkIndex) });
#endif
# endif
# if FEATURE_USE_IPV6
child->write({ F("en_ipv6"), Settings.getNetworkEnabled_IPv6(networkIndex) });
# endif
ESPEasy_key_value_store_import_export e(&kvs);
ESPEasy_key_value_store kvs;
int32_t key = nextKeyFnc(-1);
if (kvs.load(
SettingsType::Enum::NetworkInterfaceSettings_Type,
networkIndex,
0,
nwpluginID.value)) {
while (key >= 0) {
e.do_export(key, child.get(), labelFnc);
key = nextKeyFnc(key);
auto labelFnc = getLabelFnc(nwpluginID);
auto nextKeyFnc = getNextKeyFnc(nwpluginID, includeCredentials);
if ((labelFnc != nullptr) && (nextKeyFnc != nullptr)) {
ESPEasy_key_value_store_import_export e(&kvs);
int32_t key = nextKeyFnc(-1);
while (key >= 0) {
e.do_export(key, child.get(), labelFnc);
key = nextKeyFnc(key);
}
}
}
}
return EMPTY_STRING;
@@ -168,8 +168,6 @@ String NWPlugin_import_export::importConfig(
ESPEasy::net::nwpluginID_t nwpluginID(Settings.NWPluginID[networkIndex]);
if (nwpluginID.isValid()) { return F("KVS : Network Index is already in use"); }
# ifndef BUILD_NO_DEBUG
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
@@ -184,78 +182,89 @@ String NWPlugin_import_export::importConfig(
if (!e.getParsedJSON(F("nwpluginID"), value)) { return F("KVS : No NWPlugin ID"); }
nwpluginID.value = value.toInt();
}
if (!nwpluginID.isValid()) { return F("KVS : No valid NWPlugin ID"); }
if (!nwpluginID.isValid()) { return F("KVS : No valid NWPlugin ID"); }
const ESPEasy::net::nwpluginID_t cur_nwpluginID(Settings.NWPluginID[networkIndex]);
if (cur_nwpluginID.isValid() && (nwpluginID != cur_nwpluginID)) {
return F("KVS : Network Index is already in use");
}
}
auto labelFnc = getLabelFnc(nwpluginID);
auto nextKeyFnc = getNextKeyFnc(nwpluginID, true);
if ((labelFnc == nullptr) || (nextKeyFnc == nullptr)) {
return F("KVS : NWPlugin ID does not support import/export");
if ((labelFnc != nullptr) && (nextKeyFnc != nullptr)) {
const String res = e.do_import(labelFnc, nextKeyFnc);
if (!res.isEmpty()) {
return res;
}
}
# ifndef BUILD_NO_DEBUG
else {
addLog(LOG_LEVEL_DEBUG, F("KVS : NWPlugin ID does not support import/export"));
}
# endif // ifndef BUILD_NO_DEBUG
// Add entry, calls NWPLUGIN_LOAD_DEFAULTS
Settings.setNWPluginID_for_network(networkIndex, nwpluginID);
if (!kvs.store(
SettingsType::Enum::NetworkInterfaceSettings_Type,
networkIndex,
0,
nwpluginID.value))
{
return F("KVS : Error saving, see log for more details");
}
String res = e.do_import(labelFnc, nextKeyFnc);
if (res.isEmpty()) {
// Add entry, calls NWPLUGIN_LOAD_DEFAULTS
Settings.setNWPluginID_for_network(networkIndex, nwpluginID);
if (!kvs.store(
SettingsType::Enum::NetworkInterfaceSettings_Type,
networkIndex,
0,
nwpluginID.value))
{
return F("KVS : Error saving, see log for more details");
}
const String non_kvs_keys[] = {
F("enabled"),
F("route_prio"),
F("fallback"),
F("sn_block"),
F("start_delay"),
F("append_hostname") // Need to have something here even though it is ESP32-only as the code would otherwise become quite complex
const String non_kvs_keys[] = {
F("enabled"),
F("route_prio"),
F("fallback"),
F("sn_block"),
F("start_delay"),
F("append_hostname") // Need to have something here even though it is ESP32-only as the code would otherwise become quite complex
# if FEATURE_USE_IPV6
, F("en_ipv6")
, F("en_ipv6")
# endif
};
};
for (size_t i = 0; i < NR_ELEMENTS(non_kvs_keys); ++i) {
String value;
for (size_t i = 0; i < NR_ELEMENTS(non_kvs_keys); ++i) {
String value;
if (e.getParsedJSON(non_kvs_keys[i], value))
if (e.getParsedJSON(non_kvs_keys[i], value))
{
const bool bool_val = !(value.equalsIgnoreCase(F("false")) || value.equals(F("0")));
switch (i)
{
const bool bool_val = !(value.equalsIgnoreCase(F("false")) || value.equals(F("0")));
switch (i)
{
case 0: Settings.setNetworkEnabled(networkIndex, bool_val);
break;
case 1: Settings.setRoutePrio_for_network(networkIndex, value.toInt());
break;
case 2: Settings.setNetworkInterface_isFallback(networkIndex, bool_val);
break;
case 3: Settings.setNetworkInterfaceSubnetBlockClientIP(networkIndex, bool_val);
break;
case 4: Settings.setNetworkInterfaceStartupDelay(networkIndex, value.toInt());
break;
case 5:
#ifdef ESP32
Settings.setAppendNetworkAdapterNameToHostname(networkIndex, bool_val);
#endif
break;
case 0: Settings.setNetworkEnabled(networkIndex, bool_val);
break;
case 1: Settings.setRoutePrio_for_network(networkIndex, value.toInt());
break;
case 2: Settings.setNetworkInterface_isFallback(networkIndex, bool_val);
break;
case 3: Settings.setNetworkInterfaceSubnetBlockClientIP(networkIndex, bool_val);
break;
case 4: Settings.setNetworkInterfaceStartupDelay(networkIndex, value.toInt());
break;
case 5:
# ifdef ESP32
Settings.setAppendNetworkAdapterNameToHostname(networkIndex, bool_val);
# endif
break;
# if FEATURE_USE_IPV6
case 6: Settings.setNetworkEnabled_IPv6(networkIndex, bool_val);
break;
case 6: Settings.setNetworkEnabled_IPv6(networkIndex, bool_val);
break;
# endif // if FEATURE_USE_IPV6
}
}
}
}
return res;
return EMPTY_STRING;
}
} // namespace net
@@ -1510,6 +1510,14 @@ template<uint32_t N_TASKS>
void SettingsStruct_tmpl<N_TASKS>::setNWPluginID_for_network(ESPEasy::net::networkIndex_t index, ESPEasy::net::nwpluginID_t id)
{
if (validNetworkIndex(index)) {
if (index == 0 && id.value != 1) {
// STA index, only allow to set WiFi STA here
return;
}
if (index == 1 && id.value != 2) {
// AP index, only allow to set WiFi AP here
return;
}
NWPluginID[index] = id.value;
if (id.isValid()) {
ESPEasy::net::networkDriverIndex_t NetworkDriverIndex =
+2 -2
View File
@@ -152,7 +152,7 @@ void handle_networks_CopySubmittedSettings_NWPluginCall(ESPEasy::net::networkInd
# ifdef ESP32
Settings.setRoutePrio_for_network(networkindex, getFormItemInt(F("routeprio"), 0));
Settings.setNetworkInterface_isFallback(networkindex, isFormItemChecked(F("fallback")));
Settings.setAppendNetworkAdapterNameToHostname(networkindex, isFormItemChecked(F("appendtohostname")));
Settings.setAppendNetworkAdapterNameToHostname(networkindex, isFormItemChecked(F("append_hostname")));
Settings.setNetworkInterfaceSubnetBlockClientIP(networkindex, isFormItemChecked(F("block_web_access")));
# endif // ifdef ESP32
# ifdef ESP8266
@@ -389,7 +389,6 @@ void handle_networks_NetworkSettingsPage(ESPEasy::net::networkIndex_t networkind
0, 255);
addFormNote(F("The active interface with highest priority will be used for default route (gateway)."));
addFormCheckBox(F("Fallback Interface"), F("fallback"), Settings.getNetworkInterface_isFallback(networkindex));
addFormCheckBox(F("Append Name to Hostname"), F("appendtohostname"), Settings.getAppendNetworkAdapterNameToHostname(networkindex));
# endif // ifdef ESP32
# ifdef ESP8266
@@ -403,6 +402,7 @@ void handle_networks_NetworkSettingsPage(ESPEasy::net::networkIndex_t networkind
# ifdef ESP32
addFormNote(F(
"For fallback interface, it is the delay after connection of primary interface has failed. For non-fallback it is the delay from boot"));
addFormCheckBox(F("Append Name to Hostname"), F("append_hostname"), Settings.getAppendNetworkAdapterNameToHostname(networkindex));
# endif // ifdef ESP32
addFormCheckBox(F("Block Web Access"), F("block_web_access"), Settings.getNetworkInterfaceSubnetBlockClientIP(networkindex));
addFormNote(F("When checked, any host from a subnet on this network interface will be blocked to access the ESPEasy web interface"));