Просмотр исходного кода

Merge branch 'bt/add_host_only_mode' into 'master'

bt: Added BlueDroid-Only mode to use BlueDroid host only without Bluetooth Controller

See merge request espressif/esp-idf!25319
Jiang Jiang Jian 2 лет назад
Родитель
Сommit
6e0a8434a7
38 измененных файлов с 972 добавлено и 57 удалено
  1. 23 17
      components/bt/CMakeLists.txt
  2. 4 2
      components/bt/Kconfig
  3. 7 1
      components/bt/common/include/bt_user_config.h
  4. 8 7
      components/bt/host/bluedroid/Kconfig.in
  5. 89 0
      components/bt/host/bluedroid/api/esp_bluedroid_hci.c
  6. 5 0
      components/bt/host/bluedroid/api/esp_bt_main.c
  7. 2 0
      components/bt/host/bluedroid/api/esp_hf_ag_api.c
  8. 84 0
      components/bt/host/bluedroid/api/include/api/esp_bluedroid_hci.h
  9. 11 2
      components/bt/host/bluedroid/bta/dm/bta_dm_act.c
  10. 7 0
      components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c
  11. 4 0
      components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c
  12. 6 3
      components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c
  13. 1 1
      components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h
  14. 6 0
      components/bt/host/bluedroid/common/include/common/bt_target.h
  15. 10 6
      components/bt/host/bluedroid/hci/hci_hal_h4.c
  16. 5 1
      components/bt/host/bluedroid/hci/hci_layer.c
  17. 3 2
      components/bt/host/bluedroid/hci/include/hci/hci_hal.h
  18. 47 0
      components/bt/host/bluedroid/hci/include/hci/hci_trans_int.h
  19. 0 1
      components/bt/test_apps/main/test_smp.c
  20. 0 1
      components/esp_hid/src/ble_hidd.c
  21. 0 1
      components/esp_hid/src/ble_hidh.c
  22. 0 1
      components/esp_hid/src/bt_hidd.c
  23. 7 2
      components/protocomm/src/simple_ble/simple_ble.c
  24. 1 0
      components/soc/esp32p4/include/soc/soc.h
  25. 14 4
      components/wifi_provisioning/src/scheme_ble.c
  26. 6 0
      examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/CMakeLists.txt
  27. 85 0
      examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/README.md
  28. 3 0
      examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/CMakeLists.txt
  29. 8 0
      examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/Kconfig.projbuild
  30. 306 0
      examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/main.c
  31. 165 0
      examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.c
  32. 46 0
      examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.h
  33. 4 0
      examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/sdkconfig.defaults
  34. 1 1
      examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c
  35. 1 1
      examples/system/ota/advanced_https_ota/main/ble_helper/ble_api.c
  36. 1 1
      examples/system/ota/advanced_https_ota/main/ble_helper/bluedroid_gatts.c
  37. 1 1
      examples/system/ota/advanced_https_ota/main/ble_helper/include/ble_api.h
  38. 1 1
      examples/system/ota/advanced_https_ota/main/ble_helper/include/bluedroid_gatts.h

+ 23 - 17
components/bt/CMakeLists.txt

@@ -70,30 +70,35 @@ if(CONFIG_BT_ENABLED)
     set(srcs "")
     set(srcs "")
     set(include_dirs "")
     set(include_dirs "")
     set(ldfragments "linker.lf")
     set(ldfragments "linker.lf")
+    if(CONFIG_BT_CONTROLLER_ENABLED)
+        if(CONFIG_IDF_TARGET_ESP32)
+            list(APPEND srcs "controller/esp32/bt.c"
+                             "controller/esp32/hli_api.c"
+                             "controller/esp32/hli_vectors.S")
 
 
-    if(CONFIG_IDF_TARGET_ESP32)
-        list(APPEND srcs "controller/esp32/bt.c"
-                         "controller/esp32/hli_api.c"
-                         "controller/esp32/hli_vectors.S")
+        elseif(CONFIG_IDF_TARGET_ESP32C3)
+            list(APPEND srcs "controller/esp32c3/bt.c")
 
 
-    elseif(CONFIG_IDF_TARGET_ESP32C3)
-        list(APPEND srcs "controller/esp32c3/bt.c")
+        elseif(CONFIG_IDF_TARGET_ESP32S3)
+            list(APPEND srcs "controller/esp32c3/bt.c")
 
 
-    elseif(CONFIG_IDF_TARGET_ESP32S3)
-        list(APPEND srcs "controller/esp32c3/bt.c")
+        elseif(CONFIG_IDF_TARGET_ESP32C2)
+            list(APPEND srcs "controller/esp32c2/bt.c")
 
 
-    elseif(CONFIG_IDF_TARGET_ESP32C2)
-        set(ldfragments "linker.lf.esp32c2")
-        list(APPEND srcs "controller/esp32c2/bt.c")
+        elseif(CONFIG_IDF_TARGET_ESP32C2)
+            set(ldfragments "linker.lf.esp32c2")
+            list(APPEND srcs "controller/esp32c2/bt.c")
 
 
-    elseif(CONFIG_IDF_TARGET_ESP32C6)
-        list(APPEND srcs "controller/esp32c6/bt.c")
+        elseif(CONFIG_IDF_TARGET_ESP32C6)
+            list(APPEND srcs "controller/esp32c6/bt.c")
 
 
-    elseif(CONFIG_IDF_TARGET_ESP32H2)
-        list(APPEND srcs "controller/esp32h2/bt.c")
-    endif()
+        elseif(CONFIG_IDF_TARGET_ESP32H2)
+            list(APPEND srcs "controller/esp32h2/bt.c")
+        endif()
 
 
-    list(APPEND include_dirs ${target_specific_include_dirs})
+        list(APPEND include_dirs ${target_specific_include_dirs})
+
+    endif()
 
 
     # Common
     # Common
     list(APPEND include_dirs common/osi/include)
     list(APPEND include_dirs common/osi/include)
@@ -174,6 +179,7 @@ if(CONFIG_BT_ENABLED)
 
 
         list(APPEND srcs "host/bluedroid/api/esp_a2dp_api.c"
         list(APPEND srcs "host/bluedroid/api/esp_a2dp_api.c"
                    "host/bluedroid/api/esp_avrc_api.c"
                    "host/bluedroid/api/esp_avrc_api.c"
+                   "host/bluedroid/api/esp_bluedroid_hci.c"
                    "host/bluedroid/api/esp_bt_device.c"
                    "host/bluedroid/api/esp_bt_device.c"
                    "host/bluedroid/api/esp_bt_main.c"
                    "host/bluedroid/api/esp_bt_main.c"
                    "host/bluedroid/api/esp_gap_ble_api.c"
                    "host/bluedroid/api/esp_gap_ble_api.c"

+ 4 - 2
components/bt/Kconfig

@@ -1,9 +1,8 @@
 menu "Bluetooth"
 menu "Bluetooth"
-    visible if SOC_BT_SUPPORTED
 
 
     config BT_ENABLED
     config BT_ENABLED
         bool "Bluetooth"
         bool "Bluetooth"
-        depends on SOC_BT_SUPPORTED && !APP_NO_BLOBS
+        depends on !APP_NO_BLOBS
         help
         help
             Select this option to enable Bluetooth and show the submenu with Bluetooth configuration choices.
             Select this option to enable Bluetooth and show the submenu with Bluetooth configuration choices.
 
 
@@ -22,10 +21,12 @@ menu "Bluetooth"
 
 
         config BT_NIMBLE_ENABLED
         config BT_NIMBLE_ENABLED
             bool "NimBLE - BLE only"
             bool "NimBLE - BLE only"
+            depends on BT_CONTROLLER_ENABLED
             help
             help
                 This option is recommended for BLE only usecases to save on memory
                 This option is recommended for BLE only usecases to save on memory
 
 
         config BT_CONTROLLER_ONLY
         config BT_CONTROLLER_ONLY
+            depends on SOC_BT_SUPPORTED
             bool "Disabled"
             bool "Disabled"
             help
             help
                 This option is recommended when you want to communicate directly with the
                 This option is recommended when you want to communicate directly with the
@@ -42,6 +43,7 @@ menu "Bluetooth"
             This helps to choose Bluetooth controller stack
             This helps to choose Bluetooth controller stack
 
 
         config BT_CONTROLLER_ENABLED
         config BT_CONTROLLER_ENABLED
+            depends on SOC_BT_SUPPORTED
             bool "Enabled"
             bool "Enabled"
             help
             help
                 This option is recommended for Bluetooth controller usecases
                 This option is recommended for Bluetooth controller usecases

+ 7 - 1
components/bt/common/include/bt_user_config.h

@@ -1,5 +1,5 @@
 /*
 /*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  *
  * SPDX-License-Identifier: Apache-2.0
  * SPDX-License-Identifier: Apache-2.0
  */
  */
@@ -29,6 +29,12 @@
 #define UC_BT_STACK_NO_LOG               FALSE
 #define UC_BT_STACK_NO_LOG               FALSE
 #endif
 #endif
 
 
+#ifdef CONFIG_BT_CONTROLLER_ENABLED
+#define UC_BT_CONTROLLER_INCLUDED        TRUE
+#else
+#define UC_BT_CONTROLLER_INCLUDED        FALSE
+#endif
+
 /**********************************************************
 /**********************************************************
  * Thread/Task reference
  * Thread/Task reference
  **********************************************************/
  **********************************************************/

+ 8 - 7
components/bt/host/bluedroid/Kconfig.in

@@ -49,7 +49,7 @@ config BT_BLUEDROID_ESP_COEX_VSC
 
 
 config BT_CLASSIC_ENABLED
 config BT_CLASSIC_ENABLED
     bool "Classic Bluetooth"
     bool "Classic Bluetooth"
-    depends on BT_BLUEDROID_ENABLED && IDF_TARGET_ESP32
+    depends on BT_BLUEDROID_ENABLED && ((BT_CONTROLLER_ENABLED && SOC_BT_CLASSIC_SUPPORTED) || BT_CONTROLLER_DISABLED)
     default n
     default n
     help
     help
         For now this option needs "SMP_ENABLE" to be set to yes
         For now this option needs "SMP_ENABLE" to be set to yes
@@ -1116,8 +1116,9 @@ config BT_MAX_DEVICE_NAME_LEN
 
 
 config BT_BLE_RPA_SUPPORTED
 config BT_BLE_RPA_SUPPORTED
     bool "Update RPA to Controller"
     bool "Update RPA to Controller"
-    depends on BT_BLUEDROID_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED
-    default n
+    depends on (BT_BLUEDROID_ENABLED && ((BT_CONTROLLER_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED) || BT_CONTROLLER_DISABLED))
+    default n if (BT_CONTROLLER_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED)
+    default y if BT_CONTROLLER_DISABLED
     help
     help
         This enables controller RPA list function.
         This enables controller RPA list function.
         For ESP32, ESP32 only support network privacy mode. If this option is enabled, ESP32 will only accept
         For ESP32, ESP32 only support network privacy mode. If this option is enabled, ESP32 will only accept
@@ -1141,28 +1142,28 @@ config BT_BLE_RPA_TIMEOUT
 
 
 config BT_BLE_50_FEATURES_SUPPORTED
 config BT_BLE_50_FEATURES_SUPPORTED
     bool "Enable BLE 5.0 features"
     bool "Enable BLE 5.0 features"
-    depends on (BT_BLUEDROID_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || SOC_ESP_NIMBLE_CONTROLLER))
+    depends on (BT_BLUEDROID_ENABLED && ((BT_CONTROLLER_ENABLED && SOC_BLE_50_SUPPORTED) || BT_CONTROLLER_DISABLED))
     default y
     default y
     help
     help
         This enables BLE 5.0 features, this option only support esp32c3/esp32s3 chip
         This enables BLE 5.0 features, this option only support esp32c3/esp32s3 chip
 
 
 config BT_BLE_42_FEATURES_SUPPORTED
 config BT_BLE_42_FEATURES_SUPPORTED
     bool "Enable BLE 4.2 features"
     bool "Enable BLE 4.2 features"
-    depends on (BT_BLUEDROID_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || SOC_ESP_NIMBLE_CONTROLLER))
+    depends on (BT_BLUEDROID_ENABLED && ((BT_CONTROLLER_ENABLED && SOC_BLE_SUPPORTED) || BT_CONTROLLER_DISABLED))
     default n
     default n
     help
     help
         This enables BLE 4.2 features.
         This enables BLE 4.2 features.
 
 
 config BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER
 config BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER
     bool "Enable BLE periodic advertising sync transfer feature"
     bool "Enable BLE periodic advertising sync transfer feature"
