diff --git a/cores/esp32/esp32-hal-time.c b/cores/esp32/esp32-hal-time.c index 074e999be71..e66a68fa271 100644 --- a/cores/esp32/esp32-hal-time.c +++ b/cores/esp32/esp32-hal-time.c @@ -22,24 +22,24 @@ #endif static void setTimeZone(long offset, int daylight) { - char cst[17] = {0}; - char cdt[17] = "DST"; - char tz[33] = {0}; + char cst[21] = {0}; + char cdt[21] = "DST"; + char tz[41] = {0}; if (offset % 3600) { - sprintf(cst, "UTC%ld:%02u:%02u", offset / 3600, abs((offset % 3600) / 60), abs(offset % 60)); + snprintf(cst, sizeof(cst), "UTC%ld:%02u:%02u", offset / 3600, abs((offset % 3600) / 60), abs(offset % 60)); } else { - sprintf(cst, "UTC%ld", offset / 3600); + snprintf(cst, sizeof(cst), "UTC%ld", offset / 3600); } if (daylight != 3600) { long tz_dst = offset - daylight; if (tz_dst % 3600) { - sprintf(cdt, "DST%ld:%02u:%02u", tz_dst / 3600, abs((tz_dst % 3600) / 60), abs(tz_dst % 60)); + snprintf(cdt, sizeof(cdt), "DST%ld:%02u:%02u", tz_dst / 3600, abs((tz_dst % 3600) / 60), abs(tz_dst % 60)); } else { - sprintf(cdt, "DST%ld", tz_dst / 3600); + snprintf(cdt, sizeof(cdt), "DST%ld", tz_dst / 3600); } } - sprintf(tz, "%s%s", cst, cdt); + snprintf(tz, sizeof(tz), "%s%s", cst, cdt); setenv("TZ", tz, 1); tzset(); } diff --git a/libraries/AsyncUDP/src/AsyncUDP.cpp b/libraries/AsyncUDP/src/AsyncUDP.cpp index 2d533831cd5..c79169cfcc0 100644 --- a/libraries/AsyncUDP/src/AsyncUDP.cpp +++ b/libraries/AsyncUDP/src/AsyncUDP.cpp @@ -317,6 +317,33 @@ AsyncUDPPacket::AsyncUDPPacket(AsyncUDPPacket &packet) { pbuf_ref(_pb); } +AsyncUDPPacket& AsyncUDPPacket::operator=(const AsyncUDPPacket& packet) { + if (this != &packet) { + if (_pb) { + // Free existing pbuf reference + pbuf_free(_pb); + } + + // Copy all members + _udp = packet._udp; + _pb = packet._pb; + _if = packet._if; + _data = packet._data; + _len = packet._len; + _index = 0; + + memcpy(&_remoteIp, &packet._remoteIp, sizeof(ip_addr_t)); + memcpy(&_localIp, &packet._localIp, sizeof(ip_addr_t)); + _localPort = packet._localPort; + _remotePort = packet._remotePort; + memcpy(_remoteMac, packet._remoteMac, 6); + + // Increment reference count for the new pbuf + pbuf_ref(_pb); + } + return *this; +} + AsyncUDPPacket::AsyncUDPPacket(AsyncUDP *udp, pbuf *pb, const ip_addr_t *raddr, uint16_t rport, struct netif *ntif) { _udp = udp; _pb = pb; diff --git a/libraries/AsyncUDP/src/AsyncUDP.h b/libraries/AsyncUDP/src/AsyncUDP.h index cd96d852542..61d963cb5bf 100644 --- a/libraries/AsyncUDP/src/AsyncUDP.h +++ b/libraries/AsyncUDP/src/AsyncUDP.h @@ -100,6 +100,9 @@ class AsyncUDPPacket : public Stream { size_t write(const uint8_t *data, size_t len); size_t write(uint8_t data); + + // Copy assignment operator + AsyncUDPPacket& operator=(const AsyncUDPPacket& packet); }; class AsyncUDP : public Print { diff --git a/libraries/EEPROM/src/EEPROM.cpp b/libraries/EEPROM/src/EEPROM.cpp index 016e6843dd2..e53de96f60b 100644 --- a/libraries/EEPROM/src/EEPROM.cpp +++ b/libraries/EEPROM/src/EEPROM.cpp @@ -27,6 +27,7 @@ #include #include #include +#include EEPROMClass::EEPROMClass(void) : _handle(0), _data(0), _size(0), _dirty(false), _name("eeprom") {} @@ -59,7 +60,7 @@ bool EEPROMClass::begin(size_t size) { } if (size < key_size) { // truncate log_w("truncating EEPROM from %d to %d", key_size, size); - uint8_t *key_data = (uint8_t *)malloc(key_size); + uint8_t *key_data = new(std::nothrow) uint8_t[key_size]; if (!key_data) { log_e("Not enough memory to truncate EEPROM!"); return false; @@ -67,10 +68,10 @@ bool EEPROMClass::begin(size_t size) { nvs_get_blob(_handle, _name, key_data, &key_size); nvs_set_blob(_handle, _name, key_data, size); nvs_commit(_handle); - free(key_data); + delete[] key_data; } else if (size > key_size) { // expand or new size_t expand_size = size - key_size; - uint8_t *expand_key = (uint8_t *)malloc(expand_size); + uint8_t *expand_key = new(std::nothrow) uint8_t[expand_size]; if (!expand_key) { log_e("Not enough memory to expand EEPROM!"); return false; @@ -78,12 +79,12 @@ bool EEPROMClass::begin(size_t size) { // check for adequate free space if (nvs_set_blob(_handle, "expand", expand_key, expand_size)) { log_e("Not enough space to expand EEPROM from %d to %d", key_size, size); - free(expand_key); + delete[] expand_key; return false; } - free(expand_key); + delete[] expand_key; nvs_erase_key(_handle, "expand"); - uint8_t *key_data = (uint8_t *)malloc(size); + uint8_t *key_data = new(std::nothrow) uint8_t[size]; if (!key_data) { log_e("Not enough memory to expand EEPROM!"); return false; @@ -99,7 +100,7 @@ bool EEPROMClass::begin(size_t size) { } nvs_commit(_handle); nvs_set_blob(_handle, _name, key_data, size); - free(key_data); + delete[] key_data; nvs_commit(_handle); } @@ -107,7 +108,7 @@ bool EEPROMClass::begin(size_t size) { delete[] _data; } - _data = (uint8_t *)malloc(size); + _data = new(std::nothrow) uint8_t[size]; if (!_data) { log_e("Not enough memory for %d bytes in EEPROM", size); return false; @@ -212,7 +213,7 @@ uint16_t EEPROMClass::convert(bool clear, const char *EEPROMname, const char *nv } size_t size = mypart->size; - uint8_t *data = (uint8_t *)malloc(size); + uint8_t *data = new(std::nothrow) uint8_t[size]; if (!data) { log_e("Not enough memory to convert EEPROM!"); goto exit; @@ -255,7 +256,7 @@ uint16_t EEPROMClass::convert(bool clear, const char *EEPROMname, const char *nv } } exit: - free(data); + delete[] data; return result; } @@ -509,9 +510,9 @@ size_t EEPROMClass::writeBytes(int address, const void *value, size_t len) { return len; } -template T EEPROMClass::writeAll(int address, const T &value) { +template size_t EEPROMClass::writeAll(int address, const T &value) { if (address < 0 || address + sizeof(T) > _size) { - return value; + return 0; } memcpy(_data + address, (const uint8_t *)&value, sizeof(T)); diff --git a/libraries/EEPROM/src/EEPROM.h b/libraries/EEPROM/src/EEPROM.h index 2bcc97a3a21..45222b0c697 100644 --- a/libraries/EEPROM/src/EEPROM.h +++ b/libraries/EEPROM/src/EEPROM.h @@ -105,7 +105,7 @@ class EEPROMClass { size_t writeString(int address, const char *value); size_t writeString(int address, String value); size_t writeBytes(int address, const void *value, size_t len); - template T writeAll(int address, const T &); + template size_t writeAll(int address, const T &); protected: nvs_handle _handle; diff --git a/libraries/ESP32/examples/FreeRTOS/Mutex/Mutex.ino b/libraries/ESP32/examples/FreeRTOS/Mutex/Mutex.ino index f368e0e864c..800d61030d9 100644 --- a/libraries/ESP32/examples/FreeRTOS/Mutex/Mutex.ino +++ b/libraries/ESP32/examples/FreeRTOS/Mutex/Mutex.ino @@ -71,17 +71,17 @@ void Task(void *pvParameters) { // This is a task. #endif int new_value = random(1000); - char str0[32]; - sprintf(str0, " %d <- %d |", shared_variable, new_value); - char str1[32]; - sprintf(str1, " | %d <- %d", shared_variable, new_value); + char str0[35]; // Maximum possible length of the string + snprintf(str0, sizeof(str0), " %d <- %d |", shared_variable, new_value); + char str1[46]; // Maximum possible length of the string + snprintf(str1, sizeof(str1), " | %d <- %d", shared_variable, new_value); Serial.printf("%s\n", task_num ? str0 : str1); shared_variable = new_value; delay(random(100)); // wait random time of max 100 ms - simulating some computation - sprintf(str0, " R: %d |", shared_variable); - sprintf(str1, " | R: %d", shared_variable); + snprintf(str0, sizeof(str0), " R: %d |", shared_variable); + snprintf(str1, sizeof(str1), " | R: %d", shared_variable); Serial.printf("%s\n", task_num ? str0 : str1); //Serial.printf("Task %d after write: reading %d\n", task_num, shared_variable); diff --git a/libraries/ESP_NOW/examples/ESP_NOW_Network/ESP_NOW_Network.ino b/libraries/ESP_NOW/examples/ESP_NOW_Network/ESP_NOW_Network.ino index d30d6cd40cf..ec61cb57cf9 100644 --- a/libraries/ESP_NOW/examples/ESP_NOW_Network/ESP_NOW_Network.ino +++ b/libraries/ESP_NOW/examples/ESP_NOW_Network/ESP_NOW_Network.ino @@ -32,6 +32,7 @@ #include // For the MAC2STR and MACSTR macros #include +#include //std::nothrow /* Definitions */ @@ -235,7 +236,7 @@ void register_new_peer(const esp_now_recv_info_t *info, const uint8_t *data, int if (current_peer_count < ESPNOW_PEER_COUNT) { Serial.printf("New peer found: " MACSTR " with priority %d\n", MAC2STR(info->src_addr), priority); - ESP_NOW_Network_Peer *new_peer = new ESP_NOW_Network_Peer(info->src_addr, priority); + ESP_NOW_Network_Peer *new_peer = new (std::nothrow) ESP_NOW_Network_Peer(info->src_addr, priority); if (new_peer == nullptr || !new_peer->begin()) { Serial.println("Failed to create or register the new peer"); delete new_peer; diff --git a/libraries/ESP_NOW/src/ESP32_NOW.h b/libraries/ESP_NOW/src/ESP32_NOW.h index 5b5bbe72673..6bf612a1263 100644 --- a/libraries/ESP_NOW/src/ESP32_NOW.h +++ b/libraries/ESP_NOW/src/ESP32_NOW.h @@ -87,6 +87,8 @@ class ESP_NOW_Peer { friend bool ESP_NOW_Class::removePeer(ESP_NOW_Peer &); }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_ESP_NOW) extern ESP_NOW_Class ESP_NOW; +#endif #endif diff --git a/libraries/ESP_SR/src/ESP_SR.h b/libraries/ESP_SR/src/ESP_SR.h index d637f686f42..28fb68c1eb0 100644 --- a/libraries/ESP_SR/src/ESP_SR.h +++ b/libraries/ESP_SR/src/ESP_SR.h @@ -33,6 +33,8 @@ class ESP_SR_Class { esp_err_t _fill(void *out, size_t len, size_t *bytes_read, uint32_t timeout_ms); }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_ESP_SR) extern ESP_SR_Class ESP_SR; +#endif #endif // CONFIG_IDF_TARGET_ESP32S3 diff --git a/libraries/ESPmDNS/src/ESPmDNS.h b/libraries/ESPmDNS/src/ESPmDNS.h index 1fb90bbf454..74f9002461f 100644 --- a/libraries/ESPmDNS/src/ESPmDNS.h +++ b/libraries/ESPmDNS/src/ESPmDNS.h @@ -127,7 +127,9 @@ class MDNSResponder { mdns_txt_item_t *_getResultTxt(int idx, int txtIdx); }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS) extern MDNSResponder MDNS; +#endif #endif /* CONFIG_MDNS_MAX_INTERFACES */ #endif //ESP32MDNS_H diff --git a/libraries/Ethernet/src/ETH.h b/libraries/Ethernet/src/ETH.h index c52aac6ec6f..6ceb43f316d 100644 --- a/libraries/Ethernet/src/ETH.h +++ b/libraries/Ethernet/src/ETH.h @@ -268,7 +268,9 @@ class ETHClass : public NetworkInterface { friend class EthernetClass; // to access beginSPI }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_ETH) extern ETHClass ETH; +#endif #endif /* _ETH_H_ */ #endif /* CONFIG_ETH_ENABLED */ diff --git a/libraries/FFat/examples/FFat_time/FFat_time.ino b/libraries/FFat/examples/FFat_time/FFat_time.ino index 392647c9923..b21521c05d2 100644 --- a/libraries/FFat/examples/FFat_time/FFat_time.ino +++ b/libraries/FFat/examples/FFat_time/FFat_time.ino @@ -28,10 +28,11 @@ void listDir(fs::FS &fs, const char *dirname, uint8_t levels) { Serial.print(" DIR : "); Serial.print(file.name()); time_t t = file.getLastWrite(); - struct tm *tmstruct = localtime(&t); + struct tm tmstruct; + localtime_r(&t, &tmstruct); Serial.printf( - " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, - tmstruct->tm_min, tmstruct->tm_sec + " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, + tmstruct.tm_min, tmstruct.tm_sec ); if (levels) { listDir(fs, file.path(), levels - 1); @@ -42,10 +43,11 @@ void listDir(fs::FS &fs, const char *dirname, uint8_t levels) { Serial.print(" SIZE: "); Serial.print(file.size()); time_t t = file.getLastWrite(); - struct tm *tmstruct = localtime(&t); + struct tm tmstruct; + localtime_r(&t, &tmstruct); Serial.printf( - " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, - tmstruct->tm_min, tmstruct->tm_sec + " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, + tmstruct.tm_min, tmstruct.tm_sec ); } file = root.openNextFile(); diff --git a/libraries/FFat/src/FFat.h b/libraries/FFat/src/FFat.h index 3f700396777..56929f2f259 100644 --- a/libraries/FFat/src/FFat.h +++ b/libraries/FFat/src/FFat.h @@ -39,6 +39,8 @@ class F_Fat : public FS { } // namespace fs +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_FFAT) extern fs::F_Fat FFat; +#endif #endif /* _FFAT_H_ */ diff --git a/libraries/FS/src/vfs_api.cpp b/libraries/FS/src/vfs_api.cpp index 616f37ac611..da22ea1962c 100644 --- a/libraries/FS/src/vfs_api.cpp +++ b/libraries/FS/src/vfs_api.cpp @@ -13,6 +13,9 @@ // limitations under the License. #include "vfs_api.h" +#include +#include +#include using namespace fs; @@ -38,67 +41,49 @@ FileImplPtr VFSImpl::open(const char *fpath, const char *mode, const bool create strcpy(temp, _mountpoint); strcat(temp, fpath); - struct stat st; - //file found - if (!stat(temp, &st)) { - free(temp); - if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode)) { - return std::make_shared(this, fpath, mode); - } - log_e("%s has wrong mode 0x%08X", fpath, st.st_mode); - return FileImplPtr(); - } - - //try to open this as directory (might be mount point) - DIR *d = opendir(temp); - if (d) { - closedir(d); - free(temp); - return std::make_shared(this, fpath, mode); - } - - //file not found but mode permits file creation without folder creation - if ((mode && mode[0] != 'r') && (!create)) { - free(temp); - return std::make_shared(this, fpath, mode); - } - - ////file not found but mode permits file creation and folder creation - if ((mode && mode[0] != 'r') && create) { - - char *token; - char *folder = (char *)malloc(strlen(fpath)); - - int start_index = 0; - int end_index = 0; - - token = strchr(fpath + 1, '/'); - end_index = (token - fpath); - - while (token != NULL) { - memcpy(folder, fpath + start_index, end_index - start_index); - folder[end_index - start_index] = '\0'; - - if (!VFSImpl::mkdir(folder)) { - log_e("Creating folder: %s failed!", folder); - return FileImplPtr(); + // Try to open as file first - let the file operation handle errors + if (mode && mode[0] != 'r') { + // For write modes, attempt to create directories if needed + if (create) { + char *token; + char *folder = (char *)malloc(strlen(fpath) + 1); + + int start_index = 0; + int end_index = 0; + + token = strchr(fpath + 1, '/'); + end_index = (token - fpath); + + while (token != NULL) { + memcpy(folder, fpath + start_index, end_index - start_index); + folder[end_index - start_index] = '\0'; + + if (!VFSImpl::mkdir(folder)) { + log_e("Creating folder: %s failed!", folder); + free(folder); + free(temp); + return FileImplPtr(); + } + + token = strchr(token + 1, '/'); + if (token != NULL) { + end_index = (token - fpath); + memset(folder, 0, strlen(folder)); + } } - token = strchr(token + 1, '/'); - if (token != NULL) { - end_index = (token - fpath); - memset(folder, 0, strlen(folder)); - } + free(folder); } - free(folder); + // Try to open the file directly - let fopen handle errors free(temp); return std::make_shared(this, fpath, mode); } - log_e("%s does not exist, no permits for creation", temp); + // For read mode, let the VFSFileImpl constructor handle the file opening + // This avoids the TOCTOU race condition while maintaining proper functionality free(temp); - return FileImplPtr(); + return std::make_shared(this, fpath, mode); } bool VFSImpl::exists(const char *fpath) { @@ -125,10 +110,7 @@ bool VFSImpl::rename(const char *pathFrom, const char *pathTo) { log_e("bad arguments"); return false; } - if (!exists(pathFrom)) { - log_e("%s does not exists", pathFrom); - return false; - } + size_t mountpointLen = strlen(_mountpoint); char *temp1 = (char *)malloc(strlen(pathFrom) + mountpointLen + 1); if (!temp1) { @@ -148,6 +130,7 @@ bool VFSImpl::rename(const char *pathFrom, const char *pathTo) { strcpy(temp2, _mountpoint); strcat(temp2, pathTo); + // Let rename() handle the error if source doesn't exist auto rc = ::rename(temp1, temp2); free(temp1); free(temp2); @@ -165,16 +148,6 @@ bool VFSImpl::remove(const char *fpath) { return false; } - VFSFileImpl f(this, fpath, "r"); - if (!f || f.isDirectory()) { - if (f) { - f.close(); - } - log_e("%s does not exists or is directory", fpath); - return false; - } - f.close(); - char *temp = (char *)malloc(strlen(fpath) + strlen(_mountpoint) + 1); if (!temp) { log_e("malloc failed"); @@ -184,6 +157,7 @@ bool VFSImpl::remove(const char *fpath) { strcpy(temp, _mountpoint); strcat(temp, fpath); + // Let unlink() handle the error if file doesn't exist auto rc = unlink(temp); free(temp); return rc == 0; @@ -231,16 +205,6 @@ bool VFSImpl::rmdir(const char *fpath) { return false; } - VFSFileImpl f(this, fpath, "r"); - if (!f || !f.isDirectory()) { - if (f) { - f.close(); - } - log_e("%s does not exists or is a file", fpath); - return false; - } - f.close(); - char *temp = (char *)malloc(strlen(fpath) + strlen(_mountpoint) + 1); if (!temp) { log_e("malloc failed"); @@ -250,6 +214,7 @@ bool VFSImpl::rmdir(const char *fpath) { strcpy(temp, _mountpoint); strcat(temp, fpath); + // Let rmdir() handle the error if directory doesn't exist auto rc = ::rmdir(temp); free(temp); return rc == 0; @@ -271,29 +236,30 @@ VFSFileImpl::VFSFileImpl(VFSImpl *fs, const char *fpath, const char *mode) : _fs return; } - if (!stat(temp, &_stat)) { - //file found - if (S_ISREG(_stat.st_mode)) { - _isDirectory = false; - _f = fopen(temp, mode); - if (!_f) { - log_e("fopen(%s) failed", temp); - } - if (_f && (_stat.st_blksize == 0)) { - setvbuf(_f, NULL, _IOFBF, DEFAULT_FILE_BUFFER_SIZE); - } - } else if (S_ISDIR(_stat.st_mode)) { - _isDirectory = true; - _d = opendir(temp); - if (!_d) { - log_e("opendir(%s) failed", temp); + // For read mode, check if file exists first to determine type + if (!mode || mode[0] == 'r') { + if (!stat(temp, &_stat)) { + //file found + if (S_ISREG(_stat.st_mode)) { + _isDirectory = false; + _f = fopen(temp, mode); + if (!_f) { + log_e("fopen(%s) failed", temp); + } + if (_f && (_stat.st_blksize == 0)) { + setvbuf(_f, NULL, _IOFBF, DEFAULT_FILE_BUFFER_SIZE); + } + } else if (S_ISDIR(_stat.st_mode)) { + _isDirectory = true; + _d = opendir(temp); + if (!_d) { + log_e("opendir(%s) failed", temp); + } + } else { + log_e("Unknown type 0x%08X for file %s", ((_stat.st_mode) & _IFMT), temp); } } else { - log_e("Unknown type 0x%08X for file %s", ((_stat.st_mode) & _IFMT), temp); - } - } else { - //file not found - if (!mode || mode[0] == 'r') { + //file not found //try to open as directory _d = opendir(temp); if (_d) { @@ -302,16 +268,16 @@ VFSFileImpl::VFSFileImpl(VFSImpl *fs, const char *fpath, const char *mode) : _fs _isDirectory = false; //log_w("stat(%s) failed", temp); } - } else { - //lets create this new file - _isDirectory = false; - _f = fopen(temp, mode); - if (!_f) { - log_e("fopen(%s) failed", temp); - } - if (_f && (_stat.st_blksize == 0)) { - setvbuf(_f, NULL, _IOFBF, DEFAULT_FILE_BUFFER_SIZE); - } + } + } else { + //lets create this new file + _isDirectory = false; + _f = fopen(temp, mode); + if (!_f) { + log_e("fopen(%s) failed", temp); + } + if (_f && (_stat.st_blksize == 0)) { + setvbuf(_f, NULL, _IOFBF, DEFAULT_FILE_BUFFER_SIZE); } } free(temp); diff --git a/libraries/HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino b/libraries/HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino index 73e127d1261..5d173da8fc0 100644 --- a/libraries/HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino +++ b/libraries/HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino @@ -59,7 +59,8 @@ void setClock() { struct tm timeinfo; gmtime_r(&nowSecs, &timeinfo); Serial.print(F("Current time: ")); - Serial.print(asctime(&timeinfo)); + char buf[26]; + Serial.print(asctime_r(&timeinfo, buf)); } WiFiMulti WiFiMulti; diff --git a/libraries/HTTPClient/src/HTTPClient.cpp b/libraries/HTTPClient/src/HTTPClient.cpp index ec812f07201..03d9a6204d5 100644 --- a/libraries/HTTPClient/src/HTTPClient.cpp +++ b/libraries/HTTPClient/src/HTTPClient.cpp @@ -1593,8 +1593,9 @@ void HTTPClient::setCookie(String date, String headerValue) { // overwrite or delete cookie in/from cookie jar time_t now_local = time(NULL); - time_t now_gmt = mktime(gmtime(&now_local)); - + struct tm tm_gmt; + gmtime_r(&now_local, &tm_gmt); + time_t now_gmt = mktime(&tm_gmt); bool found = false; for (auto c = _cookieJar->begin(); c != _cookieJar->end(); ++c) { @@ -1619,8 +1620,9 @@ void HTTPClient::setCookie(String date, String headerValue) { bool HTTPClient::generateCookieString(String *cookieString) { time_t now_local = time(NULL); - time_t now_gmt = mktime(gmtime(&now_local)); - + struct tm tm_gmt; + gmtime_r(&now_local, &tm_gmt); + time_t now_gmt = mktime(&tm_gmt); *cookieString = ""; bool found = false; diff --git a/libraries/HTTPUpdate/examples/httpUpdateSecure/httpUpdateSecure.ino b/libraries/HTTPUpdate/examples/httpUpdateSecure/httpUpdateSecure.ino index d349c6983c1..c542985d71d 100644 --- a/libraries/HTTPUpdate/examples/httpUpdateSecure/httpUpdateSecure.ino +++ b/libraries/HTTPUpdate/examples/httpUpdateSecure/httpUpdateSecure.ino @@ -32,7 +32,8 @@ void setClock() { struct tm timeinfo; gmtime_r(&now, &timeinfo); Serial.print(F("Current time: ")); - Serial.print(asctime(&timeinfo)); + char buf[26]; + Serial.print(asctime_r(&timeinfo, buf)); } /** diff --git a/libraries/Insights/src/Insights.h b/libraries/Insights/src/Insights.h index 2e09818be94..0515d9df5da 100644 --- a/libraries/Insights/src/Insights.h +++ b/libraries/Insights/src/Insights.h @@ -101,7 +101,9 @@ class ESPInsightsClass { bool event(const char *tag, const char *format, ...); }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_INSIGHTS) extern ESPInsightsClass Insights; +#endif extern "C" { #endif diff --git a/libraries/LittleFS/examples/LITTLEFS_time/LITTLEFS_time.ino b/libraries/LittleFS/examples/LITTLEFS_time/LITTLEFS_time.ino index f169ac24954..2056e7e4894 100644 --- a/libraries/LittleFS/examples/LITTLEFS_time/LITTLEFS_time.ino +++ b/libraries/LittleFS/examples/LITTLEFS_time/LITTLEFS_time.ino @@ -40,10 +40,11 @@ void listDir(fs::FS &fs, const char *dirname, uint8_t levels) { Serial.print(" DIR : "); Serial.print(file.name()); time_t t = file.getLastWrite(); - struct tm *tmstruct = localtime(&t); + struct tm tmstruct; + localtime_r(&t, &tmstruct); Serial.printf( - " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, - tmstruct->tm_min, tmstruct->tm_sec + " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, + tmstruct.tm_min, tmstruct.tm_sec ); if (levels) { listDir(fs, file.path(), levels - 1); @@ -54,10 +55,11 @@ void listDir(fs::FS &fs, const char *dirname, uint8_t levels) { Serial.print(" SIZE: "); Serial.print(file.size()); time_t t = file.getLastWrite(); - struct tm *tmstruct = localtime(&t); + struct tm tmstruct; + localtime_r(&t, &tmstruct); Serial.printf( - " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, - tmstruct->tm_min, tmstruct->tm_sec + " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, + tmstruct.tm_min, tmstruct.tm_sec ); } file = root.openNextFile(); diff --git a/libraries/LittleFS/src/LittleFS.h b/libraries/LittleFS/src/LittleFS.h index da4ab7d1f6f..bf32bb442d0 100644 --- a/libraries/LittleFS/src/LittleFS.h +++ b/libraries/LittleFS/src/LittleFS.h @@ -38,7 +38,9 @@ class LittleFSFS : public FS { } // namespace fs +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_LITTLEFS) extern fs::LittleFSFS LittleFS; +#endif #endif /* CONFIG_LITTLEFS_PAGE_SIZE */ #endif diff --git a/libraries/Matter/src/Matter.h b/libraries/Matter/src/Matter.h index 09e59b4e04b..89360e81d4b 100644 --- a/libraries/Matter/src/Matter.h +++ b/libraries/Matter/src/Matter.h @@ -203,6 +203,8 @@ class ArduinoMatter { static void _init(); }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MATTER) extern ArduinoMatter Matter; +#endif #endif /* CONFIG_ESP_MATTER_ENABLE_DATA_MODEL */ diff --git a/libraries/Network/src/NetworkEvents.cpp b/libraries/Network/src/NetworkEvents.cpp index 161e55c5d01..195499c5138 100644 --- a/libraries/Network/src/NetworkEvents.cpp +++ b/libraries/Network/src/NetworkEvents.cpp @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include //std::nothrow + #include "NetworkEvents.h" #include "NetworkManager.h" #include "esp_task.h" @@ -82,7 +85,7 @@ bool NetworkEvents::postEvent(const arduino_event_t *data) { if (data == NULL || _arduino_event_queue == NULL) { return false; } - arduino_event_t *event = new arduino_event_t(); + arduino_event_t *event = new (std::nothrow) arduino_event_t(); if (event == NULL) { log_e("Arduino Event Malloc Failed!"); return false; diff --git a/libraries/Network/src/NetworkManager.h b/libraries/Network/src/NetworkManager.h index 6b9d5e16cfc..dafac9cd983 100644 --- a/libraries/Network/src/NetworkManager.h +++ b/libraries/Network/src/NetworkManager.h @@ -31,4 +31,6 @@ class NetworkManager : public NetworkEvents, public Printable { } }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_NETWORK) extern NetworkManager Network; +#endif diff --git a/libraries/OpenThread/src/OThread.h b/libraries/OpenThread/src/OThread.h index 6e21b854574..e477eec19fe 100644 --- a/libraries/OpenThread/src/OThread.h +++ b/libraries/OpenThread/src/OThread.h @@ -162,7 +162,9 @@ class OpenThread { void populateMulticastAddressCache() const; }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_OPENTHREAD) extern OpenThread OThread; +#endif #endif /* CONFIG_OPENTHREAD_ENABLED */ #endif /* SOC_IEEE802154_SUPPORTED */ diff --git a/libraries/OpenThread/src/OThreadCLI.h b/libraries/OpenThread/src/OThreadCLI.h index 788edc2709b..cb2f2717d4f 100644 --- a/libraries/OpenThread/src/OThreadCLI.h +++ b/libraries/OpenThread/src/OThreadCLI.h @@ -68,7 +68,9 @@ class OpenThreadCLI : public Stream { void flush(); }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_OPENTHREADCLI) extern OpenThreadCLI OThreadCLI; +#endif #endif /* CONFIG_OPENTHREAD_ENABLED */ #endif /* SOC_IEEE802154_SUPPORTED */ diff --git a/libraries/PPP/src/PPP.h b/libraries/PPP/src/PPP.h index b317f52aefc..189825b61a1 100644 --- a/libraries/PPP/src/PPP.h +++ b/libraries/PPP/src/PPP.h @@ -113,5 +113,8 @@ class PPPClass : public NetworkInterface { static bool pppDetachBus(void *bus_pointer); }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_PPP) extern PPPClass PPP; +#endif + #endif /* CONFIG_LWIP_PPP_SUPPORT && ARDUINO_HAS_ESP_MODEM */ diff --git a/libraries/RainMaker/src/RMaker.h b/libraries/RainMaker/src/RMaker.h index 21c5b0d1832..0e16e6ee387 100644 --- a/libraries/RainMaker/src/RMaker.h +++ b/libraries/RainMaker/src/RMaker.h @@ -39,5 +39,8 @@ class RMakerClass { esp_err_t stop(); }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_RAINMAKER) extern RMakerClass RMaker; #endif + +#endif diff --git a/libraries/SD/examples/SD_time/SD_time.ino b/libraries/SD/examples/SD_time/SD_time.ino index cc65d21ae20..a19f6e792b6 100644 --- a/libraries/SD/examples/SD_time/SD_time.ino +++ b/libraries/SD/examples/SD_time/SD_time.ino @@ -78,10 +78,11 @@ void listDir(fs::FS &fs, const char *dirname, uint8_t levels) { Serial.print(" DIR : "); Serial.print(file.name()); time_t t = file.getLastWrite(); - struct tm *tmstruct = localtime(&t); + struct tm tmstruct; + localtime_r(&t, &tmstruct); Serial.printf( - " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, - tmstruct->tm_min, tmstruct->tm_sec + " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, + tmstruct.tm_min, tmstruct.tm_sec ); if (levels) { listDir(fs, file.path(), levels - 1); @@ -92,10 +93,11 @@ void listDir(fs::FS &fs, const char *dirname, uint8_t levels) { Serial.print(" SIZE: "); Serial.print(file.size()); time_t t = file.getLastWrite(); - struct tm *tmstruct = localtime(&t); + struct tm tmstruct; + localtime_r(&t, &tmstruct); Serial.printf( - " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, - tmstruct->tm_min, tmstruct->tm_sec + " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, + tmstruct.tm_min, tmstruct.tm_sec ); } file = root.openNextFile(); diff --git a/libraries/SD/src/SD.h b/libraries/SD/src/SD.h index d8252ee44f7..f4311d25a11 100644 --- a/libraries/SD/src/SD.h +++ b/libraries/SD/src/SD.h @@ -43,7 +43,9 @@ class SDFS : public FS { } // namespace fs +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SD) extern fs::SDFS SD; +#endif using namespace fs; typedef fs::File SDFile; diff --git a/libraries/SD/src/sd_diskio.cpp b/libraries/SD/src/sd_diskio.cpp index 40d6ede9f81..30ba37864ac 100644 --- a/libraries/SD/src/sd_diskio.cpp +++ b/libraries/SD/src/sd_diskio.cpp @@ -462,23 +462,52 @@ struct AcquireSPI { * FATFS API * */ +/** + * @brief Initialize an SD card for use with FatFs + * + * This function implements the complete SD card initialization sequence according to + * the SD card specification. It performs card detection, type identification, + * and configuration for SPI mode operation. + * + * The initialization sequence follows the SD card protocol: + * 1. Power-up sequence with 74+ clock cycles + * 2. GO_IDLE_STATE command to reset the card + * 3. CRC_ON_OFF to enable/disable CRC checking + * 4. SEND_IF_COND to identify SDHC/SDXC cards + * 5. APP_OP_COND to set operating conditions + * 6. Card type detection (SD/SDHC/MMC) + * 7. Final configuration and sector count retrieval + * + * @param pdrv Physical drive number (0-9) + * @return DSTATUS Status of the initialization (0 = success, STA_NOINIT = failed) + */ DSTATUS ff_sd_initialize(uint8_t pdrv) { char token; unsigned int resp; unsigned int start; + + // Get the card structure for the given drive number ardu_sdcard_t *card = s_cards[pdrv]; + // If the card is already initialized, return its current status if (!(card->status & STA_NOINIT)) { return card->status; } + // Lock the SPI bus and set it to a low frequency (400kHz) for initialization + // Low frequency is required during initialization for reliable communication AcquireSPI card_locked(card, 400000); + // Step 1: Power-up sequence - Send at least 74 clock cycles with CS high and MOSI high + // This is required by the SD card specification to ensure proper card state reset + // We send 20 bytes (160 clock cycles) to exceed the minimum requirement digitalWrite(card->ssPin, HIGH); for (uint8_t i = 0; i < 20; i++) { card->spi->transfer(0XFF); } + // Step 2: Select the card and send GO_IDLE_STATE command + // This command resets the card to idle state and enables SPI mode // Fix mount issue - sdWait fail ignored before command GO_IDLE_STATE digitalWrite(card->ssPin, LOW); if (!sdWait(pdrv, 500)) { @@ -491,26 +520,34 @@ DSTATUS ff_sd_initialize(uint8_t pdrv) { } sdDeselectCard(pdrv); + // Step 3: Configure CRC checking + // Enable CRC for data transfers in SPI mode (required for reliable communication) token = sdTransaction(pdrv, CRC_ON_OFF, 1, NULL); if (token == 0x5) { - //old card maybe + // Old card that doesn't support CRC - disable CRC checking card->supports_crc = false; } else if (token != 1) { log_w("CRC_ON_OFF failed: %u", token); goto unknown_card; } + // Step 4: Card type detection and initialization + // Try to identify SDHC/SDXC cards using SEND_IF_COND command if (sdTransaction(pdrv, SEND_IF_COND, 0x1AA, &resp) == 1) { + // Card responded to SEND_IF_COND - likely SDHC/SDXC if ((resp & 0xFFF) != 0x1AA) { log_w("SEND_IF_COND failed: %03X", resp & 0xFFF); goto unknown_card; } + // Read Operating Conditions Register to check card capabilities if (sdTransaction(pdrv, READ_OCR, 0, &resp) != 1 || !(resp & (1 << 20))) { log_w("READ_OCR failed: %X", resp); goto unknown_card; } + // Send APP_OP_COND to set operating conditions for SDHC/SDXC + // Wait up to 1 second for the card to become ready start = millis(); do { token = sdTransaction(pdrv, APP_OP_COND, 0x40100000, NULL); @@ -521,37 +558,41 @@ DSTATUS ff_sd_initialize(uint8_t pdrv) { goto unknown_card; } + // Determine if it's SDHC (high capacity) or regular SD if (!sdTransaction(pdrv, READ_OCR, 0, &resp)) { if (resp & (1 << 30)) { - card->type = CARD_SDHC; + card->type = CARD_SDHC; // High capacity card (SDHC/SDXC) } else { - card->type = CARD_SD; + card->type = CARD_SD; // Standard capacity card } } else { log_w("READ_OCR failed: %X", resp); goto unknown_card; } } else { + // Card didn't respond to SEND_IF_COND - try SD or MMC initialization if (sdTransaction(pdrv, READ_OCR, 0, &resp) != 1 || !(resp & (1 << 20))) { log_w("READ_OCR failed: %X", resp); goto unknown_card; } + // Try SD card initialization first start = millis(); do { token = sdTransaction(pdrv, APP_OP_COND, 0x100000, NULL); } while (token == 0x01 && (millis() - start) < 1000); if (!token) { - card->type = CARD_SD; + card->type = CARD_SD; // Standard SD card } else { + // Try MMC card initialization start = millis(); do { token = sdTransaction(pdrv, SEND_OP_COND, 0x100000, NULL); } while (token != 0x00 && (millis() - start) < 1000); if (token == 0x00) { - card->type = CARD_MMC; + card->type = CARD_MMC; // MMC card } else { log_w("SEND_OP_COND failed: %u", token); goto unknown_card; @@ -559,6 +600,7 @@ DSTATUS ff_sd_initialize(uint8_t pdrv) { } } + // Step 5: Clear card detection for SD cards (not needed for MMC) if (card->type != CARD_MMC) { if (sdTransaction(pdrv, APP_CLR_CARD_DETECT, 0, NULL)) { log_w("APP_CLR_CARD_DETECT failed"); @@ -566,6 +608,8 @@ DSTATUS ff_sd_initialize(uint8_t pdrv) { } } + // Step 6: Set block length for non-SDHC cards + // SDHC cards have fixed 512-byte blocks, others need explicit block length setting if (card->type != CARD_SDHC) { if (sdTransaction(pdrv, SET_BLOCKLEN, 512, NULL) != 0x00) { log_w("SET_BLOCKLEN failed"); @@ -573,16 +617,20 @@ DSTATUS ff_sd_initialize(uint8_t pdrv) { } } + // Step 7: Get card capacity and finalize initialization card->sectors = sdGetSectorsCount(pdrv); + // Limit frequency to 25MHz for compatibility (SD spec maximum for non-UHS cards) if (card->frequency > 25000000) { card->frequency = 25000000; } + // Mark card as initialized card->status &= ~STA_NOINIT; return card->status; unknown_card: + // Mark card as unknown type if initialization failed card->type = CARD_UNKNOWN; return card->status; } diff --git a/libraries/SD_MMC/examples/SDMMC_time/SDMMC_time.ino b/libraries/SD_MMC/examples/SDMMC_time/SDMMC_time.ino index d1e933e4f4b..e254a37f630 100644 --- a/libraries/SD_MMC/examples/SDMMC_time/SDMMC_time.ino +++ b/libraries/SD_MMC/examples/SDMMC_time/SDMMC_time.ino @@ -83,10 +83,11 @@ void listDir(fs::FS &fs, const char *dirname, uint8_t levels) { Serial.print(" DIR : "); Serial.print(file.name()); time_t t = file.getLastWrite(); - struct tm *tmstruct = localtime(&t); + struct tm tmstruct; + localtime_r(&t, &tmstruct); Serial.printf( - " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, - tmstruct->tm_min, tmstruct->tm_sec + " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, + tmstruct.tm_min, tmstruct.tm_sec ); if (levels) { listDir(fs, file.path(), levels - 1); @@ -97,10 +98,11 @@ void listDir(fs::FS &fs, const char *dirname, uint8_t levels) { Serial.print(" SIZE: "); Serial.print(file.size()); time_t t = file.getLastWrite(); - struct tm *tmstruct = localtime(&t); + struct tm tmstruct; + localtime_r(&t, &tmstruct); Serial.printf( - " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, - tmstruct->tm_min, tmstruct->tm_sec + " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, + tmstruct.tm_min, tmstruct.tm_sec ); } file = root.openNextFile(); diff --git a/libraries/SD_MMC/src/SD_MMC.h b/libraries/SD_MMC/src/SD_MMC.h index b6fe13a0d24..7192d466b89 100644 --- a/libraries/SD_MMC/src/SD_MMC.h +++ b/libraries/SD_MMC/src/SD_MMC.h @@ -77,7 +77,9 @@ class SDMMCFS : public FS { } // namespace fs +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SD_MMC) extern fs::SDMMCFS SD_MMC; +#endif #endif /* SOC_SDMMC_HOST_SUPPORTED */ #endif /* _SDMMC_H_ */ diff --git a/libraries/SPI/src/SPI.h b/libraries/SPI/src/SPI.h index 6c300e53df2..c00b8155bb9 100644 --- a/libraries/SPI/src/SPI.h +++ b/libraries/SPI/src/SPI.h @@ -98,7 +98,9 @@ class SPIClass { } }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SPI) extern SPIClass SPI; +#endif #endif /* SOC_GPSPI_SUPPORTED */ #endif /* _SPI_H_INCLUDED */ diff --git a/libraries/SPIFFS/examples/SPIFFS_time/SPIFFS_time.ino b/libraries/SPIFFS/examples/SPIFFS_time/SPIFFS_time.ino index 78a66a94e75..9e6474c953a 100644 --- a/libraries/SPIFFS/examples/SPIFFS_time/SPIFFS_time.ino +++ b/libraries/SPIFFS/examples/SPIFFS_time/SPIFFS_time.ino @@ -28,10 +28,11 @@ void listDir(fs::FS &fs, const char *dirname, uint8_t levels) { Serial.print(" DIR : "); Serial.print(file.name()); time_t t = file.getLastWrite(); - struct tm *tmstruct = localtime(&t); + struct tm tmstruct; + localtime_r(&t, &tmstruct); Serial.printf( - " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, - tmstruct->tm_min, tmstruct->tm_sec + " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, + tmstruct.tm_min, tmstruct.tm_sec ); if (levels) { listDir(fs, file.path(), levels - 1); @@ -42,10 +43,11 @@ void listDir(fs::FS &fs, const char *dirname, uint8_t levels) { Serial.print(" SIZE: "); Serial.print(file.size()); time_t t = file.getLastWrite(); - struct tm *tmstruct = localtime(&t); + struct tm tmstruct; + localtime_r(&t, &tmstruct); Serial.printf( - " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, - tmstruct->tm_min, tmstruct->tm_sec + " LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, + tmstruct.tm_min, tmstruct.tm_sec ); } file = root.openNextFile(); diff --git a/libraries/SPIFFS/src/SPIFFS.h b/libraries/SPIFFS/src/SPIFFS.h index 2e7bf6de7d8..aad4743bb19 100644 --- a/libraries/SPIFFS/src/SPIFFS.h +++ b/libraries/SPIFFS/src/SPIFFS.h @@ -34,6 +34,8 @@ class SPIFFSFS : public FS { } // namespace fs +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SPIFFS) extern fs::SPIFFSFS SPIFFS; +#endif #endif diff --git a/libraries/Update/src/HttpsOTAUpdate.h b/libraries/Update/src/HttpsOTAUpdate.h index d470ad50722..8eadc799db5 100644 --- a/libraries/Update/src/HttpsOTAUpdate.h +++ b/libraries/Update/src/HttpsOTAUpdate.h @@ -27,5 +27,8 @@ class HttpsOTAUpdateClass { HttpsOTAStatus_t status(); }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_HTTPSOTAUPDATE) extern HttpsOTAUpdateClass HttpsOTA; #endif + +#endif diff --git a/libraries/WiFi/src/WiFi.h b/libraries/WiFi/src/WiFi.h index ea2efd97697..6cfeb1155a0 100644 --- a/libraries/WiFi/src/WiFi.h +++ b/libraries/WiFi/src/WiFi.h @@ -72,6 +72,8 @@ class WiFiClass : public WiFiGenericClass, public WiFiSTAClass, public WiFiScanC bool isProvEnabled(); }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_WIFI) extern WiFiClass WiFi; +#endif #endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/WiFiProv/src/WiFiProv.h b/libraries/WiFiProv/src/WiFiProv.h index d34727b6896..0ebc5956682 100644 --- a/libraries/WiFiProv/src/WiFiProv.h +++ b/libraries/WiFiProv/src/WiFiProv.h @@ -65,6 +65,8 @@ class WiFiProvClass { void printQR(const char *name, const char *pop, const char *transport, Print &out = Serial); }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_WIFIPROV) extern WiFiProvClass WiFiProv; +#endif #endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index 9cebdfaa304..91a9ddc44bb 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -142,6 +142,7 @@ class TwoWire : public HardwareI2C { #endif /* SOC_I2C_SUPPORT_SLAVE */ }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_WIRE) extern TwoWire Wire; #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0) #if SOC_I2C_NUM > 1 @@ -154,6 +155,7 @@ extern TwoWire Wire2; extern TwoWire Wire1; #endif /* SOC_HP_I2C_NUM */ #endif +#endif #endif /* SOC_I2C_SUPPORTED */ #endif /* TwoWire_h */ diff --git a/libraries/Zigbee/src/ZigbeeCore.h b/libraries/Zigbee/src/ZigbeeCore.h index df334e1620d..f4f6e4f6788 100644 --- a/libraries/Zigbee/src/ZigbeeCore.h +++ b/libraries/Zigbee/src/ZigbeeCore.h @@ -206,6 +206,8 @@ class ZigbeeCore { } }; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_ZIGBEE) extern ZigbeeCore Zigbee; +#endif #endif // CONFIG_ZB_ENABLED