From 04c3ff3027f0e3acebd1f5fbf79601ca973401c0 Mon Sep 17 00:00:00 2001 From: TD-er Date: Sat, 9 Mar 2024 18:14:35 +0100 Subject: [PATCH 1/6] [ESP8266 WiFi] Initialize flags for AP capabilities May fix issues where the ESP may not properly (re)connect to an AP --- src/src/DataStructs/WiFi_AP_Candidate.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/src/DataStructs/WiFi_AP_Candidate.cpp b/src/src/DataStructs/WiFi_AP_Candidate.cpp index b6fe853060..e6a1778491 100644 --- a/src/src/DataStructs/WiFi_AP_Candidate.cpp +++ b/src/src/DataStructs/WiFi_AP_Candidate.cpp @@ -49,6 +49,12 @@ WiFi_AP_Candidate::WiFi_AP_Candidate(uint8_t networkItem) : index(0), flags(0) { phy_11n = it->phy_11n; wps = it->wps; } + #else + // Need to make sure the phy isn't known as we can't get this information from the AP + phy_11b = false; + phy_11g = false; + phy_11n = false; + wps = false; #endif #endif // ifdef ESP8266 #ifdef ESP32 From 627ea8097062697c33aa912eb6b55fc0bf183ebc Mon Sep 17 00:00:00 2001 From: TD-er Date: Mon, 11 Mar 2024 00:51:35 +0100 Subject: [PATCH 2/6] [ESP8266] Get rid of several union structs which may cause weird issues --- .../DataStructs/ControllerSettingsStruct.cpp | 228 +++++++++--------- .../DataStructs/ControllerSettingsStruct.h | 73 +++--- src/src/DataStructs/ProtocolStruct.h | 37 ++- src/src/DataStructs/ProvisioningStruct.h | 25 +- src/src/DataStructs/SettingsStruct.h | 2 +- src/src/DataStructs/WiFi_AP_Candidate.cpp | 46 +++- src/src/DataStructs/WiFi_AP_Candidate.h | 32 ++- src/src/DataTypes/TaskValues_Data.cpp | 67 +++-- src/src/DataTypes/TaskValues_Data.h | 15 +- src/src/PluginStructs/P025_data_struct.cpp | 38 ++- src/src/PluginStructs/P025_data_struct.h | 7 +- 11 files changed, 316 insertions(+), 254 deletions(-) diff --git a/src/src/DataStructs/ControllerSettingsStruct.cpp b/src/src/DataStructs/ControllerSettingsStruct.cpp index 9a6bf6e490..7587379a0c 100644 --- a/src/src/DataStructs/ControllerSettingsStruct.cpp +++ b/src/src/DataStructs/ControllerSettingsStruct.cpp @@ -25,16 +25,25 @@ void ControllerSettingsStruct::reset() { // Otherwise the checksum will fail and settings will be saved too often. memset(this, 0, sizeof(ControllerSettingsStruct)); - UseDNS = DEFAULT_SERVER_USEDNS; - Port = DEFAULT_PORT; - MinimalTimeBetweenMessages = CONTROLLER_DELAY_QUEUE_DELAY_DFLT; - MaxQueueDepth = CONTROLLER_DELAY_QUEUE_DEPTH_DFLT; - MaxRetry = CONTROLLER_DELAY_QUEUE_RETRY_DFLT; - DeleteOldest = DEFAULT_CONTROLLER_DELETE_OLDEST; - ClientTimeout = CONTROLLER_CLIENTTIMEOUT_DFLT; - MustCheckReply = DEFAULT_CONTROLLER_MUST_CHECK_REPLY ; - SampleSetInitiator = INVALID_TASK_INDEX; - VariousFlags = 0; + UseDNS = DEFAULT_SERVER_USEDNS; + Port = DEFAULT_PORT; + MinimalTimeBetweenMessages = CONTROLLER_DELAY_QUEUE_DELAY_DFLT; + MaxQueueDepth = CONTROLLER_DELAY_QUEUE_DEPTH_DFLT; + MaxRetry = CONTROLLER_DELAY_QUEUE_RETRY_DFLT; + DeleteOldest = DEFAULT_CONTROLLER_DELETE_OLDEST; + ClientTimeout = CONTROLLER_CLIENTTIMEOUT_DFLT; + MustCheckReply = DEFAULT_CONTROLLER_MUST_CHECK_REPLY; + SampleSetInitiator = INVALID_TASK_INDEX; + VariousBits1.mqtt_cleanSession = 0; + VariousBits1.mqtt_not_sendLWT = 0; + VariousBits1.mqtt_not_willRetain = 0; + VariousBits1.mqtt_uniqueMQTTclientIdReconnect = 0; + VariousBits1.mqtt_retainFlag = 0; + VariousBits1.useExtendedCredentials = 0; + VariousBits1.sendBinary = 0; + VariousBits1.allowExpire = 0; + VariousBits1.deduplicate = 0; + VariousBits1.useLocalSystemTime = 0; safe_strncpy(ClientID, F(CONTROLLER_DEFAULT_CLIENTID), sizeof(ClientID)); } @@ -72,7 +81,6 @@ void ControllerSettingsStruct::validate() { ZERO_TERMINATE(LWTMessageDisconnect); } - String ControllerSettingsStruct::getHost() const { if (UseDNS) { return HostName; @@ -90,6 +98,7 @@ bool ControllerSettingsStruct::checkHostReachable(bool quick) { // No IP/hostname set return false; } + if (!NetworkConnected(10)) { return false; // Not connected, so no use in wasting time to connect to a host. } @@ -111,7 +120,7 @@ bool ControllerSettingsStruct::connectToHost(WiFiClient& client) { return false; // Host not reachable } uint8_t retry = 2; - bool connected = false; + bool connected = false; while (retry > 0 && !connected) { --retry; @@ -125,16 +134,19 @@ bool ControllerSettingsStruct::connectToHost(WiFiClient& client) { } return false; } + #endif // FEATURE_HTTP_CLIENT bool ControllerSettingsStruct::beginPacket(WiFiUDP& client) { if (!checkHostReachable(true)) { return false; // Host not reachable } - uint8_t retry = 2; + uint8_t retry = 2; + while (retry > 0) { --retry; FeedSW_watchdog(); + if (client.beginPacket(getIP(), Port) == 1) { return true; } @@ -181,101 +193,101 @@ bool ControllerSettingsStruct::updateIPcache() { /* bool ControllerSettingsStruct::mqtt_cleanSession() const { - return bitRead(VariousFlags, 1); -} - -void ControllerSettingsStruct::mqtt_cleanSession(bool value) -{ - bitWrite(VariousFlags, 1, value); -} - -bool ControllerSettingsStruct::mqtt_sendLWT() const -{ - return !bitRead(VariousFlags, 2); -} - -void ControllerSettingsStruct::mqtt_sendLWT(bool value) -{ - bitWrite(VariousFlags, 2, !value); -} - -bool ControllerSettingsStruct::mqtt_willRetain() const -{ - return !bitRead(VariousFlags, 3); -} - -void ControllerSettingsStruct::mqtt_willRetain(bool value) -{ - bitWrite(VariousFlags, 3, !value); -} - -bool ControllerSettingsStruct::mqtt_uniqueMQTTclientIdReconnect() const -{ - return bitRead(VariousFlags, 4); -} - -void ControllerSettingsStruct::mqtt_uniqueMQTTclientIdReconnect(bool value) -{ - bitWrite(VariousFlags, 4, value); -} - -bool ControllerSettingsStruct::mqtt_retainFlag() const -{ - return bitRead(VariousFlags, 5); -} - -void ControllerSettingsStruct::mqtt_retainFlag(bool value) -{ - bitWrite(VariousFlags, 5, value); -} - -bool ControllerSettingsStruct::useExtendedCredentials() const -{ - return bitRead(VariousFlags, 6); -} - -void ControllerSettingsStruct::useExtendedCredentials(bool value) -{ - bitWrite(VariousFlags, 6, value); -} - -bool ControllerSettingsStruct::sendBinary() const -{ - return bitRead(VariousFlags, 7); -} - -void ControllerSettingsStruct::sendBinary(bool value) -{ - bitWrite(VariousFlags, 7, value); -} - -bool ControllerSettingsStruct::allowExpire() const -{ - return bitRead(VariousFlags, 9); -} - -void ControllerSettingsStruct::allowExpire(bool value) -{ - bitWrite(VariousFlags, 9, value); -} - -bool ControllerSettingsStruct::deduplicate() const -{ - return bitRead(VariousFlags, 10); -} - -void ControllerSettingsStruct::deduplicate(bool value) -{ - bitWrite(VariousFlags, 10, value); -} - -bool ControllerSettingsStruct::useLocalSystemTime() const -{ - return bitRead(VariousFlags, 11); -} - -void ControllerSettingsStruct::useLocalSystemTime(bool value) -{ + return bitRead(VariousFlags, 1); + } + + void ControllerSettingsStruct::mqtt_cleanSession(bool value) + { + bitWrite(VariousFlags, 1, value); + } + + bool ControllerSettingsStruct::mqtt_sendLWT() const + { + return !bitRead(VariousFlags, 2); + } + + void ControllerSettingsStruct::mqtt_sendLWT(bool value) + { + bitWrite(VariousFlags, 2, !value); + } + + bool ControllerSettingsStruct::mqtt_willRetain() const + { + return !bitRead(VariousFlags, 3); + } + + void ControllerSettingsStruct::mqtt_willRetain(bool value) + { + bitWrite(VariousFlags, 3, !value); + } + + bool ControllerSettingsStruct::mqtt_uniqueMQTTclientIdReconnect() const + { + return bitRead(VariousFlags, 4); + } + + void ControllerSettingsStruct::mqtt_uniqueMQTTclientIdReconnect(bool value) + { + bitWrite(VariousFlags, 4, value); + } + + bool ControllerSettingsStruct::mqtt_retainFlag() const + { + return bitRead(VariousFlags, 5); + } + + void ControllerSettingsStruct::mqtt_retainFlag(bool value) + { + bitWrite(VariousFlags, 5, value); + } + + bool ControllerSettingsStruct::useExtendedCredentials() const + { + return bitRead(VariousFlags, 6); + } + + void ControllerSettingsStruct::useExtendedCredentials(bool value) + { + bitWrite(VariousFlags, 6, value); + } + + bool ControllerSettingsStruct::sendBinary() const + { + return bitRead(VariousFlags, 7); + } + + void ControllerSettingsStruct::sendBinary(bool value) + { + bitWrite(VariousFlags, 7, value); + } + + bool ControllerSettingsStruct::allowExpire() const + { + return bitRead(VariousFlags, 9); + } + + void ControllerSettingsStruct::allowExpire(bool value) + { + bitWrite(VariousFlags, 9, value); + } + + bool ControllerSettingsStruct::deduplicate() const + { + return bitRead(VariousFlags, 10); + } + + void ControllerSettingsStruct::deduplicate(bool value) + { + bitWrite(VariousFlags, 10, value); + } + + bool ControllerSettingsStruct::useLocalSystemTime() const + { + return bitRead(VariousFlags, 11); + } + + void ControllerSettingsStruct::useLocalSystemTime(bool value) + { bitWrite(VariousFlags, 11, value); } */ \ No newline at end of file diff --git a/src/src/DataStructs/ControllerSettingsStruct.h b/src/src/DataStructs/ControllerSettingsStruct.h index f11825751e..ff45d4fd21 100644 --- a/src/src/DataStructs/ControllerSettingsStruct.h +++ b/src/src/DataStructs/ControllerSettingsStruct.h @@ -124,7 +124,7 @@ struct ControllerSettingsStruct String getHostPortString() const; - // VariousFlags defaults to 0, keep in mind when adding bit lookups. + // VariousBits1 defaults to 0, keep in mind when adding bit lookups. bool mqtt_cleanSession() const { return VariousBits1.mqtt_cleanSession; } void mqtt_cleanSession(bool value) { VariousBits1.mqtt_cleanSession = value; } @@ -172,43 +172,40 @@ struct ControllerSettingsStruct bool MustCheckReply; // When set to false, a sent message is considered always successful. taskIndex_t SampleSetInitiator; // The first task to start a sample set. - union { - struct { - uint32_t unused_00 : 1; // Bit 00 - uint32_t mqtt_cleanSession : 1; // Bit 01 - uint32_t mqtt_not_sendLWT : 1; // Bit 02, !value, default enabled - uint32_t mqtt_not_willRetain : 1; // Bit 03, !value, default enabled - uint32_t mqtt_uniqueMQTTclientIdReconnect : 1; // Bit 04 - uint32_t mqtt_retainFlag : 1; // Bit 05 - uint32_t useExtendedCredentials : 1; // Bit 06 - uint32_t sendBinary : 1; // Bit 07 - uint32_t unused_08 : 1; // Bit 08 - uint32_t allowExpire : 1; // Bit 09 - uint32_t deduplicate : 1; // Bit 10 - uint32_t useLocalSystemTime : 1; // Bit 11 - uint32_t unused_12 : 1; // Bit 12 - uint32_t unused_13 : 1; // Bit 13 - uint32_t unused_14 : 1; // Bit 14 - uint32_t unused_15 : 1; // Bit 15 - uint32_t unused_16 : 1; // Bit 16 - uint32_t unused_17 : 1; // Bit 17 - uint32_t unused_18 : 1; // Bit 18 - uint32_t unused_19 : 1; // Bit 19 - uint32_t unused_20 : 1; // Bit 20 - uint32_t unused_21 : 1; // Bit 21 - uint32_t unused_22 : 1; // Bit 22 - uint32_t unused_23 : 1; // Bit 23 - uint32_t unused_24 : 1; // Bit 24 - uint32_t unused_25 : 1; // Bit 25 - uint32_t unused_26 : 1; // Bit 26 - uint32_t unused_27 : 1; // Bit 27 - uint32_t unused_28 : 1; // Bit 28 - uint32_t unused_29 : 1; // Bit 29 - uint32_t unused_30 : 1; // Bit 30 - uint32_t unused_31 : 1; // Bit 31 - } VariousBits1; - uint32_t VariousFlags; // Various flags - }; + struct { + uint32_t unused_00 : 1; // Bit 00 + uint32_t mqtt_cleanSession : 1; // Bit 01 + uint32_t mqtt_not_sendLWT : 1; // Bit 02, !value, default enabled + uint32_t mqtt_not_willRetain : 1; // Bit 03, !value, default enabled + uint32_t mqtt_uniqueMQTTclientIdReconnect : 1; // Bit 04 + uint32_t mqtt_retainFlag : 1; // Bit 05 + uint32_t useExtendedCredentials : 1; // Bit 06 + uint32_t sendBinary : 1; // Bit 07 + uint32_t unused_08 : 1; // Bit 08 + uint32_t allowExpire : 1; // Bit 09 + uint32_t deduplicate : 1; // Bit 10 + uint32_t useLocalSystemTime : 1; // Bit 11 + uint32_t unused_12 : 1; // Bit 12 + uint32_t unused_13 : 1; // Bit 13 + uint32_t unused_14 : 1; // Bit 14 + uint32_t unused_15 : 1; // Bit 15 + uint32_t unused_16 : 1; // Bit 16 + uint32_t unused_17 : 1; // Bit 17 + uint32_t unused_18 : 1; // Bit 18 + uint32_t unused_19 : 1; // Bit 19 + uint32_t unused_20 : 1; // Bit 20 + uint32_t unused_21 : 1; // Bit 21 + uint32_t unused_22 : 1; // Bit 22 + uint32_t unused_23 : 1; // Bit 23 + uint32_t unused_24 : 1; // Bit 24 + uint32_t unused_25 : 1; // Bit 25 + uint32_t unused_26 : 1; // Bit 26 + uint32_t unused_27 : 1; // Bit 27 + uint32_t unused_28 : 1; // Bit 28 + uint32_t unused_29 : 1; // Bit 29 + uint32_t unused_30 : 1; // Bit 30 + uint32_t unused_31 : 1; // Bit 31 + } VariousBits1; char ClientID[65]; // Used to define the Client ID used by the controller private: diff --git a/src/src/DataStructs/ProtocolStruct.h b/src/src/DataStructs/ProtocolStruct.h index 290ea97839..4acc2c98a6 100644 --- a/src/src/DataStructs/ProtocolStruct.h +++ b/src/src/DataStructs/ProtocolStruct.h @@ -20,26 +20,23 @@ struct ProtocolStruct } uint16_t defaultPort{}; - union { - struct { - uint16_t usesMQTT : 1; - uint16_t usesAccount : 1; - uint16_t usesPassword : 1; - uint16_t usesTemplate : 1; // When set, the protocol will pre-load some templates like default MQTT topics - uint16_t usesID : 1; // Whether a controller supports sending an IDX value sent along with plugin data - uint16_t Custom : 1; // When set, the controller has to define all parameters on the controller setup page - uint16_t usesHost : 1; - uint16_t usesPort : 1; - uint16_t usesQueue : 1; - uint16_t usesCheckReply : 1; - uint16_t usesTimeout : 1; - uint16_t usesSampleSets : 1; - uint16_t usesExtCreds : 1; - uint16_t needsNetwork : 1; - uint16_t allowsExpire : 1; - uint16_t allowLocalSystemTime : 1; - }; - uint16_t bits{}; + struct { + uint16_t usesMQTT : 1; + uint16_t usesAccount : 1; + uint16_t usesPassword : 1; + uint16_t usesTemplate : 1; // When set, the protocol will pre-load some templates like default MQTT topics + uint16_t usesID : 1; // Whether a controller supports sending an IDX value sent along with plugin data + uint16_t Custom : 1; // When set, the controller has to define all parameters on the controller setup page + uint16_t usesHost : 1; + uint16_t usesPort : 1; + uint16_t usesQueue : 1; + uint16_t usesCheckReply : 1; + uint16_t usesTimeout : 1; + uint16_t usesSampleSets : 1; + uint16_t usesExtCreds : 1; + uint16_t needsNetwork : 1; + uint16_t allowsExpire : 1; + uint16_t allowLocalSystemTime : 1; }; // uint8_t Number{}; diff --git a/src/src/DataStructs/ProvisioningStruct.h b/src/src/DataStructs/ProvisioningStruct.h index ba8007b300..25a959721b 100644 --- a/src/src/DataStructs/ProvisioningStruct.h +++ b/src/src/DataStructs/ProvisioningStruct.h @@ -39,21 +39,16 @@ struct ProvisioningStruct char pass[64] = { 0 }; char url[128] = { 0 }; - union { - uint16_t allowed{}; - struct { - uint16_t allowFetchFirmware :1; - uint16_t allowFetchConfigDat :1; - uint16_t allowFetchSecurityDat :1; - uint16_t allowFetchNotificationDat :1; - uint16_t allowFetchProvisioningDat :1; - uint16_t allowFetchRules :4; - - uint16_t unused :7; // Add to use full 16 bit. - } allowedFlags; - }; - - + struct { + uint16_t allowFetchFirmware :1; + uint16_t allowFetchConfigDat :1; + uint16_t allowFetchSecurityDat :1; + uint16_t allowFetchNotificationDat :1; + uint16_t allowFetchProvisioningDat :1; + uint16_t allowFetchRules :4; + + uint16_t unused :7; // Add to use full 16 bit. + } allowedFlags; }; typedef std::shared_ptr ProvisioningStruct_ptr_type; diff --git a/src/src/DataStructs/SettingsStruct.h b/src/src/DataStructs/SettingsStruct.h index 10a46b06c2..1bf2f8855c 100644 --- a/src/src/DataStructs/SettingsStruct.h +++ b/src/src/DataStructs/SettingsStruct.h @@ -11,7 +11,7 @@ #include "../DataTypes/NetworkMedium.h" #include "../DataTypes/NPluginID.h" #include "../DataTypes/PluginID.h" -#include "../DataTypes/TaskEnabledState.h" +//#include "../DataTypes/TaskEnabledState.h" #include "../DataTypes/TimeSource.h" #include "../Globals/Plugins.h" diff --git a/src/src/DataStructs/WiFi_AP_Candidate.cpp b/src/src/DataStructs/WiFi_AP_Candidate.cpp index e6a1778491..9f1671a131 100644 --- a/src/src/DataStructs/WiFi_AP_Candidate.cpp +++ b/src/src/DataStructs/WiFi_AP_Candidate.cpp @@ -20,8 +20,20 @@ WiFi_AP_Candidate::WiFi_AP_Candidate(uint8_t index_c, const String& ssid_c) : - last_seen(0), rssi(0), channel(0), index(index_c), flags(0) + last_seen(0), rssi(0), channel(0), index(index_c) { + lowPriority = false; + isEmergencyFallback = false; + + phy_11b = false; + phy_11g = false; + phy_11n = false; + phy_lr = false; + phy_11ax = false; + wps = false; + ftm_responder = false; + ftm_initiator = false; + const size_t ssid_length = ssid_c.length(); if ((ssid_length == 0) || equals(ssid_c, F("ssid"))) { @@ -33,7 +45,23 @@ WiFi_AP_Candidate::WiFi_AP_Candidate(uint8_t index_c, const String& ssid_c) : ssid = ssid_c; } -WiFi_AP_Candidate::WiFi_AP_Candidate(uint8_t networkItem) : index(0), flags(0) { + +WiFi_AP_Candidate::WiFi_AP_Candidate(uint8_t networkItem) : index(0) { + // Need to make sure the phy isn't known as we can't get this information from the AP + // See: https://github.com/letscontrolit/ESPEasy/issues/4996 + // Not sure why this makes any difference as the flags should already have been set to 0. + lowPriority = false; + isEmergencyFallback = false; + + phy_11b = false; + phy_11g = false; + phy_11n = false; + phy_lr = false; + phy_11ax = false; + wps = false; + ftm_responder = false; + ftm_initiator = false; + ssid = WiFi.SSID(networkItem); rssi = WiFi.RSSI(networkItem); channel = WiFi.channel(networkItem); @@ -49,12 +77,6 @@ WiFi_AP_Candidate::WiFi_AP_Candidate(uint8_t networkItem) : index(0), flags(0) { phy_11n = it->phy_11n; wps = it->wps; } - #else - // Need to make sure the phy isn't known as we can't get this information from the AP - phy_11b = false; - phy_11g = false; - phy_11n = false; - wps = false; #endif #endif // ifdef ESP8266 #ifdef ESP32 @@ -77,6 +99,7 @@ WiFi_AP_Candidate::WiFi_AP_Candidate(uint8_t networkItem) : index(0), flags(0) { last_seen = millis(); } + #ifdef ESP8266 #if FEATURE_ESP8266_DIRECT_WIFI_SCAN WiFi_AP_Candidate::WiFi_AP_Candidate(const bss_info& ap) : @@ -85,6 +108,13 @@ WiFi_AP_Candidate::WiFi_AP_Candidate(const bss_info& ap) : phy_11b(ap.phy_11b), phy_11g(ap.phy_11g), phy_11n(ap.phy_11n), wps(ap.wps) { + lowPriority = false; + isEmergencyFallback = false; + phy_lr = false; + phy_11ax = false; + ftm_responder = false; + ftm_initiator = false; + last_seen = millis(); switch(ap.authmode) { diff --git a/src/src/DataStructs/WiFi_AP_Candidate.h b/src/src/DataStructs/WiFi_AP_Candidate.h index ce93d4cbf4..3553be5b98 100644 --- a/src/src/DataStructs/WiFi_AP_Candidate.h +++ b/src/src/DataStructs/WiFi_AP_Candidate.h @@ -66,24 +66,20 @@ struct WiFi_AP_Candidate { uint8_t channel{}; uint8_t index{}; // Index of the matching credentials uint8_t enc_type{}; // Encryption used (e.g. WPA2) - union - { - struct { - uint16_t isHidden:1; // Hidden SSID - uint16_t lowPriority:1; // Try as last attempt - uint16_t isEmergencyFallback:1; - uint16_t phy_11b:1; - uint16_t phy_11g:1; - uint16_t phy_11n:1; - uint16_t phy_lr:1; - uint16_t phy_11ax:1; - uint16_t wps:1; - uint16_t ftm_responder:1; - uint16_t ftm_initiator:1; - - uint16_t unused:5; - }; - uint16_t flags{}; + struct { + uint16_t isHidden:1; // Hidden SSID + uint16_t lowPriority:1; // Try as last attempt + uint16_t isEmergencyFallback:1; + uint16_t phy_11b:1; + uint16_t phy_11g:1; + uint16_t phy_11n:1; + uint16_t phy_lr:1; + uint16_t phy_11ax:1; + uint16_t wps:1; + uint16_t ftm_responder:1; + uint16_t ftm_initiator:1; + + uint16_t unused:5; }; }; diff --git a/src/src/DataTypes/TaskValues_Data.cpp b/src/src/DataTypes/TaskValues_Data.cpp index 9fa84188e9..c4d97b717e 100644 --- a/src/src/DataTypes/TaskValues_Data.cpp +++ b/src/src/DataTypes/TaskValues_Data.cpp @@ -28,22 +28,25 @@ void TaskValues_Data_t::copyValue(const TaskValues_Data_t& other, uint8_t varNr, if (sensorType != Sensor_VType::SENSOR_TYPE_STRING) { if (is32bitOutputDataType(sensorType)) { if (varNr < VARS_PER_TASK) { - uint32s[varNr] = other.uint32s[varNr]; + constexpr unsigned int size_32bit = sizeof(float); + memcpy(binary + (varNr * size_32bit), other.binary + (varNr * size_32bit), size_32bit); } + } #if FEATURE_EXTENDED_TASK_VALUE_TYPES - } else { + else { if ((varNr < (VARS_PER_TASK / 2))) { - uint64s[varNr] = other.uint64s[varNr]; + constexpr unsigned int size_64bit = sizeof(uint64_t); + memcpy(binary + (varNr * size_64bit), other.binary + (varNr * size_64bit), size_64bit); } -#endif } +#endif } } unsigned long TaskValues_Data_t::getSensorTypeLong() const { - const uint16_t low = floats[0]; - const uint16_t high = floats[1]; + const uint16_t low = getFloat(0); + const uint16_t high = getFloat(1); unsigned long value = high; value <<= 16; @@ -53,8 +56,8 @@ unsigned long TaskValues_Data_t::getSensorTypeLong() const void TaskValues_Data_t::setSensorTypeLong(unsigned long value) { - floats[0] = value & 0xFFFF; - floats[1] = (value >> 16) & 0xFFFF; + setFloat(0, value & 0xFFFF); + setFloat(1, (value >> 16) & 0xFFFF); } #if FEATURE_EXTENDED_TASK_VALUE_TYPES @@ -62,7 +65,10 @@ void TaskValues_Data_t::setSensorTypeLong(unsigned long value) int32_t TaskValues_Data_t::getInt32(uint8_t varNr) const { if (varNr < VARS_PER_TASK) { - return int32s[varNr]; + int32_t res{}; + constexpr unsigned int size_32bit = sizeof(float); + memcpy(&res, binary + (varNr * size_32bit), size_32bit); + return res; } return 0; } @@ -70,7 +76,8 @@ int32_t TaskValues_Data_t::getInt32(uint8_t varNr) const void TaskValues_Data_t::setInt32(uint8_t varNr, int32_t value) { if (varNr < VARS_PER_TASK) { - int32s[varNr] = value; + constexpr unsigned int size_32bit = sizeof(float); + memcpy(binary + (varNr * size_32bit), &value, size_32bit); } } #endif @@ -78,7 +85,10 @@ void TaskValues_Data_t::setInt32(uint8_t varNr, int32_t value) uint32_t TaskValues_Data_t::getUint32(uint8_t varNr) const { if (varNr < VARS_PER_TASK) { - return uint32s[varNr]; + uint32_t res{}; + constexpr unsigned int size_32bit = sizeof(float); + memcpy(&res, binary + (varNr * size_32bit), size_32bit); + return res; } return 0u; } @@ -86,7 +96,8 @@ uint32_t TaskValues_Data_t::getUint32(uint8_t varNr) const void TaskValues_Data_t::setUint32(uint8_t varNr, uint32_t value) { if (varNr < VARS_PER_TASK) { - uint32s[varNr] = value; + constexpr unsigned int size_32bit = sizeof(float); + memcpy(binary + (varNr * size_32bit), &value, size_32bit); } } @@ -95,7 +106,10 @@ void TaskValues_Data_t::setUint32(uint8_t varNr, uint32_t value) int64_t TaskValues_Data_t::getInt64(uint8_t varNr) const { if ((varNr < (VARS_PER_TASK / 2))) { - return int64s[varNr]; + int64_t res{}; + constexpr unsigned int size_64bit = sizeof(uint64_t); + memcpy(&res, binary + (varNr * size_64bit), size_64bit); + return res; } return 0; } @@ -103,14 +117,18 @@ int64_t TaskValues_Data_t::getInt64(uint8_t varNr) const void TaskValues_Data_t::setInt64(uint8_t varNr, int64_t value) { if ((varNr < (VARS_PER_TASK / 2))) { - int64s[varNr] = value; + constexpr unsigned int size_64bit = sizeof(uint64_t); + memcpy(binary + (varNr * size_64bit), &value, size_64bit); } } uint64_t TaskValues_Data_t::getUint64(uint8_t varNr) const { if ((varNr < (VARS_PER_TASK / 2))) { - return uint64s[varNr]; + uint64_t res{}; + constexpr unsigned int size_64bit = sizeof(uint64_t); + memcpy(&res, binary + (varNr * size_64bit), size_64bit); + return res; } return 0u; } @@ -118,7 +136,8 @@ uint64_t TaskValues_Data_t::getUint64(uint8_t varNr) const void TaskValues_Data_t::setUint64(uint8_t varNr, uint64_t value) { if ((varNr < (VARS_PER_TASK / 2))) { - uint64s[varNr] = value; + constexpr unsigned int size_64bit = sizeof(uint64_t); + memcpy(binary + (varNr * size_64bit), &value, size_64bit); } } #endif @@ -126,7 +145,10 @@ void TaskValues_Data_t::setUint64(uint8_t varNr, uint64_t value) float TaskValues_Data_t::getFloat(uint8_t varNr) const { if (varNr < VARS_PER_TASK) { - return floats[varNr]; + float res{}; + constexpr unsigned int size_32bit = sizeof(float); + memcpy(&res, binary + (varNr * size_32bit), size_32bit); + return res; } return 0.0f; } @@ -134,7 +156,8 @@ float TaskValues_Data_t::getFloat(uint8_t varNr) const void TaskValues_Data_t::setFloat(uint8_t varNr, float value) { if (varNr < VARS_PER_TASK) { - floats[varNr] = value; + constexpr unsigned int size_32bit = sizeof(float); + memcpy(binary + (varNr * size_32bit), &value, size_32bit); } } @@ -143,7 +166,10 @@ void TaskValues_Data_t::setFloat(uint8_t varNr, float value) double TaskValues_Data_t::getDouble(uint8_t varNr) const { if ((varNr < (VARS_PER_TASK / 2))) { - return doubles[varNr]; + double res{}; + constexpr unsigned int size_64bit = sizeof(uint64_t); + memcpy(&res, binary + (varNr * size_64bit), size_64bit); + return res; } return 0.0; } @@ -151,7 +177,8 @@ double TaskValues_Data_t::getDouble(uint8_t varNr) const void TaskValues_Data_t::setDouble(uint8_t varNr, double value) { if ((varNr < (VARS_PER_TASK / 2))) { - doubles[varNr] = value; + constexpr unsigned int size_64bit = sizeof(uint64_t); + memcpy(binary + (varNr * size_64bit), &value, size_64bit); } } #endif diff --git a/src/src/DataTypes/TaskValues_Data.h b/src/src/DataTypes/TaskValues_Data.h index dbfe5e443c..9d46fac4ea 100644 --- a/src/src/DataTypes/TaskValues_Data.h +++ b/src/src/DataTypes/TaskValues_Data.h @@ -65,20 +65,7 @@ struct __attribute__((__packed__)) TaskValues_Data_t { String getAsString(uint8_t varNr, Sensor_VType sensorType, uint8_t nrDecimals = 0) const; - - union { - uint8_t binary[VARS_PER_TASK * sizeof(float)]; - float floats[VARS_PER_TASK]; - uint32_t uint32s[VARS_PER_TASK]; -#if FEATURE_EXTENDED_TASK_VALUE_TYPES - int32_t int32s[VARS_PER_TASK]; - uint64_t uint64s[VARS_PER_TASK / 2]; - int64_t int64s[VARS_PER_TASK / 2]; -#if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE - double doubles[VARS_PER_TASK / 2]; -#endif -#endif - }; + uint8_t binary[VARS_PER_TASK * sizeof(float)]{}; }; #endif // ifndef DATATYPES_TASKVALUES_DATA_H diff --git a/src/src/PluginStructs/P025_data_struct.cpp b/src/src/PluginStructs/P025_data_struct.cpp index 4f68ba8836..b58a0a5e07 100644 --- a/src/src/PluginStructs/P025_data_struct.cpp +++ b/src/src/PluginStructs/P025_data_struct.cpp @@ -9,6 +9,16 @@ # define P025_CONFIG_REGISTER 0x01 +P025_VARIOUS_BITS_t::P025_VARIOUS_BITS_t(int16_t value) { + memcpy(this, &value, sizeof(int16_t)); +} + +int16_t P025_VARIOUS_BITS_t::pconfigvalue() const { + int16_t value{}; + memcpy(&value, this, sizeof(int16_t)); + return value; +} + const __FlashStringHelper* Plugin_025_valuename(uint8_t value_nr, bool displayString) { const __FlashStringHelper *strings[] { F("AIN0 - AIN1 (Differential)"), F("AIN0_1"), @@ -36,7 +46,7 @@ const __FlashStringHelper* toString(P025_sensorType sensorType) F("ADS1015") : F("ADS1115"); } -union P025_config_register { +struct P025_config_register { struct { uint16_t comp_que : 2; uint16_t comp_lat : 1; @@ -48,14 +58,24 @@ union P025_config_register { uint16_t MUX : 3; uint16_t operatingStatus : 1; }; - uint16_t _regval = 0x8000; + P025_config_register(uint16_t regval) { + memcpy(this, ®val, sizeof(uint16_t)); + } + + void setRegval(uint16_t regval) { + memcpy(this, ®val, sizeof(uint16_t)); + } - P025_config_register(uint16_t regval) : _regval(regval) {} + uint16_t getRegval() const { + uint16_t regval{}; + memcpy(®val, this, sizeof(uint16_t)); + return regval; + } String toString() const { return strformat(F("reg: %X OS: %d MUX: %d PGA: %d mode: %d DR: %d"), - _regval, operatingStatus, MUX, PGA, mode, datarate + getRegval(), operatingStatus, MUX, PGA, mode, datarate ); } }; @@ -78,7 +98,7 @@ P025_data_struct::P025_data_struct(struct EventStruct *event) { reg.datarate = p025_variousBits.getSampleRate(); reg.PGA = P025_GAIN; - _configRegisterValue = reg._regval; + _configRegisterValue = reg.getRegval(); _fullScaleFactor = 1.0f; @@ -105,11 +125,11 @@ bool P025_data_struct::read(float& value, taskVarIndex_t index) const { reg.MUX = _mux[index]; - if (!startMeasurement(_i2cAddress, reg._regval)) { + if (!startMeasurement(_i2cAddress, reg.getRegval())) { return false; } - if (!I2C_write16_reg(_i2cAddress, P025_CONFIG_REGISTER, reg._regval)) { + if (!I2C_write16_reg(_i2cAddress, P025_CONFIG_REGISTER, reg.getRegval())) { # ifndef BUILD_NO_DEBUG if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { @@ -261,7 +281,7 @@ long P025_data_struct::waitReady025(uint8_t i2cAddress) delay(0); // Address Pointer Register is the same, so only need to read bytes again - reg._regval = I2C_read16(i2cAddress, &is_ok); + reg.setRegval(I2C_read16(i2cAddress, &is_ok)); } # ifndef BUILD_NO_DEBUG @@ -366,7 +386,7 @@ bool P025_data_struct::webformSave(struct EventStruct *event) p025_variousBits.setSampleRate(getFormItemInt(F("sps"))); p025_variousBits.outputVolt = isFormItemChecked(F("volt")); p025_variousBits.cal = isFormItemChecked(F("cal")); - P025_VARIOUS_BITS = p025_variousBits.pconfigvalue; + P025_VARIOUS_BITS = p025_variousBits.pconfigvalue(); P025_CAL_ADC1 = getFormItemInt(F("adc1")); P025_CAL_OUT1 = getFormItemFloat(F("out1")); diff --git a/src/src/PluginStructs/P025_data_struct.h b/src/src/PluginStructs/P025_data_struct.h index 85c2780cdc..6730a0ff59 100644 --- a/src/src/PluginStructs/P025_data_struct.h +++ b/src/src/PluginStructs/P025_data_struct.h @@ -5,7 +5,7 @@ #ifdef USES_P025 -union P025_VARIOUS_BITS_t { +struct P025_VARIOUS_BITS_t { struct { uint16_t cal : 1; uint16_t outputVolt : 1; @@ -13,9 +13,10 @@ union P025_VARIOUS_BITS_t { uint16_t sampleRate : 3; uint16_t unused : 10; }; - int16_t pconfigvalue{}; - P025_VARIOUS_BITS_t(int16_t value) : pconfigvalue(value) {} + P025_VARIOUS_BITS_t(int16_t value); + + int16_t pconfigvalue() const; uint16_t getSampleRate() const { if (sampleRateSet) { return sampleRate; } From a906eb1ebba8e181cabf24d16249ad6e35fbe344 Mon Sep 17 00:00:00 2001 From: TD-er Date: Mon, 11 Mar 2024 10:59:11 +0100 Subject: [PATCH 3/6] [ESP8266] Remove use of union due to issues on ESP8266 --- src/src/DataStructs/PluginStats_Config.cpp | 2 +- src/src/DataStructs/PluginStats_Config.h | 43 +++-- src/src/DataStructs/SchedulerTimerID.cpp | 19 +- src/src/DataStructs/SchedulerTimerID.h | 24 ++- .../Scheduler_ConstIntervalTimerID.h | 4 +- src/src/DataStructs/Scheduler_GPIOTimerID.cpp | 2 +- src/src/DataStructs/Scheduler_GPIOTimerID.h | 10 +- .../Scheduler_IntendedRebootTimerID.cpp | 2 +- .../Scheduler_IntendedRebootTimerID.h | 2 +- .../Scheduler_PluginDeviceTimerID.cpp | 6 +- .../Scheduler_PluginTaskTimerID.cpp | 10 +- .../DataStructs/Scheduler_RulesTimerID.cpp | 4 +- .../Scheduler_SystemEventQueueTimerID.cpp | 4 +- .../Scheduler_SystemEventQueueTimerID.h | 6 +- .../Scheduler_TaskDeviceTimerID.cpp | 4 +- .../DataStructs/Scheduler_TaskDeviceTimerID.h | 2 +- src/src/DataStructs/SettingsStruct.h | 173 ++++++++++-------- src/src/DataStructs/WiFi_AP_Candidate.cpp | 22 ++- src/src/DataStructs/WiFi_AP_Candidate.h | 7 +- src/src/DataStructs_templ/SettingsStruct.cpp | 6 +- src/src/Helpers/ESPEasy_Storage.cpp | 2 +- src/src/Helpers/Modbus_RTU.cpp | 11 +- src/src/Helpers/Scheduler_decodeTimer.cpp | 2 +- src/src/PluginStructs/P148_data_struct.cpp | 4 + src/src/PluginStructs/P151_data_struct.cpp | 2 + 25 files changed, 223 insertions(+), 150 deletions(-) diff --git a/src/src/DataStructs/PluginStats_Config.cpp b/src/src/DataStructs/PluginStats_Config.cpp index 9df1b78d66..2e8fa78bdb 100644 --- a/src/src/DataStructs/PluginStats_Config.cpp +++ b/src/src/DataStructs/PluginStats_Config.cpp @@ -6,7 +6,7 @@ PluginStats_Config_t & PluginStats_Config_t::operator=(const PluginStats_Config_t& other) { - stored = other.stored; + setStored(other.getStored()); return *this; } diff --git a/src/src/DataStructs/PluginStats_Config.h b/src/src/DataStructs/PluginStats_Config.h index 115bcf330d..2be9235f16 100644 --- a/src/src/DataStructs/PluginStats_Config.h +++ b/src/src/DataStructs/PluginStats_Config.h @@ -12,9 +12,13 @@ struct PluginStats_Config_t { Right }; - PluginStats_Config_t() : stored(0) {} + PluginStats_Config_t() { + setStored(0); + } - PluginStats_Config_t(uint8_t stored_value) : stored(stored_value) {} + PluginStats_Config_t(uint8_t stored_value) { + setStored(stored_value); + } PluginStats_Config_t& operator=(const PluginStats_Config_t& other); @@ -37,7 +41,7 @@ struct PluginStats_Config_t { } uint8_t getStoredBits() const { - return stored & ~0x02; // Mask unused_01 + return getStored() & ~0x02; // Mask unused_01 } bool isEnabled() const { @@ -58,18 +62,27 @@ struct PluginStats_Config_t { private: - union { - struct { - uint8_t enabled : 1; // Bit 00 - uint8_t unused_01 : 1; // Bit 01 Used by isDefaultTaskVarName in ExtraTaskSettingsStruct - uint8_t hidden : 1; // Bit 02 Hidden/Displayed state on initial showing of the chart - uint8_t chartAxisIndex : 2; // Bit 03 ... 04 - uint8_t chartAxisPosition : 1; // Bit 05 - uint8_t unused_06 : 1; // Bit 06 - uint8_t unused_07 : 1; // Bit 07 - } bits; - uint8_t stored{}; - }; + uint8_t getStored() const { + uint8_t res{}; + memcpy(&res, &bits, sizeof(uint8_t)); + return res; + } + + // Needs to be inline in the header file as it is used in the constructor + void setStored(uint8_t value) { + memcpy(&bits, &value, sizeof(uint8_t)); + } + + struct { + uint8_t enabled : 1; // Bit 00 + uint8_t unused_01 : 1; // Bit 01 Used by isDefaultTaskVarName in ExtraTaskSettingsStruct + uint8_t hidden : 1; // Bit 02 Hidden/Displayed state on initial showing of the chart + uint8_t chartAxisIndex : 2; // Bit 03 ... 04 + uint8_t chartAxisPosition : 1; // Bit 05 + uint8_t unused_06 : 1; // Bit 06 + uint8_t unused_07 : 1; // Bit 07 + } bits; + }; #endif // if FEATURE_PLUGIN_STATS diff --git a/src/src/DataStructs/SchedulerTimerID.cpp b/src/src/DataStructs/SchedulerTimerID.cpp index 1424061033..9cacd4c2bf 100644 --- a/src/src/DataStructs/SchedulerTimerID.cpp +++ b/src/src/DataStructs/SchedulerTimerID.cpp @@ -1,6 +1,23 @@ #include "../DataStructs/SchedulerTimerID.h" +#include "../Helpers/Misc.h" + SchedulerTimerID::SchedulerTimerID(SchedulerTimerType_e timerType) { - timer_type = static_cast(timerType); + set4BitToUL(mixed_id, 0, static_cast(timerType)); +} + +void SchedulerTimerID::setTimerType(SchedulerTimerType_e timerType) +{ + set4BitToUL(mixed_id, 0, static_cast(timerType)); +} + +SchedulerTimerType_e SchedulerTimerID::getTimerType() const +{ + return static_cast(get4BitFromUL(mixed_id, 0)); +} + +uint32_t SchedulerTimerID::getId() const +{ + return mixed_id >> 4; } diff --git a/src/src/DataStructs/SchedulerTimerID.h b/src/src/DataStructs/SchedulerTimerID.h index 42d61fceb5..c1cd05dae2 100644 --- a/src/src/DataStructs/SchedulerTimerID.h +++ b/src/src/DataStructs/SchedulerTimerID.h @@ -11,24 +11,22 @@ struct SchedulerTimerID { explicit SchedulerTimerID(uint32_t mixedID) : mixed_id(mixedID) {} - union { - struct { - uint32_t id : 28; - uint32_t timer_type : 4; // Change this when SchedulerTimerType_e needs more bits - }; + virtual ~SchedulerTimerID() {} - uint32_t mixed_id{}; - }; + void setTimerType(SchedulerTimerType_e timerType); + SchedulerTimerType_e getTimerType() const; - void setTimerType(SchedulerTimerType_e timerType) - { - timer_type = static_cast(timerType); - } - SchedulerTimerType_e getTimerType() const + uint32_t getId() const; + + // Have setId in the header file as it is used in the constructor of derived classes + // Thus it should be inline as we otherwise cannot call member functions of base class in the constructor in a derived class + void setId(uint32_t id) { - return static_cast(timer_type); + mixed_id = (id << 4) | (mixed_id & 0x0f); } + + uint32_t mixed_id{}; }; diff --git a/src/src/DataStructs/Scheduler_ConstIntervalTimerID.h b/src/src/DataStructs/Scheduler_ConstIntervalTimerID.h index a5eb92b943..17d175c6e1 100644 --- a/src/src/DataStructs/Scheduler_ConstIntervalTimerID.h +++ b/src/src/DataStructs/Scheduler_ConstIntervalTimerID.h @@ -9,12 +9,12 @@ struct ConstIntervalTimerID : SchedulerTimerID { ConstIntervalTimerID(SchedulerIntervalTimer_e timer) : SchedulerTimerID(SchedulerTimerType_e::ConstIntervalTimer) { - id = static_cast(timer); + setId(static_cast(timer)); } SchedulerIntervalTimer_e getIntervalTimer() const { - return static_cast(id); + return static_cast(getId()); } #ifndef BUILD_NO_DEBUG diff --git a/src/src/DataStructs/Scheduler_GPIOTimerID.cpp b/src/src/DataStructs/Scheduler_GPIOTimerID.cpp index 0900ebb900..10416ecf52 100644 --- a/src/src/DataStructs/Scheduler_GPIOTimerID.cpp +++ b/src/src/DataStructs/Scheduler_GPIOTimerID.cpp @@ -5,7 +5,7 @@ GPIOTimerID::GPIOTimerID(uint8_t GPIOType, uint8_t pinNumber, int Par1) : SchedulerTimerID(SchedulerTimerType_e::GPIO_timer) { - id = (Par1 << 16) + (pinNumber << 8) + GPIOType; + setId((Par1 << 16) + (pinNumber << 8) + GPIOType); } diff --git a/src/src/DataStructs/Scheduler_GPIOTimerID.h b/src/src/DataStructs/Scheduler_GPIOTimerID.h index 588617fa9a..41f5fd169f 100644 --- a/src/src/DataStructs/Scheduler_GPIOTimerID.h +++ b/src/src/DataStructs/Scheduler_GPIOTimerID.h @@ -8,18 +8,20 @@ * Special timer to handle timed GPIO actions \*********************************************************************************************/ struct GPIOTimerID : SchedulerTimerID { - GPIOTimerID(uint8_t GPIOType, uint8_t pinNumber, int Par1); + GPIOTimerID(uint8_t GPIOType, + uint8_t pinNumber, + int Par1); uint8_t getGPIO_type() const { - return static_cast((id) & 0xFF); + return static_cast((getId()) & 0xFF); } uint8_t getPinNumber() const { - return static_cast((id >> 8) & 0xFF); + return static_cast((getId() >> 8) & 0xFF); } uint8_t getPinStateValue() const { - return static_cast((id >> 16) & 0xFF); + return static_cast((getId() >> 16) & 0xFF); } #ifndef BUILD_NO_DEBUG diff --git a/src/src/DataStructs/Scheduler_IntendedRebootTimerID.cpp b/src/src/DataStructs/Scheduler_IntendedRebootTimerID.cpp index 8013bde6e3..2611b31686 100644 --- a/src/src/DataStructs/Scheduler_IntendedRebootTimerID.cpp +++ b/src/src/DataStructs/Scheduler_IntendedRebootTimerID.cpp @@ -4,6 +4,6 @@ IntendedRebootTimerID::IntendedRebootTimerID(IntendedRebootReason_e reason) : SchedulerTimerID(SchedulerTimerType_e::IntendedReboot) { - id = static_cast(reason); + setId(static_cast(reason)); } diff --git a/src/src/DataStructs/Scheduler_IntendedRebootTimerID.h b/src/src/DataStructs/Scheduler_IntendedRebootTimerID.h index afffb312c8..8df8ddd880 100644 --- a/src/src/DataStructs/Scheduler_IntendedRebootTimerID.h +++ b/src/src/DataStructs/Scheduler_IntendedRebootTimerID.h @@ -10,7 +10,7 @@ struct IntendedRebootTimerID : SchedulerTimerID { IntendedRebootReason_e getReason() const { - return static_cast(id); + return static_cast(getId()); } #ifndef BUILD_NO_DEBUG diff --git a/src/src/DataStructs/Scheduler_PluginDeviceTimerID.cpp b/src/src/DataStructs/Scheduler_PluginDeviceTimerID.cpp index 019677eb9d..979dba5dd9 100644 --- a/src/src/DataStructs/Scheduler_PluginDeviceTimerID.cpp +++ b/src/src/DataStructs/Scheduler_PluginDeviceTimerID.cpp @@ -14,7 +14,7 @@ PluginDeviceTimerID::PluginDeviceTimerID(pluginID_t pluginID, int Par1) : // FIXME TD-er: Must add a constexpr function with nr of included plugins. const unsigned nrBits = getNrBitsDeviceIndex(); const unsigned mask = MASK_BITS(nrBits); - id = (deviceIndex.value & mask) | (Par1 << nrBits); + setId((deviceIndex.value & mask) | (Par1 << nrBits)); } } @@ -22,7 +22,7 @@ deviceIndex_t PluginDeviceTimerID::get_deviceIndex() const { const unsigned nrBits = getNrBitsDeviceIndex(); const unsigned mask = MASK_BITS(nrBits); - return deviceIndex_t::toDeviceIndex(id & mask); + return deviceIndex_t::toDeviceIndex(getId() & mask); } #ifndef BUILD_NO_DEBUG @@ -33,7 +33,7 @@ String PluginDeviceTimerID::decode() const if (validDeviceIndex(deviceIndex)) { return getPluginNameFromDeviceIndex(deviceIndex); } - return String(id); + return String(getId()); } #endif // ifndef BUILD_NO_DEBUG diff --git a/src/src/DataStructs/Scheduler_PluginTaskTimerID.cpp b/src/src/DataStructs/Scheduler_PluginTaskTimerID.cpp index c0500ede38..5f0c3885eb 100644 --- a/src/src/DataStructs/Scheduler_PluginTaskTimerID.cpp +++ b/src/src/DataStructs/Scheduler_PluginTaskTimerID.cpp @@ -14,9 +14,9 @@ PluginTaskTimerID::PluginTaskTimerID(taskIndex_t taskIndex, constexpr unsigned mask_function = MASK_BITS(nrBitsPluginFunction); if (validTaskIndex(taskIndex)) { - id = (taskIndex & mask_taskIndex) | + setId((taskIndex & mask_taskIndex) | ((function & mask_function) << nrBitsTaskIndex) | - (Par1 << (nrBitsTaskIndex + nrBitsPluginFunction)); + (Par1 << (nrBitsTaskIndex + nrBitsPluginFunction))); } } @@ -25,7 +25,7 @@ taskIndex_t PluginTaskTimerID::getTaskIndex() const constexpr unsigned nrBitsTaskIndex = NR_BITS(TASKS_MAX); constexpr unsigned mask_taskIndex = MASK_BITS(nrBitsTaskIndex); - return static_cast(id & mask_taskIndex); + return static_cast(getId() & mask_taskIndex); } PluginFunctions_e PluginTaskTimerID::getFunction() const @@ -34,7 +34,7 @@ PluginFunctions_e PluginTaskTimerID::getFunction() const constexpr unsigned nrBitsPluginFunction = NrBitsPluginFunctions; constexpr unsigned mask_function = MASK_BITS(nrBitsPluginFunction); - return static_cast((id >> nrBitsTaskIndex) & mask_function); + return static_cast((getId() >> nrBitsTaskIndex) & mask_function); } #ifndef BUILD_NO_DEBUG @@ -45,7 +45,7 @@ String PluginTaskTimerID::decode() const if (validTaskIndex(taskIndex)) { return getTaskDeviceName(taskIndex); } - return String(id); + return String(getId()); } #endif // ifndef BUILD_NO_DEBUG diff --git a/src/src/DataStructs/Scheduler_RulesTimerID.cpp b/src/src/DataStructs/Scheduler_RulesTimerID.cpp index 5ee8dfc720..b5f3c2929c 100644 --- a/src/src/DataStructs/Scheduler_RulesTimerID.cpp +++ b/src/src/DataStructs/Scheduler_RulesTimerID.cpp @@ -5,13 +5,13 @@ RulesTimerID::RulesTimerID(unsigned int timerIndex) : SchedulerTimerID(SchedulerTimerType_e::RulesTimer) { - id = timerIndex; + setId(timerIndex); } #ifndef BUILD_NO_DEBUG String RulesTimerID::decode() const { - return concat(F("Rules#Timer="), id); + return concat(F("Rules#Timer="), getId()); } #endif // ifndef BUILD_NO_DEBUG diff --git a/src/src/DataStructs/Scheduler_SystemEventQueueTimerID.cpp b/src/src/DataStructs/Scheduler_SystemEventQueueTimerID.cpp index e111b545f3..a241920c4f 100644 --- a/src/src/DataStructs/Scheduler_SystemEventQueueTimerID.cpp +++ b/src/src/DataStructs/Scheduler_SystemEventQueueTimerID.cpp @@ -7,9 +7,9 @@ SystemEventQueueTimerID::SystemEventQueueTimerID(SchedulerPluginPtrType_e ptr_type, uint8_t Index, uint8_t Function) : SchedulerTimerID(SchedulerTimerType_e::SystemEventQueue) { - id = (static_cast(ptr_type) << 16) + + setId((static_cast(ptr_type) << 16) + (Index << 8) + - Function; + Function); } diff --git a/src/src/DataStructs/Scheduler_SystemEventQueueTimerID.h b/src/src/DataStructs/Scheduler_SystemEventQueueTimerID.h index 7dff58adac..10ceafed43 100644 --- a/src/src/DataStructs/Scheduler_SystemEventQueueTimerID.h +++ b/src/src/DataStructs/Scheduler_SystemEventQueueTimerID.h @@ -16,15 +16,15 @@ struct SystemEventQueueTimerID : SchedulerTimerID { uint8_t Function); uint8_t getFunction() const { - return static_cast((id) & 0xFF); + return static_cast((getId()) & 0xFF); } uint8_t getIndex() const { - return static_cast((id >> 8) & 0xFF); + return static_cast((getId() >> 8) & 0xFF); } SchedulerPluginPtrType_e getPtrType() const { - return static_cast((id >> 16) & 0xFF); + return static_cast((getId() >> 16) & 0xFF); } #ifndef BUILD_NO_DEBUG diff --git a/src/src/DataStructs/Scheduler_TaskDeviceTimerID.cpp b/src/src/DataStructs/Scheduler_TaskDeviceTimerID.cpp index 3363fef4f1..fa12d1e369 100644 --- a/src/src/DataStructs/Scheduler_TaskDeviceTimerID.cpp +++ b/src/src/DataStructs/Scheduler_TaskDeviceTimerID.cpp @@ -6,7 +6,7 @@ TaskDeviceTimerID::TaskDeviceTimerID(taskIndex_t taskIndex) : SchedulerTimerID(SchedulerTimerType_e::TaskDeviceTimer) { - id = static_cast(taskIndex); + setId(static_cast(taskIndex)); } #ifndef BUILD_NO_DEBUG @@ -16,7 +16,7 @@ String TaskDeviceTimerID::decode() const return concat(F("Task "), validTaskIndex(taskIndex) ? getTaskDeviceName(taskIndex) - : String(id)); + : String(getId())); } #endif // ifndef BUILD_NO_DEBUG diff --git a/src/src/DataStructs/Scheduler_TaskDeviceTimerID.h b/src/src/DataStructs/Scheduler_TaskDeviceTimerID.h index 6da5407bf2..6f539f07d8 100644 --- a/src/src/DataStructs/Scheduler_TaskDeviceTimerID.h +++ b/src/src/DataStructs/Scheduler_TaskDeviceTimerID.h @@ -14,7 +14,7 @@ struct TaskDeviceTimerID : SchedulerTimerID { taskIndex_t getTaskIndex() const { - return static_cast(id); + return static_cast(getId()); } #ifndef BUILD_NO_DEBUG diff --git a/src/src/DataStructs/SettingsStruct.h b/src/src/DataStructs/SettingsStruct.h index 1bf2f8855c..1fc8af9090 100644 --- a/src/src/DataStructs/SettingsStruct.h +++ b/src/src/DataStructs/SettingsStruct.h @@ -321,6 +321,26 @@ class SettingsStruct_tmpl void forceSave() { memset(md5, 0, 16); } + uint32_t getVariousBits1() const { + uint32_t res; + memcpy(&res, &VariousBits_1, sizeof(VariousBits_1)); + return res; + } + + void setVariousBits1(uint32_t value) { + memcpy(&VariousBits_1, &value, sizeof(VariousBits_1)); + } + + uint32_t getVariousBits2() const { + uint32_t res; + memcpy(&res, &VariousBits_2, sizeof(VariousBits_2)); + return res; + } + + void setVariousBits2(uint32_t value) { + memcpy(&VariousBits_2, &value, sizeof(VariousBits_2)); + } + unsigned long PID = 0; int Version = 0; @@ -368,6 +388,9 @@ class SettingsStruct_tmpl // FIXME TD-er: Must change to pluginID_t, but then also another check must be added since changing the pluginID_t will also render settings incompatible uint8_t TaskDeviceNumber[N_TASKS] = {0}; // The "plugin number" set at as task (e.g. 4 for P004_dallas) unsigned int OLD_TaskDeviceID[N_TASKS] = {0}; //UNUSED: this can be reused + + // FIXME TD-er: When used on ESP8266, this conversion union may not work + // It might work as it is 32-bit in size. union { struct { int8_t TaskDevicePin1[N_TASKS]; @@ -381,6 +404,9 @@ class SettingsStruct_tmpl int16_t TaskDevicePluginConfig[N_TASKS][PLUGIN_CONFIGVAR_MAX]{}; boolean TaskDevicePin1Inversed[N_TASKS] = {0}; float TaskDevicePluginConfigFloat[N_TASKS][PLUGIN_CONFIGFLOATVAR_MAX]{}; + + // FIXME TD-er: When used on ESP8266, this conversion union may not work + // It might work as it is 32-bit in size. union { int32_t TaskDevicePluginConfigLong[N_TASKS][PLUGIN_CONFIGLONGVAR_MAX]; uint32_t TaskDevicePluginConfigULong[N_TASKS][PLUGIN_CONFIGLONGVAR_MAX]{}; @@ -411,45 +437,43 @@ class SettingsStruct_tmpl //TODO: document config.dat somewhere here float Latitude = 0.0f; float Longitude = 0.0f; - union { - // VariousBits1 defaults to 0, keep in mind when adding bit lookups. - struct { - uint32_t unused_00 : 1; // Bit 00 - uint32_t appendUnitToHostname : 1; // Bit 01 Inverted - uint32_t unused_02 : 1; // Bit 02 uniqueMQTTclientIdReconnect_unused - uint32_t OldRulesEngine : 1; // Bit 03 Inverted - uint32_t ForceWiFi_bg_mode : 1; // Bit 04 - uint32_t WiFiRestart_connection_lost : 1; // Bit 05 - uint32_t EcoPowerMode : 1; // Bit 06 - uint32_t WifiNoneSleep : 1; // Bit 07 - uint32_t gratuitousARP : 1; // Bit 08 Inverted - uint32_t TolerantLastArgParse : 1; // Bit 09 - uint32_t SendToHttp_ack : 1; // Bit 10 - uint32_t UseESPEasyNow : 1; // Bit 11 - uint32_t IncludeHiddenSSID : 1; // Bit 12 - uint32_t UseMaxTXpowerForSending : 1; // Bit 13 - uint32_t ApDontForceSetup : 1; // Bit 14 - uint32_t unused_15 : 1; // Bit 15 was used by PeriodicalScanWiFi - uint32_t JSONBoolWithoutQuotes : 1; // Bit 16 - uint32_t DoNotStartAP : 1; // Bit 17 - uint32_t UseAlternativeDeepSleep : 1; // Bit 18 - uint32_t UseLastWiFiFromRTC : 1; // Bit 19 - uint32_t EnableTimingStats : 1; // Bit 20 - uint32_t AllowTaskValueSetAllPlugins : 1; // Bit 21 - uint32_t EnableClearHangingI2Cbus : 1; // Bit 22 - uint32_t EnableRAMTracking : 1; // Bit 23 - uint32_t EnableRulesCaching : 1; // Bit 24 Inverted - uint32_t EnableRulesEventReorder : 1; // Bit 25 Inverted - uint32_t AllowOTAUnlimited : 1; // Bit 26 - uint32_t SendToHTTP_follow_redirects : 1; // Bit 27 - uint32_t CssMode : 2; // Bit 28 + + // VariousBits_1 defaults to 0, keep in mind when adding bit lookups. + struct { + uint32_t unused_00 : 1; // Bit 00 + uint32_t appendUnitToHostname : 1; // Bit 01 Inverted + uint32_t unused_02 : 1; // Bit 02 uniqueMQTTclientIdReconnect_unused + uint32_t OldRulesEngine : 1; // Bit 03 Inverted + uint32_t ForceWiFi_bg_mode : 1; // Bit 04 + uint32_t WiFiRestart_connection_lost : 1; // Bit 05 + uint32_t EcoPowerMode : 1; // Bit 06 + uint32_t WifiNoneSleep : 1; // Bit 07 + uint32_t gratuitousARP : 1; // Bit 08 Inverted + uint32_t TolerantLastArgParse : 1; // Bit 09 + uint32_t SendToHttp_ack : 1; // Bit 10 + uint32_t UseESPEasyNow : 1; // Bit 11 + uint32_t IncludeHiddenSSID : 1; // Bit 12 + uint32_t UseMaxTXpowerForSending : 1; // Bit 13 + uint32_t ApDontForceSetup : 1; // Bit 14 + uint32_t unused_15 : 1; // Bit 15 was used by PeriodicalScanWiFi + uint32_t JSONBoolWithoutQuotes : 1; // Bit 16 + uint32_t DoNotStartAP : 1; // Bit 17 + uint32_t UseAlternativeDeepSleep : 1; // Bit 18 + uint32_t UseLastWiFiFromRTC : 1; // Bit 19 + uint32_t EnableTimingStats : 1; // Bit 20 + uint32_t AllowTaskValueSetAllPlugins : 1; // Bit 21 + uint32_t EnableClearHangingI2Cbus : 1; // Bit 22 + uint32_t EnableRAMTracking : 1; // Bit 23 + uint32_t EnableRulesCaching : 1; // Bit 24 Inverted + uint32_t EnableRulesEventReorder : 1; // Bit 25 Inverted + uint32_t AllowOTAUnlimited : 1; // Bit 26 + uint32_t SendToHTTP_follow_redirects : 1; // Bit 27 + uint32_t CssMode : 2; // Bit 28 // uint32_t unused_29 : 1; // Bit 29 - uint32_t CheckI2Cdevice : 1; // Bit 30 Inverted - uint32_t DoNotUse_31 : 1; // Bit 31 Was used to detect whether various bits were even set + uint32_t CheckI2Cdevice : 1; // Bit 30 Inverted + uint32_t DoNotUse_31 : 1; // Bit 31 Was used to detect whether various bits were even set - } VariousBits_1; - uint32_t VariousBits1 = 0; - }; + } VariousBits_1; uint32_t ResetFactoryDefaultPreference = 0; // Do not clear this one in the clearAll() uint32_t I2C_clockSpeed = 400000; @@ -488,46 +512,43 @@ class SettingsStruct_tmpl // Do not rename or move this checksum. // Checksum calculation will work "around" this uint8_t md5[16]{}; // Store checksum of the settings. - union { - // VariousBits2 defaults to 0, keep in mind when adding bit lookups. - struct { - uint32_t WaitWiFiConnect : 1; // Bit 00 - uint32_t SDK_WiFi_autoreconnect : 1; // Bit 01 - uint32_t DisableRulesCodeCompletion : 1; // Bit 02 - uint32_t HiddenSSID_SlowConnectPerBSSID : 1; // Bit 03 // inverted - uint32_t unused_04 : 1; // Bit 04 - uint32_t unused_05 : 1; // Bit 05 - uint32_t unused_06 : 1; // Bit 06 - uint32_t unused_07 : 1; // Bit 07 - uint32_t unused_08 : 1; // Bit 08 - uint32_t unused_09 : 1; // Bit 09 - uint32_t unused_10 : 1; // Bit 10 - uint32_t unused_11 : 1; // Bit 11 - uint32_t unused_12 : 1; // Bit 12 - uint32_t unused_13 : 1; // Bit 13 - uint32_t unused_14 : 1; // Bit 14 - uint32_t unused_15 : 1; // Bit 15 - uint32_t unused_16 : 1; // Bit 16 - uint32_t unused_17 : 1; // Bit 17 - uint32_t unused_18 : 1; // Bit 18 - uint32_t unused_19 : 1; // Bit 19 - uint32_t unused_20 : 1; // Bit 20 - uint32_t unused_21 : 1; // Bit 21 - uint32_t unused_22 : 1; // Bit 22 - uint32_t unused_23 : 1; // Bit 23 - uint32_t unused_24 : 1; // Bit 24 - uint32_t unused_25 : 1; // Bit 25 - uint32_t unused_26 : 1; // Bit 26 - uint32_t unused_27 : 1; // Bit 27 - uint32_t unused_28 : 1; // Bit 28 - uint32_t unused_29 : 1; // Bit 29 - uint32_t unused_30 : 1; // Bit 30 - uint32_t unused_31 : 1; // Bit 31 - - } VariousBits_2; - uint32_t VariousBits2 = 0; - }; + // VariousBits_2 defaults to 0, keep in mind when adding bit lookups. + struct { + uint32_t WaitWiFiConnect : 1; // Bit 00 + uint32_t SDK_WiFi_autoreconnect : 1; // Bit 01 + uint32_t DisableRulesCodeCompletion : 1; // Bit 02 + uint32_t HiddenSSID_SlowConnectPerBSSID : 1; // Bit 03 // inverted + uint32_t unused_04 : 1; // Bit 04 + uint32_t unused_05 : 1; // Bit 05 + uint32_t unused_06 : 1; // Bit 06 + uint32_t unused_07 : 1; // Bit 07 + uint32_t unused_08 : 1; // Bit 08 + uint32_t unused_09 : 1; // Bit 09 + uint32_t unused_10 : 1; // Bit 10 + uint32_t unused_11 : 1; // Bit 11 + uint32_t unused_12 : 1; // Bit 12 + uint32_t unused_13 : 1; // Bit 13 + uint32_t unused_14 : 1; // Bit 14 + uint32_t unused_15 : 1; // Bit 15 + uint32_t unused_16 : 1; // Bit 16 + uint32_t unused_17 : 1; // Bit 17 + uint32_t unused_18 : 1; // Bit 18 + uint32_t unused_19 : 1; // Bit 19 + uint32_t unused_20 : 1; // Bit 20 + uint32_t unused_21 : 1; // Bit 21 + uint32_t unused_22 : 1; // Bit 22 + uint32_t unused_23 : 1; // Bit 23 + uint32_t unused_24 : 1; // Bit 24 + uint32_t unused_25 : 1; // Bit 25 + uint32_t unused_26 : 1; // Bit 26 + uint32_t unused_27 : 1; // Bit 27 + uint32_t unused_28 : 1; // Bit 28 + uint32_t unused_29 : 1; // Bit 29 + uint32_t unused_30 : 1; // Bit 30 + uint32_t unused_31 : 1; // Bit 31 + + } VariousBits_2; uint8_t console_serial_port = DEFAULT_CONSOLE_PORT; int8_t console_serial_rxpin = DEFAULT_CONSOLE_PORT_RXPIN; diff --git a/src/src/DataStructs/WiFi_AP_Candidate.cpp b/src/src/DataStructs/WiFi_AP_Candidate.cpp index 9f1671a131..eaba4d6add 100644 --- a/src/src/DataStructs/WiFi_AP_Candidate.cpp +++ b/src/src/DataStructs/WiFi_AP_Candidate.cpp @@ -19,10 +19,28 @@ #define WIFI_AP_CANDIDATE_MAX_AGE 300000 // 5 minutes in msec +WiFi_AP_Candidate::WiFi_AP_Candidate() : + last_seen(0), rssi(0), channel(0), index(0), enc_type(0) +{ + lowPriority = false; + isEmergencyFallback = false; + + phy_11b = false; + phy_11g = false; + phy_11n = false; + phy_lr = false; + phy_11ax = false; + wps = false; + ftm_responder = false; + ftm_initiator = false; + +} + + WiFi_AP_Candidate::WiFi_AP_Candidate(uint8_t index_c, const String& ssid_c) : - last_seen(0), rssi(0), channel(0), index(index_c) + last_seen(0), rssi(0), channel(0), index(index_c), enc_type(0) { - lowPriority = false; + lowPriority = false; isEmergencyFallback = false; phy_11b = false; diff --git a/src/src/DataStructs/WiFi_AP_Candidate.h b/src/src/DataStructs/WiFi_AP_Candidate.h index 3553be5b98..9c41814758 100644 --- a/src/src/DataStructs/WiFi_AP_Candidate.h +++ b/src/src/DataStructs/WiFi_AP_Candidate.h @@ -5,6 +5,10 @@ #include "../DataStructs/MAC_address.h" struct WiFi_AP_Candidate { + WiFi_AP_Candidate(); + WiFi_AP_Candidate(const WiFi_AP_Candidate& other) = default; + + // Construct from stored credentials // @param index The index of the stored credentials // @param ssid_c SSID of the credentials @@ -22,9 +26,6 @@ struct WiFi_AP_Candidate { #endif - WiFi_AP_Candidate() = default; - WiFi_AP_Candidate(const WiFi_AP_Candidate& other) = default; - // Return true when this one is preferred over 'other'. bool operator<(const WiFi_AP_Candidate& other) const; diff --git a/src/src/DataStructs_templ/SettingsStruct.cpp b/src/src/DataStructs_templ/SettingsStruct.cpp index 09215d9493..3fdb3357f6 100644 --- a/src/src/DataStructs_templ/SettingsStruct.cpp +++ b/src/src/DataStructs_templ/SettingsStruct.cpp @@ -450,7 +450,7 @@ void SettingsStruct_tmpl::validate() { if ((Longitude < -180.0f) || (Longitude > 180.0f)) { Longitude = 0.0f; } - if (VariousBits1 > (1u << 31)) { VariousBits1 = 0; } // FIXME: Check really needed/useful? + if (getVariousBits1() > (1u << 31)) { setVariousBits1(0); } // FIXME: Check really needed/useful? ZERO_TERMINATE(Name); ZERO_TERMINATE(NTPHost); @@ -612,14 +612,14 @@ void SettingsStruct_tmpl::clearMisc() { Pin_Reset = -1; StructSize = sizeof(SettingsStruct_tmpl); MQTTUseUnitNameAsClientId_unused = 0; - VariousBits1 = 0; + setVariousBits1(0); + setVariousBits2(0); console_serial_port = DEFAULT_CONSOLE_PORT; console_serial_rxpin = DEFAULT_CONSOLE_PORT_RXPIN; console_serial_txpin = DEFAULT_CONSOLE_PORT_TXPIN; console_serial0_fallback = DEFAULT_CONSOLE_SER0_FALLBACK; - OldRulesEngine(DEFAULT_RULES_OLDENGINE); ForceWiFi_bg_mode(DEFAULT_WIFI_FORCE_BG_MODE); WiFiRestart_connection_lost(DEFAULT_WIFI_RESTART_WIFI_CONN_LOST); diff --git a/src/src/Helpers/ESPEasy_Storage.cpp b/src/src/Helpers/ESPEasy_Storage.cpp index 424920049f..a38cefbb72 100644 --- a/src/src/Helpers/ESPEasy_Storage.cpp +++ b/src/src/Helpers/ESPEasy_Storage.cpp @@ -404,7 +404,7 @@ bool BuildFixes() } // Remove PeriodicalScanWiFi // Reset to default 0 for future use. - bitWrite(Settings.VariousBits1, 15, 0); + Settings.VariousBits_1.unused_15 = 0; } #endif diff --git a/src/src/Helpers/Modbus_RTU.cpp b/src/src/Helpers/Modbus_RTU.cpp index 96d63d7a77..159a3afab6 100644 --- a/src/src/Helpers/Modbus_RTU.cpp +++ b/src/src/Helpers/Modbus_RTU.cpp @@ -541,13 +541,10 @@ uint32_t ModbusRTU_struct::read_32b_HoldingRegister(short address) { } float ModbusRTU_struct::read_float_HoldingRegister(short address) { - union { - uint32_t ival; - float fval; - } conversion; - - conversion.ival = read_32b_HoldingRegister(address); - return conversion.fval; + const uint32_t ival = read_32b_HoldingRegister(address); + float fval{}; + memcpy(&fval, &ival, sizeof(ival)); + return fval; // uint32_t ival = read_32b_HoldingRegister(address); // float fval = *reinterpret_cast(&ival); diff --git a/src/src/Helpers/Scheduler_decodeTimer.cpp b/src/src/Helpers/Scheduler_decodeTimer.cpp index 2582ec73b8..805b4d2710 100644 --- a/src/src/Helpers/Scheduler_decodeTimer.cpp +++ b/src/src/Helpers/Scheduler_decodeTimer.cpp @@ -62,6 +62,6 @@ String ESPEasy_Scheduler::decodeSchedulerId(SchedulerTimerID timerID) { #endif // ifndef BUILD_NO_DEBUG result += F(" timer, id: "); - result += timerID.id; + result += timerID.getId(); return result; } diff --git a/src/src/PluginStructs/P148_data_struct.cpp b/src/src/PluginStructs/P148_data_struct.cpp index 35d75cb537..9faa757a23 100644 --- a/src/src/PluginStructs/P148_data_struct.cpp +++ b/src/src/PluginStructs/P148_data_struct.cpp @@ -88,6 +88,10 @@ uint8_t P148_data_struct::TM1621GetFontCharacter(char character, bool firstrow) return 0u; } + +// FIXME TD-er: When used on ESP8266, this conversion union may not work +// However this is probably only used on ESP32 Sonoff units with display. + // Do not change the order of these as it is stored. union MonitorTaskValue_conversion { struct { diff --git a/src/src/PluginStructs/P151_data_struct.cpp b/src/src/PluginStructs/P151_data_struct.cpp index a990d1022e..20376b09fb 100644 --- a/src/src/PluginStructs/P151_data_struct.cpp +++ b/src/src/PluginStructs/P151_data_struct.cpp @@ -6,6 +6,8 @@ P151_data_struct::~P151_data_struct() {} bool P151_data_struct::plugin_read(struct EventStruct *event) { + // FIXME TD-er: When used on ESP8266, this conversion union may not work + // It might work as it is 32-bit in size. union Honeywell_struct { struct { uint32_t dummy : 5; From 8ee39955d854ac6186d67457156a247a12d9d8a3 Mon Sep 17 00:00:00 2001 From: TD-er Date: Tue, 12 Mar 2024 15:11:01 +0100 Subject: [PATCH 4/6] [ESP-IDF5.1] Revert to older SDK code due to issues with HWCDC --- platformio_core_defs.ini | 2 +- src/src/ESPEasyCore/ESPEasy_Console.cpp | 16 +++++++-- src/src/ESPEasyCore/ESPEasy_Console_Port.cpp | 2 ++ src/src/Helpers/SerialWriteBuffer.cpp | 37 ++++++++++++++------ src/src/Helpers/SerialWriteBuffer.h | 3 -- 5 files changed, 44 insertions(+), 16 deletions(-) diff --git a/platformio_core_defs.ini b/platformio_core_defs.ini index 7d1b581d00..89ecddeb89 100644 --- a/platformio_core_defs.ini +++ b/platformio_core_defs.ini @@ -211,7 +211,7 @@ lib_ignore = ;platform = https://github.com/Jason2866/platform-espressif32.git platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.02.10/platform-espressif32.zip ;platform_packages = -platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2151/framework-arduinoespressif32-release_v5.1-1a0b6e0.zip +platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2119/framework-arduinoespressif32-release_v5.1-a28d368.zip build_flags = -DESP32_STAGE -DESP_IDF_VERSION_MAJOR=5 -DLIBRARIES_NO_LOG=1 diff --git a/src/src/ESPEasyCore/ESPEasy_Console.cpp b/src/src/ESPEasyCore/ESPEasy_Console.cpp index ab23476ad0..8ee42c491f 100644 --- a/src/src/ESPEasyCore/ESPEasy_Console.cpp +++ b/src/src/ESPEasyCore/ESPEasy_Console.cpp @@ -149,10 +149,22 @@ void EspEasy_Console_t::reInit() HeapSelectDram ephemeral; # endif // ifdef USE_SECOND_HEAP + unsigned int buffsize = 128; + + const ESPEasySerialPort mainSerialPort = static_cast(_console_serial_port); + +#if USES_HWCDC + if (mainSerialPort == ESPEasySerialPort::usb_hw_cdc) { + buffsize = 512; + } +#endif // if USES_HWCDC + _mainSerial._serial = new (std::nothrow) ESPeasySerial( - static_cast(_console_serial_port), + mainSerialPort, _console_serial_rxpin, - _console_serial_txpin); + _console_serial_txpin, + false, + buffsize); somethingChanged = true; } # if USES_ESPEASY_CONSOLE_FALLBACK_PORT diff --git a/src/src/ESPEasyCore/ESPEasy_Console_Port.cpp b/src/src/ESPEasyCore/ESPEasy_Console_Port.cpp index d29323dda4..91f39d59ba 100644 --- a/src/src/ESPEasyCore/ESPEasy_Console_Port.cpp +++ b/src/src/ESPEasyCore/ESPEasy_Console_Port.cpp @@ -24,10 +24,12 @@ EspEasy_Console_Port::~EspEasy_Console_Port() { +#if FEATURE_DEFINE_SERIAL_CONSOLE_PORT if (_serial != nullptr) { delete _serial; _serial = nullptr; } +#endif } EspEasy_Console_Port::operator bool() const diff --git a/src/src/Helpers/SerialWriteBuffer.cpp b/src/src/Helpers/SerialWriteBuffer.cpp index ca4364f971..cf4fbc2feb 100644 --- a/src/src/Helpers/SerialWriteBuffer.cpp +++ b/src/src/Helpers/SerialWriteBuffer.cpp @@ -57,11 +57,6 @@ void SerialWriteBuffer_t::clear() _buffer.clear(); } -int SerialWriteBuffer_t::availableForWrite() const -{ - return _buffer.size(); -} - size_t SerialWriteBuffer_t::write(Stream& stream, size_t nrBytesToWrite) { size_t bytesWritten = 0; @@ -77,14 +72,36 @@ size_t SerialWriteBuffer_t::write(Stream& stream, size_t nrBytesToWrite) } while (nrBytesToWrite > 0 && !_buffer.empty()) { - const char c = _buffer.front(); + #ifdef ESP32 + uint8_t tmpBuffer[1]{}; + #else + uint8_t tmpBuffer[16]{}; + #endif - if (stream.write((uint8_t)c) == 0) { + size_t tmpBufferUsed = 0; + + auto it = _buffer.begin(); + + for (; tmpBufferUsed < sizeof(tmpBuffer) && tmpBufferUsed < nrBytesToWrite && it != _buffer.end(); ) { + tmpBuffer[tmpBufferUsed] = (uint8_t)(*it); + ++tmpBufferUsed; + ++it; + } + + bool done = false; + const size_t written = stream.write(tmpBuffer, tmpBufferUsed); + + if (written < tmpBufferUsed) { + done = true; + } + for (size_t i = 0; i < written; ++i) { + _buffer.pop_front(); + --nrBytesToWrite; + ++bytesWritten; + } + if (done) { return bytesWritten; } - _buffer.pop_front(); - --nrBytesToWrite; - ++bytesWritten; } } return bytesWritten; diff --git a/src/src/Helpers/SerialWriteBuffer.h b/src/src/Helpers/SerialWriteBuffer.h index f2bd1ed33e..7e5932df4f 100644 --- a/src/src/Helpers/SerialWriteBuffer.h +++ b/src/src/Helpers/SerialWriteBuffer.h @@ -28,9 +28,6 @@ class SerialWriteBuffer_t { void clear(); - - int availableForWrite() const; - size_t write(Stream& stream, size_t nrBytesToWrite); From 7a73e8d418a296270efdc3f13a6e181ebbe03846 Mon Sep 17 00:00:00 2001 From: TD-er Date: Tue, 12 Mar 2024 15:12:11 +0100 Subject: [PATCH 5/6] [Build] Reduce build size regarding WiFi AP Candidate duplicate code --- src/src/DataStructs/WiFi_AP_Candidate.cpp | 181 ++++++++---------- src/src/DataStructs/WiFi_AP_Candidate.h | 78 ++++---- src/src/ESPEasyCore/ESPEasyWifi.cpp | 16 +- .../ESPEasyCore/ESPEasyWifi_ProcessEvent.cpp | 2 +- src/src/Helpers/WiFi_AP_CandidatesList.cpp | 16 +- src/src/WebServer/SetupPage.cpp | 2 +- 6 files changed, 141 insertions(+), 154 deletions(-) diff --git a/src/src/DataStructs/WiFi_AP_Candidate.cpp b/src/src/DataStructs/WiFi_AP_Candidate.cpp index eaba4d6add..9c1f41e982 100644 --- a/src/src/DataStructs/WiFi_AP_Candidate.cpp +++ b/src/src/DataStructs/WiFi_AP_Candidate.cpp @@ -22,35 +22,13 @@ WiFi_AP_Candidate::WiFi_AP_Candidate() : last_seen(0), rssi(0), channel(0), index(0), enc_type(0) { - lowPriority = false; - isEmergencyFallback = false; - - phy_11b = false; - phy_11g = false; - phy_11n = false; - phy_lr = false; - phy_11ax = false; - wps = false; - ftm_responder = false; - ftm_initiator = false; - + memset(&bits, 0, sizeof(bits)); } - WiFi_AP_Candidate::WiFi_AP_Candidate(uint8_t index_c, const String& ssid_c) : last_seen(0), rssi(0), channel(0), index(index_c), enc_type(0) { - lowPriority = false; - isEmergencyFallback = false; - - phy_11b = false; - phy_11g = false; - phy_11n = false; - phy_lr = false; - phy_11ax = false; - wps = false; - ftm_responder = false; - ftm_initiator = false; + memset(&bits, 0, sizeof(bits)); const size_t ssid_length = ssid_c.length(); @@ -63,108 +41,98 @@ WiFi_AP_Candidate::WiFi_AP_Candidate(uint8_t index_c, const String& ssid_c) : ssid = ssid_c; } - WiFi_AP_Candidate::WiFi_AP_Candidate(uint8_t networkItem) : index(0) { // Need to make sure the phy isn't known as we can't get this information from the AP // See: https://github.com/letscontrolit/ESPEasy/issues/4996 // Not sure why this makes any difference as the flags should already have been set to 0. - lowPriority = false; - isEmergencyFallback = false; - - phy_11b = false; - phy_11g = false; - phy_11n = false; - phy_lr = false; - phy_11ax = false; - wps = false; - ftm_responder = false; - ftm_initiator = false; - - ssid = WiFi.SSID(networkItem); - rssi = WiFi.RSSI(networkItem); - channel = WiFi.channel(networkItem); - bssid = WiFi.BSSID(networkItem); + memset(&bits, 0, sizeof(bits)); + + ssid = WiFi.SSID(networkItem); + rssi = WiFi.RSSI(networkItem); + channel = WiFi.channel(networkItem); + bssid = WiFi.BSSID(networkItem); enc_type = WiFi.encryptionType(networkItem); #ifdef ESP8266 - isHidden = WiFi.isHidden(networkItem); - #ifdef CORE_POST_3_0_0 - const bss_info* it = reinterpret_cast(WiFi.getScanInfoByIndex(networkItem)); + bits.isHidden = WiFi.isHidden(networkItem); + # ifdef CORE_POST_3_0_0 + const bss_info *it = reinterpret_cast(WiFi.getScanInfoByIndex(networkItem)); + if (it) { - phy_11b = it->phy_11b; - phy_11g = it->phy_11g; - phy_11n = it->phy_11n; - wps = it->wps; + bits.phy_11b = it->phy_11b; + bits.phy_11g = it->phy_11g; + bits.phy_11n = it->phy_11n; + bits.wps = it->wps; } - #endif + # endif // ifdef CORE_POST_3_0_0 #endif // ifdef ESP8266 #ifdef ESP32 - isHidden = ssid.isEmpty(); - wifi_ap_record_t* it = reinterpret_cast(WiFi.getScanInfoByIndex(networkItem)); + bits.isHidden = ssid.isEmpty(); + wifi_ap_record_t *it = reinterpret_cast(WiFi.getScanInfoByIndex(networkItem)); + if (it) { - phy_11b = it->phy_11b; - phy_11g = it->phy_11g; - phy_11n = it->phy_11n; - phy_lr = it->phy_lr; -#if ESP_IDF_VERSION_MAJOR >= 5 - phy_11ax = it->phy_11ax; - ftm_initiator = it->ftm_initiator; - ftm_responder = it->ftm_responder; -#endif - wps = it->wps; + bits.phy_11b = it->phy_11b; + bits.phy_11g = it->phy_11g; + bits.phy_11n = it->phy_11n; + bits.phy_lr = it->phy_lr; +# if ESP_IDF_VERSION_MAJOR >= 5 + bits.phy_11ax = it->phy_11ax; + bits.ftm_initiator = it->ftm_initiator; + bits.ftm_responder = it->ftm_responder; +# endif // if ESP_IDF_VERSION_MAJOR >= 5 + bits.wps = it->wps; + // FIXME TD-er: Maybe also add other info like 2nd channel, ftm and phy_lr support? } #endif // ifdef ESP32 last_seen = millis(); } - #ifdef ESP8266 -#if FEATURE_ESP8266_DIRECT_WIFI_SCAN +# if FEATURE_ESP8266_DIRECT_WIFI_SCAN WiFi_AP_Candidate::WiFi_AP_Candidate(const bss_info& ap) : - rssi(ap.rssi), channel(ap.channel), bssid(ap.bssid), + rssi(ap.rssi), channel(ap.channel), bssid(ap.bssid), index(0), enc_type(0), isHidden(ap.is_hidden), phy_11b(ap.phy_11b), phy_11g(ap.phy_11g), phy_11n(ap.phy_11n), wps(ap.wps) { - lowPriority = false; - isEmergencyFallback = false; - phy_lr = false; - phy_11ax = false; - ftm_responder = false; - ftm_initiator = false; + memset(&bits, 0, sizeof(bits)); last_seen = millis(); - switch(ap.authmode) { - case AUTH_OPEN: enc_type = ENC_TYPE_NONE; break; - case AUTH_WEP: enc_type = ENC_TYPE_WEP; break; - case AUTH_WPA_PSK: enc_type = ENC_TYPE_TKIP; break; - case AUTH_WPA2_PSK: enc_type = ENC_TYPE_CCMP; break; + switch (ap.authmode) { + case AUTH_OPEN: enc_type = ENC_TYPE_NONE; break; + case AUTH_WEP: enc_type = ENC_TYPE_WEP; break; + case AUTH_WPA_PSK: enc_type = ENC_TYPE_TKIP; break; + case AUTH_WPA2_PSK: enc_type = ENC_TYPE_CCMP; break; case AUTH_WPA_WPA2_PSK: enc_type = ENC_TYPE_AUTO; break; case AUTH_MAX: break; } - char tmp[33]; //ssid can be up to 32chars, => plus null term + char tmp[33]; // ssid can be up to 32chars, => plus null term const size_t ssid_len = std::min(static_cast(ap.ssid_len), sizeof(ap.ssid)); + memcpy(tmp, ap.ssid, ssid_len); tmp[ssid_len] = 0; // nullterm marking end of string - ssid = String(reinterpret_cast(tmp)); + ssid = String(reinterpret_cast(tmp)); } -#endif -#endif + +# endif // if FEATURE_ESP8266_DIRECT_WIFI_SCAN +#endif // ifdef ESP8266 bool WiFi_AP_Candidate::operator<(const WiFi_AP_Candidate& other) const { - if (isEmergencyFallback != other.isEmergencyFallback) { - return isEmergencyFallback; + if (bits.isEmergencyFallback != other.bits.isEmergencyFallback) { + return bits.isEmergencyFallback; } - if (lowPriority != other.lowPriority) { - return !lowPriority; + + if (bits.lowPriority != other.bits.lowPriority) { + return !bits.lowPriority; } + // Prefer non hidden over hidden. - if (isHidden != other.isHidden) { - return !isHidden; + if (bits.isHidden != other.bits.isHidden) { + return !bits.isHidden; } // RSSI values >= 0 are invalid @@ -179,19 +147,21 @@ bool WiFi_AP_Candidate::operator<(const WiFi_AP_Candidate& other) const { bool WiFi_AP_Candidate::usable() const { // Allow for empty pass // if (key.isEmpty()) return false; - if (isEmergencyFallback) { + if (bits.isEmergencyFallback) { int allowedUptimeMinutes = 10; #ifdef CUSTOM_EMERGENCY_FALLBACK_ALLOW_MINUTES_UPTIME allowedUptimeMinutes = CUSTOM_EMERGENCY_FALLBACK_ALLOW_MINUTES_UPTIME; - #endif - if (getUptimeMinutes() > allowedUptimeMinutes || - !SecuritySettings.hasWiFiCredentials() || + #endif // ifdef CUSTOM_EMERGENCY_FALLBACK_ALLOW_MINUTES_UPTIME + + if ((getUptimeMinutes() > allowedUptimeMinutes) || + !SecuritySettings.hasWiFiCredentials() || WiFiEventData.performedClearWiFiCredentials || - lastBootCause != BOOT_CAUSE_COLD_BOOT) { + (lastBootCause != BOOT_CAUSE_COLD_BOOT)) { return false; } } - if (!isHidden && (ssid.isEmpty())) { return false; } + + if (!bits.isHidden && (ssid.isEmpty())) { return false; } return !expired(); } @@ -203,12 +173,12 @@ bool WiFi_AP_Candidate::expired() const { return timePassedSince(last_seen) > WIFI_AP_CANDIDATE_MAX_AGE; } - String WiFi_AP_Candidate::toString(const String& separator) const { String result = ssid; htmlEscape(result); - if (isHidden) { + + if (bits.isHidden) { result += F("#Hidden#"); } result += strformat( @@ -225,18 +195,25 @@ String WiFi_AP_Candidate::toString(const String& separator) const { } result += encryption_type(); + if (phy_known()) { String phy_str; - - if (phy_11b) phy_str += 'b'; - if (phy_11g) phy_str += 'g'; - if (phy_11n) phy_str += 'n'; + + if (bits.phy_11b) { phy_str += 'b'; } + + if (bits.phy_11g) { phy_str += 'g'; } + + if (bits.phy_11n) { phy_str += 'n'; } #ifdef ESP32 - if (phy_11ax) phy_str += F("/ax"); - if (phy_lr) phy_str += F("/lr"); - if (ftm_initiator) phy_str += F("/FTM_i"); - if (ftm_responder) phy_str += F("/FTM_r"); -#endif + + if (bits.phy_11ax) { phy_str += F("/ax"); } + + if (bits.phy_lr) { phy_str += F("/lr"); } + + if (bits.ftm_initiator) { phy_str += F("/FTM_i"); } + + if (bits.ftm_responder) { phy_str += F("/FTM_r"); } +#endif // ifdef ESP32 if (phy_str.length()) { result += strformat(F(" (%s)"), phy_str.c_str()); diff --git a/src/src/DataStructs/WiFi_AP_Candidate.h b/src/src/DataStructs/WiFi_AP_Candidate.h index 9c41814758..b3ce8f8c35 100644 --- a/src/src/DataStructs/WiFi_AP_Candidate.h +++ b/src/src/DataStructs/WiFi_AP_Candidate.h @@ -13,25 +13,24 @@ struct WiFi_AP_Candidate { // @param index The index of the stored credentials // @param ssid_c SSID of the credentials // @param pass Password/key of the credentials - WiFi_AP_Candidate(uint8_t index, + WiFi_AP_Candidate(uint8_t index, const String& ssid_c); // Construct using index from WiFi scan result WiFi_AP_Candidate(uint8_t networkItem); #ifdef ESP8266 - #if FEATURE_ESP8266_DIRECT_WIFI_SCAN + # if FEATURE_ESP8266_DIRECT_WIFI_SCAN WiFi_AP_Candidate(const bss_info& ap); - #endif - #endif - + # endif // if FEATURE_ESP8266_DIRECT_WIFI_SCAN + #endif // ifdef ESP8266 // Return true when this one is preferred over 'other'. - bool operator<(const WiFi_AP_Candidate& other) const; + bool operator<(const WiFi_AP_Candidate& other) const; - bool operator==(const WiFi_AP_Candidate& other) const { - return bssid_match(other.bssid) && ssid.equals(other.ssid);// && key.equals(other.key); + bool operator==(const WiFi_AP_Candidate& other) const { + return bssid_match(other.bssid) && ssid.equals(other.ssid); // && key.equals(other.key); } WiFi_AP_Candidate& operator=(const WiFi_AP_Candidate& other) = default; @@ -43,46 +42,57 @@ struct WiFi_AP_Candidate { bool expired() const; // For quick connection the channel and BSSID are needed - bool allowQuickConnect() const { return (channel != 0) && bssid_set(); } + bool allowQuickConnect() const { + return (channel != 0) && bssid_set(); + } // Check to see if the BSSID is set - bool bssid_set() const { return !bssid.all_zero(); } + bool bssid_set() const { + return !bssid.all_zero(); + } + + bool bssid_match(const uint8_t bssid_c[6]) const { + return bssid == bssid_c; + } - bool bssid_match(const uint8_t bssid_c[6]) const { return bssid == bssid_c; } - bool bssid_match(const MAC_address& other) const { return bssid == other; } + bool bssid_match(const MAC_address& other) const { + return bssid == other; + } // Create a formatted string - String toString(const String& separator = " ") const; + String toString(const String& separator = " ") const; - String encryption_type() const; + String encryption_type() const; + + bool phy_known() const { + return bits.phy_11b || bits.phy_11g || bits.phy_11n; + } - bool phy_known() const { return phy_11b || phy_11g || phy_11n; } + String ssid; - String ssid; -// String key; + // String key; unsigned long last_seen = 0u; MAC_address bssid; int8_t rssi{}; uint8_t channel{}; - uint8_t index{}; // Index of the matching credentials - uint8_t enc_type{}; // Encryption used (e.g. WPA2) + uint8_t index{}; // Index of the matching credentials + uint8_t enc_type{}; // Encryption used (e.g. WPA2) struct { - uint16_t isHidden:1; // Hidden SSID - uint16_t lowPriority:1; // Try as last attempt - uint16_t isEmergencyFallback:1; - uint16_t phy_11b:1; - uint16_t phy_11g:1; - uint16_t phy_11n:1; - uint16_t phy_lr:1; - uint16_t phy_11ax:1; - uint16_t wps:1; - uint16_t ftm_responder:1; - uint16_t ftm_initiator:1; - - uint16_t unused:5; - }; - + uint16_t isHidden : 1; // Hidden SSID + uint16_t lowPriority : 1; // Try as last attempt + uint16_t isEmergencyFallback : 1; + uint16_t phy_11b : 1; + uint16_t phy_11g : 1; + uint16_t phy_11n : 1; + uint16_t phy_lr : 1; + uint16_t phy_11ax : 1; + uint16_t wps : 1; + uint16_t ftm_responder : 1; + uint16_t ftm_initiator : 1; + + uint16_t unused : 5; + } bits; }; #endif // ifndef DATASTRUCTS_WIFI_AP_CANDIDATES_H diff --git a/src/src/ESPEasyCore/ESPEasyWifi.cpp b/src/src/ESPEasyCore/ESPEasyWifi.cpp index b0738bfded..58ca747a8e 100644 --- a/src/src/ESPEasyCore/ESPEasyWifi.cpp +++ b/src/src/ESPEasyCore/ESPEasyWifi.cpp @@ -497,13 +497,13 @@ void AttemptWiFiConnect() { WiFi.enableIPv6(true); #endif - if ((Settings.HiddenSSID_SlowConnectPerBSSID() || !candidate.isHidden) + if ((Settings.HiddenSSID_SlowConnectPerBSSID() || !candidate.bits.isHidden) && candidate.allowQuickConnect()) { WiFi.begin(candidate.ssid.c_str(), key.c_str(), candidate.channel, candidate.bssid.mac); } else { WiFi.begin(candidate.ssid.c_str(), key.c_str()); } - if (Settings.WaitWiFiConnect() || candidate.isHidden) { + if (Settings.WaitWiFiConnect() || candidate.bits.isHidden) { // WiFi.waitForConnectResult(candidate.isHidden ? 3000 : 1000); // https://github.com/arendst/Tasmota/issues/14985 WiFi.waitForConnectResult(1000); // https://github.com/arendst/Tasmota/issues/14985 } @@ -1460,11 +1460,11 @@ void setConnectionSpeed() { WiFiPhyMode_t phyMode = (Settings.ForceWiFi_bg_mode() || forcedByAPmode) ? WIFI_PHY_MODE_11G : WIFI_PHY_MODE_11N; if (!forcedByAPmode) { const WiFi_AP_Candidate candidate = WiFi_AP_Candidates.getCurrent(); - if (candidate.phy_known() && (candidate.phy_11g != candidate.phy_11n)) { - if ((WIFI_PHY_MODE_11G == phyMode) && !candidate.phy_11g) { + if (candidate.phy_known() && (candidate.bits.phy_11g != candidate.bits.phy_11n)) { + if ((WIFI_PHY_MODE_11G == phyMode) && !candidate.bits.phy_11g) { phyMode = WIFI_PHY_MODE_11N; addLog(LOG_LEVEL_INFO, F("WIFI : AP is set to 802.11n only")); - } else if ((WIFI_PHY_MODE_11N == phyMode) && !candidate.phy_11n) { + } else if ((WIFI_PHY_MODE_11N == phyMode) && !candidate.bits.phy_11n) { phyMode = WIFI_PHY_MODE_11G; addLog(LOG_LEVEL_INFO, F("WIFI : AP is set to 802.11g only")); } @@ -1522,14 +1522,14 @@ void setConnectionSpeed() { if (candidate.phy_known()) { // Check to see if the access point is set to "N-only" if ((protocol & WIFI_PROTOCOL_11N) == 0) { - if (!candidate.phy_11b && !candidate.phy_11g && candidate.phy_11n) { - if (candidate.phy_11n) { + if (!candidate.bits.phy_11b && !candidate.bits.phy_11g && candidate.bits.phy_11n) { + if (candidate.bits.phy_11n) { // Set to use BGN protocol |= WIFI_PROTOCOL_11N; addLog(LOG_LEVEL_INFO, F("WIFI : AP is set to 802.11n only")); } #ifdef ESP32C6 - if (candidate.phy_11ax) { + if (candidate.bits.phy_11ax) { // Set to use WiFi6 protocol |= WIFI_PROTOCOL_11AX; addLog(LOG_LEVEL_INFO, F("WIFI : AP is set to 802.11ax")); diff --git a/src/src/ESPEasyCore/ESPEasyWifi_ProcessEvent.cpp b/src/src/ESPEasyCore/ESPEasyWifi_ProcessEvent.cpp index 7e81f864fe..0453dc0497 100644 --- a/src/src/ESPEasyCore/ESPEasyWifi_ProcessEvent.cpp +++ b/src/src/ESPEasyCore/ESPEasyWifi_ProcessEvent.cpp @@ -308,7 +308,7 @@ void processConnect() { WiFiEventData.setWiFiConnected(); ++WiFiEventData.wifi_reconnects; - if (WiFi_AP_Candidates.getCurrent().isEmergencyFallback) { + if (WiFi_AP_Candidates.getCurrent().bits.isEmergencyFallback) { #ifdef CUSTOM_EMERGENCY_FALLBACK_RESET_CREDENTIALS const bool mustResetCredentials = CUSTOM_EMERGENCY_FALLBACK_RESET_CREDENTIALS; #else diff --git a/src/src/Helpers/WiFi_AP_CandidatesList.cpp b/src/src/Helpers/WiFi_AP_CandidatesList.cpp index 6deadfce4d..7627d0f5b9 100644 --- a/src/src/Helpers/WiFi_AP_CandidatesList.cpp +++ b/src/src/Helpers/WiFi_AP_CandidatesList.cpp @@ -62,9 +62,9 @@ void WiFi_AP_CandidatesList::load_knownCredentials() { known.emplace_back(index, ssid); if (SettingsIndexMatchCustomCredentials(index)) { if (SettingsIndexMatchEmergencyFallback(index)) { - known.back().isEmergencyFallback = true; + known.back().bits.isEmergencyFallback = true; } else { - known.back().lowPriority = true; + known.back().bits.lowPriority = true; } } ++index; @@ -155,7 +155,7 @@ bool WiFi_AP_CandidatesList::getNext(bool scanAllowed) { currentCandidate = candidates.front(); bool mustPop = true; - if (currentCandidate.isHidden) { + if (currentCandidate.bits.isHidden) { // Iterate over the known credentials to try them all // Hidden SSID stations do not broadcast their SSID, so we must fill it in ourselves. if (known_it != known.end()) { @@ -171,9 +171,9 @@ bool WiFi_AP_CandidatesList::getNext(bool scanAllowed) { if (mustPop) { if (attemptsLeft == 0) { - if (currentCandidate.isHidden) { + if (currentCandidate.bits.isHidden) { // We tried to connect to hidden SSIDs in 1 run, so pop all hidden candidates. - for (auto cand_it = candidates.begin(); cand_it != candidates.end() && cand_it->isHidden; ) { + for (auto cand_it = candidates.begin(); cand_it != candidates.end() && cand_it->bits.isHidden; ) { cand_it = candidates.erase(cand_it); } } else { @@ -334,7 +334,7 @@ void WiFi_AP_CandidatesList::loadCandidatesFromScanned() { if (scan->expired()) { scan = scanned.erase(scan); } else { - if (scan->isHidden) { + if (scan->bits.isHidden) { if (Settings.IncludeHiddenSSID()) { if (SecuritySettings.hasWiFiCredentials()) { candidates.push_back(*scan); @@ -345,8 +345,8 @@ void WiFi_AP_CandidatesList::loadCandidatesFromScanned() { if (scan->ssid.equals(kn_it->ssid)) { WiFi_AP_Candidate tmp = *scan; tmp.index = kn_it->index; - tmp.lowPriority = kn_it->lowPriority; - tmp.isEmergencyFallback = kn_it->isEmergencyFallback; + tmp.bits.lowPriority = kn_it->bits.lowPriority; + tmp.bits.isEmergencyFallback = kn_it->bits.isEmergencyFallback; if (tmp.usable()) { candidates.push_back(tmp); diff --git a/src/src/WebServer/SetupPage.cpp b/src/src/WebServer/SetupPage.cpp index 496471948c..ef94bf0f14 100644 --- a/src/src/WebServer/SetupPage.cpp +++ b/src/src/WebServer/SetupPage.cpp @@ -266,7 +266,7 @@ void handle_setup_scan_and_show(const String& ssid, const String& other, const S addHtml('>'); addHtml(F("ssid; From 548dd5959fb388dfb024d6cf8c13549c780a74ff Mon Sep 17 00:00:00 2001 From: TD-er Date: Fri, 15 Mar 2024 22:14:41 +0100 Subject: [PATCH 6/6] [HWCDC] Test for ESP32-C3/C6/S3 HWCDC issues --- platformio_core_defs.ini | 4 +++- src/src/ESPEasyCore/ESPEasy_Console.cpp | 2 +- src/src/Helpers/SerialWriteBuffer.cpp | 20 +++++++++++++------- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/platformio_core_defs.ini b/platformio_core_defs.ini index 89ecddeb89..b665e8a01a 100644 --- a/platformio_core_defs.ini +++ b/platformio_core_defs.ini @@ -211,7 +211,9 @@ lib_ignore = ;platform = https://github.com/Jason2866/platform-espressif32.git platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.02.10/platform-espressif32.zip ;platform_packages = -platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2119/framework-arduinoespressif32-release_v5.1-a28d368.zip +;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2119/framework-arduinoespressif32-release_v5.1-a28d368.zip +;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2180/framework-arduinoespressif32-all-release_v5.1-735d740.zip +platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2189/framework-arduinoespressif32-all-release_v5.1-be1a568.zip build_flags = -DESP32_STAGE -DESP_IDF_VERSION_MAJOR=5 -DLIBRARIES_NO_LOG=1 diff --git a/src/src/ESPEasyCore/ESPEasy_Console.cpp b/src/src/ESPEasyCore/ESPEasy_Console.cpp index 8ee42c491f..056bb5261f 100644 --- a/src/src/ESPEasyCore/ESPEasy_Console.cpp +++ b/src/src/ESPEasyCore/ESPEasy_Console.cpp @@ -155,7 +155,7 @@ void EspEasy_Console_t::reInit() #if USES_HWCDC if (mainSerialPort == ESPEasySerialPort::usb_hw_cdc) { - buffsize = 512; + buffsize = 2048; } #endif // if USES_HWCDC diff --git a/src/src/Helpers/SerialWriteBuffer.cpp b/src/src/Helpers/SerialWriteBuffer.cpp index cf4fbc2feb..f81b24766a 100644 --- a/src/src/Helpers/SerialWriteBuffer.cpp +++ b/src/src/Helpers/SerialWriteBuffer.cpp @@ -67,29 +67,35 @@ size_t SerialWriteBuffer_t::write(Stream& stream, size_t nrBytesToWrite) } if (nrBytesToWrite > 0) { + // FIXME TD-er: Work-around for bug in HWCDC when writing exactly the amount of free bytes in the buffer. +// --nrBytesToWrite; if (nrBytesToWrite > bufferSize) { nrBytesToWrite = bufferSize; } while (nrBytesToWrite > 0 && !_buffer.empty()) { - #ifdef ESP32 - uint8_t tmpBuffer[1]{}; - #else uint8_t tmpBuffer[16]{}; - #endif size_t tmpBufferUsed = 0; auto it = _buffer.begin(); - for (; tmpBufferUsed < sizeof(tmpBuffer) && tmpBufferUsed < nrBytesToWrite && it != _buffer.end(); ) { + bool done = false; + + for (; tmpBufferUsed < sizeof(tmpBuffer) && + !done && + it != _buffer.end(); ) { tmpBuffer[tmpBufferUsed] = (uint8_t)(*it); + if (*it == '\n' || + tmpBufferUsed >= nrBytesToWrite) { + done = true; + } ++tmpBufferUsed; ++it; } - bool done = false; - const size_t written = stream.write(tmpBuffer, tmpBufferUsed); +// done = false; + const size_t written = (tmpBufferUsed == 0) ? 0 : stream.write(tmpBuffer, tmpBufferUsed); if (written < tmpBufferUsed) { done = true;