diff --git a/components/bt/host/bluedroid/api/esp_bt_main.c b/components/bt/host/bluedroid/api/esp_bt_main.c index adb7a12a34..fb7d59f02f 100644 --- a/components/bt/host/bluedroid/api/esp_bt_main.c +++ b/components/bt/host/bluedroid/api/esp_bt_main.c @@ -18,20 +18,11 @@ #include "hci_log/bt_hci_log.h" #include "bt_common.h" -static bool bd_already_enable = false; -static bool bd_already_init = false; +static esp_bluedroid_status_t s_bt_host_state = ESP_BLUEDROID_STATUS_UNINITIALIZED; esp_bluedroid_status_t esp_bluedroid_get_status(void) { - if (bd_already_init) { - if (bd_already_enable) { - return ESP_BLUEDROID_STATUS_ENABLED; - } else { - return ESP_BLUEDROID_STATUS_INITIALIZED; - } - } else { - return ESP_BLUEDROID_STATUS_UNINITIALIZED; - } + return s_bt_host_state; } esp_err_t esp_bluedroid_enable(void) @@ -39,12 +30,12 @@ esp_err_t esp_bluedroid_enable(void) btc_msg_t msg; future_t **future_p; - if (!bd_already_init) { + if (s_bt_host_state == ESP_BLUEDROID_STATUS_UNINITIALIZED) { LOG_ERROR("Bludroid not initialised\n"); return ESP_ERR_INVALID_STATE; } - if (bd_already_enable) { + if (s_bt_host_state == ESP_BLUEDROID_STATUS_ENABLED) { LOG_ERROR("Bluedroid already enabled\n"); return ESP_ERR_INVALID_STATE; } @@ -70,8 +61,7 @@ esp_err_t esp_bluedroid_enable(void) return ESP_FAIL; } - bd_already_enable = true; - + s_bt_host_state = ESP_BLUEDROID_STATUS_ENABLED; return ESP_OK; } @@ -80,15 +70,18 @@ esp_err_t esp_bluedroid_disable(void) btc_msg_t msg; future_t **future_p; - if (!bd_already_enable) { + if (s_bt_host_state != ESP_BLUEDROID_STATUS_ENABLED) { LOG_ERROR("Bluedroid already disabled\n"); return ESP_ERR_INVALID_STATE; } + s_bt_host_state = ESP_BLUEDROID_STATUS_DISABLING; + future_p = btc_main_get_future_p(BTC_MAIN_DISABLE_FUTURE); *future_p = future_new(); if (*future_p == NULL) { LOG_ERROR("Bluedroid disable failed\n"); + s_bt_host_state = ESP_BLUEDROID_STATUS_ENABLED; return ESP_ERR_NO_MEM; } @@ -98,16 +91,17 @@ esp_err_t esp_bluedroid_disable(void) if (btc_transfer_context(&msg, NULL, 0, NULL, NULL) != BT_STATUS_SUCCESS) { LOG_ERROR("Bluedroid disable failed\n"); + s_bt_host_state = ESP_BLUEDROID_STATUS_ENABLED; return ESP_FAIL; } if (future_await(*future_p) == FUTURE_FAIL) { LOG_ERROR("Bluedroid disable failed\n"); + s_bt_host_state = ESP_BLUEDROID_STATUS_ENABLED; return ESP_FAIL; } - bd_already_enable = false; - + s_bt_host_state = ESP_BLUEDROID_STATUS_INITIALIZED; return ESP_OK; } @@ -150,7 +144,7 @@ esp_err_t esp_bluedroid_init_with_cfg(esp_bluedroid_config_t *cfg) } #endif - if (bd_already_init) { + if (s_bt_host_state != ESP_BLUEDROID_STATUS_UNINITIALIZED) { LOG_ERROR("Bluedroid already initialised\n"); return ESP_ERR_INVALID_STATE; } @@ -195,28 +189,28 @@ esp_err_t esp_bluedroid_init_with_cfg(esp_bluedroid_config_t *cfg) return ESP_FAIL; } - bd_already_init = true; - #if (BT_HCI_LOG_INCLUDED == TRUE) bt_hci_log_init(); #endif // (BT_HCI_LOG_INCLUDED == TRUE) + s_bt_host_state = ESP_BLUEDROID_STATUS_INITIALIZED; + return ESP_OK; } - esp_err_t esp_bluedroid_deinit(void) { btc_msg_t msg; future_t **future_p; - if (!bd_already_init) { + if (s_bt_host_state == ESP_BLUEDROID_STATUS_UNINITIALIZED) { LOG_ERROR("Bluedroid already de-initialised\n"); return ESP_ERR_INVALID_STATE; } - if (bd_already_enable) { - LOG_ERROR("Bludroid already enabled, do disable first\n"); + if (s_bt_host_state == ESP_BLUEDROID_STATUS_ENABLED || + s_bt_host_state == ESP_BLUEDROID_STATUS_DISABLING) { + LOG_ERROR("Bludroid still enabled or stopping, disable first\n"); return ESP_ERR_INVALID_STATE; } @@ -249,8 +243,7 @@ esp_err_t esp_bluedroid_deinit(void) bt_hci_log_deinit(); #endif // (BT_HCI_LOG_INCLUDED == TRUE) - bd_already_init = false; - + s_bt_host_state = ESP_BLUEDROID_STATUS_UNINITIALIZED; return ESP_OK; } diff --git a/components/bt/host/bluedroid/api/include/api/esp_bt_main.h b/components/bt/host/bluedroid/api/include/api/esp_bt_main.h index f0f10afdd7..ad9252bfd9 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_bt_main.h +++ b/components/bt/host/bluedroid/api/include/api/esp_bt_main.h @@ -20,9 +20,10 @@ extern "C" { * @brief Bluetooth stack status type, to indicate whether the bluetooth stack is ready. */ typedef enum { - ESP_BLUEDROID_STATUS_UNINITIALIZED = 0, /*!< Bluetooth not initialized */ - ESP_BLUEDROID_STATUS_INITIALIZED, /*!< Bluetooth initialized but not enabled */ - ESP_BLUEDROID_STATUS_ENABLED /*!< Bluetooth initialized and enabled */ + ESP_BLUEDROID_STATUS_UNINITIALIZED = 0, /*!< Bluetooth stack is not initialized */ + ESP_BLUEDROID_STATUS_INITIALIZED, /*!< Bluetooth stack is initialized but not yet enabled */ + ESP_BLUEDROID_STATUS_ENABLED, /*!< Bluetooth stack is fully initialized and enabled */ + ESP_BLUEDROID_STATUS_DISABLING /*!< Bluetooth stack is in the process of being disabled */ } esp_bluedroid_status_t; /** diff --git a/components/bt/host/bluedroid/hci/hci_hal_h4.c b/components/bt/host/bluedroid/hci/hci_hal_h4.c index ef874844ed..5baf97fc08 100644 --- a/components/bt/host/bluedroid/hci/hci_hal_h4.c +++ b/components/bt/host/bluedroid/hci/hci_hal_h4.c @@ -25,6 +25,7 @@ #include "hci/hci_trans_int.h" #include "osi/thread.h" #include "osi/pkt_queue.h" +#include "esp_bt_main.h" #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) #include "osi/mutex.h" #include "osi/alarm.h" @@ -645,6 +646,11 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) fixed_queue_enqueue(hci_hal_env.rx_q, pkt, FIXED_QUEUE_MAX_TIMEOUT); } } else { + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + // Prevent race condition during host deinit/disable + // Host not ready, dropped advertising report + return 0; + } #if (BLE_42_SCAN_EN == TRUE) #if !BLE_ADV_REPORT_FLOW_CONTROL // drop the packets if pkt_queue length goes beyond upper limit