From 3560d6ca9698aa4f29eeff4e77c169bf1e284764 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 29 Sep 2025 12:45:24 -0500 Subject: [PATCH] sane --- esphome/components/api/__init__.py | 35 ++++++++++++++++++++++------- esphome/components/api/api_server.h | 7 ++---- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/esphome/components/api/__init__.py b/esphome/components/api/__init__.py index 9336d31491..c91051ba20 100644 --- a/esphome/components/api/__init__.py +++ b/esphome/components/api/__init__.py @@ -160,12 +160,29 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_ON_CLIENT_DISCONNECTED): automation.validate_automation( single=True ), - cv.SplitDefault(CONF_LISTEN_BACKLOG, esp8266=1, default=4): cv.int_range( - min=1, max=10 - ), - cv.SplitDefault(CONF_MAX_CONNECTIONS, esp8266=4, default=8): cv.int_range( - min=1, max=20 - ), + # Connection limits to prevent memory exhaustion on resource-constrained devices + # Each connection uses ~500-1000 bytes of RAM plus system resources + # Platform defaults based on available RAM and network stack implementation: + cv.SplitDefault( + CONF_LISTEN_BACKLOG, + esp8266=1, # Limited RAM (~40KB free), LWIP raw sockets + esp32=4, # More RAM (520KB), BSD sockets + rp2040=1, # Limited RAM (264KB), LWIP raw sockets like ESP8266 + bk72xx=4, # Moderate RAM, BSD-style sockets + rtl87xx=4, # Moderate RAM, BSD-style sockets + host=4, # Abundant resources + ln882x=4, # Moderate RAM + ): cv.int_range(min=1, max=10), + cv.SplitDefault( + CONF_MAX_CONNECTIONS, + esp8266=4, # ~40KB free RAM, each connection uses ~500-1000 bytes + esp32=8, # 520KB RAM available + rp2040=4, # 264KB RAM but LWIP constraints + bk72xx=8, # Moderate RAM + rtl87xx=8, # Moderate RAM + host=8, # Abundant resources + ln882x=8, # Moderate RAM + ): cv.int_range(min=1, max=20), } ).extend(cv.COMPONENT_SCHEMA), cv.rename_key(CONF_SERVICES, CONF_ACTIONS), @@ -184,8 +201,10 @@ async def to_code(config): cg.add(var.set_password(config[CONF_PASSWORD])) cg.add(var.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT])) cg.add(var.set_batch_delay(config[CONF_BATCH_DELAY])) - cg.add(var.set_listen_backlog(config[CONF_LISTEN_BACKLOG])) - cg.add(var.set_max_connections(config[CONF_MAX_CONNECTIONS])) + if CONF_LISTEN_BACKLOG in config: + cg.add(var.set_listen_backlog(config[CONF_LISTEN_BACKLOG])) + if CONF_MAX_CONNECTIONS in config: + cg.add(var.set_max_connections(config[CONF_MAX_CONNECTIONS])) # Set USE_API_SERVICES if any services are enabled if config.get(CONF_ACTIONS) or config[CONF_CUSTOM_SERVICES]: diff --git a/esphome/components/api/api_server.h b/esphome/components/api/api_server.h index f0c51af460..b9049c1700 100644 --- a/esphome/components/api/api_server.h +++ b/esphome/components/api/api_server.h @@ -191,13 +191,10 @@ class APIServer : public Component, public Controller { // Group smaller types together uint16_t port_{6053}; uint16_t batch_delay_{100}; -#ifdef USE_ESP8266 - uint8_t listen_backlog_{1}; - uint8_t max_connections_{4}; -#else + // Connection limits - these defaults will be overridden by config values + // from cv.SplitDefault in __init__.py which sets platform-specific defaults uint8_t listen_backlog_{4}; uint8_t max_connections_{8}; -#endif bool shutting_down_ = false; // 7 bytes used, 1 byte padding