diff --git a/esphome/components/esp32_ble_tracker/__init__.py b/esphome/components/esp32_ble_tracker/__init__.py index 69d46bf5f27..3a4a1f39803 100644 --- a/esphome/components/esp32_ble_tracker/__init__.py +++ b/esphome/components/esp32_ble_tracker/__init__.py @@ -443,15 +443,13 @@ async def to_code(config: ConfigType) -> None: cg.add_define("USE_ESP32_BLE_SOFTWARE_COEXISTENCE") -# First release per series with espressif/esp-idf@82e71c1767 (see bluedroid_stubs.cpp). -# 5.4.5, 5.5.6 and 6.1.1 are not tagged yet but the fix is on their branches. +# First tagged release per series with espressif/esp-idf@82e71c1767 (see bluedroid_stubs.cpp). +# A series without an entry keeps the guard until a fixed release is tagged; the guard is +# harmless on fixed sources. The 5.4, 5.5 and 6.1 branches carry the fix but have no tag yet. DIRECT_CONN_FIX_VERSIONS = { (5, 2): cv.Version(5, 2, 8), (5, 3): cv.Version(5, 3, 6), - (5, 4): cv.Version(5, 4, 5), - (5, 5): cv.Version(5, 5, 6), (6, 0): cv.Version(6, 0, 3), - (6, 1): cv.Version(6, 1, 1), } DIRECT_CONN_FIX_ALL_FROM = cv.Version(6, 2, 0) diff --git a/esphome/components/esp32_ble_tracker/bluedroid_stubs.cpp b/esphome/components/esp32_ble_tracker/bluedroid_stubs.cpp index a013942aa69..5cedc22d069 100644 --- a/esphome/components/esp32_ble_tracker/bluedroid_stubs.cpp +++ b/esphome/components/esp32_ble_tracker/bluedroid_stubs.cpp @@ -11,10 +11,13 @@ #ifdef USE_ESP32_BLE_TRACKER_DIRECT_CONN_GUARD #include +#include +#include "esphome/core/log.h" -namespace esphome::esp32_ble_tracker {} +namespace esphome::esp32_ble_tracker { +static const char *const TAG = "esp32_ble_tracker"; +} // namespace esphome::esp32_ble_tracker -// in_use is the first member of the private tL2C_LCB (checked ESP-IDF 5.0 to 6.1) static_assert(ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(6, 2, 0), "ESP-IDF 6.2 and later have the fix, this guard should not be enabled (esphome/esphome#19373)"); @@ -25,12 +28,15 @@ bool __real_l2cble_init_direct_conn(void *p_lcb); void l2cu_release_lcb(void *p_lcb); bool __wrap_l2cble_init_direct_conn(void *p_lcb) { - if (p_lcb == nullptr || !*static_cast(p_lcb)) { + // in_use is the first member of the private tL2C_LCB (checked ESP-IDF 5.0 to 6.1) + const auto *in_use = static_cast(p_lcb); + if (p_lcb == nullptr || *in_use == 0) { + ESP_LOGW(esphome::esp32_ble_tracker::TAG, "Dropped queued connect on a released link block"); return false; } const bool started = __real_l2cble_init_direct_conn(p_lcb); // Every failure path releases the block except unknown device, also fixed upstream - if (!started && *static_cast(p_lcb)) { + if (!started && *in_use != 0) { l2cu_release_lcb(p_lcb); } return started; diff --git a/tests/component_tests/esp32_ble_tracker/test_direct_conn_guard.py b/tests/component_tests/esp32_ble_tracker/test_direct_conn_guard.py index a58d2302fbf..d3aa2ba8787 100644 --- a/tests/component_tests/esp32_ble_tracker/test_direct_conn_guard.py +++ b/tests/component_tests/esp32_ble_tracker/test_direct_conn_guard.py @@ -55,13 +55,13 @@ def test_guard_only_in_client_builds_on_unfixed_idf( ("5.3.5", True), ("5.3.6", False), ("5.4.4", True), - ("5.4.5", False), + ("5.4.5", True), # no fixed 5.4, 5.5 or 6.1 tag yet ("5.5.5", True), - ("5.5.6", False), + ("5.5.6", True), ("6.0.2", True), ("6.0.3", False), ("6.1.0", True), - ("6.1.1", False), + ("6.1.1", True), ("6.2.0", False), ("7.0.0", False), ],