mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Merge remote-tracking branch 'upstream/dev' into integration
This commit is contained in:
		| @@ -1,4 +1,5 @@ | ||||
| #include "esphome/core/helpers.h" | ||||
| #include "esphome/core/defines.h" | ||||
|  | ||||
| #ifdef USE_ESP32 | ||||
|  | ||||
| @@ -36,7 +37,15 @@ IRAM_ATTR InterruptLock::~InterruptLock() { portENABLE_INTERRUPTS(); } | ||||
|  | ||||
| LwIPLock::LwIPLock() { | ||||
| #ifdef CONFIG_LWIP_TCPIP_CORE_LOCKING | ||||
|   // Only lock if we're not already in the TCPIP thread | ||||
|   // When CONFIG_LWIP_TCPIP_CORE_LOCKING is enabled, lwIP uses a global mutex to protect | ||||
|   // its internal state. Any thread can take this lock to safely access lwIP APIs. | ||||
|   // | ||||
|   // sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER) returns true if the current thread | ||||
|   // already holds the lwIP core lock. This prevents recursive locking attempts and | ||||
|   // allows nested LwIPLock instances to work correctly. | ||||
|   // | ||||
|   // If we don't already hold the lock, acquire it. This will block until the lock | ||||
|   // is available if another thread currently holds it. | ||||
|   if (!sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) { | ||||
|     LOCK_TCPIP_CORE(); | ||||
|   } | ||||
| @@ -45,7 +54,16 @@ LwIPLock::LwIPLock() { | ||||
|  | ||||
| LwIPLock::~LwIPLock() { | ||||
| #ifdef CONFIG_LWIP_TCPIP_CORE_LOCKING | ||||
|   // Only unlock if we hold the lock | ||||
|   // Only release the lwIP core lock if this thread currently holds it. | ||||
|   // | ||||
|   // sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER) queries lwIP's internal lock | ||||
|   // ownership tracking. It returns true only if the current thread is registered | ||||
|   // as the lock holder. | ||||
|   // | ||||
|   // This check is essential because: | ||||
|   // 1. We may not have acquired the lock in the constructor (if we already held it) | ||||
|   // 2. The lock might have been released by other means between constructor and destructor | ||||
|   // 3. Calling UNLOCK_TCPIP_CORE() without holding the lock causes undefined behavior | ||||
|   if (sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) { | ||||
|     UNLOCK_TCPIP_CORE(); | ||||
|   } | ||||
|   | ||||
| @@ -22,6 +22,10 @@ void Mutex::unlock() {} | ||||
| IRAM_ATTR InterruptLock::InterruptLock() { state_ = xt_rsil(15); } | ||||
| IRAM_ATTR InterruptLock::~InterruptLock() { xt_wsr_ps(state_); } | ||||
|  | ||||
| // ESP8266 doesn't support lwIP core locking, so this is a no-op | ||||
| LwIPLock::LwIPLock() {} | ||||
| LwIPLock::~LwIPLock() {} | ||||
|  | ||||
| void get_mac_address_raw(uint8_t *mac) {  // NOLINT(readability-non-const-parameter) | ||||
|   wifi_get_macaddr(STATION_IF, mac); | ||||
| } | ||||
|   | ||||
| @@ -26,6 +26,10 @@ void Mutex::unlock() { xSemaphoreGive(this->handle_); } | ||||
| IRAM_ATTR InterruptLock::InterruptLock() { portDISABLE_INTERRUPTS(); } | ||||
| IRAM_ATTR InterruptLock::~InterruptLock() { portENABLE_INTERRUPTS(); } | ||||
|  | ||||
| // LibreTiny doesn't support lwIP core locking, so this is a no-op | ||||
| LwIPLock::LwIPLock() {} | ||||
| LwIPLock::~LwIPLock() {} | ||||
|  | ||||
| void get_mac_address_raw(uint8_t *mac) {  // NOLINT(readability-non-const-parameter) | ||||
|   WiFi.macAddress(mac); | ||||
| } | ||||
|   | ||||
| @@ -204,7 +204,7 @@ def add_pio_file(component: str, key: str, data: str): | ||||
|         cv.validate_id_name(key) | ||||
|     except cv.Invalid as e: | ||||
|         raise EsphomeError( | ||||
|             f"[{component}] Invalid PIO key: {key}. Allowed characters: [{ascii_letters}{digits}_]\nPlease report an issue https://github.com/esphome/issues" | ||||
|             f"[{component}] Invalid PIO key: {key}. Allowed characters: [{ascii_letters}{digits}_]\nPlease report an issue https://github.com/esphome/esphome/issues" | ||||
|         ) from e | ||||
|     CORE.data[KEY_RP2040][KEY_PIO_FILES][key] = data | ||||
|  | ||||
|   | ||||
| @@ -44,6 +44,10 @@ void Mutex::unlock() {} | ||||
| IRAM_ATTR InterruptLock::InterruptLock() { state_ = save_and_disable_interrupts(); } | ||||
| IRAM_ATTR InterruptLock::~InterruptLock() { restore_interrupts(state_); } | ||||
|  | ||||
| // RP2040 doesn't support lwIP core locking, so this is a no-op | ||||
| LwIPLock::LwIPLock() {} | ||||
| LwIPLock::~LwIPLock() {} | ||||
|  | ||||
| void get_mac_address_raw(uint8_t *mac) {  // NOLINT(readability-non-const-parameter) | ||||
| #ifdef USE_WIFI | ||||
|   WiFi.macAddress(mac); | ||||
|   | ||||
| @@ -317,3 +317,15 @@ async def to_code(config): | ||||
|     if (sorting_group_config := config.get(CONF_SORTING_GROUPS)) is not None: | ||||
|         cg.add_define("USE_WEBSERVER_SORTING") | ||||
|         add_sorting_groups(var, sorting_group_config) | ||||
|  | ||||
|  | ||||
| def FILTER_SOURCE_FILES() -> list[str]: | ||||
|     """Filter out web_server_v1.cpp when version is not 1.""" | ||||
|     files_to_filter: list[str] = [] | ||||
|  | ||||
|     # web_server_v1.cpp is only needed when version is 1 | ||||
|     config = CORE.config.get("web_server", {}) | ||||
|     if config.get(CONF_VERSION, 2) != 1: | ||||
|         files_to_filter.append("web_server_v1.cpp") | ||||
|  | ||||
|     return files_to_filter | ||||
|   | ||||
| @@ -1620,7 +1620,9 @@ void WebServer::handle_event_request(AsyncWebServerRequest *request, const UrlMa | ||||
|   request->send(404); | ||||
| } | ||||
|  | ||||
| static std::string get_event_type(event::Event *event) { return event->last_event_type ? *event->last_event_type : ""; } | ||||
| static std::string get_event_type(event::Event *event) { | ||||
|   return (event && event->last_event_type) ? *event->last_event_type : ""; | ||||
| } | ||||
|  | ||||
| std::string WebServer::event_state_json_generator(WebServer *web_server, void *source) { | ||||
|   auto *event = static_cast<event::Event *>(source); | ||||
|   | ||||
| @@ -54,6 +54,10 @@ void Mutex::unlock() { k_mutex_unlock(static_cast<k_mutex *>(this->handle_)); } | ||||
| IRAM_ATTR InterruptLock::InterruptLock() { state_ = irq_lock(); } | ||||
| IRAM_ATTR InterruptLock::~InterruptLock() { irq_unlock(state_); } | ||||
|  | ||||
| // Zephyr doesn't support lwIP core locking, so this is a no-op | ||||
| LwIPLock::LwIPLock() {} | ||||
| LwIPLock::~LwIPLock() {} | ||||
|  | ||||
| uint32_t random_uint32() { return rand(); }  // NOLINT(cert-msc30-c, cert-msc50-cpp) | ||||
| bool random_bytes(uint8_t *data, size_t len) { | ||||
|   sys_rand_get(data, len); | ||||
|   | ||||
| @@ -695,6 +695,10 @@ class LwIPLock { | ||||
|  public: | ||||
|   LwIPLock(); | ||||
|   ~LwIPLock(); | ||||
|  | ||||
|   // Delete copy constructor and copy assignment operator to prevent accidental copying | ||||
|   LwIPLock(const LwIPLock &) = delete; | ||||
|   LwIPLock &operator=(const LwIPLock &) = delete; | ||||
| }; | ||||
|  | ||||
| /** Helper class to request `loop()` to be called as fast as possible. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user