-    depends on (BT_BLUEDROID_ENABLED && BT_BLE_50_FEATURES_SUPPORTED && SOC_ESP_NIMBLE_CONTROLLER)
+    depends on (BT_BLUEDROID_ENABLED && BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_ESP_NIMBLE_CONTROLLER) || BT_CONTROLLER_DISABLED))
     default n
     default n
     help
     help
         This enables BLE periodic advertising sync transfer feature
         This enables BLE periodic advertising sync transfer feature
 
 
 config BT_BLE_FEAT_PERIODIC_ADV_ENH
 config BT_BLE_FEAT_PERIODIC_ADV_ENH
     bool "Enable periodic adv enhancements(adi support)"
     bool "Enable periodic adv enhancements(adi support)"
-    depends on (BT_BLUEDROID_ENABLED && BT_BLE_50_FEATURES_SUPPORTED && SOC_ESP_NIMBLE_CONTROLLER)
+    depends on (BT_BLUEDROID_ENABLED && BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_ESP_NIMBLE_CONTROLLER) || BT_CONTROLLER_DISABLED))
     default n
     default n
     help
     help
         Enable the periodic advertising enhancements
         Enable the periodic advertising enhancements

+ 89 - 0
components/bt/host/bluedroid/api/esp_bluedroid_hci.c

@@ -0,0 +1,89 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+#include "esp_log.h"
+#include "esp_bluedroid_hci.h"
+#include "common/bt_target.h"
+#include "hci/hci_trans_int.h"
+#if (BT_CONTROLLER_INCLUDED == TRUE)
+#include "esp_bt.h"
+#endif
+
+#define LOG_TAG "HCI_API"
+
+static esp_bluedroid_hci_driver_operations_t s_hci_driver_ops = { 0 };
+
+esp_err_t esp_bluedroid_attach_hci_driver(const esp_bluedroid_hci_driver_operations_t *p_ops)
+{
+    if (!p_ops) {
+        ESP_LOGE(LOG_TAG, "%s invalid function parameter", __func__);
+        return ESP_FAIL;
+    }
+
+    s_hci_driver_ops.send                   = p_ops->send;
+    s_hci_driver_ops.check_send_available   = p_ops->check_send_available;
+    s_hci_driver_ops.register_host_callback = p_ops->register_host_callback;
+
+    return ESP_OK;
+}
+
+esp_err_t esp_bluedroid_detach_hci_driver(void)
+{
+    s_hci_driver_ops.send                   = NULL;
+    s_hci_driver_ops.check_send_available   = NULL;
+    s_hci_driver_ops.register_host_callback = NULL;
+
+    return ESP_OK;
+}
+
+/****************************************************************
+ *                         INTERNAL USE                         *
+ ****************************************************************/
+
+bool hci_host_check_send_available(void)
+{
+    bool can_send = false;
+#if (BT_CONTROLLER_INCLUDED == TRUE)
+    can_send = esp_vhci_host_check_send_available();
+#else /* BT_CONTROLLER_INCLUDED == TRUE */
+    if (s_hci_driver_ops.check_send_available) {
+        can_send = s_hci_driver_ops.check_send_available();
+    }
+#endif /* BT_CONTROLLER_INCLUDED == TRUE */
+    return can_send;
+}
+
+void hci_host_send_packet(uint8_t *data, uint16_t len)
+{
+#if (BT_CONTROLLER_INCLUDED == TRUE)
+    esp_vhci_host_send_packet(data, len);
+#else /* BT_CONTROLLER_INCLUDED == TRUE */
+    if (s_hci_driver_ops.send) {
+        s_hci_driver_ops.send(data, len);
+    }
+#endif /* BT_CONTROLLER_INCLUDED == TRUE */
+}
+
+esp_err_t hci_host_register_callback(const esp_bluedroid_hci_driver_callbacks_t *callback)
+{
+    esp_err_t ret = ESP_FAIL;
+
+    if (!callback) {
+        ESP_LOGE(LOG_TAG, "%s invalid function parameter", __func__);
+        return ESP_FAIL;
+    }
+
+#if (BT_CONTROLLER_INCLUDED == TRUE)
+    ret = esp_vhci_host_register_callback((esp_vhci_host_callback_t *)callback);
+#else /* BT_CONTROLLER_INCLUDED == TRUE */
+    if (s_hci_driver_ops.register_host_callback) {
+        ret = s_hci_driver_ops.register_host_callback(callback);
+    }
+#endif /* BT_CONTROLLER_INCLUDED == TRUE */
+
+    return ret;
+}

+ 5 - 0
components/bt/host/bluedroid/api/esp_bt_main.c

@@ -5,10 +5,13 @@
  */
  */
 
 
 
 
+#include "common/bt_target.h"
 #include "esp_bt_main.h"
 #include "esp_bt_main.h"
 #include "btc/btc_task.h"
 #include "btc/btc_task.h"
 #include "btc/btc_main.h"
 #include "btc/btc_main.h"
+#if (BT_CONTROLLER_INCLUDED == TRUE)
 #include "esp_bt.h"
 #include "esp_bt.h"
+#endif
 #include "osi/future.h"
 #include "osi/future.h"
 #include "osi/allocator.h"
 #include "osi/allocator.h"
 #include "config/stack_config.h"
 #include "config/stack_config.h"
@@ -123,10 +126,12 @@ esp_err_t esp_bluedroid_init_with_cfg(esp_bluedroid_config_t *cfg)
         return ESP_ERR_INVALID_ARG;
         return ESP_ERR_INVALID_ARG;
     }
     }
 
 
+#if (BT_CONTROLLER_INCLUDED == TRUE)
     if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
     if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
         LOG_ERROR("Controller not initialised\n");
         LOG_ERROR("Controller not initialised\n");
         return ESP_ERR_INVALID_STATE;
         return ESP_ERR_INVALID_STATE;
     }
     }
