Merge branch 'mega' of https://github.com/letscontrolit/ESPEasy into feature/Menu-interfaces-split-into-tabs

This commit is contained in:
Ton Huisman
2026-03-17 21:23:55 +01:00
45 changed files with 559 additions and 207 deletions
+2
View File
@@ -91,3 +91,5 @@ src/src/CustomBuild/CompiletimeDefines_generated.h
sdkconfig.normal_ESP32solo1_4M316k
src/Custom_.h
+87 -1
View File
@@ -11,12 +11,22 @@ The first 2 entries will be the same for every ESPEasy setup and these cannot be
- Wi-Fi AP: To let the ESP board act as an access point.
.. note::
The network code of ESPEasy has been rewritten in 2025/2026.
Older builds of ESPEasy do have a different organisation of network related parameters.
Most of these were accessible via the ``Tools->Advanced`` page.
.. _Network Plugins:
Network Plugins
==================
.. note::
ESP32 builds do have a lot more networking capabilities compared to ESP8266.
For ESP8266 we only have support for WiFi and no other network interfaces will be added for ESP8266.
.. csv-table::
:header: "Plugin name", "Plugin status", "Plugin number"
:widths: 10, 8, 5
@@ -28,4 +38,80 @@ Network Plugins
":ref:`NW005_page`","|NW005_status|","NW005"
Network Parameters
=====================
==================
Route Priority
--------------
(ESP32 only)
When using multiple network interfaces, like WiFi, Ethernet or PPP LTE Modem, it must be made clear which interface should be used for new connections initiated from ESPEasy to some other host.
The connected network interface with the highest Route Priority is considered to be the default route.
Default Route Priority values are:
* WiFi STA = 100
* Ethernet = 50
* PPP (LTE modem) = 20
* WiFi AP = 10
Fallback Interface
------------------
(ESP32 only)
.. note::
The concept of a Fallback Interface is available on ESP8266, but only for WiFi AP.
This is a special case, which is discussed here: :ref:`NW002_page` .
A network interface can be marked as "Fallback Interface".
A fallback interface will only be scheduled to start when:
* A non-fallback interface failed to connect.
* Route Priority changed to a value which is less than the set priority for the fallback interface.
The scheduled delay to start the fallback interface is set as "Delay Startup" (see below).
A fallback interface will be stopped when there is a default route with a route priority higher than the set Route Priority of the fallback interface.
It is possible to set multiple interfaces as Fallback Interface.
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.
Block Web Access
----------------
When checked, the ESPEasy web interface cannot be accessed via the IP-range of the network interface.
.. note::
The PPP Network Interface (ESP32-only) will have this checked by default, since you typically can't access devices from the network of the mobile provider.
If this is possible for some odd reason, you very likely would never want to allow this.
Enable IPv6
-----------
(ESP32 only)
Checking this checkbox, will allow the network device to use IPv6.
+26 -4
View File
@@ -67,6 +67,7 @@ lib_ignore = ESP32_ping
; See: https://github.com/platformio/platform-espressif8266/issues/288
; For "-fno-strict-aliasing"
; See: https://github.com/esp8266/Arduino/issues/8261
; Suggestion to go for -Os: https://www.youtube.com/watch?v=cqHH2NXcf5E
[esp82xx_2_7_x]
build_flags = -DNDEBUG
-mtarget-align
@@ -83,7 +84,7 @@ build_flags = -DNDEBUG
-DNO_GLOBAL_I2S
-I$PROJECT_DIR/src/include
-include "ESPEasy_config.h"
-O2
-Os
-s
-DBEARSSL_SSL_BASIC
-DCORE_POST_2_6_0
@@ -170,8 +171,11 @@ extra_scripts = ${esp82xx_common.extra_scripts}
;platform = https://github.com/Jason2866/platform-espressif32.git#23aed73e4e570d3b6608c15677fea01d6a722d94
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1311-2008-5.5_orig/framework-arduinoespressif32-release_v5.5_orig-276436da.tar.xz
platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc15
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1002-1125-5.5_gcc151/framework-arduinoespressif32-release_v5.5_gcc151-7eede06a.tar.xz
;platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc15
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1002-1125-5.5_gcc151/framework-arduinoespressif32-release_v5.5_gcc151-7eede06a.tar.xz
platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152
platform_packages =
custom_remove_include = true
@@ -208,8 +212,26 @@ build_flags = -DESP32_STAGE
-include "ESPEasy_config.h"
-include "esp32x_fixes.h"
-DUPDATE_NOCRYPT
-O3
-Os
; -Wnull-dereference
-DNO_GLOBAL_ESP_NOW
-DNO_GLOBAL_EEPROM
-DNO_GLOBAL_INSIGHTS
-DNO_GLOBAL_NETBIOS
-DNO_GLOBAL_OPENTHREAD
-DNO_GLOBAL_MATTER
-DNO_GLOBAL_ZIGBEE
-DNO_GLOBAL_SPIFFS
-DNO_GLOBAL_OPENTHREADCLI
-DNO_GLOBAL_WIFIPROV
lib_ignore = BLE
Zigbee
ESP RainMaker
+2 -2
View File
@@ -277,12 +277,12 @@ build_flags = ${ir.build_flags}
; Keep optimization flag to -O2
; See: https://github.com/platformio/platform-espressif8266/issues/288
; Suggestion to go for -Os: https://www.youtube.com/watch?v=cqHH2NXcf5E
[esp82xx_1M]
extends = esp82xx_common
build_flags = -DBUILD_NO_DEBUG
-DFEATURE_SD=0
-O2
-Os
-s
-DNO_GLOBAL_MDNS
${esp82xx_common.build_flags}
@@ -59,6 +59,17 @@ NWPluginData_base::~NWPluginData_base()
#endif // if FEATURE_STORE_NETWORK_INTERFACE_SETTINGS
}
#ifdef ESP32
bool NWPluginData_base::isDefaultRoute() const {
if (_netif) {
return _netif->isDefault();
}
return false;
}
#endif
bool NWPluginData_base::hasPluginStats() const {
#if FEATURE_NETWORK_STATS
@@ -39,6 +39,10 @@ struct NWPluginData_base {
virtual bool exit(EventStruct *event) = 0;
#ifdef ESP32
virtual bool isDefaultRoute() const;
#endif
bool hasPluginStats() const;
bool hasPeaks() const;
@@ -103,6 +103,8 @@ struct NWPluginData_static_runtime {
void mark_disconnected();
void log_disconnected();
void mark_connect_failed();
// =============================================
// Keep track of connection durations
// per host/interface
@@ -108,7 +108,7 @@ void NWPluginData_static_runtime::mark_start()
# endif // if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
# if NW_PLUGIN_LOG_EVENTS
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
if (!_eventInterfaceName.isEmpty() && loglevelActiveFor(LOG_LEVEL_INFO)) {
addLog(LOG_LEVEL_INFO, strformat(
F("%s: Started"),
_eventInterfaceName.c_str()));
@@ -121,7 +121,7 @@ void NWPluginData_static_runtime::mark_stop()
_startStopStats.setOff();
# if NW_PLUGIN_LOG_EVENTS
if (_netif && loglevelActiveFor(LOG_LEVEL_INFO)) {
if (_netif && !_eventInterfaceName.isEmpty() && loglevelActiveFor(LOG_LEVEL_INFO)) {
addLog(LOG_LEVEL_INFO, strformat(
F("%s: Stopped"),
_eventInterfaceName.c_str()));
@@ -134,7 +134,7 @@ void NWPluginData_static_runtime::mark_got_IP()
// Set OnOffTimer to off so we can also count how often we get new IP
_gotIPStats.forceSet(true);
if (!_netif) { return; }
if (!_netif || _eventInterfaceName.isEmpty()) { return; }
if (!_netif->isDefault()) {
nonDefaultNetworkInterface_gotIP = true;
@@ -200,7 +200,7 @@ void NWPluginData_static_runtime::mark_lost_IP()
# endif
# if NW_PLUGIN_LOG_EVENTS
if (_netif && loglevelActiveFor(LOG_LEVEL_INFO)) {
if (_netif && !_eventInterfaceName.isEmpty() && loglevelActiveFor(LOG_LEVEL_INFO)) {
addLog(LOG_LEVEL_INFO, strformat(
F("%s: Lost IP"),
_eventInterfaceName.c_str()));
@@ -235,7 +235,7 @@ void NWPluginData_static_runtime::mark_connected()
void NWPluginData_static_runtime::log_connected()
{
if (_netif && loglevelActiveFor(LOG_LEVEL_INFO)) {
if (_netif && !_eventInterfaceName.isEmpty() && loglevelActiveFor(LOG_LEVEL_INFO)) {
if (_establishConnectStats.getCycleCount()) {
// Log duration
addLog(LOG_LEVEL_INFO, strformat(
@@ -269,7 +269,7 @@ void NWPluginData_static_runtime::mark_disconnected()
void NWPluginData_static_runtime::log_disconnected()
{
if (_netif && loglevelActiveFor(LOG_LEVEL_INFO)) {
if (_netif && !_eventInterfaceName.isEmpty() && loglevelActiveFor(LOG_LEVEL_INFO)) {
addLog(LOG_LEVEL_INFO, strformat(
F("%s: Disconnected. Connected for: %s"),
_eventInterfaceName.c_str(),
@@ -278,6 +278,13 @@ void NWPluginData_static_runtime::log_disconnected()
}
}
void NWPluginData_static_runtime::mark_connect_failed()
{
networkConnectionFailed = true;
}
} // namespace net
} // namespace ESPEasy
@@ -3,6 +3,8 @@
#ifdef ESP8266
# include "../../../src/Helpers/StringConverter.h"
# include "../Globals/NetworkState.h"
# include "../ESPEasyNetwork.h"
namespace ESPEasy {
namespace net {
@@ -71,6 +73,9 @@ void NWPluginData_static_runtime::mark_begin_establish_connection()
_establishConnectStats.forceSet(true);
_connectedStats.setOff();
_operationalStats.setOff();
const String hostname = NetworkCreateRFCCompliantHostname();
wifi_station_set_hostname(hostname.c_str());
WiFi.hostname(hostname.c_str());
}
void NWPluginData_static_runtime::mark_connected()
@@ -115,6 +120,11 @@ void NWPluginData_static_runtime::log_disconnected()
# endif // ifndef BUILD_NO_DEBUG
}
void NWPluginData_static_runtime::mark_connect_failed()
{
networkConnectionFailed = true;
}
} // namespace net
} // namespace ESPEasy
+162 -98
View File
@@ -84,9 +84,57 @@ bool NWPluginCall(NWPlugin::Function Function, EventStruct *event, String& str)
if (Settings.getNWPluginID_for_network(x) && checkedEnabled) {
if (Function == NWPlugin::Function::NWPLUGIN_INIT_ALL) {
Scheduler.setNetworkInitTimer(Settings.getNetworkInterfaceStartupDelayAtBoot(x), x);
if (!Settings.getNetworkInterface_isFallback(x)) {
Scheduler.setNetworkInitTimer(Settings.getNetworkInterfaceStartupDelay(x), x);
}
}
if (Function == NWPlugin::Function::NWPLUGIN_WEBSERVER_SHOULD_RUN &&
Settings.getNetworkInterfaceSubnetBlockClientIP(x))
{
// Skip check for this network interface as access to the web UI should be blocked anyway
} else {
event->NetworkIndex = x;
#ifdef ESP32
if ((Function == NWPlugin::Function::NWPLUGIN_PRIORITY_ROUTE_CHANGED) &&
Settings.getNetworkInterface_isFallback(x))
{
// Deal with the fallback interface(s)
// TODO TD-er: What to do with the WiFi-AP as that's a special case of a fallback interface.
NetworkInterface *currentDefaultInterface = Network.getDefaultInterface();
if (!currentDefaultInterface) {
String dummy;
if (do_NWPluginCall(
getNetworkDriverIndex_from_NetworkIndex(x),
NWPlugin::Function::NWPLUGIN_FALLBACK_INTERFACE_SHOULD_START,
event,
dummy))
{
// No current default interface, thus we need to start this one.
Scheduler.setNetworkInitTimer(Settings.getNetworkInterfaceStartupDelay(x), x);
}
} else {
if (currentDefaultInterface->getRoutePrio() > Settings.getRoutePrio_for_network(x)) {
// There is some network active with higher route priority, so this one is no longer needed
Scheduler.setNetworkExitTimer(10, x);
} else {
// Check for the special case where there are multiple fallback interfaces with the same route prio.
// Then only stop the fallback interfaces which are not the default route.
auto *NW_data = ESPEasy::net::getNWPluginData(x);
if (NW_data) {
if (!NW_data->isDefaultRoute() &&
(currentDefaultInterface->getRoutePrio() == Settings.getRoutePrio_for_network(x))) {
Scheduler.setNetworkExitTimer(10, x);
}
}
}
}
}
#endif // ifdef ESP32
String command;
if (Function == NWPlugin::Function::NWPLUGIN_WRITE) {
@@ -109,10 +157,11 @@ bool NWPluginCall(NWPlugin::Function Function, EventStruct *event, String& str)
}
}
#ifdef ESP32
if (Function == NWPlugin::Function::NWPLUGIN_PRIORITY_ROUTE_CHANGED) {
CheckRunningServices();
}
#endif
#endif // ifdef ESP32
return success;
}
@@ -221,7 +270,7 @@ bool NWPluginCall(NWPlugin::Function Function, EventStruct *event, String& str)
if (runtime_data && runtime_data->_connectedStats.isSet()) {
const bool connected = runtime_data->_connectedStats.isOn();
auto duration = connected
auto duration = connected
? runtime_data->_connectedStats.getLastOnDuration_ms()
: runtime_data->_connectedStats.getLastOffDuration_ms();
@@ -230,9 +279,9 @@ bool NWPluginCall(NWPlugin::Function Function, EventStruct *event, String& str)
event->Par64_2 = runtime_data->_connectedStats.getCycleCount();
if (event->kvWriter) {
event->kvWriter->write({
connected ? F("Connection Duration") : F("Disconnected Duration"),
format_msec_duration_HMS(duration) });
event->kvWriter->write({
connected ? F("Connection Duration") : F("Disconnected Duration"),
format_msec_duration_HMS(duration) });
if (!event->kvWriter->summaryValueOnly()) {
event->kvWriter->write({ F("Number of Reconnects"), event->Par64_2 });
@@ -266,6 +315,7 @@ bool NWPluginCall(NWPlugin::Function Function, EventStruct *event, String& str)
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_HOSTNAME:
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_NAME:
case NWPlugin::Function::NWPLUGIN_CLIENT_IP_WEB_ACCESS_ALLOWED:
case NWPlugin::Function::NWPLUGIN_FALLBACK_INTERFACE_SHOULD_START:
#ifdef ESP32
case NWPlugin::Function::NWPLUGIN_GET_INTERFACE:
@@ -305,105 +355,118 @@ bool NWPluginCall(NWPlugin::Function Function, EventStruct *event, String& str)
if (!success && NWPlugin::canQueryViaNetworkInterface(Function)) {
String dummy_str;
if (do_NWPluginCall(
if (!do_NWPluginCall(
networkDriverIndex,
NWPlugin::Function::NWPLUGIN_GET_INTERFACE,
event,
dummy_str)) {
if (event->networkInterface != nullptr) {
switch (Function)
{
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_ROUTE_PRIO:
# if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2)
if (Function == NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_ROUTE_PRIO) {
if (Settings.getNetworkInterface_isFallback(networkIndex)) {
// Show route prio for fallback network interfaces as it is useful for determining which might be the fallback device.
event->Par1 = Settings.getRoutePrio_for_network(networkIndex);
event->Par3 = Settings.getNetworkInterfaceStartupDelay(networkIndex);
// TODO TD-er: Must also add option to set route prio
// See: https://github.com/espressif/arduino-esp32/pull/11617
event->Par1 = event->networkInterface->getRoutePrio();
# else // if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
event->Par1 = event->networkInterface->route_prio();
# endif // if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
event->Par2 = event->networkInterface->isDefault();
success = true;
break;
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_ACTIVE:
{
success = event->networkInterface->started();
break;
}
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_NAME:
if (event->kvWriter) {
event->kvWriter->write({ F("Name"), event->networkInterface->desc() });
success = true;
}
break;
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_HOSTNAME:
if (event->kvWriter) {
event->kvWriter->write({ F("Hostname"), event->networkInterface->getHostname() });
success = true;
}
break;
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_HW_ADDRESS:
if (event->kvWriter) {
if (event->kvWriter->summaryValueOnly()) {
event->kvWriter->write({
EMPTY_STRING,
concat(F("MAC: "), event->networkInterface->macAddress()) });
}
else {
event->kvWriter->write({
F("MAC"),
event->networkInterface->macAddress(),
KeyValueStruct::Format::PreFormatted
});
}
success = true;
}
break;
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_IP:
{
if (event->kvWriter) {
PrintToString prstr;
success = NWPlugin::print_IP_address(
static_cast<NWPlugin::IP_type>(event->Par1),
event->networkInterface,
prstr);
event->kvWriter->write({ F("ip"), prstr.getMove() });
success = true;
}
break;
}
case NWPlugin::Function::NWPLUGIN_CLIENT_IP_WEB_ACCESS_ALLOWED:
{
IPAddress client_ip;
client_ip.fromString(str);
if ((SecuritySettings.IPblockLevel == LOCAL_SUBNET_ALLOWED) &&
!Settings.getNetworkInterfaceSubnetBlockClientIP(event->NetworkIndex)) {
success = NWPlugin::IP_in_subnet(client_ip, event->networkInterface);
} else if (SecuritySettings.IPblockLevel == ONLY_IP_RANGE_ALLOWED) {
const IPAddress low(SecuritySettings.AllowedIPrangeLow);
const IPAddress high(SecuritySettings.AllowedIPrangeHigh);
success = NWPlugin::ipInRange(client_ip, low, high) &&
NWPlugin::IP_in_subnet(low, event->networkInterface) &&
NWPlugin::IP_in_subnet(high, event->networkInterface);
} else {
success = true;
}
break;
}
default: break;
success = true;
}
}
} else if (event->networkInterface != nullptr) {
switch (Function)
{
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_ROUTE_PRIO:
# if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2)
// TODO TD-er: Must also add option to set route prio
// See: https://github.com/espressif/arduino-esp32/pull/11617
event->Par1 = event->networkInterface->getRoutePrio();
# else // if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
event->Par1 = event->networkInterface->route_prio();
# endif // if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
event->Par2 = event->networkInterface->isDefault();
if (Settings.getNetworkInterface_isFallback(networkIndex)) {
event->Par3 = Settings.getNetworkInterfaceStartupDelay(networkIndex);
}
success = true;
break;
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_ACTIVE:
{
success = event->networkInterface->started();
break;
}
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_NAME:
if (event->kvWriter) {
event->kvWriter->write({ F("Name"), event->networkInterface->desc() });
success = true;
}
break;
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_HOSTNAME:
if (event->kvWriter) {
event->kvWriter->write({ F("Hostname"), event->networkInterface->getHostname() });
success = true;
}
break;
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_HW_ADDRESS:
if (event->kvWriter) {
if (event->kvWriter->summaryValueOnly()) {
event->kvWriter->write({
EMPTY_STRING,
concat(F("MAC: "), event->networkInterface->macAddress()) });
}
else {
event->kvWriter->write({
F("MAC"),
event->networkInterface->macAddress(),
KeyValueStruct::Format::PreFormatted
});
}
success = true;
}
break;
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_IP:
{
if (event->kvWriter) {
PrintToString prstr;
success = NWPlugin::print_IP_address(
static_cast<NWPlugin::IP_type>(event->Par1),
event->networkInterface,
prstr);
event->kvWriter->write({ F("ip"), prstr.getMove() });
success = true;
}
break;
}
case NWPlugin::Function::NWPLUGIN_CLIENT_IP_WEB_ACCESS_ALLOWED:
{
IPAddress client_ip;
client_ip.fromString(str);
if ((SecuritySettings.IPblockLevel == LOCAL_SUBNET_ALLOWED) &&
!Settings.getNetworkInterfaceSubnetBlockClientIP(event->NetworkIndex)) {
success = NWPlugin::IP_in_subnet(client_ip, event->networkInterface);
} else if (SecuritySettings.IPblockLevel == ONLY_IP_RANGE_ALLOWED) {
const IPAddress low(SecuritySettings.AllowedIPrangeLow);
const IPAddress high(SecuritySettings.AllowedIPrangeHigh);
success = NWPlugin::ipInRange(client_ip, low, high) &&
NWPlugin::IP_in_subnet(low, event->networkInterface) &&
NWPlugin::IP_in_subnet(high, event->networkInterface);
} else {
success = true;
}
break;
}
default: break;
}
}
}
#endif // ifdef ESP32
@@ -533,6 +596,7 @@ const NWPluginData_static_runtime* getDefaultRoute_NWPluginData_static_runtime()
if (NW_data) {
const int route_prio = NW_data->_routePrio;
if (route_prio > highest_prio) {
index_highest_prio = i;
highest_prio = route_prio;
+1 -1
View File
@@ -28,4 +28,4 @@ WiFiUDP portUDP;
#ifdef ESP32
bool nonDefaultNetworkInterface_gotIP{};
#endif
bool networkConnectionFailed{};
+1
View File
@@ -32,3 +32,4 @@ extern WiFiUDP portUDP;
#ifdef ESP32
extern bool nonDefaultNetworkInterface_gotIP;
#endif
extern bool networkConnectionFailed;
@@ -135,7 +135,7 @@ String NWPlugin_import_export::exportConfig(
child->write({ F("enabled"), Settings.getNetworkEnabled(networkIndex) });
child->write({ F("route_prio"), Settings.getRoutePrio_for_network(networkIndex) });
child->write({ F("sn_block"), Settings.getNetworkInterfaceSubnetBlockClientIP(networkIndex) });
child->write({ F("start_delay"), Settings.getNetworkInterfaceStartupDelayAtBoot(networkIndex) });
child->write({ F("start_delay"), Settings.getNetworkInterfaceStartupDelay(networkIndex) });
# if FEATURE_USE_IPV6
child->write({ F("en_ipv6"), Settings.getNetworkEnabled_IPv6(networkIndex) });
@@ -223,7 +223,7 @@ String NWPlugin_import_export::importConfig(
break;
case 2: Settings.setNetworkInterfaceSubnetBlockClientIP(networkIndex, bool_val);
break;
case 3: Settings.setNetworkInterfaceStartupDelayAtBoot(networkIndex, value.toInt());
case 3: Settings.setNetworkInterfaceStartupDelay(networkIndex, value.toInt());
break;
# if FEATURE_USE_IPV6
case 4: Settings.setNetworkEnabled_IPv6(networkIndex, bool_val);
@@ -27,7 +27,7 @@ namespace net {
namespace wifi {
# ifdef ESP32
static NWPluginData_static_runtime stats_and_cache(true, &NW_PLUGIN_INTERFACE);
static NWPluginData_static_runtime stats_and_cache(true, &NW_PLUGIN_INTERFACE, "AP");
# else
static NWPluginData_static_runtime stats_and_cache(true, "AP"); // Cannot use flash strings during init of static objects
# endif // ifdef ESP32
@@ -93,9 +93,7 @@ bool NW002_data_struct_WiFi_AP::init(EventStruct *event)
nw002_enable_NAPT = Settings.WiFi_AP_enable_NAPT();
# endif
if (Settings.StartAP_on_NW002_init()) {
ESPEasy::net::wifi::setAPinternal(true);
}
ESPEasy::net::wifi::setAPinternal(true);
# ifdef ESP32
NW002_update_NAPT();
# endif
@@ -504,7 +504,9 @@ bool NW003_data_struct_ETH_RMII::ETHConnectRelaxed() {
if (!(data && iface)) { return false; }
if (data->started() && data->connected()) {
return EthLinkUp();
if (EthLinkUp()) return true;
data->mark_connect_failed();
return false;
}
ethPrintSettings();
@@ -512,6 +514,7 @@ bool NW003_data_struct_ETH_RMII::ETHConnectRelaxed() {
{
addLog(LOG_LEVEL_ERROR, F("ETH: Settings not correct!!!"));
data->mark_stop();
data->mark_connect_failed();
return false;
}
@@ -565,8 +568,11 @@ bool NW003_data_struct_ETH_RMII::ETHConnectRelaxed() {
if (EthLinkUp()) {
// We might miss the connected event, since we are already connected.
data->mark_connected();
} else {
data->mark_connect_failed();
}
} else {
data->mark_connect_failed();
addLog(LOG_LEVEL_ERROR, F("ETH : Failed to initialize ETH"));
}
return success;
@@ -408,7 +408,9 @@ bool NW004_data_struct_ETH_SPI::ETHConnectRelaxed() {
if (!(data && iface)) { return false; }
if (data->started() && data->connected()) {
return EthLinkUp();
if (EthLinkUp()) return true;
data->mark_connect_failed();
return false;
}
ethPrintSettings();
@@ -416,6 +418,7 @@ bool NW004_data_struct_ETH_SPI::ETHConnectRelaxed() {
{
addLog(LOG_LEVEL_ERROR, F("ETH: Settings not correct!!!"));
data->mark_stop();
data->mark_connect_failed();
return false;
}
@@ -498,8 +501,11 @@ bool NW004_data_struct_ETH_SPI::ETHConnectRelaxed() {
if (EthLinkUp()) {
// We might miss the connected event, since we are already connected.
data->mark_connected();
} else {
data->mark_connect_failed();
}
} else {
data->mark_connect_failed();
addLog(LOG_LEVEL_ERROR, F("ETH : Failed to initialize ETH"));
}
return success;
@@ -865,7 +865,7 @@ void NW005_begin_modem_task(void *parameter)
{
delay(100);
}
while (timePassedSince(start) < 5000 && !NW_PLUGIN_INTERFACE.attached());
while (timePassedSince(start) < 10000 && !NW_PLUGIN_INTERFACE.attached());
NW_PLUGIN_INTERFACE.mode(ESP_MODEM_MODE_CMUX);
modem_task_data->AT_CPSI = NW_PLUGIN_INTERFACE.cmd(F("AT+CPSI?"), 3000);
@@ -874,6 +874,9 @@ void NW005_begin_modem_task(void *parameter)
NW_PLUGIN_INTERFACE.cmd(F("AT&D1"), 9000);
digitalWrite(modem_task_data->dtrPin, HIGH);
}
if (!NW_PLUGIN_INTERFACE.attached()) modem_task_data->modem_init_failed = true;
} else {
modem_task_data->modem_init_failed = true;
}
modem_task_data->modem_initialized = res;
}
@@ -1037,6 +1040,20 @@ bool NW005_data_struct_PPP_modem::handle_nwplugin_write(EventStruct *event, Stri
return success;
}
bool NW005_data_struct_PPP_modem::check_connect_failed()
{
if (_modem_task_data.modem_init_failed)
{
_modem_task_data.modem_init_failed = false;
auto stats = getNWPluginData_static_runtime();
if (stats) {
stats->mark_connect_failed();
}
return true;
}
return false;
}
# if FEATURE_NETWORK_STATS
bool NW005_data_struct_PPP_modem::initPluginStats()
@@ -18,6 +18,7 @@ struct NW005_modem_task_data {
int baud_rate = 115200;
bool initializing{};
bool modem_initialized{};
bool modem_init_failed{};
int dtrPin = -1;
String logString;
String AT_CPSI; // Result from "AT+CPSI?"
@@ -66,6 +67,8 @@ static int32_t getNextKey_noCredentials(int32_t key);
bool handle_nwplugin_write(EventStruct *event,
String & str) override;
bool check_connect_failed();
String write_AT_cmd(const String& cmd,
int timeout = 1000);
+10 -3
View File
@@ -78,7 +78,7 @@ bool NWPlugin_001(NWPlugin::Function function, EventStruct *event, String& strin
Settings.setRoutePrio_for_network(event->NetworkIndex, 100);
# endif // ifdef ESP32
Settings.setNetworkInterfaceSubnetBlockClientIP(event->NetworkIndex, false);
Settings.setNetworkInterfaceStartupDelayAtBoot(event->NetworkIndex, 1000);
Settings.setNetworkInterfaceStartupDelay(event->NetworkIndex, 1000);
Settings.ConnectFailRetryCount = 1;
break;
@@ -108,6 +108,12 @@ bool NWPlugin_001(NWPlugin::Function function, EventStruct *event, String& strin
break;
}
case NWPlugin::Function::NWPLUGIN_FALLBACK_INTERFACE_SHOULD_START:
{
success = true;
break;
}
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_ACTIVE:
{
success = ESPEasy::net::wifi::WifiIsSTA(WiFi.getMode());
@@ -241,16 +247,17 @@ bool NWPlugin_001(NWPlugin::Function function, EventStruct *event, String& strin
break;
}
# ifdef ESP8266
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_NAME:
{
if (event->kvWriter) {
event->kvWriter->write({ F("Name"), F("sta") });
event->kvWriter->write({ F("Name"), F("WiFi") });
success = true;
}
break;
}
# ifdef ESP8266
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_HOSTNAME:
{
if (event->kvWriter) {
+14 -6
View File
@@ -62,8 +62,8 @@ bool NWPlugin_002(NWPlugin::Function function, EventStruct *event, String& strin
Settings.setRoutePrio_for_network(event->NetworkIndex, 10);
# endif
Settings.setNetworkInterfaceSubnetBlockClientIP(event->NetworkIndex, false);
Settings.setNetworkInterfaceStartupDelayAtBoot(event->NetworkIndex, 10000);
Settings.StartAP_on_NW002_init(false);
Settings.setNetworkInterfaceStartupDelay(event->NetworkIndex, 10000);
Settings.setNetworkInterface_isFallback(event->NetworkIndex, true);
Settings.StartAPfallback_NoCredentials(true);
Settings.DoNotStartAPfallback_ConnectFail(false);
Settings.APfallback_autostart_max_uptime_m(0);
@@ -88,11 +88,22 @@ bool NWPlugin_002(NWPlugin::Function function, EventStruct *event, String& strin
case NWPlugin::Function::NWPLUGIN_WEBSERVER_SHOULD_RUN:
{
success = ESPEasy::net::wifi::wifiAPmodeActivelyUsed();
success = ESPEasy::net::wifi::WifiIsAP(WiFi.getMode());
// success = ESPEasy::net::wifi::wifiAPmodeActivelyUsed();
break;
}
case NWPlugin::Function::NWPLUGIN_FALLBACK_INTERFACE_SHOULD_START:
{
if (Settings.getNetworkInterface_isFallback(event->NetworkIndex)){
success = ESPEasy::net::wifi::shouldStartAP_fallback();
} else {
success = true;
}
break;
}
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_ACTIVE:
{
success = ESPEasy::net::wifi::WifiIsAP(WiFi.getMode());
@@ -246,7 +257,6 @@ bool NWPlugin_002(NWPlugin::Function function, EventStruct *event, String& strin
// Usually the AP will be started when no WiFi is defined, or the defined one cannot be found. This flag may prevent it.
Settings.StartAPfallback_NoCredentials(isFormItemChecked(LabelType::WIFI_START_AP_NO_CREDENTIALS));
Settings.DoNotStartAPfallback_ConnectFail(!isFormItemChecked(LabelType::WIFI_START_AP_ON_CONNECT_FAIL));
Settings.StartAP_on_NW002_init(isFormItemChecked(LabelType::WIFI_START_AP_ON_NW002_INIT));
Settings.APfallback_autostart_max_uptime_m(getFormItemInt(LabelType::WIFI_MAX_UPTIME_AUTO_START_AP));
Settings.APfallback_minimal_on_time_sec(getFormItemInt(LabelType::WIFI_AP_MINIMAL_ON_TIME));
@@ -260,8 +270,6 @@ bool NWPlugin_002(NWPlugin::Function function, EventStruct *event, String& strin
case NWPlugin::Function::NWPLUGIN_WEBFORM_LOAD:
{
addFormCheckBox(LabelType::WIFI_START_AP_ON_NW002_INIT);
addFormSubHeader(F("Wifi AP Settings"));
addFormPasswordBox(F("WPA AP Mode Key"), F("apkey"), SecuritySettings.WifiAPKey, 63);
addFormNote(F("WPA Key must be at least 8 characters long"));
+7 -1
View File
@@ -60,7 +60,7 @@ bool NWPlugin_003(NWPlugin::Function function, EventStruct *event, String& strin
{
Settings.setRoutePrio_for_network(event->NetworkIndex, 50);
Settings.setNetworkInterfaceSubnetBlockClientIP(event->NetworkIndex, false);
Settings.setNetworkInterfaceStartupDelayAtBoot(event->NetworkIndex, 500 * event->NetworkIndex);
Settings.setNetworkInterfaceStartupDelay(event->NetworkIndex, 500 * event->NetworkIndex);
ESPEasy_key_value_store kvs;
ESPEasy::net::eth::NW003_data_struct_ETH_RMII::loadDefaults(
@@ -96,6 +96,12 @@ bool NWPlugin_003(NWPlugin::Function function, EventStruct *event, String& strin
break;
}
case NWPlugin::Function::NWPLUGIN_FALLBACK_INTERFACE_SHOULD_START:
{
success = true;
break;
}
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_CONNECTED:
{
auto iface = ESPEasy::net::eth::ETH_NWPluginData_static_runtime::getInterface(event->NetworkIndex);
+7 -1
View File
@@ -55,7 +55,7 @@ bool NWPlugin_004(NWPlugin::Function function, EventStruct *event, String& strin
{
Settings.setRoutePrio_for_network(event->NetworkIndex, 50);
Settings.setNetworkInterfaceSubnetBlockClientIP(event->NetworkIndex, false);
Settings.setNetworkInterfaceStartupDelayAtBoot(event->NetworkIndex, 500 * event->NetworkIndex);
Settings.setNetworkInterfaceStartupDelay(event->NetworkIndex, 500 * event->NetworkIndex);
ESPEasy_key_value_store kvs;
ESPEasy::net::eth::NW004_data_struct_ETH_SPI::loadDefaults(
@@ -91,6 +91,12 @@ bool NWPlugin_004(NWPlugin::Function function, EventStruct *event, String& strin
break;
}
case NWPlugin::Function::NWPLUGIN_FALLBACK_INTERFACE_SHOULD_START:
{
success = true;
break;
}
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_CONNECTED:
{
auto iface = ESPEasy::net::eth::ETH_NWPluginData_static_runtime::getInterface(event->NetworkIndex);
+17 -1
View File
@@ -55,7 +55,7 @@ bool NWPlugin_005(NWPlugin::Function function, EventStruct *event, String& strin
{
Settings.setRoutePrio_for_network(event->NetworkIndex, 20);
Settings.setNetworkInterfaceSubnetBlockClientIP(event->NetworkIndex, true);
Settings.setNetworkInterfaceStartupDelayAtBoot(event->NetworkIndex, 500 * event->NetworkIndex);
Settings.setNetworkInterfaceStartupDelay(event->NetworkIndex, 500 * event->NetworkIndex);
break;
}
@@ -84,6 +84,12 @@ bool NWPlugin_005(NWPlugin::Function function, EventStruct *event, String& strin
break;
}
case NWPlugin::Function::NWPLUGIN_FALLBACK_INTERFACE_SHOULD_START:
{
success = true;
break;
}
case NWPlugin::Function::NWPLUGIN_WEBFORM_SHOW_CONNECTED:
{
if (event->kvWriter) {
@@ -229,6 +235,16 @@ bool NWPlugin_005(NWPlugin::Function function, EventStruct *event, String& strin
break;
}
case NWPlugin::Function::NWPLUGIN_TEN_PER_SECOND:
{
ESPEasy::net::ppp::NW005_data_struct_PPP_modem *NW_data =
static_cast<ESPEasy::net::ppp::NW005_data_struct_PPP_modem *>(getNWPluginData(event->NetworkIndex));
if (NW_data) {
NW_data->check_connect_failed();
}
break;
}
case NWPlugin::Function::NWPLUGIN_FIFTY_PER_SECOND:
{
@@ -145,6 +145,7 @@ void ESPEasyWiFi_t::loop()
// WiFiEventData.warnedNoValidWiFiSettings = true;
}
wifi_STA_data->mark_connect_failed();
wifi_STA_data->_establishConnectStats.clear();
@@ -185,6 +186,7 @@ void ESPEasyWiFi_t::loop()
if (WiFi_AP_Candidates.hasCandidates()) {
setState(WiFiState_e::WiFiOFF, 100);
} else {
// FIXME TD-er: This might not be a responsibility of this state machine....
if (shouldStartAP_fallback()) {
setState(WiFiState_e::AP_Fallback, Settings.APfallback_minimal_on_time_sec() * 1000);
// TODO TD-er: Must keep track of whether the user has forced AP to be autostarted.
@@ -258,6 +260,7 @@ void ESPEasyWiFi_t::loop()
if (_state == WiFiState_e::STA_Connecting) {
setState(WiFiState_e::STA_Reconnecting, WIFI_STATE_MACHINE_STA_CONNECTING_TIMEOUT);
} else {
wifi_STA_data->mark_connect_failed();
setState(WiFiState_e::WiFiOFF);
}
}
@@ -73,8 +73,12 @@ private:
STA_connected_state getSTA_connected_state() const;
public:
bool shouldStartAP_fallback() const;
private:
// WiFi_AP_Candidate _active_sta;
// WiFi_AP_Candidate _AP_conf;
+8
View File
@@ -171,6 +171,10 @@ void exitWiFi() { ESPEasyWiFi.disable(); }
void loopWiFi() { ESPEasyWiFi.loop(); }
bool shouldStartAP_fallback() {
return ESPEasyWiFi.shouldStartAP_fallback();
}
# ifdef BOARD_HAS_SDIO_ESP_HOSTED
// ********************************************************************************
@@ -228,9 +232,13 @@ String GetHostedFwVersion(EspHostTypes hostType)
String GetHostedMCU()
{
// Function is not yet implemented in Arduino Core so emulate it here
#if defined(CONFIG_ESP_HOSTED_CP_TARGET_ESP32C6) && CONFIG_ESP_HOSTED_CP_TARGET_ESP32C6==1
return String("ESP32-C6");
#else
if (equals(F(CONFIG_ESP_HOSTED_IDF_SLAVE_TARGET), F("esp32c6"))) {
return String("ESP32-C6");
}
#endif
return String("Unknown");
}
+2
View File
@@ -51,6 +51,8 @@ void initWiFi();
void exitWiFi();
void loopWiFi();
bool shouldStartAP_fallback();
# ifdef BOARD_HAS_SDIO_ESP_HOSTED
// ********************************************************************************
@@ -33,14 +33,9 @@ bool WiFi_pre_STA_setup() {
// FIXME TD-er: Should ESP8266 first disable autoconnect/autoreconnect?
// On ESP32 this does clear the last used credentials, so it will be able to accept different credentials to connect to.
// Assign to 2 separate bools to make sure both are executed.
const bool autoConnect = WiFi.setAutoConnect(true);
const bool autoReconnect = WiFi.setAutoReconnect(true);
#ifndef LIMIT_BUILD_SIZE
if (!autoConnect || !autoReconnect) {
addLog(LOG_LEVEL_ERROR, F("WiFi : Disabling auto (re)connect failed"));
}
#endif
WiFi.setAutoConnect(Settings.SDK_WiFi_autoreconnect());
WiFi.setAutoReconnect(Settings.SDK_WiFi_autoreconnect());
WiFi.hostname(NetworkCreateRFCCompliantHostname().c_str());
delay(100);
return true;
}
+1 -1
View File
@@ -43,7 +43,7 @@ bool CPlugin_002(CPlugin::Function function, struct EventStruct *event, String&
proto.usesExtCreds = true;
proto.defaultPort = 1883;
proto.usesID = true;
# if FEATURE_MQTT_TLS
#if FEATURE_MQTT_TLS
proto.usesTLS = true;
# endif // if FEATURE_MQTT_TLS
break;
+2 -2
View File
@@ -23,9 +23,9 @@ bool CPlugin_004(CPlugin::Function function, struct EventStruct *event, String&
proto.usesPassword = true;
proto.defaultPort = 80;
proto.usesID = true;
# if FEATURE_HTTP_TLS
#if FEATURE_HTTP_TLS
proto.usesTLS = true;
# endif // if FEATURE_HTTP_TLS
# endif
break;
}
@@ -77,7 +77,7 @@ struct ControllerSettingsStruct
CONTROLLER_HOSTNAME,
CONTROLLER_IP,
CONTROLLER_PORT,
#if FEATURE_MQTT_TLS
#if FEATURE_MQTT_TLS || FEATURE_HTTP_TLS
CONTROLLER_MQTT_TLS_TYPE,
CONTROLLER_MQTT_TLS_STORE_FINGERPRINT,
CONTROLLER_MQTT_TLS_STORE_CERT,
+1 -1
View File
@@ -38,7 +38,7 @@ struct ProtocolStruct
uint32_t needsNetwork : 1;
uint32_t allowsExpire : 1;
uint32_t allowLocalSystemTime : 1;
#if FEATURE_MQTT_TLS
#if FEATURE_MQTT_TLS || FEATURE_HTTP_TLS
uint32_t usesTLS : 1; // May offer TLS related settings and options
#else
uint32_t dontUseBit16 : 1;
+9 -8
View File
@@ -260,9 +260,6 @@ class SettingsStruct_tmpl
inline bool StartAPfallback_NoCredentials() const { return !VariousBits_2.StartAPfallback_NoCredentials; }
inline void StartAPfallback_NoCredentials(bool value) { VariousBits_2.StartAPfallback_NoCredentials = !value; }
inline bool StartAP_on_NW002_init() const { return VariousBits_2.StartAP_on_NW002_init; }
inline void StartAP_on_NW002_init(bool value) { VariousBits_2.StartAP_on_NW002_init = value; }
inline bool DoNotStartAPfallback_ConnectFail() const { return VariousBits_1.DoNotStartAPfallback_ConnectFail; }
inline void DoNotStartAPfallback_ConnectFail(bool value) { VariousBits_1.DoNotStartAPfallback_ConnectFail = value; }
@@ -463,6 +460,10 @@ public:
void setNetworkEnabled(ESPEasy::net::networkIndex_t index, bool enabled);
bool getNetworkInterface_isFallback(ESPEasy::net::networkIndex_t index) const;
void setNetworkInterface_isFallback(ESPEasy::net::networkIndex_t index, bool enabled);
bool getNetworkInterfaceSubnetBlockClientIP(ESPEasy::net::networkIndex_t index) const;
void setNetworkInterfaceSubnetBlockClientIP(ESPEasy::net::networkIndex_t index, bool enabled);
@@ -483,9 +484,9 @@ public:
void setRoutePrio_for_network(ESPEasy::net::networkIndex_t index, uint8_t prio);
#endif
uint32_t getNetworkInterfaceStartupDelayAtBoot(ESPEasy::net::networkIndex_t index) const;
uint32_t getNetworkInterfaceStartupDelay(ESPEasy::net::networkIndex_t index) const;
void setNetworkInterfaceStartupDelayAtBoot(ESPEasy::net::networkIndex_t index, uint32_t delay_ms);
void setNetworkInterfaceStartupDelay(ESPEasy::net::networkIndex_t index, uint32_t delay_ms);
uint32_t PID = 0;
int Version = 0;
@@ -741,7 +742,7 @@ public:
uint32_t MQTTConnectInBackground : 1; // Bit 13 // inverted
uint32_t StartAPfallback_NoCredentials : 1; // Bit 14 // inverted
uint32_t StartAP_on_NW002_init : 1; // Bit 15
uint32_t Unused_bit15 : 1; // Bit 15
uint32_t APfallback_minimal_on_time_sec : 8; // Bit 16 - 23
uint32_t APfallback_autostart_max_uptime_m : 8; // Bit 23 - 31 '0' == disabled
};
@@ -762,12 +763,12 @@ public:
uint8_t NetworkEnabled_bits{};
uint8_t NetworkInterfaceSubnetBlockClientIP_bits{}; // Client IP Block Level. Allow from subnet of this interface
uint8_t NetworkEnabled_ipv6_bits{}; // Whether or not to use IPv6 for the given interface (Settings.EnableIPv6() is the global on/off for IPv6)
uint8_t NetworkUnused_3{};
uint8_t NetworkInterface_isFallback_bits{};
#ifdef ESP32
uint8_t NetworkRoutePrio[NETWORK_MAX] = {0};
#endif
// TODO TD-er: For ESP8266 we may likely ever use upto 2 or 3 network interfaces, so maybe re-use the rest later?
uint16_t NetworkInterfaceStartupDelayAtBoot[NETWORK_MAX]{};
uint16_t NetworkInterfaceStartupDelay[NETWORK_MAX]{};
// Try to extend settings to make the checksum 4-uint8_t aligned.
+20 -4
View File
@@ -1541,6 +1541,22 @@ void SettingsStruct_tmpl<N_TASKS>::setNetworkEnabled(ESPEasy::net::networkIndex_
}
}
template<uint32_t N_TASKS>
bool SettingsStruct_tmpl<N_TASKS>::getNetworkInterface_isFallback(ESPEasy::net::networkIndex_t index) const
{
if (validNetworkIndex(index)) return bitRead(NetworkInterface_isFallback_bits, index);
return false;
}
template<uint32_t N_TASKS>
void SettingsStruct_tmpl<N_TASKS>::setNetworkInterface_isFallback(ESPEasy::net::networkIndex_t index, bool enabled)
{
if (validNetworkIndex(index)) {
bitWrite(NetworkInterface_isFallback_bits, index, enabled);
}
}
template<uint32_t N_TASKS>
bool SettingsStruct_tmpl<N_TASKS>::getNetworkInterfaceSubnetBlockClientIP(ESPEasy::net::networkIndex_t index) const {
if (validNetworkIndex(index)) return bitRead(NetworkInterfaceSubnetBlockClientIP_bits, index);
@@ -1591,19 +1607,19 @@ void SettingsStruct_tmpl<N_TASKS>::setRoutePrio_for_network(ESPEasy::net::networ
#endif
template<uint32_t N_TASKS>
uint32_t SettingsStruct_tmpl<N_TASKS>::getNetworkInterfaceStartupDelayAtBoot(ESPEasy::net::networkIndex_t index) const
uint32_t SettingsStruct_tmpl<N_TASKS>::getNetworkInterfaceStartupDelay(ESPEasy::net::networkIndex_t index) const
{
if (validNetworkIndex(index)) {
return static_cast<uint32_t>(NetworkInterfaceStartupDelayAtBoot[index]) * 10ul;
return static_cast<uint32_t>(NetworkInterfaceStartupDelay[index]) * 10ul;
}
return 0;
}
template<uint32_t N_TASKS>
void SettingsStruct_tmpl<N_TASKS>::setNetworkInterfaceStartupDelayAtBoot(ESPEasy::net::networkIndex_t index, uint32_t delay_ms)
void SettingsStruct_tmpl<N_TASKS>::setNetworkInterfaceStartupDelay(ESPEasy::net::networkIndex_t index, uint32_t delay_ms)
{
if (validNetworkIndex(index)) {
NetworkInterfaceStartupDelayAtBoot[index] = delay_ms/10ul;
NetworkInterfaceStartupDelay[index] = delay_ms/10ul;
}
}
@@ -176,6 +176,7 @@ public:
NWPLUGIN_EXIT,
NWPLUGIN_WRITE, // Send commands to a network adapter.
NWPLUGIN_CREDENTIALS_CHANGED,
NWPLUGIN_FALLBACK_INTERFACE_SHOULD_START,
#ifdef ESP32
NWPLUGIN_GET_INTERFACE,
NWPLUGIN_WEBFORM_SHOW_ROUTE_PRIO,
+6 -3
View File
@@ -1197,11 +1197,15 @@ void MQTTStatus(struct EventStruct *event, const String& status)
}
}
# if FEATURE_MQTT_TLS
#endif
# if FEATURE_MQTT_TLS || FEATURE_HTTP_TLS
bool GetTLSfingerprint(String& fp)
{
# ifdef ESP32
# if FEATURE_MQTT_TLS
// FIXME TD-er: We need to have a closer look at this as currently FEATURE_HTTP_TLS really needs FEATURE_MQTT_TLS
if (MQTTclient_connected && (mqtt_tls != nullptr)) {
const uint8_t *recv_fingerprint = mqtt_tls->getRecvPubKeyFingerprint();
@@ -1228,6 +1232,7 @@ bool GetTLSfingerprint(String& fp)
return true;
}
}
#endif
# endif // ifdef ESP32
return false;
}
@@ -1254,8 +1259,6 @@ bool GetTLS_Certificate(String& cert, bool caRoot)
# endif // if FEATURE_MQTT_TLS
#endif // if FEATURE_MQTT
/*********************************************************************************************\
* send specific sensor task data, effectively calling PluginCall(PLUGIN_READ...)
\*********************************************************************************************/
+3 -2
View File
@@ -77,15 +77,16 @@ bool MQTTpublish(controllerIndex_t controller_idx, taskIndex_t taskIndex, Strin
* Send status info back to channel where request came from
\*********************************************************************************************/
void MQTTStatus(struct EventStruct *event, const String& status);
#endif //if FEATURE_MQTT
#if FEATURE_MQTT_TLS
# if FEATURE_MQTT_TLS || FEATURE_HTTP_TLS
bool GetTLSfingerprint(String& fp);
bool GetTLS_Certificate(String& cert, bool caRoot);
#endif
#endif //if FEATURE_MQTT
/*********************************************************************************************\
+2 -2
View File
@@ -31,8 +31,8 @@ void update_mDNS() {
if (webserverRunning) {
if (!mDNS_init) {
addLog(LOG_LEVEL_INFO, F("mDNS : Starting mDNS..."));
mDNS_init = MDNS.begin(NetworkGetHostname().c_str());
MDNS.setInstanceName(NetworkGetHostname()); // Needed for when the hostname has changed.
mDNS_init = MDNS.begin(ESPEasy::net::NetworkGetHostname().c_str());
MDNS.setInstanceName(ESPEasy::net::NetworkGetHostname()); // Needed for when the hostname has changed.
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
String log = F("mDNS : ");
+25 -21
View File
@@ -15,11 +15,12 @@
#include "../Helpers/StringConverter.h"
#include "../Helpers/StringParser.h"
#include "../../ESPEasy/net/_NWPlugin_Helper.h"
#if FEATURE_SD
# include <SD.h>
#endif // if FEATURE_SD
bool remoteConfig(struct EventStruct *event, const String& string)
{
// FIXME TD-er: Why have an event here as argument? It is not used.
@@ -80,18 +81,25 @@ bool setNetworkEnableStatus(ESPEasy::net::networkIndex_t networkIndex, bool enab
#endif // ifndef BUILD_NO_RAM_TRACKER
// Only enable network if it has a network interface configured
if (Settings.getNWPluginID_for_network(networkIndex) != ESPEasy::net::INVALID_NW_PLUGIN_ID || !enabled) {
if ((Settings.getNWPluginID_for_network(networkIndex) != ESPEasy::net::INVALID_NW_PLUGIN_ID) || !enabled) {
struct EventStruct TempEvent;
TempEvent.NetworkIndex = networkIndex;
String dummy;
if (!enabled) {
ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_EXIT, &TempEvent, dummy);
// Use the scheduler as this also removes any pending init calls.
Scheduler.setNetworkExitTimer(10, networkIndex);
}
Settings.setNetworkEnabled(networkIndex, enabled);
if (enabled) {
if (!ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_INIT, &TempEvent, dummy))
return false;
if (ESPEasy::net::getNWPluginData(networkIndex) == nullptr) {
// Only init when not yet started
if (!ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_INIT, &TempEvent, dummy)) {
return false;
}
}
}
return true;
@@ -99,7 +107,6 @@ bool setNetworkEnableStatus(ESPEasy::net::networkIndex_t networkIndex, bool enab
return false;
}
/********************************************************************************************\
Toggle controller enabled state
\*********************************************************************************************/
@@ -115,6 +122,7 @@ bool setControllerEnableStatus(controllerIndex_t controllerIndex, bool enabled)
struct EventStruct TempEvent;
TempEvent.ControllerIndex = controllerIndex;
String dummy;
if (!enabled) {
CPluginCall(CPlugin::Function::CPLUGIN_EXIT, &TempEvent, dummy);
}
@@ -217,6 +225,7 @@ void taskClear(taskIndex_t taskIndex, bool save)
it is excluded from the calculation !
\*********************************************************************************************/
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0)
void dump(uint32_t addr) { // Seems already included in core 2.4 ...
serialPrint(String(addr, HEX));
serialPrint(": ");
@@ -275,9 +284,7 @@ void dump(uint32_t addr) { // Seems already included in core 2.4 ...
/********************************************************************************************\
Handler for keeping ExtraTaskSettings up to date using cache
\*********************************************************************************************/
String getTaskDeviceName(taskIndex_t TaskIndex) {
return Cache.getTaskDeviceName(TaskIndex);
}
String getTaskDeviceName(taskIndex_t TaskIndex) { return Cache.getTaskDeviceName(TaskIndex); }
/********************************************************************************************\
Handler for getting Value Names from TaskIndex
@@ -578,22 +585,16 @@ void RGB2HSV(uint8_t r, uint8_t g, uint8_t b, float hsv[3]) {
hsv[2] = v * 255.0f;
}
float getCPUload() {
return 100.0f - Scheduler.getIdleTimePct();
}
float getCPUload() { return 100.0f - Scheduler.getIdleTimePct(); }
int getLoopCountPerSec() {
return loopCounterLast / 30;
}
int getLoopCountPerSec() { return loopCounterLast / 30; }
int getUptimeMinutes() {
return wdcounter / 2;
}
int getUptimeMinutes() { return wdcounter / 2; }
/******************************************************************************
* scan an int array of specified size for a value
*****************************************************************************/
bool intArrayContains(const int arraySize, const int array[], const int& value) {
bool intArrayContains(const int arraySize, const int array[], const int& value) {
for (int i = 0; i < arraySize; i++) {
if (array[i] == value) { return true; }
}
@@ -608,6 +609,7 @@ bool intArrayContains(const int arraySize, const uint8_t array[], const uint8_t&
}
#ifndef BUILD_NO_RAM_TRACKER
void logMemUsageAfter(const __FlashStringHelper *function, int value) {
// Store free memory in an int, as subtracting may sometimes result in negative value.
// The recorded used memory is not an exact value, as background (or interrupt) tasks may also allocate or free heap memory.
@@ -625,11 +627,13 @@ void logMemUsageAfter(const __FlashStringHelper *function, int value) {
log += value;
}
while (log.length() < 30) { log += ' '; }
while (log.length() < 30) { log += ' ';
}
log += F("Free mem after: ");
log += freemem_end;
while (log.length() < 55) { log += ' '; }
while (log.length() < 55) { log += ' ';
}
log += F("diff: ");
log += last_freemem - freemem_end;
addLogMove(LOG_LEVEL_DEBUG, log);
+6 -1
View File
@@ -62,8 +62,13 @@ void run50TimesPerSecond() {
#ifdef ESP32
static const NetworkInterface *lastDefaultInterface = nullptr;
NetworkInterface * currentDefaultInterface = Network.getDefaultInterface();
if (nonDefaultNetworkInterface_gotIP || lastDefaultInterface != currentDefaultInterface) {
if (nonDefaultNetworkInterface_gotIP ||
networkConnectionFailed ||
lastDefaultInterface != currentDefaultInterface) {
nonDefaultNetworkInterface_gotIP = false;
// TODO TD-er: Must do something else here on failed connect?
networkConnectionFailed = false;
ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_PRIORITY_ROUTE_CHANGED, 0, dummy);
lastDefaultInterface = currentDefaultInterface;
}
+20 -5
View File
@@ -4,6 +4,8 @@
#include "../Globals/Settings.h"
#include "../../ESPEasy/net/_NWPlugin_Helper.h"
/*********************************************************************************************\
* Network Adapter Timer (NWPLUGIN_TASKTIMER_IN)
* Can be scheduled per combo networkIndex & Par1 (20 least significant bits)
@@ -11,12 +13,22 @@
void ESPEasy_Scheduler::setNetworkInitTimer(unsigned long msecFromNow,
ESPEasy::net::networkIndex_t networkIndex)
{
setNetworkTimer(msecFromNow, networkIndex, NWPlugin::Function::NWPLUGIN_INIT);
if (ESPEasy::net::getNWPluginData(networkIndex) == nullptr) {
// Only init when not yet started
setNetworkTimer(msecFromNow, networkIndex, NWPlugin::Function::NWPLUGIN_INIT);
}
}
void ESPEasy_Scheduler::setNetworkExitTimer(unsigned long msecFromNow,
ESPEasy::net::networkIndex_t networkIndex)
{
// First check if there are any pending INIT timers
const NWPluginTimerID timerID(networkIndex, 0, NWPlugin::Function::NWPLUGIN_INIT);
auto it = systemTimers.find(timerID.mixed_id);
if (it != systemTimers.end()) {
systemTimers.erase(it);
}
setNetworkTimer(msecFromNow, networkIndex, NWPlugin::Function::NWPLUGIN_EXIT);
}
@@ -35,11 +47,14 @@ void ESPEasy_Scheduler::setNetworkTimer(unsigned long msecFromNow
const NWPluginTimerID timerID(networkIndex, Par1, function);
systemTimerStruct timer_data;
if (systemTimers.find(timerID.mixed_id) == systemTimers.end()) {
// Only set timer if not already set.
systemTimerStruct timer_data;
timer_data.fromEvent(networkIndex, Par1, Par2, Par3, Par4, Par5);
systemTimers[timerID.mixed_id] = timer_data;
setNewTimerAt(timerID, millis() + msecFromNow);
timer_data.fromEvent(networkIndex, Par1, Par2, Par3, Par4, Par5);
systemTimers[timerID.mixed_id] = timer_data;
setNewTimerAt(timerID, millis() + msecFromNow);
}
}
void ESPEasy_Scheduler::process_network_timer(SchedulerTimerID id)
+1 -9
View File
@@ -220,10 +220,6 @@ KeyValueStruct getKeyValue(LabelType::Enum label, bool extendedValue)
{
return KeyValueStruct(F("Start AP on Connect Fail"), !Settings.DoNotStartAPfallback_ConnectFail());
}
case LabelType::WIFI_START_AP_ON_NW002_INIT:
{
return KeyValueStruct(F("Auto Start AP"), Settings.StartAP_on_NW002_init());
}
case LabelType::WIFI_NR_RECONNECT_ATTEMPTS:
{
return KeyValueStruct(F("Connect Retry Attempts"), Settings.ConnectFailRetryCount);
@@ -621,7 +617,7 @@ KeyValueStruct getKeyValue(LabelType::Enum label, bool extendedValue)
#if FEATURE_MDNS
case LabelType::M_DNS:
{
const String url = NetworkGetHostname() + F(".local");
const String url = ESPEasy::net::NetworkGetHostname() + F(".local");
if (extendedValue) {
return KeyValueStruct(F("mDNS"),
@@ -1382,10 +1378,6 @@ String getFormNote(LabelType::Enum label)
break;
#endif
case LabelType::WIFI_START_AP_ON_NW002_INIT:
flash_str = F("Always start AP mode when this network interface is enabled");
break;
#endif // ifndef MINIMAL_OTA
#if FEATURE_SET_WIFI_TX_PWR
-1
View File
@@ -36,7 +36,6 @@ struct LabelType {
WIFI_ENABLE_CAPTIVE_PORTAL,
WIFI_START_AP_NO_CREDENTIALS,
WIFI_START_AP_ON_CONNECT_FAIL,
WIFI_START_AP_ON_NW002_INIT,
WIFI_NR_RECONNECT_ATTEMPTS,
WIFI_MAX_UPTIME_AUTO_START_AP,
WIFI_AP_MINIMAL_ON_TIME,
+1 -1
View File
@@ -141,7 +141,7 @@ void addControllerEnabledForm(controllerIndex_t controllerindex) {
addFormCheckBox(displayName, internalName, Settings.ControllerEnabled[controllerindex]);
}
#if FEATURE_MQTT_TLS
#if FEATURE_MQTT_TLS || FEATURE_HTTP_TLS
void addCertificateFileNote(const ControllerSettingsStruct& ControllerSettings, const String& description, TLS_types tls_type) {
const String certFile = ControllerSettings.getCertificateFilename(tls_type);
+25 -4
View File
@@ -160,12 +160,20 @@ void handle_networks_CopySubmittedSettings_NWPluginCall(ESPEasy::net::networkInd
# endif
# ifdef ESP32
Settings.setRoutePrio_for_network(networkindex, getFormItemInt(F("routeprio"), 0));
Settings.setNetworkInterface_isFallback(networkindex, isFormItemChecked(F("fallback")));
Settings.setNetworkInterfaceSubnetBlockClientIP(networkindex, isFormItemChecked(F("block_web_access")));
# endif // ifdef ESP32
# ifdef ESP8266
if (networkindex == 1) {
// Only add fallback checkbox to AP on ESP8266
Settings.setNetworkInterface_isFallback(networkindex, isFormItemChecked(F("fallback")));
}
# endif // ifdef ESP32
# if FEATURE_USE_IPV6
Settings.setNetworkEnabled_IPv6(networkindex, isFormItemChecked(F("en_ipv6")));
# endif
Settings.setNetworkInterfaceStartupDelayAtBoot(networkindex, getFormItemInt(F("delay_start")));
Settings.setNetworkInterfaceStartupDelay(networkindex, getFormItemInt(F("delay_start")));
String dummy;
ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_WEBFORM_SAVE, &TempEvent, dummy);
}
@@ -258,6 +266,9 @@ void handle_networks_ShowAllNetworksTable()
if (TempEvent.Par2) {
addHtml(F("(*)"));
}
// if (TempEvent.Par3 > 0) {
// addHtml(strformat(F("<BR>%u ms"), TempEvent.Par3));
// }
}
break;
# endif // ifdef ESP32
@@ -375,11 +386,21 @@ void handle_networks_NetworkSettingsPage(ESPEasy::net::networkIndex_t networkind
Settings.getRoutePrio_for_network(networkindex),
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));
# endif
# ifdef ESP8266
if (networkindex == 1) {
// Only add fallback checkbox to AP on ESP8266
addFormCheckBox(F("Fallback Interface"), F("fallback"), Settings.getNetworkInterface_isFallback(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"));
addFormNumericBox(F("Delay Startup At Boot"), F("delay_start"), Settings.getNetworkInterfaceStartupDelayAtBoot(networkindex), 0, 60000);
addFormNumericBox(F("Delay Startup"), F("delay_start"), Settings.getNetworkInterfaceStartupDelay(networkindex), 0, 60000);
addUnit(F("ms"));
#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"));
#endif
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"));
# if FEATURE_USE_IPV6
addFormCheckBox(F("Enable IPv6"), F("en_ipv6"), Settings.getNetworkEnabled_IPv6(networkindex));