mirror of
https://github.com/esphome/esphome.git
synced 2025-11-20 00:35:44 +00:00
[esp32_ble] Fix max_connections architecture (shared client+server limit) (#11006)
This commit is contained in:
@@ -1,14 +1,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable, MutableMapping
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from esphome import automation
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import esp32_ble
|
||||
from esphome.components.esp32 import add_idf_sdkconfig_option
|
||||
from esphome.components.esp32_ble import (
|
||||
IDF_MAX_CONNECTIONS,
|
||||
BTLoggers,
|
||||
bt_uuid,
|
||||
bt_uuid16_format,
|
||||
@@ -39,18 +38,12 @@ AUTO_LOAD = ["esp32_ble"]
|
||||
DEPENDENCIES = ["esp32"]
|
||||
CODEOWNERS = ["@bdraco"]
|
||||
|
||||
KEY_ESP32_BLE_TRACKER = "esp32_ble_tracker"
|
||||
KEY_USED_CONNECTION_SLOTS = "used_connection_slots"
|
||||
|
||||
CONF_ESP32_BLE_ID = "esp32_ble_id"
|
||||
CONF_SCAN_PARAMETERS = "scan_parameters"
|
||||
CONF_WINDOW = "window"
|
||||
CONF_ON_SCAN_END = "on_scan_end"
|
||||
CONF_SOFTWARE_COEXISTENCE = "software_coexistence"
|
||||
|
||||
DEFAULT_MAX_CONNECTIONS = 3
|
||||
IDF_MAX_CONNECTIONS = 9
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -128,6 +121,15 @@ def validate_scan_parameters(config):
|
||||
return config
|
||||
|
||||
|
||||
def validate_max_connections_deprecated(config: ConfigType) -> ConfigType:
|
||||
if CONF_MAX_CONNECTIONS in config:
|
||||
_LOGGER.warning(
|
||||
"The 'max_connections' option in 'esp32_ble_tracker' is deprecated. "
|
||||
"Please move it to the 'esp32_ble' component instead."
|
||||
)
|
||||
return config
|
||||
|
||||
|
||||
def as_hex(value):
|
||||
return cg.RawExpression(f"0x{value}ULL")
|
||||
|
||||
@@ -150,24 +152,12 @@ def as_reversed_hex_array(value):
|
||||
)
|
||||
|
||||
|
||||
def consume_connection_slots(
|
||||
value: int, consumer: str
|
||||
) -> Callable[[MutableMapping], MutableMapping]:
|
||||
def _consume_connection_slots(config: MutableMapping) -> MutableMapping:
|
||||
data: dict[str, Any] = CORE.data.setdefault(KEY_ESP32_BLE_TRACKER, {})
|
||||
slots: list[str] = data.setdefault(KEY_USED_CONNECTION_SLOTS, [])
|
||||
slots.extend([consumer] * value)
|
||||
return config
|
||||
|
||||
return _consume_connection_slots
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ESP32BLETracker),
|
||||
cv.GenerateID(esp32_ble.CONF_BLE_ID): cv.use_id(esp32_ble.ESP32BLE),
|
||||
cv.Optional(CONF_MAX_CONNECTIONS, default=DEFAULT_MAX_CONNECTIONS): cv.All(
|
||||
cv.Optional(CONF_MAX_CONNECTIONS): cv.All(
|
||||
cv.positive_int, cv.Range(min=0, max=IDF_MAX_CONNECTIONS)
|
||||
),
|
||||
cv.Optional(CONF_SCAN_PARAMETERS, default={}): cv.All(
|
||||
@@ -224,48 +214,11 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.OnlyWith(CONF_SOFTWARE_COEXISTENCE, "wifi", default=True): bool,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA),
|
||||
validate_max_connections_deprecated,
|
||||
)
|
||||
|
||||
|
||||
def validate_remaining_connections(config):
|
||||
data: dict[str, Any] = CORE.data.get(KEY_ESP32_BLE_TRACKER, {})
|
||||
slots: list[str] = data.get(KEY_USED_CONNECTION_SLOTS, [])
|
||||
used_slots = len(slots)
|
||||
if used_slots <= config[CONF_MAX_CONNECTIONS]:
|
||||
return config
|
||||
slot_users = ", ".join(slots)
|
||||
|
||||
if used_slots < IDF_MAX_CONNECTIONS:
|
||||
_LOGGER.warning(
|
||||
"esp32_ble_tracker exceeded `%s`: components attempted to consume %d "
|
||||
"connection slot(s) out of available configured maximum %d connection "
|
||||
"slot(s); The system automatically increased `%s` to %d to match the "
|
||||
"number of used connection slot(s) by components: %s.",
|
||||
CONF_MAX_CONNECTIONS,
|
||||
used_slots,
|
||||
config[CONF_MAX_CONNECTIONS],
|
||||
CONF_MAX_CONNECTIONS,
|
||||
used_slots,
|
||||
slot_users,
|
||||
)
|
||||
config[CONF_MAX_CONNECTIONS] = used_slots
|
||||
return config
|
||||
|
||||
msg = (
|
||||
f"esp32_ble_tracker exceeded `{CONF_MAX_CONNECTIONS}`: "
|
||||
f"components attempted to consume {used_slots} connection slot(s) "
|
||||
f"out of available configured maximum {config[CONF_MAX_CONNECTIONS]} "
|
||||
f"connection slot(s); Decrease the number of BLE clients ({slot_users})"
|
||||
)
|
||||
if config[CONF_MAX_CONNECTIONS] < IDF_MAX_CONNECTIONS:
|
||||
msg += f" or increase {CONF_MAX_CONNECTIONS}` to {used_slots}"
|
||||
msg += f" to stay under the {IDF_MAX_CONNECTIONS} connection slot(s) limit."
|
||||
raise cv.Invalid(msg)
|
||||
|
||||
|
||||
FINAL_VALIDATE_SCHEMA = cv.All(
|
||||
validate_remaining_connections, esp32_ble.validate_variant
|
||||
)
|
||||
FINAL_VALIDATE_SCHEMA = esp32_ble.validate_variant
|
||||
|
||||
ESP_BLE_DEVICE_SCHEMA = cv.Schema(
|
||||
{
|
||||
@@ -345,10 +298,8 @@ async def to_code(config):
|
||||
# Match arduino CONFIG_BTU_TASK_STACK_SIZE
|
||||
# https://github.com/espressif/arduino-esp32/blob/fd72cf46ad6fc1a6de99c1d83ba8eba17d80a4ee/tools/sdk/esp32/sdkconfig#L1866
|
||||
add_idf_sdkconfig_option("CONFIG_BT_BTU_TASK_STACK_SIZE", 8192)
|
||||
add_idf_sdkconfig_option("CONFIG_BT_ACL_CONNECTIONS", 9)
|
||||
add_idf_sdkconfig_option(
|
||||
"CONFIG_BTDM_CTRL_BLE_MAX_CONN", config[CONF_MAX_CONNECTIONS]
|
||||
)
|
||||
# Note: CONFIG_BT_ACL_CONNECTIONS and CONFIG_BTDM_CTRL_BLE_MAX_CONN are now
|
||||
# configured in esp32_ble component based on max_connections setting
|
||||
|
||||
cg.add_define("USE_OTA_STATE_CALLBACK") # To be notified when an OTA update starts
|
||||
cg.add_define("USE_ESP32_BLE_CLIENT")
|
||||
|
||||
Reference in New Issue
Block a user