diff --git a/components/bt/controller/esp32c3/Kconfig.in b/components/bt/controller/esp32c3/Kconfig.in index 05f34c11f86..13898617351 100644 --- a/components/bt/controller/esp32c3/Kconfig.in +++ b/components/bt/controller/esp32c3/Kconfig.in @@ -561,6 +561,31 @@ config BT_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS This improves security by ensuring that only connection requests with valid Access Addresses are accepted. If disabled, only basic checks are applied, improving compatibility. +config BT_CTRL_BLE_MIN_CONN_INTERVAL_ENABLE + bool "Allow BLE connection interval below the spec minimum" + default y + select BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT if BT_BLUEDROID_ENABLED + help + Enabling this option allows the BLE controller to use a connection interval + smaller than the Bluetooth Core specification minimum of 7.5 ms. On + ESP32-C3/S3, when this option is enabled, the connection interval can go as + low as 3 * 1.25 ms = 3.75 ms. + + Note: Because the connection interval is very short, the time available within + a single connection event is also very limited. It is best not to send or + receive long payloads (e.g. large ATT MTU, Data Length Extension with large + Tx/Rx octets) when this lower interval is used. + + This option is enabled by default. Disable it to stay compliant with the BLE + specification (minimum connection interval 7.5 ms). + + Host stack: When Bluedroid is the BLE host, enabling this option also selects + BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT so the host accepts connection + intervals below the spec minimum. NimBLE host does not provide equivalent + support yet; it is planned for a future release. Until then, use Bluedroid + if you need coordinated host and controller behavior for sub-minimum + intervals. + menu "Controller debug log Options (Experimental)" config BT_CTRL_LE_LOG_EN depends on BT_CTRL_RUN_IN_FLASH_ONLY diff --git a/components/bt/controller/esp32c3/bt.c b/components/bt/controller/esp32c3/bt.c index e0bf95f0c2e..22e85feff62 100644 --- a/components/bt/controller/esp32c3/bt.c +++ b/components/bt/controller/esp32c3/bt.c @@ -309,6 +309,7 @@ extern void ets_backup_dma_copy(uint32_t reg, uint32_t mem_addr, uint32_t num, b extern void btdm_cca_feature_enable(void); extern void btdm_aa_check_enhance_enable(void); +extern void ble_min_conn_interval_enable(uint16_t min_interval); #if (CONFIG_BT_BLUEDROID_ENABLED || CONFIG_BT_NIMBLE_ENABLED) extern void scan_stack_enableAdvFlowCtrlVsCmd(bool en); @@ -1349,6 +1350,9 @@ static void btdm_funcs_table_ready_wrapper(void) #if BLE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS_ENABLED btdm_aa_check_enhance_enable(); #endif +#if CONFIG_BT_CTRL_BLE_MIN_CONN_INTERVAL_ENABLE + ble_min_conn_interval_enable(3); // 3 * 1.25 = 3.75ms +#endif #if CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY // do nothing #else diff --git a/components/bt/controller/lib_esp32c3_family b/components/bt/controller/lib_esp32c3_family index ebd6043a8e3..58d499bba10 160000 --- a/components/bt/controller/lib_esp32c3_family +++ b/components/bt/controller/lib_esp32c3_family @@ -1 +1 @@ -Subproject commit ebd6043a8e3c3bbde45ee483895303b9c1229ab5 +Subproject commit 58d499bba1019a80a622df60aa38f59c1e4565ba diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 25d1bf169c2..f7723128f64 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1309,6 +1309,23 @@ config BT_BLE_RPA_TIMEOUT This set RPA timeout of Controller and Host. Default is 900 s (15 minutes). Range is 1 s to 1 hour (3600 s). +config BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT + bool "Allow BLE connection interval below Bluetooth Core Spec minimum (disable host check)" + depends on BT_BLE_ENABLED + default n + help + When enabled, the Bluedroid host skips the minimum BLE connection + interval validation (Bluetooth Core Spec minimum is 0x0006 / 7.5 ms) + and accepts any non-zero interval value from the application. The + BLE controller then enforces what is actually allowed; how small the + connection interval may be depends on controller capability and its + own configuration, not on this host option text. + + End users should NOT set this option directly. In typical IDF builds it + follows the active Controller integration when that Controller supports + this mode; use the Controller's own configuration (menu entries and symbol + names differ by chip) instead of toggling this host symbol manually. + menuconfig BT_BLE_50_FEATURES_SUPPORTED bool "Enable BLE 5.0 and above features(please disable BLE 4.2 if enable BLE 5.0)" depends on (BT_BLE_ENABLED && ((BT_CONTROLLER_ENABLED && SOC_BLE_50_SUPPORTED) || BT_CONTROLLER_DISABLED)) diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 067de4d9871..311c5d281ca 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -154,8 +154,8 @@ esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params) return ESP_FAIL; } - if (ESP_BLE_IS_VALID_PARAM(params->min_int, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && - ESP_BLE_IS_VALID_PARAM(params->max_int, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + if (ESP_BLE_IS_VALID_PARAM(params->min_int, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(params->max_int, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(params->timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && (params->latency <= ESP_BLE_CONN_LATENCY_MAX) && ((params->timeout * 10) >= ((1 + params->latency) * ((params->max_int * 5) >> 1))) && params->min_int <= params->max_int) { @@ -393,8 +393,8 @@ esp_err_t esp_ble_gap_set_prefer_conn_params(esp_bd_addr_t bd_addr, return ESP_ERR_INVALID_ARG; } - if (ESP_BLE_IS_VALID_PARAM(min_conn_int, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && - ESP_BLE_IS_VALID_PARAM(max_conn_int, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + if (ESP_BLE_IS_VALID_PARAM(min_conn_int, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(max_conn_int, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(supervision_tout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && (slave_latency <= ESP_BLE_CONN_LATENCY_MAX) && ((supervision_tout * 10) >= ((1 + slave_latency) * ((max_conn_int * 5) >> 1))) && min_conn_int <= max_conn_int) { @@ -1747,8 +1747,8 @@ esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr, return ESP_ERR_INVALID_ARG; } - if (ESP_BLE_IS_VALID_PARAM(phy_1m_conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && - ESP_BLE_IS_VALID_PARAM(phy_1m_conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + if (ESP_BLE_IS_VALID_PARAM(phy_1m_conn_params->interval_min, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(phy_1m_conn_params->interval_max, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(phy_1m_conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && (phy_1m_conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) && ((phy_1m_conn_params->supervision_timeout * 10) >= ((1 + phy_1m_conn_params->latency) * ((phy_1m_conn_params->interval_max * 5) >> 1))) && @@ -1771,8 +1771,8 @@ esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr, return ESP_ERR_INVALID_ARG; } - if (ESP_BLE_IS_VALID_PARAM(phy_2m_conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && - ESP_BLE_IS_VALID_PARAM(phy_2m_conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + if (ESP_BLE_IS_VALID_PARAM(phy_2m_conn_params->interval_min, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(phy_2m_conn_params->interval_max, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(phy_2m_conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && (phy_2m_conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) && ((phy_2m_conn_params->supervision_timeout * 10) >= ((1 + phy_2m_conn_params->latency) * ((phy_2m_conn_params->interval_max * 5) >> 1))) && @@ -1795,8 +1795,8 @@ esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr, return ESP_ERR_INVALID_ARG; } - if (ESP_BLE_IS_VALID_PARAM(phy_coded_conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && - ESP_BLE_IS_VALID_PARAM(phy_coded_conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + if (ESP_BLE_IS_VALID_PARAM(phy_coded_conn_params->interval_min, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(phy_coded_conn_params->interval_max, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(phy_coded_conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && (phy_coded_conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) && ((phy_coded_conn_params->supervision_timeout * 10) >= ((1 + phy_coded_conn_params->latency) * ((phy_coded_conn_params->interval_max * 5) >> 1))) && diff --git a/components/bt/host/bluedroid/api/esp_gattc_api.c b/components/bt/host/bluedroid/api/esp_gattc_api.c index b0d2458ca3c..0e2befd18d7 100644 --- a/components/bt/host/bluedroid/api/esp_gattc_api.c +++ b/components/bt/host/bluedroid/api/esp_gattc_api.c @@ -115,8 +115,8 @@ esp_err_t esp_ble_gattc_enh_open(esp_gatt_if_t gattc_if, esp_ble_gatt_creat_conn } conn_params = creat_conn_params->phy_1m_conn_params; - if (ESP_BLE_IS_VALID_PARAM(conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && - ESP_BLE_IS_VALID_PARAM(conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + if (ESP_BLE_IS_VALID_PARAM(conn_params->interval_min, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(conn_params->interval_max, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && (conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) && ((conn_params->supervision_timeout * 10) >= ((1 + conn_params->latency) * ((conn_params->interval_max * 5) >> 1))) && @@ -138,8 +138,8 @@ esp_err_t esp_ble_gattc_enh_open(esp_gatt_if_t gattc_if, esp_ble_gatt_creat_conn } conn_params = creat_conn_params->phy_2m_conn_params; - if (ESP_BLE_IS_VALID_PARAM(conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && - ESP_BLE_IS_VALID_PARAM(conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + if (ESP_BLE_IS_VALID_PARAM(conn_params->interval_min, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(conn_params->interval_max, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && (conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) && ((conn_params->supervision_timeout * 10) >= ((1 + conn_params->latency) * ((conn_params->interval_max * 5) >> 1))) && @@ -161,8 +161,8 @@ esp_err_t esp_ble_gattc_enh_open(esp_gatt_if_t gattc_if, esp_ble_gatt_creat_conn } conn_params = creat_conn_params->phy_coded_conn_params; - if (ESP_BLE_IS_VALID_PARAM(conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && - ESP_BLE_IS_VALID_PARAM(conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + if (ESP_BLE_IS_VALID_PARAM(conn_params->interval_min, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(conn_params->interval_max, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && (conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) && ((conn_params->supervision_timeout * 10) >= ((1 + conn_params->latency) * ((conn_params->interval_max * 5) >> 1))) && @@ -251,8 +251,8 @@ esp_err_t esp_ble_gattc_aux_open_with_pawr_synced(esp_gatt_if_t gattc_if, esp_bl } conn_params = pawr_conn_params->phy_1m_conn_params; - if (ESP_BLE_IS_VALID_PARAM(conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && - ESP_BLE_IS_VALID_PARAM(conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + if (ESP_BLE_IS_VALID_PARAM(conn_params->interval_min, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(conn_params->interval_max, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && (conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) && ((conn_params->supervision_timeout * 10) >= ((1 + conn_params->latency) * ((conn_params->interval_max * 5) >> 1))) && @@ -274,8 +274,8 @@ esp_err_t esp_ble_gattc_aux_open_with_pawr_synced(esp_gatt_if_t gattc_if, esp_bl } conn_params = pawr_conn_params->phy_2m_conn_params; - if (ESP_BLE_IS_VALID_PARAM(conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && - ESP_BLE_IS_VALID_PARAM(conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + if (ESP_BLE_IS_VALID_PARAM(conn_params->interval_min, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(conn_params->interval_max, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && (conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) && ((conn_params->supervision_timeout * 10) >= ((1 + conn_params->latency) * ((conn_params->interval_max * 5) >> 1))) && @@ -297,8 +297,8 @@ esp_err_t esp_ble_gattc_aux_open_with_pawr_synced(esp_gatt_if_t gattc_if, esp_bl } conn_params = pawr_conn_params->phy_coded_conn_params; - if (ESP_BLE_IS_VALID_PARAM(conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && - ESP_BLE_IS_VALID_PARAM(conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && + if (ESP_BLE_IS_VALID_PARAM(conn_params->interval_min, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && + ESP_BLE_IS_VALID_PARAM(conn_params->interval_max, BLE_CONN_INT_MIN_HOST_CHECK, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && (conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) && ((conn_params->supervision_timeout * 10) >= ((1 + conn_params->latency) * ((conn_params->interval_max * 5) >> 1))) && diff --git a/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h b/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h index d6a2718ab19..bd4b2c7e763 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h +++ b/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,7 @@ #include #include +#include "sdkconfig.h" #ifdef __cplusplus extern "C" { @@ -215,7 +216,11 @@ typedef uint8_t esp_link_key[ESP_BT_OCTET16_LEN]; /* Link Key */ #define ESP_BLE_PRIM_ADV_INT_MIN 0x000020 /*!< Minimum advertising interval for undirected and low duty cycle directed advertising */ #endif #define ESP_BLE_PRIM_ADV_INT_MAX 0xFFFFFF /*!< Maximum advertising interval for undirected and low duty cycle directed advertising */ -#define ESP_BLE_CONN_INT_MIN 0x0006 /*!< relate to BTM_BLE_CONN_INT_MIN in stack/btm_ble_api.h */ +/* Public API constant pinned to the Bluetooth Core Spec minimum (7.5 ms). + * Applications that want a sub-spec connection interval must pass the + * desired value as an integer literal; whether it is actually accepted + * depends on the controller. */ +#define ESP_BLE_CONN_INT_MIN 0x0006 /*!< Minimum connection interval, 7.5 ms (BLE Core Spec minimum) */ #define ESP_BLE_CONN_INT_MAX 0x0C80 /*!< relate to BTM_BLE_CONN_INT_MAX in stack/btm_ble_api.h */ #define ESP_BLE_CONN_LATENCY_MAX 499 /*!< relate to ESP_BLE_CONN_LATENCY_MAX in stack/btm_ble_api.h */ #define ESP_BLE_CONN_SUP_TOUT_MIN 0x000A /*!< relate to BTM_BLE_CONN_SUP_TOUT_MIN in stack/btm_ble_api.h */ @@ -232,8 +237,8 @@ typedef uint8_t esp_ble_phy_mask_t; typedef struct { uint16_t scan_interval; /*!< Initial scan interval, in units of 0.625ms, the range is 0x0004(2.5ms) to 0xFFFF(10.24s). */ uint16_t scan_window; /*!< Initial scan window, in units of 0.625ms, the range is 0x0004(2.5ms) to 0xFFFF(10.24s). */ - uint16_t interval_min; /*!< Minimum connection interval, in units of 1.25ms, the range is 0x0006(7.5ms) to 0x0C80(4s). */ - uint16_t interval_max; /*!< Maximum connection interval, in units of 1.25ms, the range is 0x0006(7.5ms) to 0x0C80(4s). */ + uint16_t interval_min; /*!< Minimum connection interval, in units of 1.25 ms, the range is 0x0006(7.5ms) to 0x0C80(4s). Sub-spec values are accepted only if the controller supports them. */ + uint16_t interval_max; /*!< Maximum connection interval, in units of 1.25 ms, the range is 0x0006(7.5ms) to 0x0C80(4s). Same bounds as interval_min. */ uint16_t latency; /*!< Connection latency, the range is 0x0000(0) to 0x01F3(499). */ uint16_t supervision_timeout; /*!< Connection supervision timeout, in units of 10ms, the range is from 0x000A(100ms) to 0x0C80(32s). */ uint16_t min_ce_len; /*!< Minimum connection event length, in units of 0.625ms, setting to 0 for no preferred parameters. */ diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index 76ce330e529..b886849626b 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -1958,7 +1958,7 @@ static void btc_ble_update_conn_params(BD_ADDR bd_addr, uint16_t min_int, min_int = max_int; } - if (min_int < BTM_BLE_CONN_INT_MIN || max_int > BTM_BLE_CONN_INT_MAX) { + if (min_int < BLE_CONN_INT_MIN_HOST_CHECK || max_int > BTM_BLE_CONN_INT_MAX) { BTC_TRACE_ERROR("Invalid interval value.\n"); } diff --git a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h index 36d39b8a654..7caa9e6261a 100644 --- a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h +++ b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h @@ -382,6 +382,18 @@ #define UC_BT_BLE_HIGH_DUTY_ADV_INTERVAL FALSE #endif +/* When set to 1, the Bluedroid host's parameter validation no longer enforces + * a minimum BLE connection interval; the actual lower limit is then left to + * the controller. See BLE_CONN_INT_MIN_HOST_CHECK in common/bt_target.h. + * + * Do not turn this on manually in menuconfig unless you know the implications. + * In normal IDF builds it follows the active Controller integration. */ +#ifdef CONFIG_BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT +#define UC_BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT 1 +#else +#define UC_BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT 0 +#endif + //GATTS #ifdef CONFIG_BT_GATTS_ENABLE #define UC_BT_GATTS_ENABLE CONFIG_BT_GATTS_ENABLE diff --git a/components/bt/host/bluedroid/common/include/common/bt_target.h b/components/bt/host/bluedroid/common/include/common/bt_target.h index e8bb2d68830..99d6254d092 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -437,6 +437,24 @@ #define BLE_HIGH_DUTY_ADV_INTERVAL FALSE #endif +/* Host-side parameter validation floor (in 1.25 ms units) for the BLE + * connection interval. Internal to the Bluedroid host: not sent on air, not + * exposed via the GATT Preferred Connection Parameters Characteristic, and + * not a public API constant - those use BTM_BLE_CONN_INT_MIN (0x0006). + * + * When UC_BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT == 1 the host stops + * enforcing a minimum (the actual lower limit is then defined entirely by + * the controller). 0x0001 is used rather than 0x0000 so the existing + * `uint16_t < MIN` range checks remain well-defined under GCC + * `-Wtype-limits`. */ +#ifndef BLE_CONN_INT_MIN_HOST_CHECK +#if (UC_BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT == 1) +#define BLE_CONN_INT_MIN_HOST_CHECK 0x0001 +#else +#define BLE_CONN_INT_MIN_HOST_CHECK 0x0006 +#endif +#endif + #if (UC_BT_BLE_RPA_SUPPORTED == TRUE) #define CONTROLLER_RPA_LIST_ENABLE TRUE #else diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble.c b/components/bt/host/bluedroid/stack/btm/btm_ble.c index 71dcdc0768b..95b44c35889 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble.c @@ -578,8 +578,8 @@ void BTM_BleSetPrefConnParams (BD_ADDR bd_addr, tout: %u", min_conn_int, max_conn_int, slave_latency, supervision_tout); - if (BTM_BLE_ISVALID_PARAM(min_conn_int, BTM_BLE_CONN_INT_MIN, BTM_BLE_CONN_INT_MAX) && - BTM_BLE_ISVALID_PARAM(max_conn_int, BTM_BLE_CONN_INT_MIN, BTM_BLE_CONN_INT_MAX) && + if (BTM_BLE_ISVALID_PARAM(min_conn_int, BLE_CONN_INT_MIN_HOST_CHECK, BTM_BLE_CONN_INT_MAX) && + BTM_BLE_ISVALID_PARAM(max_conn_int, BLE_CONN_INT_MIN_HOST_CHECK, BTM_BLE_CONN_INT_MAX) && BTM_BLE_ISVALID_PARAM(supervision_tout, BTM_BLE_CONN_SUP_TOUT_MIN, BTM_BLE_CONN_SUP_TOUT_MAX) && (slave_latency <= BTM_BLE_CONN_LATENCY_MAX || slave_latency == BTM_BLE_CONN_PARAM_UNDEF)) { if (p_dev_rec) { diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h index 5ccf477d7bd..6084ffa6afa 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h @@ -122,6 +122,11 @@ typedef UINT8 tBTM_BLE_SFP; #define BTM_BLE_SCAN_INT_MAX 0x4000 #define BTM_BLE_SCAN_WIN_MIN 0x0004 #define BTM_BLE_SCAN_WIN_MAX 0x4000 +/* Bluetooth Core Spec minimum BLE connection interval (7.5 ms). Used inside + * the host stack wherever the on-air or interoperability semantics require + * the spec value. For host-side parameter validation (which can be relaxed + * to accept sub-spec intervals) use BLE_CONN_INT_MIN_HOST_CHECK from + * common/bt_target.h instead. */ #define BTM_BLE_CONN_INT_MIN 0x0006 #define BTM_BLE_CONN_INT_MAX 0x0C80 #define BTM_BLE_CONN_LATENCY_MAX 499 diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c index 817d0b94b83..65d4e643b06 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c @@ -377,9 +377,9 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, p_lcb->ble_addr_type = type; /* If there are any preferred connection parameters, set them now */ - if ( (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN ) && + if ( (p_dev_rec->conn_params.min_conn_int >= BLE_CONN_INT_MIN_HOST_CHECK ) && (p_dev_rec->conn_params.min_conn_int <= BTM_BLE_CONN_INT_MAX ) && - (p_dev_rec->conn_params.max_conn_int >= BTM_BLE_CONN_INT_MIN ) && + (p_dev_rec->conn_params.max_conn_int >= BLE_CONN_INT_MIN_HOST_CHECK ) && (p_dev_rec->conn_params.max_conn_int <= BTM_BLE_CONN_INT_MAX ) && (p_dev_rec->conn_params.slave_latency <= BTM_BLE_CONN_LATENCY_MAX ) && (p_dev_rec->conn_params.supervision_tout >= BTM_BLE_CONN_SUP_TOUT_MIN) && @@ -762,8 +762,8 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) STREAM_TO_UINT16 (timeout, p); /* 0x000A - 0x0C80 */ /* If we are a master, the slave wants to update the parameters */ if (p_lcb->link_role == HCI_ROLE_MASTER) { - if (min_interval < BTM_BLE_CONN_INT_MIN || min_interval > BTM_BLE_CONN_INT_MAX || - max_interval < BTM_BLE_CONN_INT_MIN || max_interval > BTM_BLE_CONN_INT_MAX || + if (min_interval < BLE_CONN_INT_MIN_HOST_CHECK || min_interval > BTM_BLE_CONN_INT_MAX || + max_interval < BLE_CONN_INT_MIN_HOST_CHECK || max_interval > BTM_BLE_CONN_INT_MAX || latency > BTM_BLE_CONN_LATENCY_MAX || timeout < BTM_BLE_CONN_SUP_TOUT_MIN || timeout > BTM_BLE_CONN_SUP_TOUT_MAX || /* The supervision_timeout parameter defines the link supervision timeout for the connection. diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7_bt_funcs.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7_bt_funcs.ld index 70033d6c7c0..b04334e54bc 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7_bt_funcs.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7_bt_funcs.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -21,10 +21,7 @@ r_llc_rem_encrypt_proc_continue_eco = 0x40001cf0; r_lld_ext_adv_dynamic_aux_pti_process_eco = 0x40001cfc; r_lld_adv_start_eco = 0x40001d04; r_lld_con_evt_canceled_cbk_eco = 0x40001d08; -r_lld_con_evt_time_update_eco = 0x40001d0c; r_lld_con_start_eco = 0x40001d10; -r_lld_con_frm_isr_eco = 0x40001d14; -r_lld_con_tx_eco = 0x40001d18; r_lld_ext_scan_dynamic_pti_process_eco = 0x40001d28; r_lld_scan_frm_eof_isr_eco = 0x40001d2c; r_lld_sync_start_eco = 0x40001d30; @@ -110,7 +107,6 @@ r_lld_adv_frm_isr_eco = 0x40001d00; r_lld_res_list_clear = 0x40004638; r_lld_res_list_rem = 0x40004680; r_lld_adv_start_hook = 0x40001c80; -r_lld_con_evt_start_cbk_eco = 0x40001d1c; r_lld_con_tx_prog_new_packet = 0x40001b74; r_lld_adv_ext_chain_none_construct = 0x40001b50; r_llc_llcp_send_eco = 0x40001cf4; @@ -127,4 +123,8 @@ r_lld_scan_process_pkt_rx_adv_rep = 0x40001284; r_register_esp_vendor_cmd_handler = 0x40001400; r_llc_llcp_pdu_handler_get_overwrite = 0x40001d5c; r_llc_start_eco = 0x40001cf8; +r_lld_con_tx_eco = 0x40001d18; +r_lld_con_evt_time_update_eco = 0x40001d0c; +r_lld_con_evt_start_cbk_eco = 0x40001d1c; +r_lld_con_frm_isr_eco = 0x40001d14; */