+#endif
 
 
     if (bd_already_init) {
     if (bd_already_init) {
         LOG_ERROR("Bluedroid already initialised\n");
         LOG_ERROR("Bluedroid already initialised\n");

+ 2 - 0
components/bt/host/bluedroid/api/esp_hf_ag_api.c

@@ -21,7 +21,9 @@
 #include "common/bt_target.h"
 #include "common/bt_target.h"
 #include "common/bt_defs.h"
 #include "common/bt_defs.h"
 #include "device/bdaddr.h"
 #include "device/bdaddr.h"
+#if (BT_CONTROLLER_INCLUDED == TRUE)
 #include "esp_bt.h"
 #include "esp_bt.h"
+#endif
 #include "esp_hf_ag_api.h"
 #include "esp_hf_ag_api.h"
 #include "esp_err.h"
 #include "esp_err.h"
 #include "esp_bt_main.h"
 #include "esp_bt_main.h"

+ 84 - 0
components/bt/host/bluedroid/api/include/api/esp_bluedroid_hci.h

@@ -0,0 +1,84 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __ESP_BLUEDROID_HCI_H__
+#define __ESP_BLUEDROID_HCI_H__
+
+#include <stdbool.h>
+#include "esp_err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* HCI driver callbacks */
+typedef struct esp_bluedroid_hci_driver_callbacks {
+    /**
+     * @brief callback used to notify that the host can send packet to controller
+     */
+    void (*notify_host_send_available)(void);
+
+    /**
+     * @brief callback used to notify that the controller has a packet to send to the host
+     *
+     * @param[in] data  pointer to data buffer
+     * @param[in] len   length of data
+     *
+     * @return 0 received successfully, failed otherwise
+     */
+    int (*notify_host_recv)(uint8_t *data, uint16_t len);
+} esp_bluedroid_hci_driver_callbacks_t;
+
+/* HCI driver operations */
+typedef struct esp_bluedroid_hci_driver_operations {
+    /**
+     * @brief send data from host to controller
+     *
+     * @param[in] data  pointer to data buffer
+     * @param[in] len   length of data
+     */
+    void (*send)(uint8_t *data, uint16_t len);
+
+    /**
+     * @brief host checks whether it can send data to controller
+     *
+     * @return true if host can send data, false otherwise
+     */
+    bool (*check_send_available)(void);
+
+    /**
+     * @brief register host callback
+     *
+     * @param[in] callback  HCI driver callbacks
+     */
+    esp_err_t (* register_host_callback)(const esp_bluedroid_hci_driver_callbacks_t *callback);
+} esp_bluedroid_hci_driver_operations_t;
+
+/**
+ * @brief get the operations of HCI transport layer. This API should only be used in
+ *        Bluedroid Host-only mode before Bluedroid initialization.
+ *
+ * @param[in] ops struct containing operations of HCI transport layer
+ *
+ * @return ESP_OK if get successfully, ESP_FAIL otherwise
+ */
+esp_err_t esp_bluedroid_attach_hci_driver(const esp_bluedroid_hci_driver_operations_t *ops);
+
+/**
+ * @brief remove the operations of HCI transport layer. This API should only be used in
+ *        Bluedroid Host-only mode before Bluedroid initialization.
+ *
+ * @param[in] ops struct containing operations of HCI transport layer
+ *
+ * @return ESP_OK if get successfully, ESP_FAIL otherwise
+ */
+esp_err_t esp_bluedroid_detach_hci_driver(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ESP_BLUEDROID_HCI_H__ */

+ 11 - 2
components/bt/host/bluedroid/bta/dm/bta_dm_act.c

@@ -46,6 +46,9 @@
 #if (GAP_INCLUDED == TRUE)
 #if (GAP_INCLUDED == TRUE)
 #include "stack/gap_api.h"
 #include "stack/gap_api.h"
 #endif
 #endif
+#if (BT_CONTROLLER_INCLUDED == TRUE)
+#include "esp_bt.h"
+#endif
 
 
 static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir);
 static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir);
 static void bta_dm_inq_cmpl_cb (void *p_result);
 static void bta_dm_inq_cmpl_cb (void *p_result);
@@ -136,7 +139,6 @@ static void bta_dm_observe_discard_cb (uint32_t num_dis);
 static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle);
 static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle);
 extern void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8 *p_uuid128);
 extern void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8 *p_uuid128);
 static void bta_dm_disable_timer_cback(TIMER_LIST_ENT *p_tle);
 static void bta_dm_disable_timer_cback(TIMER_LIST_ENT *p_tle);
