From dbbbba3cf8ff5ad73f200c085f0a7f84c6be9aa1 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 5 Dec 2022 09:49:39 -1000 Subject: [PATCH] Fix crash with bluetooth tracker and esp-idf (#4140) --- .../components/esp32_ble_tracker/__init__.py | 5 ++++ .../esp32_ble_tracker/esp32_ble_tracker.cpp | 24 +++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/esphome/components/esp32_ble_tracker/__init__.py b/esphome/components/esp32_ble_tracker/__init__.py index 0d7abe32f9..a3938faff2 100644 --- a/esphome/components/esp32_ble_tracker/__init__.py +++ b/esphome/components/esp32_ble_tracker/__init__.py @@ -238,6 +238,11 @@ async def to_code(config): if CORE.using_esp_idf: add_idf_sdkconfig_option("CONFIG_BT_ENABLED", True) + # https://github.com/espressif/esp-idf/issues/4101 + # https://github.com/espressif/esp-idf/issues/2503 + # 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_BTU_TASK_STACK_SIZE", 8192) cg.add_define("USE_OTA_STATE_CALLBACK") # To be notified when an OTA update starts diff --git a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp index 9df81a8905..853e998c80 100644 --- a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +++ b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp @@ -180,7 +180,13 @@ void ESP32BLETracker::loop() { ESP_LOGE(TAG, "ESP-IDF BLE scan could not restart after 255 attempts, rebooting to restore BLE stack..."); App.reboot(); } - esp_ble_gap_stop_scanning(); + if (xSemaphoreTake(this->scan_end_lock_, 0L)) { + xSemaphoreGive(this->scan_end_lock_); + } else { + ESP_LOGD(TAG, "Stopping scan after failure..."); + esp_ble_gap_stop_scanning(); + this->cancel_timeout("scan"); + } if (this->scan_start_failed_) { ESP_LOGE(TAG, "Scan start failed: %d", this->scan_start_failed_); this->scan_start_failed_ = ESP_BT_STATUS_SUCCESS; @@ -199,10 +205,18 @@ void ESP32BLETracker::loop() { if (promote_to_connecting) { for (auto *client : this->clients_) { if (client->state() == ClientState::DISCOVERED) { - ESP_LOGD(TAG, "Pausing scan to make connection..."); - esp_ble_gap_stop_scanning(); - // We only want to promote one client at a time. - client->set_state(ClientState::READY_TO_CONNECT); + if (xSemaphoreTake(this->scan_end_lock_, 0L)) { + // Scanner is not running since we got the + // lock, so we can promote the client. + xSemaphoreGive(this->scan_end_lock_); + // We only want to promote one client at a time. + // once the scanner is fully stopped. + client->set_state(ClientState::READY_TO_CONNECT); + } else { + ESP_LOGD(TAG, "Pausing scan to make connection..."); + esp_ble_gap_stop_scanning(); + this->cancel_timeout("scan"); + } break; } }