-extern int bredr_txpwr_get(int *min_power_level, int *max_power_level);
 
 
 const UINT16 bta_service_id_to_uuid_lkup_tbl [BTA_MAX_SERVICE_ID] = {
 const UINT16 bta_service_id_to_uuid_lkup_tbl [BTA_MAX_SERVICE_ID] = {
     UUID_SERVCLASS_PNP_INFORMATION,         /* Reserved */
     UUID_SERVCLASS_PNP_INFORMATION,         /* Reserved */
@@ -4313,7 +4315,14 @@ static void bta_dm_set_eir (char *local_name)
     if (p_bta_dm_eir_cfg->bta_dm_eir_included_tx_power) {
     if (p_bta_dm_eir_cfg->bta_dm_eir_included_tx_power) {
         if (free_eir_length >= 3) {
         if (free_eir_length >= 3) {
             int min_power_level, max_power_level;
             int min_power_level, max_power_level;
-            if (bredr_txpwr_get(&min_power_level, &max_power_level) == 0) {
+#if (BT_CONTROLLER_INCLUDED == TRUE)
+            if (esp_bredr_tx_power_get((esp_power_level_t *)&min_power_level, (esp_power_level_t *)&max_power_level) == ESP_OK) {
+#else
+            {
+                min_power_level = 0;
+                max_power_level = 0;
+                UNUSED(min_power_level);
+#endif
                 INT8 btm_tx_power[BTM_TX_POWER_LEVEL_MAX + 1] = BTM_TX_POWER;
                 INT8 btm_tx_power[BTM_TX_POWER_LEVEL_MAX + 1] = BTM_TX_POWER;
                 p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power = btm_tx_power[max_power_level];
                 p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power = btm_tx_power[max_power_level];
                 UINT8_TO_STREAM(p, 2);      /* Length field */
                 UINT8_TO_STREAM(p, 2);      /* Length field */

+ 7 - 0
components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c

@@ -9,6 +9,7 @@
 #include "osi/allocator.h"
 #include "osi/allocator.h"
 #include "stack/bt_types.h"
 #include "stack/bt_types.h"
 #include "common/bt_defs.h"
 #include "common/bt_defs.h"
+#include "common/bt_target.h"
 #include "bta/bta_api.h"
 #include "bta/bta_api.h"
 #include "bta/bta_dm_co.h"
 #include "bta/bta_dm_co.h"
 #include "btc/btc_task.h"
 #include "btc/btc_task.h"
@@ -23,7 +24,9 @@
 #include "osi/mutex.h"
 #include "osi/mutex.h"
 #include "osi/thread.h"
 #include "osi/thread.h"
 #include "osi/pkt_queue.h"
 #include "osi/pkt_queue.h"
+#if (BT_CONTROLLER_INCLUDED == TRUE)
 #include "esp_bt.h"
 #include "esp_bt.h"
+#endif
 
 
 #if (BLE_INCLUDED == TRUE)
 #if (BLE_INCLUDED == TRUE)
 #if (BLE_42_FEATURE_SUPPORT == TRUE)
 #if (BLE_42_FEATURE_SUPPORT == TRUE)
@@ -187,7 +190,11 @@ static void btc_to_bta_adv_data(esp_ble_adv_data_t *p_adv_data, tBTA_BLE_ADV_DAT
 
 
     if (p_adv_data->include_txpower) {
     if (p_adv_data->include_txpower) {
         mask |= BTM_BLE_AD_BIT_TX_PWR;
         mask |= BTM_BLE_AD_BIT_TX_PWR;
+#if (BT_CONTROLLER_INCLUDED == TRUE)
         bta_adv_data->tx_power = esp_ble_tx_power_get(ESP_BLE_PWR_TYPE_ADV);
         bta_adv_data->tx_power = esp_ble_tx_power_get(ESP_BLE_PWR_TYPE_ADV);
+#else
+        bta_adv_data->tx_power = 0;
+#endif
     }
     }
 
 
     if (p_adv_data->min_interval > 0 && p_adv_data->max_interval > 0 &&
     if (p_adv_data->min_interval > 0 && p_adv_data->max_interval > 0 &&

+ 4 - 0
components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c

@@ -29,7 +29,9 @@
 #include "common/bt_trace.h"
 #include "common/bt_trace.h"
 #include "common/bt_defs.h"
 #include "common/bt_defs.h"
 #include "device/bdaddr.h"
 #include "device/bdaddr.h"
+#if (BT_CONTROLLER_INCLUDED == TRUE)
 #include "esp_bt.h"
 #include "esp_bt.h"
+#endif
 #include "esp_hf_ag_api.h"
 #include "esp_hf_ag_api.h"
 #include "osi/allocator.h"
 #include "osi/allocator.h"
 
 
@@ -328,12 +330,14 @@ bt_status_t btc_hf_init(void)
     // custom initialization here
     // custom initialization here
     hf_local_param[idx].btc_hf_cb.initialized = true;
     hf_local_param[idx].btc_hf_cb.initialized = true;
 // set audio path
 // set audio path
+#if (BT_CONTROLLER_INCLUDED == TRUE)
 #if BTM_SCO_HCI_INCLUDED
 #if BTM_SCO_HCI_INCLUDED
     uint8_t data_path = ESP_SCO_DATA_PATH_HCI;
     uint8_t data_path = ESP_SCO_DATA_PATH_HCI;
 #else
 #else
     uint8_t data_path = ESP_SCO_DATA_PATH_PCM;
     uint8_t data_path = ESP_SCO_DATA_PATH_PCM;
 #endif
 #endif
     esp_bredr_sco_datapath_set(data_path);
     esp_bredr_sco_datapath_set(data_path);
+#endif
     return BT_STATUS_SUCCESS;
     return BT_STATUS_SUCCESS;
 }
 }
 
 

+ 6 - 3
components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c

@@ -25,7 +25,9 @@
 #include "btc/btc_util.h"
 #include "btc/btc_util.h"
 #include "esp_hf_client_api.h"
 #include "esp_hf_client_api.h"
 #include "bta/bta_hf_client_api.h"
 #include "bta/bta_hf_client_api.h"
+#if (BT_CONTROLLER_INCLUDED == TRUE)
 #include "esp_bt.h"
 #include "esp_bt.h"
+#endif
 #include <assert.h>
 #include <assert.h>
 
 
 #if BT_HF_CLIENT_BQB_INCLUDED
 #if BT_HF_CLIENT_BQB_INCLUDED
@@ -167,19 +169,20 @@ bt_status_t btc_hf_client_init(void)
 {
 {
     BTC_TRACE_EVENT("%s", __FUNCTION__);
     BTC_TRACE_EVENT("%s", __FUNCTION__);
 
 
-    uint8_t data_path;
     btc_dm_enable_service(BTA_HFP_HS_SERVICE_ID);
     btc_dm_enable_service(BTA_HFP_HS_SERVICE_ID);
 
 
     clear_state();
     clear_state();
 
 
     hf_client_local_param.btc_hf_client_cb.initialized = true;
     hf_client_local_param.btc_hf_client_cb.initialized = true;
 
 
+#if (BT_CONTROLLER_INCLUDED == TRUE)
 #if BTM_SCO_HCI_INCLUDED
 #if BTM_SCO_HCI_INCLUDED
-    data_path = ESP_SCO_DATA_PATH_HCI;
+    uint8_t data_path = ESP_SCO_DATA_PATH_HCI;
 #else
 #else
-    data_path = ESP_SCO_DATA_PATH_PCM;
+    uint8_t data_path = ESP_SCO_DATA_PATH_PCM;
 #endif
 #endif
     esp_bredr_sco_datapath_set(data_path);
     esp_bredr_sco_datapath_set(data_path);
+#endif
     return BT_STATUS_SUCCESS;
     return BT_STATUS_SUCCESS;
 }
 }
 
 

+ 1 - 1
components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h

@@ -105,7 +105,7 @@
 #ifdef CONFIG_BT_BLE_RPA_SUPPORTED
 #ifdef CONFIG_BT_BLE_RPA_SUPPORTED
 #define UC_BT_BLE_RPA_SUPPORTED            CONFIG_BT_BLE_RPA_SUPPORTED
 #define UC_BT_BLE_RPA_SUPPORTED            CONFIG_BT_BLE_RPA_SUPPORTED
 #else
 #else
-#if SOC_BLE_DEVICE_PRIVACY_SUPPORTED
+#if (CONFIG_BT_CONTROLLER_ENABLED && SOC_BLE_DEVICE_PRIVACY_SUPPORTED)
 #define UC_BT_BLE_RPA_SUPPORTED            TRUE
 #define UC_BT_BLE_RPA_SUPPORTED            TRUE
 #else
 #else
 #define UC_BT_BLE_RPA_SUPPORTED            FALSE
 #define UC_BT_BLE_RPA_SUPPORTED            FALSE

+ 6 - 0
components/bt/host/bluedroid/common/include/common/bt_target.h

@@ -51,6 +51,12 @@
 #define ESP_COEX_VSC_INCLUDED        FALSE
 #define ESP_COEX_VSC_INCLUDED        FALSE
 #endif
 #endif
 
 
+#if (UC_BT_CONTROLLER_INCLUDED == TRUE)
+#define BT_CONTROLLER_INCLUDED       TRUE
+#else
+#define BT_CONTROLLER_INCLUDED       FALSE
+#endif
+
 /******************************************************************************
 /******************************************************************************
 **
 **
 ** Classic BT features
 ** Classic BT features

+ 10 - 6
components/bt/host/bluedroid/hci/hci_hal_h4.c

@@ -22,16 +22,20 @@
 #include "hci/hci_hal.h"
 #include "hci/hci_hal.h"
 #include "hci/hci_internals.h"
 #include "hci/hci_internals.h"
 #include "hci/hci_layer.h"
 #include "hci/hci_layer.h"
+#include "hci/hci_trans_int.h"
 #include "osi/thread.h"
 #include "osi/thread.h"
 #include "osi/pkt_queue.h"
 #include "osi/pkt_queue.h"
 #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
 #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
 #include "osi/mutex.h"
 #include "osi/mutex.h"
 #include "osi/alarm.h"
 #include "osi/alarm.h"
 #endif
 #endif
+#if (BT_CONTROLLER_INCLUDED == TRUE)
 #include "esp_bt.h"
 #include "esp_bt.h"
+#endif
+#include "esp_bluedroid_hci.h"
 #include "stack/hcimsgs.h"
 #include "stack/hcimsgs.h"
 
 
-#if SOC_ESP_NIMBLE_CONTROLLER
+#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER)
 #include "nimble/ble_hci_trans.h"
 #include "nimble/ble_hci_trans.h"
 #endif
 #endif
 
 
@@ -87,7 +91,7 @@ typedef struct {
 
 
 static hci_hal_env_t hci_hal_env;
 static hci_hal_env_t hci_hal_env;
 static const hci_hal_t interface;
 static const hci_hal_t interface;
-static const esp_vhci_host_callback_t vhci_host_cb;
+static const esp_bluedroid_hci_driver_callbacks_t hci_host_cb;
 
 
 static void host_send_pkt_available_cb(void);
 static void host_send_pkt_available_cb(void);
 static int host_recv_pkt_cb(uint8_t *data, uint16_t len);
 static int host_recv_pkt_cb(uint8_t *data, uint16_t len);
@@ -167,7 +171,7 @@ static bool hal_open(const hci_hal_callbacks_t *upper_callbacks, void *task_thre
     hci_hal_env_init(upper_callbacks, (osi_thread_t *)task_thread);
     hci_hal_env_init(upper_callbacks, (osi_thread_t *)task_thread);
 
 
     //register vhci host cb
     //register vhci host cb
-    if (esp_vhci_host_register_callback(&vhci_host_cb) != ESP_OK) {
+    if (hci_host_register_callback(&hci_host_cb) != ESP_OK) {
         return false;
         return false;
     }
     }
 
 
@@ -207,7 +211,7 @@ static uint16_t transmit_data(serial_data_type_t type,
     BTTRC_DUMP_BUFFER("Transmit Pkt", data, length);
     BTTRC_DUMP_BUFFER("Transmit Pkt", data, length);
 
 
     // TX Data to target
     // TX Data to target
-    esp_vhci_host_send_packet(data, length);
+    hci_host_send_packet(data, length);
 
 
     // Be nice and restore the old value of that byte
     // Be nice and restore the old value of that byte
     *(data) = previous_byte;
     *(data) = previous_byte;
@@ -590,7 +594,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
 
 
     return 0;
     return 0;
 }
 }
-#if SOC_ESP_NIMBLE_CONTROLLER
+#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER)
 
 
 int
 int
 ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg)
 ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg)
@@ -625,7 +629,7 @@ ble_hs_rx_data(struct os_mbuf *om, void *arg)
 }
 }
 
 
 #endif
 #endif
-static const esp_vhci_host_callback_t vhci_host_cb = {
+static const esp_bluedroid_hci_driver_callbacks_t hci_host_cb = {
     .notify_host_send_available = host_send_pkt_available_cb,
     .notify_host_send_available = host_send_pkt_available_cb,
     .notify_host_recv = host_recv_pkt_cb,
     .notify_host_recv = host_recv_pkt_cb,
 };
 };

+ 5 - 1
components/bt/host/bluedroid/hci/hci_layer.c

@@ -17,7 +17,10 @@
  ******************************************************************************/
  ******************************************************************************/
 #include <string.h>
 #include <string.h>
 #include "sdkconfig.h"
 #include "sdkconfig.h"
+#include "common/bt_target.h"
+#if (BT_CONTROLLER_INCLUDED == TRUE)
 #include "esp_bt.h"
 #include "esp_bt.h"
+#endif
 
 
 #include "common/bt_defs.h"
 #include "common/bt_defs.h"
 #include "common/bt_trace.h"
 #include "common/bt_trace.h"
@@ -28,6 +31,7 @@
 #include "hci/hci_internals.h"
 #include "hci/hci_internals.h"
 #include "hci/hci_hal.h"
 #include "hci/hci_hal.h"
 #include "hci/hci_layer.h"
 #include "hci/hci_layer.h"
+#include "hci/hci_trans_int.h"
 #include "osi/allocator.h"
 #include "osi/allocator.h"
 #include "hci/packet_fragmenter.h"
 #include "hci/packet_fragmenter.h"
 #include "osi/list.h"
 #include "osi/list.h"
@@ -226,7 +230,7 @@ static void hci_downstream_data_handler(void *arg)
      * All packets will be directly copied to single queue in driver layer with
      * All packets will be directly copied to single queue in driver layer with
      * H4 type header added (1 byte).
      * H4 type header added (1 byte).
      */
      */
-    while (esp_vhci_host_check_send_available()) {
+    while (hci_host_check_send_available()) {
         /*Now Target only allowed one packet per TX*/
         /*Now Target only allowed one packet per TX*/
         BT_HDR *pkt = packet_fragmenter->fragment_current_packet();
         BT_HDR *pkt = packet_fragmenter->fragment_current_packet();
         if (pkt != NULL) {
         if (pkt != NULL) {

+ 3 - 2
components/bt/host/bluedroid/hci/include/hci/hci_hal.h

@@ -21,9 +21,10 @@
 
 
 #include <stdbool.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdint.h>
+#include "common/bt_target.h"
 #include "osi/pkt_queue.h"
 #include "osi/pkt_queue.h"
 #include "stack/bt_types.h"
 #include "stack/bt_types.h"
-#if SOC_ESP_NIMBLE_CONTROLLER
+#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER)
 #include "os/os_mbuf.h"
 #include "os/os_mbuf.h"
 #endif
 #endif
 typedef enum {
 typedef enum {
@@ -85,7 +86,7 @@ typedef struct hci_hal_t {
 
 
 // Gets the correct hal implementation, as compiled for.
 // Gets the correct hal implementation, as compiled for.
 const hci_hal_t *hci_hal_h4_get_interface(void);
 const hci_hal_t *hci_hal_h4_get_interface(void);
-#if SOC_ESP_NIMBLE_CONTROLLER
+#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER)
 int ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg);
 int ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg);
 
 
 int ble_hs_rx_data(struct os_mbuf *om, void *arg);
 int ble_hs_rx_data(struct os_mbuf *om, void *arg);

+ 47 - 0
components/bt/host/bluedroid/hci/include/hci/hci_trans_int.h

@@ -0,0 +1,47 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __HCI_TRANS_INT_H__
+#define __HCI_TRANS_INT_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "esp_err.h"
+#include "esp_bluedroid_hci.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief host checks whether it can send data to controller
+ *
+ * @return true if host can send data, false otherwise
+ */
+bool hci_host_check_send_available(void);
+
+/**
+ * @brief host sends packet to controller
+ *
+ * @param[in] data pointer to data buffer
+ * @param[in] len  length of data in byte
+ */
+void hci_host_send_packet(uint8_t *data, uint16_t len);
+
+/**
+ * @brief register the HCI function interface
+ *
+ * @param[in] callback HCI function interface
+ *
+ * @return ESP_OK register successfully, ESP_FAIL otherwise
+ */
+esp_err_t hci_host_register_callback(const esp_bluedroid_hci_driver_callbacks_t *callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HCI_TRANS_INT_H__ */

+ 0 - 1
components/bt/test_apps/main/test_smp.c

@@ -15,7 +15,6 @@
 #include "unity.h"
 #include "unity.h"
 #include "esp_random.h"
 #include "esp_random.h"
 
 
-#include "esp_bt.h"
 #include "esp_bt_main.h"
 #include "esp_bt_main.h"
 #include "esp_bt_device.h"
 #include "esp_bt_device.h"
 #include "esp_gap_ble_api.h"
 #include "esp_gap_ble_api.h"

+ 0 - 1
components/esp_hid/src/ble_hidd.c

@@ -12,7 +12,6 @@
 
 
 #include "esp_hidd_private.h"
 #include "esp_hidd_private.h"
 #include "esp_log.h"
 #include "esp_log.h"
-#include "esp_bt.h"
 #include "esp_bt_main.h"
 #include "esp_bt_main.h"
 #include "esp_bt_defs.h"
 #include "esp_bt_defs.h"
 #include "esp_gatts_api.h"
 #include "esp_gatts_api.h"

+ 0 - 1
components/esp_hid/src/ble_hidh.c

@@ -11,7 +11,6 @@
 #include "esp_err.h"
 #include "esp_err.h"
 #include "esp_log.h"
 #include "esp_log.h"
 
 
-#include "esp_bt.h"
 #include "esp_bt_defs.h"
 #include "esp_bt_defs.h"
 #include "esp_bt_main.h"
 #include "esp_bt_main.h"
 #include "esp_gattc_api.h"
 #include "esp_gattc_api.h"

+ 0 - 1
components/esp_hid/src/bt_hidd.c

@@ -6,7 +6,6 @@
 #include "bt_hidd.h"
 #include "bt_hidd.h"
 
 
 #if CONFIG_BT_HID_DEVICE_ENABLED
 #if CONFIG_BT_HID_DEVICE_ENABLED
-#include "esp_bt.h"
 #include "esp_bt_defs.h"
 #include "esp_bt_defs.h"
 #include "esp_bt_main.h"
 #include "esp_bt_main.h"
 #include "esp_hidd.h"
 #include "esp_hidd.h"

+ 7 - 2
components/protocomm/src/simple_ble/simple_ble.c

@@ -1,5 +1,5 @@
 /*
 /*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  *
  * SPDX-License-Identifier: Apache-2.0
  * SPDX-License-Identifier: Apache-2.0
  */
  */
@@ -8,7 +8,9 @@
 #include <freertos/FreeRTOS.h>
 #include <freertos/FreeRTOS.h>
 #include <esp_system.h>
 #include <esp_system.h>
 #include <esp_log.h>
 #include <esp_log.h>
+#ifdef CONFIG_BT_CONTROLLER_ENABLED
 #include "esp_bt.h"
 #include "esp_bt.h"
+#endif
 #include <esp_gap_ble_api.h>
 #include <esp_gap_ble_api.h>
 #include <esp_gatts_api.h>
 #include <esp_gatts_api.h>
 #include <esp_bt_main.h>
 #include <esp_bt_main.h>
@@ -213,6 +215,7 @@ esp_err_t simple_ble_start(simple_ble_cfg_t *cfg)
     ESP_LOGD(TAG, "Free mem at start of simple_ble_init %" PRIu32, esp_get_free_heap_size());
     ESP_LOGD(TAG, "Free mem at start of simple_ble_init %" PRIu32, esp_get_free_heap_size());
     esp_err_t ret;
     esp_err_t ret;
 
 
+#ifdef CONFIG_BT_CONTROLLER_ENABLED
     esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
     esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
     ret = esp_bt_controller_init(&bt_cfg);
     ret = esp_bt_controller_init(&bt_cfg);
     if (ret) {
     if (ret) {
@@ -232,6 +235,7 @@ esp_err_t simple_ble_start(simple_ble_cfg_t *cfg)
         ESP_LOGE(TAG, "%s enable controller failed %d", __func__, ret);
         ESP_LOGE(TAG, "%s enable controller failed %d", __func__, ret);
         return ret;
         return ret;
     }
     }
+#endif
 
 
     esp_bluedroid_config_t bluedroid_cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT();
     esp_bluedroid_config_t bluedroid_cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT();
     ret = esp_bluedroid_init_with_cfg(&bluedroid_cfg);
     ret = esp_bluedroid_init_with_cfg(&bluedroid_cfg);
@@ -307,6 +311,7 @@ esp_err_t simple_ble_stop(void)
         return err;
         return err;
     }
     }
     ESP_LOGD(TAG, "esp_bluedroid_deinit called successfully");
     ESP_LOGD(TAG, "esp_bluedroid_deinit called successfully");
+#ifdef CONFIG_BT_CONTROLLER_ENABLED
     err = esp_bt_controller_disable();
     err = esp_bt_controller_disable();
     if (err != ESP_OK) {
     if (err != ESP_OK) {
         return ESP_FAIL;
         return ESP_FAIL;
@@ -321,7 +326,7 @@ esp_err_t simple_ble_stop(void)
         return ESP_FAIL;
         return ESP_FAIL;
     }
     }
     ESP_LOGD(TAG, "esp_bt_controller_deinit called successfully");
     ESP_LOGD(TAG, "esp_bt_controller_deinit called successfully");
-
+#endif
     ESP_LOGD(TAG, "Free mem at end of simple_ble_stop %" PRIu32, esp_get_free_heap_size());
     ESP_LOGD(TAG, "Free mem at end of simple_ble_stop %" PRIu32, esp_get_free_heap_size());
     return ESP_OK;
     return ESP_OK;
 }
 }

+ 1 - 0
components/soc/esp32p4/include/soc/soc.h

@@ -142,6 +142,7 @@
 #define  CPU_CLK_FREQ_MHZ_BTLD                       (80)               // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
 #define  CPU_CLK_FREQ_MHZ_BTLD                       (80)               // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
 #define  CPU_CLK_FREQ                                APB_CLK_FREQ
 #define  CPU_CLK_FREQ                                APB_CLK_FREQ
 #define  APB_CLK_FREQ                                ( 40*1000000 )
 #define  APB_CLK_FREQ                                ( 40*1000000 )
+#define  MODEM_REQUIRED_MIN_APB_CLK_FREQ             ( 80*1000000 )
 #define  REF_CLK_FREQ                                ( 1000000 )
 #define  REF_CLK_FREQ                                ( 1000000 )
 #define  XTAL_CLK_FREQ                               (40*1000000)
 #define  XTAL_CLK_FREQ                               (40*1000000)
 #define  GPIO_MATRIX_DELAY_NS                        0
 #define  GPIO_MATRIX_DELAY_NS                        0

+ 14 - 4
components/wifi_provisioning/src/scheme_ble.c

@@ -1,5 +1,5 @@
 /*
 /*
- * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
  *
  *
  * SPDX-License-Identifier: Apache-2.0
  * SPDX-License-Identifier: Apache-2.0
  */
  */
@@ -7,7 +7,9 @@
 #include <string.h>
 #include <string.h>
 #include <esp_log.h>
 #include <esp_log.h>
 #include <esp_err.h>
 #include <esp_err.h>
+#ifdef CONFIG_BT_CONTROLLER_ENABLED
 #include "esp_bt.h"
 #include "esp_bt.h"
+#endif
 
 
 #include <protocomm.h>
 #include <protocomm.h>
 #include <protocomm_ble.h>
 #include <protocomm_ble.h>
@@ -197,9 +199,10 @@ static esp_err_t set_config_endpoint(void *config, const char *endpoint_name, ui
 /* Used when both BT and BLE are not needed by application */
 /* Used when both BT and BLE are not needed by application */
 void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event_t event, void *event_data)
 void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event_t event, void *event_data)
 {
 {
-    esp_err_t err;
     switch (event) {
     switch (event) {
         case WIFI_PROV_INIT:
         case WIFI_PROV_INIT:
+#ifdef CONFIG_BT_CONTROLLER_ENABLED
+            esp_err_t err;
             /* Release BT memory, as we need only BLE */
             /* Release BT memory, as we need only BLE */
             err = esp_bt_mem_release(ESP_BT_MODE_CLASSIC_BT);
             err = esp_bt_mem_release(ESP_BT_MODE_CLASSIC_BT);
             if (err != ESP_OK) {
             if (err != ESP_OK) {
@@ -207,10 +210,12 @@ void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event
             } else {
             } else {
                 ESP_LOGI(TAG, "BT memory released");
                 ESP_LOGI(TAG, "BT memory released");
             }
             }
+#endif
             break;
             break;
 
 
         case WIFI_PROV_DEINIT:
         case WIFI_PROV_DEINIT:
 #ifndef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
 #ifndef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
+#ifdef CONFIG_BT_CONTROLLER_ENABLED
             /* Release memory used by BLE and Bluedroid host stack */
             /* Release memory used by BLE and Bluedroid host stack */
             err = esp_bt_mem_release(ESP_BT_MODE_BTDM);
             err = esp_bt_mem_release(ESP_BT_MODE_BTDM);
             if (err != ESP_OK) {
             if (err != ESP_OK) {
@@ -218,6 +223,7 @@ void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event
             } else {
             } else {
                 ESP_LOGI(TAG, "BTDM memory released");
                 ESP_LOGI(TAG, "BTDM memory released");
             }
             }
+#endif
 #endif
 #endif
             break;
             break;
 
 
@@ -229,9 +235,10 @@ void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event
 /* Used when BT is not needed by application */
 /* Used when BT is not needed by application */
 void wifi_prov_scheme_ble_event_cb_free_bt(void *user_data, wifi_prov_cb_event_t event, void *event_data)
 void wifi_prov_scheme_ble_event_cb_free_bt(void *user_data, wifi_prov_cb_event_t event, void *event_data)
 {
 {
-    esp_err_t err;
     switch (event) {
     switch (event) {
         case WIFI_PROV_INIT:
         case WIFI_PROV_INIT:
+#ifdef CONFIG_BT_CONTROLLER_ENABLED
+            esp_err_t err;
             /* Release BT memory, as we need only BLE */
             /* Release BT memory, as we need only BLE */
             err = esp_bt_mem_release(ESP_BT_MODE_CLASSIC_BT);
             err = esp_bt_mem_release(ESP_BT_MODE_CLASSIC_BT);
             if (err != ESP_OK) {
             if (err != ESP_OK) {
@@ -239,6 +246,7 @@ void wifi_prov_scheme_ble_event_cb_free_bt(void *user_data, wifi_prov_cb_event_t
             } else {
             } else {
                 ESP_LOGI(TAG, "BT memory released");
                 ESP_LOGI(TAG, "BT memory released");
             }
             }
+#endif
             break;
             break;
 
 
         default:
         default:
@@ -249,10 +257,11 @@ void wifi_prov_scheme_ble_event_cb_free_bt(void *user_data, wifi_prov_cb_event_t
 /* Used when BLE is not needed by application */
 /* Used when BLE is not needed by application */
 void wifi_prov_scheme_ble_event_cb_free_ble(void *user_data, wifi_prov_cb_event_t event, void *event_data)
 void wifi_prov_scheme_ble_event_cb_free_ble(void *user_data, wifi_prov_cb_event_t event, void *event_data)
 {
 {
-    esp_err_t err;
     switch (event) {
     switch (event) {
         case WIFI_PROV_DEINIT:
         case WIFI_PROV_DEINIT:
 #ifndef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
 #ifndef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
+#ifdef CONFIG_BT_CONTROLLER_ENABLED
+            esp_err_t err;
             /* Release memory used by BLE stack */
             /* Release memory used by BLE stack */
             err = esp_bt_mem_release(ESP_BT_MODE_BLE);
             err = esp_bt_mem_release(ESP_BT_MODE_BLE);
             if (err != ESP_OK) {
             if (err != ESP_OK) {
@@ -260,6 +269,7 @@ void wifi_prov_scheme_ble_event_cb_free_ble(void *user_data, wifi_prov_cb_event_
             } else {
             } else {
                 ESP_LOGI(TAG, "BLE memory released");
                 ESP_LOGI(TAG, "BLE memory released");
             }
             }
+#endif
 #endif
 #endif
             break;
             break;
 
 

+ 6 - 0
examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/CMakeLists.txt

@@ -0,0 +1,6 @@
+# The following lines of boilerplate have to be in your project's CMakeLists
+# in this exact order for cmake to work correctly
+cmake_minimum_required(VERSION 3.16)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(host_hci_uart)

+ 85 - 0
examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/README.md

@@ -0,0 +1,85 @@
+| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 |
+| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
+
+ESP-IDF UART HCI Host
+=====================
+
+This is a Bluetooth Host use UART as HCI IO. This require the UART device support RTS/CTS mandatory.
+
+It can do the configuration of UART baudrate by menuconfig.
+
+## Example Layout
+
+This example is modified based on [bt_discovery](../../classic_bt/bt_discovery), and all modifications are listed below:
+
+- Removed all dependencies on controller from `main.c`.
+
+```
+#include "esp_bt.h"
+
+...
+
+ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE));
+
+esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
+if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
+    ESP_LOGE(GAP_TAG, "%s initialize controller failed: %s", __func__, esp_err_to_name(ret));
+    return;
+}
+
+if ((ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) {
+    ESP_LOGE(GAP_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
+    return;
+}
+```
+
+- Add support for uart driver: `uart_driver.c` and `uart_driver.h`.
+
+- Initialize UART driver in `main.c`.
+
+```
+#include "esp_hci_api.h"
+#include "uart_driver.h"
+
+...
+
+/* initialize HCI TRANSPORT first */
+hci_uart_open();
+/* get HCI driver operations */
+esp_bluedroid_hci_driver_operations_t operations = {
+    .send = hci_uart_send,
+    .check_send_available = hci_check_send_available,
+    .register_host_callback = hci_register_host_callback,
+};
+esp_bluedroid_attach_hci_driver(&operations);
+```
+
+## How to use example
+
+### Hardware Required
+
+This example should be able to run on any commonly available ESP development board. To connect UART to another board running a Bluetooth controller. For example, [controller_hci_uart_esp32](../../../hci/controller_hci_uart_esp32).
+
+### Configure the project
+
+```
+idf.py menuconfig
+```
+
+- UART baudrate can be configured in `Example Configuration > UART Baudrate for HCI`
+
+### Build and Flash
+
+Build the project and flash it to the board, then run monitor tool to view serial output:
+
+```
+idf.py -p PORT flash monitor
+```
+
+(Replace PORT with the name of the serial port to use.)
+
+(To exit the serial monitor, type ``Ctrl-]``.)
+
+See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
+
+## Troubleshooting

+ 3 - 0
examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/CMakeLists.txt

@@ -0,0 +1,3 @@
+idf_component_register(SRCS "main.c"
+                            "uart_driver.c"
+                    INCLUDE_DIRS ".")

+ 8 - 0
examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/Kconfig.projbuild

@@ -0,0 +1,8 @@
+menu "Example Configuration"
+    config EXAMPLE_HCI_UART_BAUDRATE
+        int "UART Baudrate for HCI"
+        range 115200 921600
+        default 921600
+        help
+            UART Baudrate for HCI. Please use standard baudrate.
+endmenu

+ 306 - 0
examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/main.c

@@ -0,0 +1,306 @@
+/*
+ * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Unlicense OR CC0-1.0
+ */
+
+
+
+/****************************************************************************
+*
+* This file is for Classic Bluetooth device and service discovery Demo.
+*
+****************************************************************************/
+
+#include <stdint.h>
+#include <string.h>
+#include <inttypes.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "nvs.h"
+#include "nvs_flash.h"
+#include "esp_system.h"
+#include "esp_log.h"
+#include "esp_bt_main.h"
+#include "esp_bt_device.h"
+#include "esp_gap_bt_api.h"
+#include "esp_bluedroid_hci.h"
+#include "uart_driver.h"
+
+#define GAP_TAG          "GAP"
+
+typedef enum {
+    APP_GAP_STATE_IDLE = 0,
+    APP_GAP_STATE_DEVICE_DISCOVERING,
+    APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE,
+    APP_GAP_STATE_SERVICE_DISCOVERING,
+    APP_GAP_STATE_SERVICE_DISCOVER_COMPLETE,
+} app_gap_state_t;
+
+typedef struct {
+    bool dev_found;
+    uint8_t bdname_len;
+    uint8_t eir_len;
+    uint8_t rssi;
+    uint32_t cod;
+    uint8_t eir[ESP_BT_GAP_EIR_DATA_LEN];
+    uint8_t bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
+    esp_bd_addr_t bda;
+    app_gap_state_t state;
+} app_gap_cb_t;
+
+static app_gap_cb_t m_dev_info;
+
+static char *bda2str(esp_bd_addr_t bda, char *str, size_t size)
+{
+    if (bda == NULL || str == NULL || size < 18) {
+        return NULL;
+    }
+
+    uint8_t *p = bda;
+    sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
+            p[0], p[1], p[2], p[3], p[4], p[5]);
+    return str;
+}
+
+static char *uuid2str(esp_bt_uuid_t *uuid, char *str, size_t size)
+{
+    if (uuid == NULL || str == NULL) {
+        return NULL;
+    }
+
+    if (uuid->len == 2 && size >= 5) {
+        sprintf(str, "%04x", uuid->uuid.uuid16);
+    } else if (uuid->len == 4 && size >= 9) {
+        sprintf(str, "%08"PRIx32, uuid->uuid.uuid32);
+    } else if (uuid->len == 16 && size >= 37) {
+        uint8_t *p = uuid->uuid.uuid128;
+        sprintf(str, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+                p[15], p[14], p[13], p[12], p[11], p[10], p[9], p[8],
+                p[7], p[6], p[5], p[4], p[3], p[2], p[1], p[0]);
+    } else {
+        return NULL;
+    }
+
+    return str;
+}
+
+static bool get_name_from_eir(uint8_t *eir, uint8_t *bdname, uint8_t *bdname_len)
+{
+    uint8_t *rmt_bdname = NULL;
+    uint8_t rmt_bdname_len = 0;
+
+    if (!eir) {
+        return false;
+    }
+
+    rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &rmt_bdname_len);
+    if (!rmt_bdname) {
+        rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &rmt_bdname_len);
+    }
+
+    if (rmt_bdname) {
+        if (rmt_bdname_len > ESP_BT_GAP_MAX_BDNAME_LEN) {
+            rmt_bdname_len = ESP_BT_GAP_MAX_BDNAME_LEN;
+        }
+
+        if (bdname) {
+            memcpy(bdname, rmt_bdname, rmt_bdname_len);
+            bdname[rmt_bdname_len] = '\0';
+        }
+        if (bdname_len) {
+            *bdname_len = rmt_bdname_len;
+        }
+        return true;
+    }
+
+    return false;
+}
+
+static void update_device_info(esp_bt_gap_cb_param_t *param)
+{
+    char bda_str[18];
+    uint32_t cod = 0;
+    int32_t rssi = -129; /* invalid value */
+    uint8_t *bdname = NULL;
+    uint8_t bdname_len = 0;
+    uint8_t *eir = NULL;
+    uint8_t eir_len = 0;
+    esp_bt_gap_dev_prop_t *p;
+
+    ESP_LOGI(GAP_TAG, "Device found: %s", bda2str(param->disc_res.bda, bda_str, 18));
+    for (int i = 0; i < param->disc_res.num_prop; i++) {
+        p = param->disc_res.prop + i;
+        switch (p->type) {
+        case ESP_BT_GAP_DEV_PROP_COD:
+            cod = *(uint32_t *)(p->val);
+            ESP_LOGI(GAP_TAG, "--Class of Device: 0x%"PRIx32, cod);
+            break;
+        case ESP_BT_GAP_DEV_PROP_RSSI:
+            rssi = *(int8_t *)(p->val);
+            ESP_LOGI(GAP_TAG, "--RSSI: %"PRId32, rssi);
+            break;
+        case ESP_BT_GAP_DEV_PROP_BDNAME:
+            bdname_len = (p->len > ESP_BT_GAP_MAX_BDNAME_LEN) ? ESP_BT_GAP_MAX_BDNAME_LEN :
+                          (uint8_t)p->len;
+            bdname = (uint8_t *)(p->val);
+            break;
+        case ESP_BT_GAP_DEV_PROP_EIR: {
+            eir_len = p->len;
+            eir = (uint8_t *)(p->val);
+            break;
+        }
+        default:
+            break;
+        }
+    }
+
+    /* search for device with Major device type "PHONE" or "Audio/Video" in COD */
+    app_gap_cb_t *p_dev = &m_dev_info;
+    if (p_dev->dev_found) {
+        return;
+    }
+
+    if (!esp_bt_gap_is_valid_cod(cod) ||
+	    (!(esp_bt_gap_get_cod_major_dev(cod) == ESP_BT_COD_MAJOR_DEV_PHONE) &&
+             !(esp_bt_gap_get_cod_major_dev(cod) == ESP_BT_COD_MAJOR_DEV_AV))) {
+        return;
+    }
+
+    memcpy(p_dev->bda, param->disc_res.bda, ESP_BD_ADDR_LEN);
+    p_dev->dev_found = true;
+
+    p_dev->cod = cod;
+    p_dev->rssi = rssi;
+    if (bdname_len > 0) {
+        memcpy(p_dev->bdname, bdname, bdname_len);
+        p_dev->bdname[bdname_len] = '\0';
+        p_dev->bdname_len = bdname_len;
+    }
+    if (eir_len > 0) {
+        memcpy(p_dev->eir, eir, eir_len);
+        p_dev->eir_len = eir_len;
+    }
+
+    if (p_dev->bdname_len == 0) {
+        get_name_from_eir(p_dev->eir, p_dev->bdname, &p_dev->bdname_len);
+    }
+
+    ESP_LOGI(GAP_TAG, "Found a target device, address %s, name %s", bda_str, p_dev->bdname);
+    p_dev->state = APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE;
+    ESP_LOGI(GAP_TAG, "Cancel device discovery ...");
+    esp_bt_gap_cancel_discovery();
+}
+
+static void bt_app_gap_init(void)
+{
+    app_gap_cb_t *p_dev = &m_dev_info;
+    memset(p_dev, 0, sizeof(app_gap_cb_t));
+
+    p_dev->state = APP_GAP_STATE_IDLE;
+}
+
+static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
+{
+    app_gap_cb_t *p_dev = &m_dev_info;
+    char bda_str[18];
+    char uuid_str[37];
+
+    switch (event) {
+    case ESP_BT_GAP_DISC_RES_EVT: {
+        update_device_info(param);
+        break;
+    }
+    case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: {
+        if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) {
+            ESP_LOGI(GAP_TAG, "Device discovery stopped.");
+            if ( (p_dev->state == APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE ||
+                    p_dev->state == APP_GAP_STATE_DEVICE_DISCOVERING)
+                    && p_dev->dev_found) {
+                p_dev->state = APP_GAP_STATE_SERVICE_DISCOVERING;
+                ESP_LOGI(GAP_TAG, "Discover services ...");
+                esp_bt_gap_get_remote_services(p_dev->bda);
+            }
+        } else if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) {
+            ESP_LOGI(GAP_TAG, "Discovery started.");
+        }
+        break;
+    }
+    case ESP_BT_GAP_RMT_SRVCS_EVT: {
+        if (memcmp(param->rmt_srvcs.bda, p_dev->bda, ESP_BD_ADDR_LEN) == 0 &&
+                p_dev->state == APP_GAP_STATE_SERVICE_DISCOVERING) {
+            p_dev->state = APP_GAP_STATE_SERVICE_DISCOVER_COMPLETE;
+            if (param->rmt_srvcs.stat == ESP_BT_STATUS_SUCCESS) {
+                ESP_LOGI(GAP_TAG, "Services for device %s found",  bda2str(p_dev->bda, bda_str, 18));
+                for (int i = 0; i < param->rmt_srvcs.num_uuids; i++) {
+                    esp_bt_uuid_t *u = param->rmt_srvcs.uuid_list + i;
+                    ESP_LOGI(GAP_TAG, "--%s", uuid2str(u, uuid_str, 37));
+                }
+            } else {
+                ESP_LOGI(GAP_TAG, "Services for device %s not found",  bda2str(p_dev->bda, bda_str, 18));
+            }
+        }
+        break;
+    }
+    case ESP_BT_GAP_RMT_SRVC_REC_EVT:
+    default: {
+        ESP_LOGI(GAP_TAG, "event: %d", event);
+        break;
+    }
+    }
+    return;
+}
+
+static void bt_app_gap_start_up(void)
+{
+    /* register GAP callback function */
+    esp_bt_gap_register_callback(bt_app_gap_cb);
+
+    char *dev_name = "ESP_GAP_INQRUIY";
+    esp_bt_dev_set_device_name(dev_name);
+
+    /* set discoverable and connectable mode, wait to be connected */
+    esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
+
+    /* inititialize device information and status */
+    bt_app_gap_init();
+
+    /* start to discover nearby Bluetooth devices */
+    app_gap_cb_t *p_dev = &m_dev_info;
+    p_dev->state = APP_GAP_STATE_DEVICE_DISCOVERING;
+    esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0);
+}
+
+void app_main(void)
+{
+    /* Initialize NVS — it is used to store PHY calibration data and save key-value pairs in flash memory*/
+    esp_err_t ret = nvs_flash_init();
+    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
+        ESP_ERROR_CHECK(nvs_flash_erase());
+        ret = nvs_flash_init();
+    }
+    ESP_ERROR_CHECK( ret );
+
+    /* initialize HCI TRANSPORT first */
+    hci_uart_open();
+    /* get HCI driver operations */
+    esp_bluedroid_hci_driver_operations_t operations = {
+        .send = hci_uart_send,
+        .check_send_available = hci_check_send_available,
+        .register_host_callback = hci_register_host_callback,
+    };
+    esp_bluedroid_attach_hci_driver(&operations);
+
+    esp_bluedroid_config_t bluedroid_cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT();
+    if ((ret = esp_bluedroid_init_with_cfg(&bluedroid_cfg)) != ESP_OK) {
+        ESP_LOGE(GAP_TAG, "%s initialize bluedroid failed: %s", __func__, esp_err_to_name(ret));
+        return;
+    }
+
+    if ((ret = esp_bluedroid_enable()) != ESP_OK) {
+        ESP_LOGE(GAP_TAG, "%s enable bluedroid failed: %s", __func__, esp_err_to_name(ret));
+        return;
+    }
+
+    bt_app_gap_start_up();
+}

+ 165 - 0
examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.c

@@ -0,0 +1,165 @@
+/*
+ * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Unlicense OR CC0-1.0
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+#include "driver/uart.h"
+#include "esp_log.h"
+#include "esp_attr.h"
+#include "esp_bluedroid_hci.h"
+#include "uart_driver.h"
+
+#define TAG "UART_HCI"
+
+#define UART_NO       (1)
+#define UART_BUF_SZ   (1024)
+
+#define UART_TX_PIN   (5)
+#define UART_RX_PIN   (18)
+#define UART_RTS_PIN  (19)
+#define UART_CTS_PIN  (23)
+
+enum {
+    UART_RX_TYPE = 0,
+    UART_RX_LEN,
+    UART_RX_DATA,
+};
+
+enum {
+    DATA_TYPE_COMMAND = 1,
+    DATA_TYPE_ACL     = 2,
+    DATA_TYPE_SCO     = 3,
+    DATA_TYPE_EVENT   = 4
+};
+
+TaskHandle_t s_rx_task_hdl;
+esp_bluedroid_hci_driver_callbacks_t s_callback = { 0 };
+
+static void IRAM_ATTR hci_uart_rx_task(void *arg)
+{
+    uint8_t buf[1026];
+    int len_now_read = -1;
+    uint32_t len_to_read = 1;
+    uint32_t len_total_read = 0;
+    uint8_t rx_st = UART_RX_TYPE;
+
+    while (1) {
+        len_now_read = uart_read_bytes(UART_NO, &buf[len_total_read], len_to_read, portMAX_DELAY);
+        assert(len_now_read == len_to_read);
+        len_total_read += len_now_read;
+
+        switch (rx_st) {
+        case UART_RX_TYPE: {
+            assert(buf[0] >= DATA_TYPE_ACL && buf[0] <= DATA_TYPE_EVENT);
+            if (buf[0] == DATA_TYPE_ACL) {
+                len_to_read = 4;
+            } else if (buf[0] == DATA_TYPE_SCO) {
+                len_to_read = 3;
+            } else if (buf[0] == DATA_TYPE_EVENT) {
+                len_to_read = 2;
+            } else {
+                assert(0);
+            }
+            rx_st = UART_RX_LEN;
+        }
+        break;
+
+        case UART_RX_LEN: {
+            if (buf[0] == DATA_TYPE_ACL) {
+                len_to_read = buf[3] | (buf[4] << 8);
+            } else if (buf[0] == DATA_TYPE_SCO) {
+                len_to_read = buf[3];
+            } else if (buf[0] == DATA_TYPE_EVENT) {
+                len_to_read = buf[2];
+            } else {
+                assert(0);
+            }
+            rx_st = UART_RX_DATA;
+        }
+        break;
+
+        case UART_RX_DATA: {
+            if (s_callback.notify_host_recv) {
+                s_callback.notify_host_recv(buf, len_total_read);
+            }
+
+            rx_st = UART_RX_TYPE;
+            len_to_read = 1;
+            len_total_read = 0;
+        }
+        break;
+
+        default: {
+            assert(0);
+            break;
+        }
+        }
+    }
+
+    vTaskDelete(NULL);
+}
+
+void hci_uart_send(uint8_t *buf, uint16_t len)
+{
+    uint8_t *p = buf;
+    int len_write = 0;
+
+    while (len) {
+        len_write = uart_write_bytes(UART_NO, p, len);
+        assert(len_write > 0);
+        len -= len_write;
+        p += len_write;
+    }
+}
+
+bool hci_check_send_available(void)
+{
+    return true;
+}
+
+esp_err_t hci_register_host_callback(const esp_bluedroid_hci_driver_callbacks_t *callback)
+{
+    s_callback.notify_host_send_available = callback->notify_host_send_available;
+    s_callback.notify_host_recv = callback->notify_host_recv;
+
+    return ESP_OK;
+}
+
+void hci_uart_open(void)
+{
+    uart_config_t uart_config = {
+        .baud_rate  = CONFIG_EXAMPLE_HCI_UART_BAUDRATE,
+        .data_bits  = UART_DATA_8_BITS,
+        .parity     = UART_PARITY_DISABLE,
+        .stop_bits  = UART_STOP_BITS_1,
+        .flow_ctrl  = UART_HW_FLOWCTRL_CTS_RTS,
+        .source_clk = UART_SCLK_DEFAULT,
+        .rx_flow_ctrl_thresh = UART_HW_FIFO_LEN(UART_NO) - 1,
+    };
+
+    int intr_alloc_flags = 0;
+#if CONFIG_UART_ISR_IN_IRAM
+    intr_alloc_flags = ESP_INTR_FLAG_IRAM;
+#endif
+
+    ESP_ERROR_CHECK(uart_driver_install(UART_NO, UART_BUF_SZ * 2, UART_BUF_SZ * 2, 0, NULL, intr_alloc_flags));
+    ESP_ERROR_CHECK(uart_param_config(UART_NO, &uart_config));
+    ESP_ERROR_CHECK(uart_set_pin(UART_NO, UART_TX_PIN, UART_RX_PIN, UART_RTS_PIN, UART_CTS_PIN));
+
+    xTaskCreate(hci_uart_rx_task, "hci_uart_rx_task", 2048, NULL, 12, &s_rx_task_hdl);
+}
+
+void hci_uart_close(void)
+{
+    if (s_rx_task_hdl) {
+        vTaskDelete(s_rx_task_hdl);
+    }
+    uart_driver_delete(UART_NO);
+    memset(&s_callback, 0, sizeof(esp_bluedroid_hci_driver_callbacks_t));
+}

+ 46 - 0
examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.h

@@ -0,0 +1,46 @@
+/*
+ * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Unlicense OR CC0-1.0
+ */
+
+#ifndef __UART_DRIVER_H__
+#define __UART_DRIVER_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "esp_bluedroid_hci.h"
+
+/**
+ * @brief open HCI transport of uart
+ */
+void hci_uart_open(void);
+
+/**
+ * @brief close HCI transport of uart
+ */
+void hci_uart_close(void);
+
+/**
+ * @brief send data from host to HCI transport
+ *
+ * @param[in] data  pointer to data buffer
+ * @param[in] len   length of data
+ */
+void hci_uart_send(uint8_t *data, uint16_t len);
+
+/**
+ * @brief host checks whether it can send data to HCI transport
+ *
+ * @return true if host can send data, false otherwise
+ */
+bool hci_check_send_available(void);
+
+/**
+ * @brief register host callbacks
+ *
+ * @param[in] callback  HCI driver callbacks
+ */
+esp_err_t hci_register_host_callback(const esp_bluedroid_hci_driver_callbacks_t *callback);
+
+#endif /* __UART_DRIVER_H__ */

+ 4 - 0
examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/sdkconfig.defaults

@@ -0,0 +1,4 @@
+CONFIG_BT_CONTROLLER_DISABLED=y
+CONFIG_BT_ENABLED=y
+CONFIG_BT_BLUEDROID_ENABLED=y
+CONFIG_BT_CLASSIC_ENABLED=y

+ 1 - 1
examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c

@@ -272,7 +272,7 @@ void app_main(void)
 #endif // CONFIG_BT_ENABLED
 #endif // CONFIG_BT_ENABLED
 #endif // CONFIG_EXAMPLE_CONNECT_WIFI
 #endif // CONFIG_EXAMPLE_CONNECT_WIFI
 
 
-#if CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED
+#if CONFIG_BT_CONTROLLER_ENABLED && (CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED)
     ESP_ERROR_CHECK(esp_ble_helper_init());
     ESP_ERROR_CHECK(esp_ble_helper_init());
 #endif
 #endif
 
 

+ 1 - 1
examples/system/ota/advanced_https_ota/main/ble_helper/ble_api.c

@@ -6,7 +6,7 @@
 
 
 #include "sdkconfig.h"
 #include "sdkconfig.h"
 
 
-#if CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED
+#if CONFIG_BT_CONTROLLER_ENABLED && (CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED)
 
 
 #include "ble_api.h"
 #include "ble_api.h"
 #include "esp_log.h"
 #include "esp_log.h"

+ 1 - 1
examples/system/ota/advanced_https_ota/main/ble_helper/bluedroid_gatts.c

@@ -9,7 +9,7 @@
 #include "esp_log.h"
 #include "esp_log.h"
 #include "string.h"
 #include "string.h"
 
 
-#if CONFIG_BT_BLE_ENABLED
+#if CONFIG_BT_CONTROLLER_ENABLED && CONFIG_BT_BLE_ENABLED
 
 
 static const char *TAG = "bluedroid_gatts";
 static const char *TAG = "bluedroid_gatts";
 static prepare_type_env_t a_prepare_write_env;
 static prepare_type_env_t a_prepare_write_env;

+ 1 - 1
examples/system/ota/advanced_https_ota/main/ble_helper/include/ble_api.h

@@ -12,7 +12,7 @@
 extern "C" {
 extern "C" {
 #endif
 #endif
 
 
-#if CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED
+#if CONFIG_BT_CONTROLLER_ENABLED && (CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED)
 esp_err_t esp_ble_helper_init(void);
 esp_err_t esp_ble_helper_init(void);
 #endif
 #endif
 
 

+ 1 - 1
examples/system/ota/advanced_https_ota/main/ble_helper/include/bluedroid_gatts.h

@@ -9,7 +9,7 @@
 
 
 
 
 #include "sdkconfig.h"
 #include "sdkconfig.h"
-#if CONFIG_BT_BLE_ENABLED
+#if CONFIG_BT_CONTROLLER_ENABLED && CONFIG_BT_BLE_ENABLED
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 extern "C" {
 extern "C" {