From b51a9d59656c74c427c82da8ce33712f7d44712e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20M=C3=BAdry?= Date: Mon, 11 Aug 2025 14:43:51 +0200 Subject: [PATCH 001/226] feat(sdspi): Add an option to modify wait time for MISO before sending next command Closes https://github.com/espressif/esp-idf/issues/16909 --- .../include/driver/sdspi_host.h | 9 ++- components/esp_driver_sdspi/src/sdspi_host.c | 57 ++++++++++++++++--- .../sdspi_tests/sdmmc_test_begin_end_spi.c | 17 +++++- .../sdspi_tests/sdmmc_test_begin_end_spi.h | 6 +- .../sdspi_tests/sdmmc_test_erase_spi.c | 2 +- .../sdspi_tests/sdmmc_test_probe_spi.c | 2 +- .../sdspi_tests/sdmmc_test_rw_spi.c | 37 ++++++++++-- examples/storage/sd_card/sdspi/README.md | 12 ++++ 8 files changed, 121 insertions(+), 21 deletions(-) diff --git a/components/esp_driver_sdspi/include/driver/sdspi_host.h b/components/esp_driver_sdspi/include/driver/sdspi_host.h index 73410bdb02..c397930b9e 100644 --- a/components/esp_driver_sdspi/include/driver/sdspi_host.h +++ b/components/esp_driver_sdspi/include/driver/sdspi_host.h @@ -80,6 +80,10 @@ typedef struct { 0 means "active low", i.e. card is protected when the GPIO is low; 1 means "active high", i.e. card is protected when GPIO is high. */ uint16_t duty_cycle_pos; ///< Duty cycle of positive clock, in 1/256th increments (128 = 50%/50% duty). Setting this to 0 (=not setting it) is equivalent to setting this to 128. + int8_t wait_for_miso; /*!< Timeout value in the driver will be waiting for MISO to be high before sending commands. Possible values are the following: + 0: default value (40ms); -1: no waiting (0ms); 1-127: timeout in ms; else: invalid value, default will be used. + This can be used to speed up transactions in certain scenarios but should not be needed if correct pull-up resistors are used. + Use with care on devices where multiple SPI slaves use the same SPI bus.*/ } sdspi_device_config_t; #define SDSPI_SLOT_NO_CS GPIO_NUM_NC ///< indicates that card select line is not used @@ -91,14 +95,15 @@ typedef struct { /** * Macro defining default configuration of SD SPI device. */ -#define SDSPI_DEVICE_CONFIG_DEFAULT() {\ +#define SDSPI_DEVICE_CONFIG_DEFAULT() { \ .host_id = SDSPI_DEFAULT_HOST, \ .gpio_cs = GPIO_NUM_13, \ .gpio_cd = SDSPI_SLOT_NO_CD, \ .gpio_wp = SDSPI_SLOT_NO_WP, \ .gpio_int = GPIO_NUM_NC, \ .gpio_wp_polarity = SDSPI_IO_ACTIVE_LOW, \ - .duty_cycle_pos = 0,\ + .duty_cycle_pos = 0, \ + .wait_for_miso = 0, \ } /** diff --git a/components/esp_driver_sdspi/src/sdspi_host.c b/components/esp_driver_sdspi/src/sdspi_host.c index 90f4df8042..6fa6633021 100644 --- a/components/esp_driver_sdspi/src/sdspi_host.c +++ b/components/esp_driver_sdspi/src/sdspi_host.c @@ -43,10 +43,15 @@ typedef struct { spi_host_device_t host_id; //!< SPI host id. spi_device_handle_t spi_handle; //!< SPI device handle, used for transactions + uint8_t* block_buf; + /// semaphore of gpio interrupt + SemaphoreHandle_t semphr_int; + uint16_t duty_cycle_pos; ///< Duty cycle of positive clock, in 1/256th increments (128 = 50%/50% duty). Setting this to 0 (=not setting it) is equivalent to setting this to 128. uint8_t gpio_cs; //!< CS GPIO, or GPIO_UNUSED uint8_t gpio_cd; //!< Card detect GPIO, or GPIO_UNUSED uint8_t gpio_wp; //!< Write protect GPIO, or GPIO_UNUSED uint8_t gpio_int; //!< Write protect GPIO, or GPIO_UNUSED + uint8_t poll_busy_start_command_timeout; ///< Timeout value in milliseconds the driver will be waiting for MISO to be high before sending commands. /// GPIO write protect polarity. /// 0 means "active low", i.e. card is protected when the GPIO is low; /// 1 means "active high", i.e. card is protected when GPIO is high. @@ -55,10 +60,6 @@ typedef struct { uint8_t data_crc_enabled : 1; /// Intermediate buffer used when application buffer is not in DMA memory; /// allocated on demand, SDSPI_BLOCK_BUF_SIZE bytes long. May be zero. - uint8_t* block_buf; - /// semaphore of gpio interrupt - SemaphoreHandle_t semphr_int; - uint16_t duty_cycle_pos; ///< Duty cycle of positive clock, in 1/256th increments (128 = 50%/50% duty). Setting this to 0 (=not setting it) is equivalent to setting this to 128. } slot_info_t; // Reserved for old API to be back-compatible @@ -327,6 +328,28 @@ static void gpio_intr(void* arg) } } +static inline int wait_for_miso_to_poll_busy_timeout_ms(int8_t wait_for_miso) +{ + static int default_timeout = 40; // default timeout in ms + int ret; + switch (wait_for_miso) { + case -1: + ret = 0; // no waiting + break; + case 0: + ret = default_timeout; + break; + case 1 ... 127: + ret = (int) wait_for_miso; // timeout in ms + break; + default: + ret = default_timeout; // unsupported values (from -128 to -2), use default + break; + } + assert(ret >= 0); + return ret; +} + esp_err_t sdspi_host_init_device(const sdspi_device_config_t* slot_config, sdspi_dev_handle_t* out_handle) { ESP_LOGD(TAG, "%s: SPI%d cs=%d cd=%d wp=%d wp_polarity:%d", @@ -341,6 +364,7 @@ esp_err_t sdspi_host_init_device(const sdspi_device_config_t* slot_config, sdspi .host_id = slot_config->host_id, .gpio_cs = slot_config->gpio_cs, .duty_cycle_pos = slot_config->duty_cycle_pos, + .poll_busy_start_command_timeout = wait_for_miso_to_poll_busy_timeout_ms(slot_config->wait_for_miso), }; // Attach the SD card to the SPI bus @@ -452,7 +476,6 @@ cleanup: } free(slot); return ret; - } esp_err_t sdspi_host_start_command(sdspi_dev_handle_t handle, sdspi_hw_cmd_t *cmd, void *data, @@ -473,8 +496,21 @@ esp_err_t sdspi_host_start_command(sdspi_dev_handle_t handle, sdspi_hw_cmd_t *cm ESP_LOGV(TAG, "%s: slot=%i, CMD%d, arg=0x%08"PRIx32" flags=0x%x, data=%p, data_size=%"PRIu32" crc=0x%02x", __func__, handle, cmd_index, cmd_arg, flags, data, data_size, cmd->crc7); - spi_device_acquire_bus(slot->spi_handle, portMAX_DELAY); - poll_busy(slot, 40, true); + esp_err_t ret; + ret = spi_device_acquire_bus(slot->spi_handle, portMAX_DELAY); + if (ret != ESP_OK) { + ESP_LOGD(TAG, "%s: spi_device_acquire_bus returned 0x%x", __func__, ret); + return ret; + } + + ret = poll_busy(slot, slot->poll_busy_start_command_timeout, true); + if (ret != ESP_OK && ret != ESP_ERR_TIMEOUT) { + ESP_LOGD(TAG, "%s: poll_busy error=0x%x", __func__, ret); + cs_high(slot); + release_bus(slot); + spi_device_release_bus(slot->spi_handle); + return ret; + } // For CMD0, clock out 80 cycles to help the card enter idle state, // *before* CS is asserted. @@ -482,7 +518,7 @@ esp_err_t sdspi_host_start_command(sdspi_dev_handle_t handle, sdspi_hw_cmd_t *cm go_idle_clockout(slot); } // actual transaction - esp_err_t ret = ESP_OK; + ret = ESP_OK; cs_low(slot); if (flags & SDSPI_CMD_FLAG_DATA) { @@ -574,6 +610,11 @@ static esp_err_t start_command_default(slot_info_t *slot, int flags, sdspi_hw_cm // Wait until MISO goes high static esp_err_t poll_busy(slot_info_t *slot, int timeout_ms, bool polling) { + if (timeout_ms < 0) { + return ESP_ERR_INVALID_ARG; + } else if (timeout_ms == 0) { + return ESP_OK; + } uint8_t t_rx; spi_transaction_t t = { .tx_buffer = &t_rx, diff --git a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_begin_end_spi.c b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_begin_end_spi.c index 53cb1f08fa..bc426cdaf4 100644 --- a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_begin_end_spi.c +++ b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_begin_end_spi.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -37,13 +37,24 @@ void sdmmc_test_spi_skip_if_board_incompatible(int slot, int freq_khz) } -void sdmmc_test_spi_begin(int slot, int freq_khz, sdmmc_card_t *out_card) +void sdmmc_test_spi_begin(int slot, int freq_khz, sdmmc_card_t *out_card, + sdmmc_host_t *_config, sdspi_device_config_t *_dev_config, spi_bus_config_t *_bus_config) { sdmmc_host_t config = SDSPI_HOST_DEFAULT(); sdspi_device_config_t dev_config = SDSPI_DEVICE_CONFIG_DEFAULT(); spi_bus_config_t bus_config = {}; - sdspi_dev_handle_t handle; + if (_config != NULL) { + config = *_config; + } + if (_dev_config != NULL) { + dev_config = *_dev_config; + } + if (_bus_config != NULL) { + bus_config = *_bus_config; + } + + sdspi_dev_handle_t handle; /* Similar to the checks in sdmmc_test_spi_skip_if_board_incompatible, but * we fail the test if we somehow got to this point with an incompatible board. */ diff --git a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_begin_end_spi.h b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_begin_end_spi.h index 95f20c8a2a..d45bf5fc3b 100644 --- a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_begin_end_spi.h +++ b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_begin_end_spi.h @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include "sd_protocol_types.h" +#include "driver/sdspi_host.h" #ifdef __cplusplus extern "C" { @@ -29,7 +30,8 @@ void sdmmc_test_spi_skip_if_board_incompatible(int slot, int freq_khz); * @brief Helper function to initialize the SDMMC host and slot for the test using the given settings, for SPI mode * @see sdmmc_test_sd_begin */ -void sdmmc_test_spi_begin(int slot, int freq_khz, sdmmc_card_t *out_card); +void sdmmc_test_spi_begin(int slot, int freq_khz, sdmmc_card_t *out_card, + sdmmc_host_t *_config, sdspi_device_config_t *_dev_config, spi_bus_config_t *_bus_config); /** * @brief Helper function to deinitialize the SDMMC host and slot after the test, for SPI mode diff --git a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_erase_spi.c b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_erase_spi.c index 5f1e3c10f3..4303191766 100644 --- a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_erase_spi.c +++ b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_erase_spi.c @@ -16,7 +16,7 @@ static void do_one_sdspi_erase(int slot, int freq_khz) { sdmmc_card_t card; sdmmc_test_spi_skip_if_board_incompatible(slot, freq_khz); - sdmmc_test_spi_begin(slot, freq_khz, &card); + sdmmc_test_spi_begin(slot, freq_khz, &card, NULL, NULL, NULL); sdmmc_card_print_info(stdout, &card); sdmmc_test_sd_erase_blocks(&card); sdmmc_test_spi_end(slot, &card); diff --git a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_probe_spi.c b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_probe_spi.c index f765e52a65..c669727338 100644 --- a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_probe_spi.c +++ b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_probe_spi.c @@ -14,7 +14,7 @@ static void do_one_sdspi_probe(int slot, int freq_khz) { sdmmc_card_t card; sdmmc_test_spi_skip_if_board_incompatible(slot, freq_khz); - sdmmc_test_spi_begin(slot, freq_khz, &card); + sdmmc_test_spi_begin(slot, freq_khz, &card, NULL, NULL, NULL); sdmmc_card_print_info(stdout, &card); uint8_t* buffer = heap_caps_calloc(512, 1, MALLOC_CAP_DMA); TEST_ESP_OK(sdmmc_read_sectors(&card, buffer, 0, 1)); diff --git a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_rw_spi.c b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_rw_spi.c index 916498b3c9..986ff591ad 100644 --- a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_rw_spi.c +++ b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_rw_spi.c @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include "unity.h" #include "sdmmc_cmd.h" +#include "driver/sdspi_host.h" #include "sdmmc_test_begin_end_spi.h" #include "sdmmc_test_rw_common.h" @@ -15,7 +16,7 @@ static void do_one_sdspi_perf_test(int slot, int freq_khz) { sdmmc_card_t card; sdmmc_test_spi_skip_if_board_incompatible(slot, freq_khz); - sdmmc_test_spi_begin(slot, freq_khz, &card); + sdmmc_test_spi_begin(slot, freq_khz, &card, NULL, NULL, NULL); sdmmc_card_print_info(stdout, &card); sdmmc_test_rw_performance(&card, NULL); sdmmc_test_spi_end(slot, &card); @@ -39,7 +40,7 @@ static void do_one_sdspi_rw_test_with_offset(int slot, int freq_khz) { sdmmc_card_t card; sdmmc_test_spi_skip_if_board_incompatible(slot, freq_khz); - sdmmc_test_spi_begin(slot, freq_khz, &card); + sdmmc_test_spi_begin(slot, freq_khz, &card, NULL, NULL, NULL); sdmmc_card_print_info(stdout, &card); sdmmc_test_rw_with_offset(&card); sdmmc_test_spi_end(slot, &card); @@ -63,7 +64,7 @@ static void do_one_sdspi_rw_test_unaligned_buffer(int slot, int freq_khz) { sdmmc_card_t card; sdmmc_test_spi_skip_if_board_incompatible(slot, freq_khz); - sdmmc_test_spi_begin(slot, freq_khz, &card); + sdmmc_test_spi_begin(slot, freq_khz, &card, NULL, NULL, NULL); sdmmc_card_print_info(stdout, &card); sdmmc_test_rw_unaligned_buffer(&card); sdmmc_test_spi_end(slot, &card); @@ -78,3 +79,31 @@ TEST_CASE("sdspi read/write using unaligned buffer, slot 1", "[sdspi]") { do_one_sdspi_rw_test_unaligned_buffer(SLOT_1, SDMMC_FREQ_DEFAULT); } + +/* ========== Read/write performance tests with wait_for_miso == -1, SPI ========== */ + +static void do_one_sdspi_perf_test_dont_wait_for_miso(int slot, int freq_khz) +{ + sdmmc_card_t card; + sdmmc_host_t config = SDSPI_HOST_DEFAULT(); + sdspi_device_config_t dev_config = SDSPI_DEVICE_CONFIG_DEFAULT(); + dev_config.wait_for_miso = -1; // no waiting for MISO + spi_bus_config_t bus_config = {}; + sdmmc_test_spi_skip_if_board_incompatible(slot, freq_khz); + sdmmc_test_spi_begin(slot, freq_khz, &card, &config, &dev_config, &bus_config); + sdmmc_card_print_info(stdout, &card); + sdmmc_test_rw_performance(&card, NULL); + sdmmc_test_spi_end(slot, &card); +} + +TEST_CASE("sdspi read/write performance - wait_for_miso == -1, slot 0", "[sdspi]") +{ + do_one_sdspi_perf_test_dont_wait_for_miso(SLOT_0, SDMMC_FREQ_HIGHSPEED); +} + +TEST_CASE("sdspi read/write performance - wait_for_miso == -1, slot 1", "[sdspi]") +{ + //TODO: IDF-8749 + //here freq should be changed to SDMMC_FREQ_HIGHSPEED after fixing IDF-8749 + do_one_sdspi_perf_test_dont_wait_for_miso(SLOT_1, SDMMC_FREQ_DEFAULT); +} diff --git a/examples/storage/sd_card/sdspi/README.md b/examples/storage/sd_card/sdspi/README.md index bb5ba7dcb8..7b147b1692 100644 --- a/examples/storage/sd_card/sdspi/README.md +++ b/examples/storage/sd_card/sdspi/README.md @@ -236,3 +236,15 @@ In the absence of connected pullups and having the weak pullups enabled, you can It will also provide the voltage levels at the corresponding SD pins. By default, this information is provided for ESP32 chip only, and for other chipsets, verify the availability of ADC pins for the respective GPIO using [this](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html#gpio-summary) and configure ADC mapped pins using menuconfig. Then test the voltage levels accordingly. You can monitor the voltage levels of individual pins using `PIN voltage levels` and `PIN voltage levels with weak pullup`. However, if one pin being pulled low and experiencing interference with another pin, you can detect it through `PIN cross-talk` and `PIN cross-talk with weak pullup`. In the absence of pullups, voltage levels at each pin should range from 0 to 0.3V. With 10k pullups connected, the voltage will be between 3.1V to 3.3V, contingent on the connection between ADC pins and SD pins, and with weak pullups connected, it can fluctuate between 0.8V to 1.2V, depending on pullup strength. + +### Slow performance / low throughput (no or incorrect pull-up resistor on MISO line) + +The current driver implementation waits for the MISO line to be high before sending the next transaction. This is the correct behavior and fixes certain issues especially when there are more SPI devices connected to same SPI bus. However this can slow down SD throughput on boards lacking a sufficiently strong pull-up resistor on the MISO line. + +If you experience this slowdown, you can try adding the following line. Modifying this value can cause problems in certain scenarios (e.g. SD card and another device like TFT screen sharing the same SPI bus resulting in failed communication with SD card), so please use it with caution. + +```c + sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT() + slot_config.wait_for_miso = -1; // <--- Add this line + // If this causes problems, try to set the value higher (-1: no waiting (0ms); 0: default value (40ms); 1-127: timeout in ms; else: invalid value, default will be used) +``` From bbcc13be8b38283547883bfee4920331bea80cd1 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Fri, 21 Nov 2025 15:54:14 +0530 Subject: [PATCH 002/226] fix(esp_http_client): prevent out-of-bounds read in Digest auth Fixed vulnerability where malicious HTTP servers could trigger OOB reads by sending empty or very short algorithm fields in WWW-Authenticate headers. Changes: - Replace unsafe memcmp() with strcasecmp() for algorithm comparison - Add algorithm NULL validation at function entry point - Fix duplicate md5-sess check, add missing SHA-256 check --- components/esp_http_client/lib/http_auth.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/components/esp_http_client/lib/http_auth.c b/components/esp_http_client/lib/http_auth.c index 6ba025933e..862bc25665 100644 --- a/components/esp_http_client/lib/http_auth.c +++ b/components/esp_http_client/lib/http_auth.c @@ -122,14 +122,15 @@ char *http_auth_digest(const char *username, const char *password, esp_http_auth password == NULL || auth_data->nonce == NULL || auth_data->uri == NULL || - auth_data->realm == NULL) { + auth_data->realm == NULL || + auth_data->algorithm == NULL) { return NULL; } int digest_size = MD5_MAX_LEN; int (*digest_func)(char *digest, const char *fmt, ...) = md5_printf; - if (!memcmp(auth_data->algorithm, "SHA256", strlen("SHA256")) || - !memcmp(auth_data->algorithm, "SHA-256", strlen("SHA-256"))) { + if (strcasecmp(auth_data->algorithm, "SHA256") == 0 || + strcasecmp(auth_data->algorithm, "SHA-256") == 0) { digest_size = SHA256_HEX_LEN; digest_func = sha256_sprintf; } @@ -150,7 +151,7 @@ char *http_auth_digest(const char *username, const char *password, esp_http_auth ESP_LOGD(TAG, "%s %s %s %s", "Digest", username, auth_data->realm, password); if ((strcasecmp(auth_data->algorithm, "md5-sess") == 0) || (strcasecmp(auth_data->algorithm, "SHA256") == 0) || - (strcasecmp(auth_data->algorithm, "md5-sess") == 0)) { + (strcasecmp(auth_data->algorithm, "SHA-256") == 0)) { if (digest_func(ha1, "%s:%s:%016llx", ha1, auth_data->nonce, auth_data->cnonce) <= 0) { goto _digest_exit; } From f8e7ae3df29ad0b87add98ad2c394f54ef988139 Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Thu, 18 Dec 2025 15:50:48 +0100 Subject: [PATCH 003/226] fix(freertos): Added stability fixes to tick hook test --- .../freertos/misc/test_idf_additions.c | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/components/freertos/test_apps/freertos/misc/test_idf_additions.c b/components/freertos/test_apps/freertos/misc/test_idf_additions.c index 5c5c3d69ad..99e67eb97b 100644 --- a/components/freertos/test_apps/freertos/misc/test_idf_additions.c +++ b/components/freertos/test_apps/freertos/misc/test_idf_additions.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -282,7 +282,7 @@ Expected: --------------------------------------------------------------------------------------------------------------------- */ #define TEST_DELAY_MS 200 -static uint32_t tick_hook_count[portNUM_PROCESSORS]; +static volatile uint32_t tick_hook_count[portNUM_PROCESSORS]; static void IRAM_ATTR tick_hook(void) { @@ -296,10 +296,21 @@ static void suspend_task(void *arg) /* Fetch the current core ID */ BaseType_t xCoreID = portGET_CORE_ID(); + /* Warm up the cache by running the scheduler suspension/resumption once. + * This reduces the execution time variance caused by cache misses during + * the actual test on targets like the esp32p4. + */ + vTaskSuspendAll(); + xTaskResumeAll(); + vTaskDelay(pdMS_TO_TICKS(10)); + /* Register tick hook */ - memset(tick_hook_count, 0, sizeof(tick_hook_count)); + tick_hook_count[xCoreID] = 0; esp_register_freertos_tick_hook_for_cpu(tick_hook, xCoreID); + /* Read the tick hook count before suspending */ + uint32_t initial_count = tick_hook_count[xCoreID]; + /* Suspend scheduler */ vTaskSuspendAll(); @@ -312,30 +323,39 @@ static void suspend_task(void *arg) /* Delay for a further TEST_DELAY_MS milliseconds after scheduler resumption */ vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MS)); + /* Read the final tick hook count */ + uint32_t final_count = tick_hook_count[xCoreID]; + /* De-register tick hook */ esp_deregister_freertos_tick_hook_for_cpu(tick_hook, xCoreID); /* Verify that the tick hook callback count equals the scheduler suspension time + the delay time. * We add a variation of 2 ticks to account for delays encountered during test setup and teardown. */ - printf("Core%d tick_hook_count = %"PRIu32"\n", xCoreID, tick_hook_count[xCoreID]); - TEST_ASSERT_INT_WITHIN(portTICK_PERIOD_MS * 2, TEST_DELAY_MS * 2, tick_hook_count[xCoreID]); + printf("Core%d initial_count = %"PRIu32"\n", xCoreID, initial_count); + printf("Core%d final_count = %"PRIu32"\n", xCoreID, final_count); + TEST_ASSERT_INT_WITHIN(portTICK_PERIOD_MS * 2, TEST_DELAY_MS * 2, final_count - initial_count); /* Signal main task of test completion */ xTaskNotifyGive(main_task_hdl); - /* Cleanup */ - vTaskDelete(NULL); + vTaskSuspend(NULL); } TEST_CASE("IDF additions: IDF tick hooks during scheduler suspension", "[freertos]") { /* Run test for each core */ + TaskHandle_t suspend_task_handle[portNUM_PROCESSORS]; for (int x = 0; x < portNUM_PROCESSORS; x++) { - xTaskCreatePinnedToCore(&suspend_task, "suspend_task", 8192, (void *)xTaskGetCurrentTaskHandle(), UNITY_FREERTOS_PRIORITY, NULL, x); + xTaskCreatePinnedToCore(&suspend_task, "suspend_task", 8192, (void *)xTaskGetCurrentTaskHandle(), UNITY_FREERTOS_PRIORITY, &suspend_task_handle[x], x); /* Wait for test completion */ ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + /* Cleanup */ + vTaskSuspend(suspend_task_handle[x]); + vTaskDelay(pdMS_TO_TICKS(10)); + vTaskDelete(suspend_task_handle[x]); } } From 5931eb29084eec72f155a8714a8f3d61dc1f79ae Mon Sep 17 00:00:00 2001 From: Wei Yu Han Date: Fri, 26 Dec 2025 15:52:33 +0800 Subject: [PATCH 004/226] docs(ble): Added BLE Multi Connection Guide (cherry picked from commit 80905af2f030380a560333d164494f683e41bda9) Co-authored-by: Wei Yuhan --- docs/conf_common.py | 1 + .../ble/ble-multiconnection-guide.rst | 63 +++++++++++++++++++ docs/en/api-guides/ble/index.rst | 1 + .../ble/ble-multiconnection-guide.rst | 63 +++++++++++++++++++ docs/zh_CN/api-guides/ble/index.rst | 1 + 5 files changed, 129 insertions(+) create mode 100644 docs/en/api-guides/ble/ble-multiconnection-guide.rst create mode 100644 docs/zh_CN/api-guides/ble/ble-multiconnection-guide.rst diff --git a/docs/conf_common.py b/docs/conf_common.py index 7637498e78..5278e0c685 100644 --- a/docs/conf_common.py +++ b/docs/conf_common.py @@ -34,6 +34,7 @@ BLE_DOCS = [ 'api-guides/ble/ble-feature-support-status.rst', 'api-guides/ble/host-feature-support-status.rst', 'api-guides/ble/ble-qualification.rst', + 'api-guides/ble/ble-multiconnection-guide.rst', 'api-guides/ble/get-started/ble-introduction.rst', 'api-guides/ble/get-started/ble-device-discovery.rst', 'api-guides/ble/get-started/ble-connection.rst', diff --git a/docs/en/api-guides/ble/ble-multiconnection-guide.rst b/docs/en/api-guides/ble/ble-multiconnection-guide.rst new file mode 100644 index 0000000000..38f0c1cb43 --- /dev/null +++ b/docs/en/api-guides/ble/ble-multiconnection-guide.rst @@ -0,0 +1,63 @@ +Multi-Connection Guide +========================================== + +:link_to_translation:`zh_CN:[中文]` + +Introduction +-------------- + +The following table provides an overview of the maximum number of concurrent connections supported for each ESP Bluetooth LE Host. In multi-connection scenarios, connection parameters must be configured appropriately. In general, as the number of connections increases, the connection interval should be increased accordingly. For detailed parameter configuration recommendations and SDK configuration details, please refer to the corresponding example code in the following table. + +In this document, the maximum number of connections refers to the maximum number of simultaneous active connections that the device can maintain, whether operating as a central or peripheral. + +.. table:: Maximum Concurrent Connections by ESP Bluetooth LE Host + + +---------------+-----------------------------+------------------------------+---------------------+ + | Host | Max Connections | SDKconfig | Example | + +===============+=============================+==============================+=====================+ + | | | |bluedroid_enable_config| | | + | ESP-Bluedroid | |max_bluedroid_connections| | | |bluedroid_example| | + | | | |bluedroid_connection_num| | | + +---------------+-----------------------------+------------------------------+---------------------+ + | ESP-NimBLE | |max_nimble_connections| | |nimble_connection_num| | |nimble_example| | + +---------------+-----------------------------+------------------------------+---------------------+ + + +Note +---- + +1. The ability to support multiple connections highly depends on the application’s overall memory usage. It is recommended to disable unnecessary features to optimize multi-connection performance. + +2. When the device operates in the peripheral role, connection stability and overall performance will be influenced by the central device and the negotiated connection parameters. + +.. only:: not esp32 and not esp32c3 and not esp32s3 and not esp32c2 + + 3. Due to the relatively higher memory usage of ESP-Bluedroid, it supports fewer concurrent connections compared to ESP-Nimble. + + 4. If your application requires more simultaneous connections than the values listed above, please contact our `customer support team `__ for further assistance. + +.. |bluedroid_enable_config| replace:: :ref:`BT_MULTI_CONNECTION_ENBALE ` +.. |bluedroid_connection_num| replace:: :ref:`BT_ACL_CONNECTIONS ` +.. |bluedroid_example| replace:: :example:`multi_conn ` +.. |nimble_connection_num| replace:: :ref:`BT_NIMBLE_MAX_CONNECTIONS ` +.. |nimble_example| replace:: :example:`multi_conn` + +.. only:: esp32 or esp32c3 or esp32s3 + + .. |max_bluedroid_connections| replace:: 9 + .. |max_nimble_connections| replace:: 9 + +.. only:: esp32c2 + + .. |max_bluedroid_connections| replace:: 2 + .. |max_nimble_connections| replace:: 2 + +.. only:: esp32h2 + + .. |max_bluedroid_connections| replace:: 15 + .. |max_nimble_connections| replace:: 70 + +.. only:: esp32c6 or esp32c5 or esp32c61 + + .. |max_bluedroid_connections| replace:: 50 + .. |max_nimble_connections| replace:: 70 diff --git a/docs/en/api-guides/ble/index.rst b/docs/en/api-guides/ble/index.rst index e9deeee59f..1663f253f9 100644 --- a/docs/en/api-guides/ble/index.rst +++ b/docs/en/api-guides/ble/index.rst @@ -14,6 +14,7 @@ Overview ble-feature-support-status ble-qualification Low Power Mode Introduction <../low-power-mode/low-power-mode-ble> + ble-multiconnection-guide *************** Get Started diff --git a/docs/zh_CN/api-guides/ble/ble-multiconnection-guide.rst b/docs/zh_CN/api-guides/ble/ble-multiconnection-guide.rst new file mode 100644 index 0000000000..504e5ade46 --- /dev/null +++ b/docs/zh_CN/api-guides/ble/ble-multiconnection-guide.rst @@ -0,0 +1,63 @@ +多连接指南 +============================= + +:link_to_translation:`en:[English]` + +介绍 +---- + +下表展示了每个 ESP 低功耗蓝牙主机所支持的最大多连接个数。在多连接场景下,需要对连接参数进行合理配置。通常情况下,随着连接数量的增加,连接间隔(Connection Interval)也应相应增大。具体的参数配置建议和 sdkconfig 详细信息,请参阅下表中的相应示例代码。 + +在本文档中,最大连接数指设备作为中心设备或外围设备时,能够同时维持的最大连接数量。 + +.. table:: ESP 低功耗蓝牙主机支持的最大连接数 + + +---------------+-----------------------------+------------------------------+---------------------+ + | 主机(Host) | 最大连接个数 | SDKconfig | 示例 | + +===============+=============================+==============================+=====================+ + | | | |bluedroid_enable_config| | | + | ESP-Bluedroid | |max_bluedroid_connections| | | |bluedroid_example| | + | | | |bluedroid_connection_num| | | + +---------------+-----------------------------+------------------------------+---------------------+ + | ESP-NimBLE | |max_nimble_connections| | |nimble_connection_num| | |nimble_example| | + +---------------+-----------------------------+------------------------------+---------------------+ + + +注意 +---- + +1. 应用能够支持的最大连接数在很大程度上取决于整体内存使用情况。建议禁用不必要的功能,以优化多连接性能。 + +2. 当设备处于外围角色时,连接稳定性和整体性能将受到中心设备和协商连接参数的影响。 + +.. only:: not esp32 and not esp32c3 and not esp32s3 and not esp32c2 + + 3. 由于 ESP-Bluedroid 的内存占用相对更高,其支持的最大连接数会少于 ESP-Nimble。 + + 4. 如果您的应用需要的同时连接数量超过上述数值,请联系 `乐鑫客户支持团队 `__ 以获取进一步的协助。 + +.. |bluedroid_enable_config| replace:: :ref:`BT_MULTI_CONNECTION_ENBALE ` +.. |bluedroid_connection_num| replace:: :ref:`BT_ACL_CONNECTIONS ` +.. |bluedroid_example| replace:: :example:`multi_conn ` +.. |nimble_connection_num| replace:: :ref:`BT_NIMBLE_MAX_CONNECTIONS ` +.. |nimble_example| replace:: :example:`multi_conn` + +.. only:: esp32 or esp32c3 or esp32s3 + + .. |max_bluedroid_connections| replace:: 9 + .. |max_nimble_connections| replace:: 9 + +.. only:: esp32c2 + + .. |max_bluedroid_connections| replace:: 2 + .. |max_nimble_connections| replace:: 2 + +.. only:: esp32h2 + + .. |max_bluedroid_connections| replace:: 15 + .. |max_nimble_connections| replace:: 70 + +.. only:: esp32c6 or esp32c5 or esp32c61 + + .. |max_bluedroid_connections| replace:: 50 + .. |max_nimble_connections| replace:: 70 diff --git a/docs/zh_CN/api-guides/ble/index.rst b/docs/zh_CN/api-guides/ble/index.rst index 201911777f..79c7db0f7e 100644 --- a/docs/zh_CN/api-guides/ble/index.rst +++ b/docs/zh_CN/api-guides/ble/index.rst @@ -14,6 +14,7 @@ ble-feature-support-status ble-qualification 低功耗模式介绍 <../low-power-mode/low-power-mode-ble> + ble-multiconnection-guide ********** 快速入门 From 382174fdf011af9355d6b91411d96476b0c2ea14 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Tue, 13 May 2025 19:46:50 +0800 Subject: [PATCH 005/226] feat(ble/bluedroid): Add bluedroid host PAwR feature --- components/bt/host/bluedroid/Kconfig.in | 7 + .../bt/host/bluedroid/api/esp_gap_ble_api.c | 98 +++++++++ .../api/include/api/esp_gap_ble_api.h | 185 ++++++++++++++++- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 19 ++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 71 +++++++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 5 + .../bluedroid/bta/dm/include/bta_dm_int.h | 60 ++++++ .../host/bluedroid/bta/include/bta/bta_api.h | 24 ++- .../btc/profile/std/gap/btc_gap_ble.c | 187 +++++++++++++++++- .../btc/profile/std/include/btc_gap_ble.h | 36 +++- .../include/common/bluedroid_user_config.h | 6 + .../common/include/common/bt_target.h | 6 + .../bt/host/bluedroid/device/controller.c | 2 +- .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 75 ++++++- .../bluedroid/stack/btm/include/btm_ble_int.h | 4 + .../bt/host/bluedroid/stack/btu/btu_hcif.c | 139 +++++++++++-- .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 146 +++++++++++++- .../stack/include/stack/btm_ble_api.h | 81 +++++++- .../bluedroid/stack/include/stack/hcidefs.h | 15 ++ .../bluedroid/stack/include/stack/hcimsgs.h | 24 ++- 20 files changed, 1162 insertions(+), 28 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index edf146769c..cb2b1dc4ba 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1509,6 +1509,13 @@ config BT_BLE_FEAT_CONN_SUBRATING help Enable BLE connection subrating feature +config BT_BLE_FEAT_PAWR_EN + bool "Enable Periodic Advertisement with Response(PAwR)" + depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_PAWR_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR + default n + help + Enable BLE Periodic Advertisement with Response(PAwR) feature + config BT_BLE_VENDOR_HCI_EN bool "Enable BLE Vendor HCI command and event" depends on BT_BLE_ENABLED 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 d592b6b77f..d90d55cebe 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -2082,3 +2082,101 @@ esp_err_t esp_ble_gap_set_host_feature(uint16_t bit_num, uint8_t bit_val) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) + +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +esp_err_t esp_ble_gap_set_periodic_adv_subevent_data(esp_ble_per_adv_subevent_data_params *subevent_data_params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if ((!subevent_data_params) || (!subevent_data_params->subevent_params)) { + return ESP_ERR_NOT_ALLOWED; + } + + for (uint8_t i = 0; i < subevent_data_params->num_subevents_with_data; i++) + { + if (subevent_data_params->subevent_params[i].subevent_data_len && (subevent_data_params->subevent_params[i].subevent_data == NULL)) { + return ESP_ERR_NOT_ALLOWED; + } + } + + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_PA_SUBEVT_DATA; + + arg.per_adv_subevent_data_params.adv_handle = subevent_data_params->adv_handle; + arg.per_adv_subevent_data_params.num_subevents_with_data = subevent_data_params->num_subevents_with_data; + arg.per_adv_subevent_data_params.subevent_params = subevent_data_params->subevent_params; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy, btc_gap_ble_arg_deep_free) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_set_periodic_adv_response_data(esp_ble_per_adv_response_data_params *rsp_data_params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!rsp_data_params) { + return ESP_ERR_NOT_ALLOWED; + } + + if ((rsp_data_params->response_data == NULL) && rsp_data_params->response_data_len) { + return ESP_ERR_NOT_ALLOWED; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_PA_RSP_DATA; + + arg.per_adv_response_data_params.sync_handle = rsp_data_params->sync_handle; + arg.per_adv_response_data_params.request_event = rsp_data_params->request_event; + arg.per_adv_response_data_params.request_subevent = rsp_data_params->request_subevent; + arg.per_adv_response_data_params.response_subevent = rsp_data_params->response_subevent; + arg.per_adv_response_data_params.response_slot = rsp_data_params->response_slot; + arg.per_adv_response_data_params.response_data_len = rsp_data_params->response_data_len; + arg.per_adv_response_data_params.response_data = rsp_data_params->response_data; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy, btc_gap_ble_arg_deep_free) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_set_periodic_sync_subevent(esp_ble_per_sync_subevent_params *sync_subevent_params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!sync_subevent_params) { + return ESP_ERR_NOT_ALLOWED; + } + + if ((sync_subevent_params->subevent == NULL) && sync_subevent_params->num_subevents_to_sync) { + return ESP_ERR_NOT_ALLOWED; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_PA_SYNC_SUBEVT; + + arg.per_sync_subevent_params.sync_handle = sync_subevent_params->sync_handle; + arg.per_sync_subevent_params.periodic_adv_properties = sync_subevent_params->periodic_adv_properties; + arg.per_sync_subevent_params.num_subevents_to_sync = sync_subevent_params->num_subevents_to_sync; + arg.per_sync_subevent_params.subevent = sync_subevent_params->subevent; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy, btc_gap_ble_arg_deep_free) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 89b14f7b75..c23c403d3b 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -249,6 +249,11 @@ typedef enum { ESP_GAP_BLE_SET_COMMON_FACTOR_CMPL_EVT, /*!< When set the common factor complete, the event comes */ ESP_GAP_BLE_SET_SCH_LEN_CMPL_EVT, /*!< When set the scheduling length complete, the event comes */ ESP_GAP_BLE_SET_SCAN_CHAN_MAP_CMPL_EVT, /*!< When set the channel map for scanning complete, the event comes */ + ESP_GAP_BLE_SET_PERIODIC_ADV_SUBEVT_DATA_EVT, /*!< When BLE update periodic adv subevent data complete, the event comes */ + ESP_GAP_BLE_SET_PERIODIC_ADV_RESPONSE_DATA_EVT, /*!< When BLE update periodic adv response data complete, the event comes */ + ESP_GAP_BLE_SET_PERIODIC_SYNC_SUBEVT_EVT, /*!< When BLE update periodic sync subevent complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_SUBEVT_DATA_REQUEST_EVT, /*!< When Controller is ready to transmit one or more subevents and is requesting the advertising data for these subevents, the event comes*/ + ESP_GAP_BLE_PERIODIC_ADV_RESPONSE_REPORT_EVT, /*!< When one or more devices have responded to a periodic advertising subevent during a PAwR train, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ } esp_gap_ble_cb_event_t; @@ -975,7 +980,25 @@ typedef struct { typedef struct { uint16_t interval_min; /*!< periodic advertising minimum interval */ uint16_t interval_max; /*!< periodic advertising maximum interval */ - uint8_t properties; /*!< periodic advertising properties */ + uint16_t properties; /*!< periodic advertising properties */ +#if (CONFIG_BT_BLE_FEAT_PAWR_EN) + uint8_t num_subevents; /*!< Number of subevents in the PAwR. Range: 0x00 to 0x80 + 0x00: Periodic Advertising without responses */ + uint8_t subevent_interval; /*!< Interval between subevents. + Range: 0x06 to 0xFF. + Time = N × 1.25 ms. + Time Range: 7.5 ms to 318.75 ms. */ + uint8_t rsp_slot_delay; /*!< Time between the advertising packet in a subevent and the first response slot. + Range: 0x01 to 0xFE. + Time = N × 1.25 ms. + Time Range: 1.25 ms to 317.5 ms. */ + uint8_t rsp_slot_spacing; /*!< Time between response slots. + Range: 0x02 to 0xFF. + Time = N × 0.125 ms. + Time Range: 0.25 ms to 31.875 ms */ + uint8_t num_rsp_slots; /*!< Number of subevent response slots + Range: 0x01 to 0xFF. */ +#endif // (CONFIG_BT_BLE_FEAT_PAWR_EN) } esp_ble_gap_periodic_adv_params_t; /** @@ -1044,6 +1067,10 @@ typedef struct { 0x02: AoD Constant Tone Extension with 2 μs slots 0xFF: No Constant Tone Extension */ #endif // BT_BLE_FEAT_CTE_EN +#if (CONFIG_BT_BLE_FEAT_PAWR_EN) + uint16_t periodic_evt_counter; /*!< The value of paEventCounter for the reported periodic advertising packet */ + uint8_t subevt; /*!< The subevent number */ +#endif // (CONFIG_BT_BLE_FEAT_PAWR_EN) esp_ble_gap_ext_adv_data_status_t data_status; /*!< periodic advertising data type*/ uint8_t data_length; /*!< periodic advertising data length */ uint8_t data[251]; /*!< periodic advertising data */ @@ -1221,6 +1248,70 @@ typedef struct { The supervision_timeout, in milliseconds, shall be greater than 2 × current connection interval × subrate_max × (max_latency + 1) */ } esp_ble_subrate_req_param_t; +/** +* @brief Periodic adv subevent parameters +*/ +typedef struct { + uint8_t subevent; /*!< The subevent index of the data contained in this command. Range: 0x00 to 0x7F */ + uint8_t response_slot_start; /*!< The first response slots to be used in this subevent */ + uint8_t response_slot_count; /*!< The number of response slots to be used */ + uint8_t subevent_data_len; /*!< The number of octets in the Subevent_Data parameter. Range: 0 to 251 */ + uint8_t *subevent_data; /*!< The advertising data to be transmitted in the subevent of the advertising set */ +} esp_ble_subevent_params; + +/** +* @brief Periodic adv subevent data parameters +*/ +typedef struct { + uint8_t adv_handle; /*!< Used to identify a periodic advertising train */ + uint8_t num_subevents_with_data; /*!< Number of subevent data in the command. Range: 0x0001 to 0x0F */ + esp_ble_subevent_params *subevent_params; /*!< Periodic adv subevent parameters */ +} esp_ble_per_adv_subevent_data_params; + +/** +* @brief Periodic adv response data parameters +*/ +typedef struct { + uint16_t sync_handle; /*!< Sync_Handle identifying the PAwR train */ + uint16_t request_event; /*!< The value of eventCounter for the periodic advertising packet that the Host is responding to */ + uint8_t request_subevent; /*!< The subevent for the periodic advertising packet that the Host is responding to */ + uint8_t response_subevent; /*!< Used to identify the subevent of the PAwR train. Range: 0x00 to 0x7F */ + uint8_t response_slot; /*!< Used to identify the response slot of the PAwR train. Range: 0x00 to 0xFF */ + uint8_t response_data_len; /*!< The number of octets in the Response_Data parameter. Range: 0 to 251 */ + uint8_t *response_data; /*!< Response data */ +} esp_ble_per_adv_response_data_params; + +/** +* @brief Periodic sync subevent parameters +*/ +typedef struct { + uint16_t sync_handle; /*!< Sync_Handle identifying the PAwR train */ + uint16_t periodic_adv_properties; /*!< Include TxPower in the advertising PDU */ + uint8_t num_subevents_to_sync; /*!< Number of subevents. Range: 0x01 to 0x80 */ + uint8_t *subevent; /*!< The subevent to synchronize with. Range 0x00 to 0x7F */ +} esp_ble_per_sync_subevent_params; + +/** +* @brief Periodic response information +*/ +typedef struct { + int8_t tx_power; /*!< Range: -127 to +20, Units: dBm + 0x7F: Tx Power information not available*/ + int8_t rssi; /*!< Range: -127 to +20. Units: dBm + 0x7F: RSSI is not available */ + uint8_t cte_type; /*!< cte type + 0x00: AoA Constant Tone Extension + 0x01: AoD Constant Tone Extension with 1 µs slots + 0x02: AoD Constant Tone Extension with 2 µs slots + 0xFF: No Constant Tone Extension*/ + uint8_t rsp_slot; /*!< The response slot the data was received in. */ + uint8_t data_status; /*!< Data status + 0x00: Data complete + 0x01: Data incomplete, more data to come + 0xFF: Failed to receive or listen for an AUX_SYNC_SUBEVENT_RSP PDU*/ + uint8_t data_len; /*!< Length of the Data field */ + uint8_t *data; /*!< Periodic advertising response data formatted as defined in [Vol 3] Part C, Section 11*/ +} esp_ble_pa_rsp_info; /** * @brief Gap callback parameters union @@ -1634,6 +1725,12 @@ typedef union { esp_ble_gap_phy_t adv_phy; /*!< periodic advertising phy type */ uint16_t period_adv_interval; /*!< periodic advertising interval */ uint8_t adv_clk_accuracy; /*!< periodic advertising clock accuracy */ +#if (CONFIG_BT_BLE_FEAT_PAWR_EN) + uint8_t num_subevt; /*!< Number of subevents, Range: 0x00 to 0x80 */ + uint8_t subevt_interval; /*!< Subevent interval, Time = N × 1.25 ms */ + uint8_t rsp_slot_delay; /*!< Response slot delay, Time = N × 1.25 ms */ + uint8_t rsp_slot_spacing; /*!< Response slot spacing, Time = N × 0.125 ms */ +#endif // (CONFIG_BT_BLE_FEAT_PAWR_EN) } periodic_adv_sync_estab; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SYNC_ESTAB_EVT */ /** * @brief ESP_GAP_BLE_PHY_UPDATE_COMPLETE_EVT @@ -1879,6 +1976,49 @@ typedef union { esp_bt_status_t status; /*!< Indicate host feature update success status */ } host_feature; /*!< Event parameter of ESP_GAP_BLE_SET_HOST_FEATURE_CMPL_EVT */ #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + /** + * @brief ESP_GAP_BLE_SET_PERIODIC_ADV_SUBEVT_DATA_EVT + */ + struct ble_pa_subevt_data_evt { + esp_bt_status_t status; /*!< Indicate periodic adv subevent data update success status */ + uint8_t adv_handle; /*!< Used to identify a periodic advertising train */ + } pa_subevt_data_evt; /*!< Event parameter of ESP_GAP_BLE_SET_PERIODIC_ADV_SUBEVT_DATA_EVT */ + /** + * @brief ESP_GAP_BLE_SET_PERIODIC_ADV_RESPONSE_DATA_EVT + */ + struct ble_pa_rsp_data_evt { + esp_bt_status_t status; /*!< Indicate periodic adv response data update success status */ + uint16_t sync_handle; /*!< identifying the periodic advertising train */ + } pa_rsp_data_evt; /*!< Event parameter of ESP_GAP_BLE_SET_PERIODIC_ADV_RESPONSE_DATA_EVT */ + /** + * @brief ESP_GAP_BLE_SET_PERIODIC_SYNC_SUBEVT_EVT + */ + struct ble_pa_sync_subevt_evt { + esp_bt_status_t status; /*!< Indicate periodic sync subevent update success status */ + uint16_t sync_handle; /*!< identifying the periodic advertising train */ + } pa_sync_subevt_evt; /*!< Event parameter of ESP_GAP_BLE_SET_PERIODIC_SYNC_SUBEVT_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_SUBEVT_DATA_REQUEST_EVT + */ + struct ble_pa_subevt_data_req_evt { + uint8_t adv_handle; /*!< Used to identify a periodic advertising train */ + uint8_t subevt_start; /*!< The first subevent that data is requested for.*/ + uint8_t subevt_data_count; /*!< The number of subevents that data is requested for.*/ + } pa_subevt_data_req_evt; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SUBEVT_DATA_REQUEST_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_RESPONSE_REPORT_EVT + */ + struct ble_pa_rsp_rpt_evt { + uint8_t adv_handle; /*!< Used to identify a periodic advertising train */ + uint8_t subevt; /*!< The subevent number */ + uint8_t tx_status; /*!< + 0x00 AUX_SYNC_SUBEVENT_IND packet was transmitted. + 0x01 AUX_SYNC_SUBEVENT_IND packet was not transmitted.*/ + uint8_t num_rsp; /*!< Number of responses in event */ + esp_ble_pa_rsp_info *pa_rsp_info; /*!< response information */ + } pa_rsp_rpt_evt; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_RESPONSE_REPORT_EVT */ +#endif // #if (CONFIG_BT_BLE_FEAT_PAWR_EN == TRUE) } esp_ble_gap_cb_param_t; /** @@ -3317,6 +3457,49 @@ esp_err_t esp_ble_gap_subrate_request(esp_ble_subrate_req_param_t *subrate_req_p */ esp_err_t esp_ble_gap_set_host_feature(uint16_t bit_num, uint8_t bit_val); +/** + * @brief This function is used to set the data for one or more subevents of PAwR in reply to a PA subevent data request event. + * The data for a subevent shall be transmitted only once. + * + * + * @param[in] subevent_data_params: Periodic adv subevent data parameters. + * + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_set_periodic_adv_subevent_data(esp_ble_per_adv_subevent_data_params *subevent_data_params); + +/** + * @brief This function is used to set the data for a response slot in a specific subevent of the PAwR identified. + * The data for a response slot shall be transmitted only once. + * + * + * @param[in] rsp_data_params: Periodic adv response data parameters. + * + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_gap_set_periodic_adv_response_data(esp_ble_per_adv_response_data_params *rsp_data_params); + +/** + * @brief This function is used to instruct the Controller to synchronize with a subset of the subevents within a PAwR train, + * listen for packets sent by the peer device and pass any received data up to the Host. + * + * + * @param[in] sync_subevent_params: Periodic sync subevent parameters. + * + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_gap_set_periodic_sync_subevent(esp_ble_per_sync_subevent_params *sync_subevent_params); + #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index fd7d665acc..5082201278 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6347,6 +6347,25 @@ void bta_dm_ble_set_host_feature(tBTA_DM_MSG *p_data) } #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +void bta_dm_api_set_periodic_adv_subevt_data(tBTA_DM_MSG *p_data) +{ + BTM_BleSetPaSubeventData(p_data->pa_subevt_data.adv_handle, p_data->pa_subevt_data.num_subevents_with_data, (uint8_t *)(p_data->pa_subevt_data.subevent_params)); +} + +void bta_dm_api_set_periodic_adv_response_data(tBTA_DM_MSG *p_data) +{ + BTM_BleSetPaResponseData(p_data->pa_rsp_data.sync_handle, p_data->pa_rsp_data.request_event, p_data->pa_rsp_data.request_subevent, + p_data->pa_rsp_data.rsp_subevent, p_data->pa_rsp_data.rsp_slot, p_data->pa_rsp_data.rsp_data_len, + p_data->pa_rsp_data.rsp_data); +} + +void bta_dm_api_set_periodic_sync_subevt(tBTA_DM_MSG *p_data) +{ + BTM_BleSetPaSyncSubevt(p_data->pa_sync_subevt.sync_handle, p_data->pa_sync_subevt.periodic_adv_properties, p_data->pa_sync_subevt.num_subevents_to_sync, p_data->pa_sync_subevt.subevent); +} +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 08510894e6..65f564ac08 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -3169,6 +3169,77 @@ void BTA_DmBleGapSetHostFeature(uint16_t bit_num, uint8_t bit_val) } #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +void BTA_DmBleGapSetPASubevtData(uint8_t adv_handle, uint8_t num_subevents_with_data, uint8_t *subevent_params) +{ + tBTA_DM_API_BLE_PA_SUBEVENT_DATA *p_msg; + tBTA_BLE_SUBEVENT_PARAMS *p_subevent_params = (tBTA_BLE_SUBEVENT_PARAMS*)subevent_params; + + if ((p_msg = (tBTA_DM_API_BLE_PA_SUBEVENT_DATA *)osi_malloc(sizeof(tBTA_DM_API_BLE_PA_SUBEVENT_DATA) + num_subevents_with_data * sizeof(tBTA_DM_API_BLE_SUBEVENT_PARAMS))) + != NULL) { + p_msg->hdr.event = BTA_DM_API_SET_PA_SUBEVT_DATA; + p_msg->adv_handle = adv_handle; + p_msg->num_subevents_with_data = num_subevents_with_data; + p_msg->subevent_params = (tBTA_DM_API_BLE_SUBEVENT_PARAMS *)(p_msg + 1); + for (uint8_t i = 0; i < num_subevents_with_data; i++) + { + p_msg->subevent_params[i].subevent = p_subevent_params[i].subevent; + p_msg->subevent_params[i].response_slot_start = p_subevent_params[i].response_slot_start; + p_msg->subevent_params[i].response_slot_count = p_subevent_params[i].response_slot_count; + p_msg->subevent_params[i].subevent_data_len = p_subevent_params[i].subevent_data_len; + memcpy(&(p_msg->subevent_params[i].subevent_data), p_subevent_params[i].subevent_data, p_subevent_params[i].subevent_data_len); + } + + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleGapSetPeriodicAdvRspData(uint16_t sync_handle, uint16_t request_event, uint8_t request_subevent, + uint8_t rsp_subevent, uint8_t rsp_slot, uint8_t rsp_data_len, uint8_t *rsp_data) +{ + tBTA_DM_API_BLE_PA_RSP_DATA *p_msg; + + if ((p_msg = (tBTA_DM_API_BLE_PA_RSP_DATA *)osi_malloc(sizeof(tBTA_DM_API_BLE_PA_RSP_DATA) + rsp_data_len)) + != NULL) { + p_msg->hdr.event = BTA_DM_API_SET_PA_RSP_DATA; + p_msg->sync_handle = sync_handle; + p_msg->request_event = request_event; + p_msg->request_subevent = request_subevent; + p_msg->rsp_subevent = rsp_subevent; + p_msg->rsp_slot = rsp_slot; + p_msg->rsp_data_len = rsp_data_len; + p_msg->rsp_data = (UINT8 *)(p_msg + 1); + if (rsp_data_len && rsp_data) { + memcpy(p_msg->rsp_data, rsp_data, rsp_data_len); + } else if (rsp_data_len) { + APPL_TRACE_ERROR("%s rsp_data is NULL", __func__); + } + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleGapSetPeriodicSyncSubevt(uint16_t sync_handle, uint16_t periodic_adv_properties, uint8_t num_subevents_to_sync, uint8_t *subevent) +{ + tBTA_DM_API_BLE_PA_SYNC_SUBEVT *p_msg; + + if ((p_msg = (tBTA_DM_API_BLE_PA_SYNC_SUBEVT *)osi_malloc(sizeof(tBTA_DM_API_BLE_PA_SYNC_SUBEVT) + num_subevents_to_sync)) + != NULL) { + p_msg->hdr.event = BTA_DM_API_SET_PA_SYNC_SUBEVT; + p_msg->sync_handle = sync_handle; + p_msg->periodic_adv_properties = periodic_adv_properties; + p_msg->num_subevents_to_sync = num_subevents_to_sync; + p_msg->subevent = (UINT8 *)(p_msg + 1); + if (num_subevents_to_sync && subevent) { + memcpy(p_msg->subevent, subevent, num_subevents_to_sync); + } else if (num_subevents_to_sync) { + APPL_TRACE_ERROR("%s subevent is NULL", __func__); + } + bta_sys_sendmsg(p_msg); + } +} + +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + /******************************************************************************* ** ** Function BTA_VendorInit diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 9fe5e7696e..362795cd32 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -344,6 +344,11 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { #if (BLE_50_FEATURE_SUPPORT == TRUE) bta_dm_ble_set_host_feature, /* BTA_DM_API_SET_HOST_FEATURE_EVT */ #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + bta_dm_api_set_periodic_adv_subevt_data, /* BTA_DM_API_SET_PA_SUBEVT_DATA */ + bta_dm_api_set_periodic_adv_response_data, /* BTA_DM_API_SET_PA_RSP_DATA */ + bta_dm_api_set_periodic_sync_subevt, /* BTA_DM_API_SET_PA_SYNC_SUBEVT */ +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) }; diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index e724b37c3a..32b7e40a61 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -335,6 +335,11 @@ enum { #if (BLE_50_FEATURE_SUPPORT == TRUE) BTA_DM_API_SET_HOST_FEATURE_EVT, #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + BTA_DM_API_SET_PA_SUBEVT_DATA, + BTA_DM_API_SET_PA_RSP_DATA, + BTA_DM_API_SET_PA_SYNC_SUBEVT, +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) BTA_DM_MAX_EVT }; @@ -1156,6 +1161,51 @@ typedef struct { } tBTA_DM_API_SET_HOST_FEATURE; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + +typedef struct { + UINT8 subevent; + UINT8 response_slot_start; + UINT8 response_slot_count; + UINT8 subevent_data_len; + UINT8 *subevent_data; +} tBTA_BLE_SUBEVENT_PARAMS; + +typedef struct { + UINT8 subevent; + UINT8 response_slot_start; + UINT8 response_slot_count; + UINT8 subevent_data_len; + UINT8 subevent_data[251]; +} tBTA_DM_API_BLE_SUBEVENT_PARAMS; + +typedef struct { + BT_HDR hdr; + UINT8 adv_handle; + UINT8 num_subevents_with_data; + tBTA_DM_API_BLE_SUBEVENT_PARAMS *subevent_params; +} tBTA_DM_API_BLE_PA_SUBEVENT_DATA; + +typedef struct { + BT_HDR hdr; + UINT16 sync_handle; + UINT16 request_event; + UINT8 request_subevent; + UINT8 rsp_subevent; + UINT8 rsp_slot; + UINT8 rsp_data_len; + UINT8 *rsp_data; +} tBTA_DM_API_BLE_PA_RSP_DATA; + +typedef struct { + BT_HDR hdr; + UINT16 sync_handle; + UINT16 periodic_adv_properties; + UINT8 num_subevents_to_sync; + UINT8 *subevent; +} tBTA_DM_API_BLE_PA_SYNC_SUBEVT; +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + #endif /* BLE_INCLUDED */ #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) @@ -1876,6 +1926,11 @@ typedef union { #if (BLE_50_FEATURE_SUPPORT == TRUE) tBTA_DM_API_SET_HOST_FEATURE set_host_feat; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + tBTA_DM_API_BLE_PA_SUBEVENT_DATA pa_subevt_data; + tBTA_DM_API_BLE_PA_RSP_DATA pa_rsp_data; + tBTA_DM_API_BLE_PA_SYNC_SUBEVT pa_sync_subevt; +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) } tBTA_DM_MSG; @@ -2543,4 +2598,9 @@ void bta_dm_api_subrate_request(tBTA_DM_MSG *p_data); #if (BLE_50_FEATURE_SUPPORT == TRUE) extern void bta_dm_ble_set_host_feature(tBTA_DM_MSG *p_data); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +void bta_dm_api_set_periodic_adv_subevt_data(tBTA_DM_MSG *p_data); +void bta_dm_api_set_periodic_adv_response_data(tBTA_DM_MSG *p_data); +void bta_dm_api_set_periodic_sync_subevt(tBTA_DM_MSG *p_data); +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) #endif /* BTA_DM_INT_H */ diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index aa1b632aad..b87d33acf3 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1584,7 +1584,14 @@ typedef struct { typedef struct { UINT16 interval_min; UINT16 interval_max; - UINT8 properties; + UINT16 properties; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + UINT8 num_subevents; + UINT8 subevent_interval; + UINT8 rsp_slot_delay; + UINT8 rsp_slot_spacing; + UINT8 num_rsp_slots; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) } tBTA_DM_BLE_Periodic_Adv_Params; typedef struct { @@ -1701,6 +1708,14 @@ typedef struct { #define BTA_BLE_GAP_SET_HOST_FEATURE_EVT BTM_BLE_GAP_SET_HOST_FEATURE_EVT #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +#define BTA_BLE_GAP_SET_PERIODIC_ADV_SUBEVT_DATA_EVT BTM_BLE_GAP_SET_PERIODIC_ADV_SUBEVT_DATA_EVT +#define BTA_BLE_GAP_SET_PERIODIC_ADV_RESPONSE_DATA_EVT BTM_BLE_GAP_SET_PERIODIC_ADV_RESPONSE_DATA_EVT +#define BTA_BLE_GAP_SET_PERIODIC_SYNC_SUBEVT_EVT BTM_BLE_GAP_SET_PERIODIC_SYNC_SUBEVT_EVT +#define BTA_BLE_GAP_PERIODIC_ADV_SUBEVT_DATA_REQUEST_EVT BTM_BLE_GAP_PERIODIC_ADV_SUBEVT_DATA_REQUEST_EVT +#define BTA_BLE_GAP_PERIODIC_ADV_RESPONSE_REPORT_EVT BTM_BLE_GAP_PERIODIC_ADV_RESPONSE_REPORT_EVT +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + #define BTA_DM_BLE_5_GAP_UNKNOWN_EVT BTM_BLE_5_GAP_UNKNOWN_EVT typedef tBTM_BLE_5_GAP_EVENT tBTA_DM_BLE_5_GAP_EVENT; @@ -3094,6 +3109,13 @@ void BTA_DmBleGapSubrateReqest(uint16_t conn_handle, uint16_t subrate_min, uint1 extern void BTA_DmBleGapSetHostFeature(uint16_t bit_num, uint8_t bit_val); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +void BTA_DmBleGapSetPASubevtData(uint8_t adv_handle, uint8_t num_subevents_with_data, uint8_t *subevent_params); +void BTA_DmBleGapSetPeriodicAdvRspData(uint16_t sync_handle, uint16_t request_event, uint8_t request_subevent, + uint8_t rsp_subevent, uint8_t rsp_slot, uint8_t rsp_data_len, uint8_t *rsp_data); +void BTA_DmBleGapSetPeriodicSyncSubevt(uint16_t sync_handle, uint16_t periodic_adv_properties, uint8_t num_subevents_to_sync, uint8_t *subevent); +#endif// (BT_BLE_FEAT_PAWR_EN == TRUE) + /******************************************************************************* ** ** Function BTA_DmBleSetStorageParams 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 67b54deea8..b517dea902 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 @@ -1155,6 +1155,10 @@ void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, #if (BLE_FEAT_CTE_EN == TRUE) param.period_adv_report.params.cte_type = params->period_adv_report.cte_type; #endif // #if (BLE_FEAT_CTE_EN == TRUE) + #if (BT_BLE_FEAT_PAWR_EN == TRUE) + param.period_adv_report.params.periodic_evt_counter = params->period_adv_report.periodic_evt_cnt; + param.period_adv_report.params.subevt = params->period_adv_report.subevt; + #endif // (BT_BLE_FEAT_PAWR_EN == TRUE) param.period_adv_report.params.data_status = params->period_adv_report.data_status; param.period_adv_report.params.data_length = params->period_adv_report.data_length; if (params->period_adv_report.data) { @@ -1179,6 +1183,12 @@ void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, param.periodic_adv_sync_estab.adv_phy = params->sync_estab.adv_phy; param.periodic_adv_sync_estab.period_adv_interval = params->sync_estab.period_adv_interval; param.periodic_adv_sync_estab.adv_clk_accuracy = params->sync_estab.adv_clk_accuracy; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + param.periodic_adv_sync_estab.num_subevt = params->sync_estab.num_subevt; + param.periodic_adv_sync_estab.subevt_interval = params->sync_estab.subevt_interval; + param.periodic_adv_sync_estab.rsp_slot_delay = params->sync_estab.rsp_slot_delay; + param.periodic_adv_sync_estab.rsp_slot_spacing = params->sync_estab.rsp_slot_spacing; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) break; } #endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) @@ -1287,12 +1297,43 @@ void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, param.host_feature.status = btc_btm_status_to_esp_status(params->status); break; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + case BTA_BLE_GAP_SET_PERIODIC_ADV_SUBEVT_DATA_EVT: + msg.act = ESP_GAP_BLE_SET_PERIODIC_ADV_SUBEVT_DATA_EVT; + param.pa_subevt_data_evt.status = btc_btm_status_to_esp_status(params->pa_subevt_data_evt.status); + param.pa_subevt_data_evt.adv_handle = params->pa_subevt_data_evt.adv_handle; + break; + case BTA_BLE_GAP_SET_PERIODIC_ADV_RESPONSE_DATA_EVT: + msg.act = ESP_GAP_BLE_SET_PERIODIC_ADV_RESPONSE_DATA_EVT; + param.pa_rsp_data_evt.status = btc_btm_status_to_esp_status(params->pa_rsp_data_evt.status); + param.pa_rsp_data_evt.sync_handle = params->pa_rsp_data_evt.sync_handle; + break; + case BTA_BLE_GAP_SET_PERIODIC_SYNC_SUBEVT_EVT: + msg.act = ESP_GAP_BLE_SET_PERIODIC_SYNC_SUBEVT_EVT; + param.pa_sync_subevt_evt.status = btc_btm_status_to_esp_status(params->pa_sync_subevt_evt.status); + param.pa_sync_subevt_evt.sync_handle = params->pa_sync_subevt_evt.sync_handle; + break; + case BTA_BLE_GAP_PERIODIC_ADV_SUBEVT_DATA_REQUEST_EVT: + msg.act = ESP_GAP_BLE_PERIODIC_ADV_SUBEVT_DATA_REQUEST_EVT; + param.pa_subevt_data_req_evt.adv_handle = params->pa_subevent_data_req_evt.adv_handle; + param.pa_subevt_data_req_evt.subevt_start = params->pa_subevent_data_req_evt.subevt_start; + param.pa_subevt_data_req_evt.subevt_data_count = params->pa_subevent_data_req_evt.subevt_data_count; + break; + case BTA_BLE_GAP_PERIODIC_ADV_RESPONSE_REPORT_EVT: + msg.act = ESP_GAP_BLE_PERIODIC_ADV_RESPONSE_REPORT_EVT; + param.pa_rsp_rpt_evt.adv_handle = params->pa_rsp_rpt_evt.adv_handle; + param.pa_rsp_rpt_evt.subevt = params->pa_rsp_rpt_evt.subevt; + param.pa_rsp_rpt_evt.tx_status = params->pa_rsp_rpt_evt.tx_status; + param.pa_rsp_rpt_evt.num_rsp = params->pa_rsp_rpt_evt.num_rsp; + param.pa_rsp_rpt_evt.pa_rsp_info = (esp_ble_pa_rsp_info *)params->pa_rsp_rpt_evt.rsp_data_info; + break; +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) default: break; } ret = btc_transfer_context(&msg, ¶m, - sizeof(esp_ble_gap_cb_param_t), NULL, NULL); + sizeof(esp_ble_gap_cb_param_t), btc_gap_ble_cb_deep_copy, btc_gap_ble_cb_deep_free); if (ret != BT_STATUS_SUCCESS) { BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__); @@ -1978,6 +2019,60 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) } break; } +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + case BTC_GAP_BLE_SET_PA_SUBEVT_DATA: { + btc_ble_5_gap_args_t *src = (btc_ble_5_gap_args_t *)p_src; + btc_ble_5_gap_args_t *dst = (btc_ble_5_gap_args_t *)p_dest; + if (src->per_adv_subevent_data_params.subevent_params) { + uint16_t params_len = src->per_adv_subevent_data_params.num_subevents_with_data * sizeof(esp_ble_subevent_params); + dst->per_adv_subevent_data_params.subevent_params = osi_malloc(params_len); + if (dst->per_adv_subevent_data_params.subevent_params) { + + for (uint8_t i = 0; i < src->per_adv_subevent_data_params.num_subevents_with_data; i++) + { + memcpy(&dst->per_adv_subevent_data_params.subevent_params[i], &src->per_adv_subevent_data_params.subevent_params[i], params_len); + // dst->per_adv_subevent_data_params.subevent_params[i].subevent = src->per_adv_subevent_data_params.subevent_params[i].subevent; + // dst->per_adv_subevent_data_params.subevent_params[i].response_slot_start = src->per_adv_subevent_data_params.subevent_params[i].response_slot_start; + // dst->per_adv_subevent_data_params.subevent_params[i].response_slot_count = src->per_adv_subevent_data_params.subevent_params[i].response_slot_count; + // dst->per_adv_subevent_data_params.subevent_params[i].subevent_data_len = src->per_adv_subevent_data_params.subevent_params[i].subevent_data_len; + dst->per_adv_subevent_data_params.subevent_params[i].subevent_data = osi_malloc(src->per_adv_subevent_data_params.subevent_params[i].subevent_data_len); + if (dst->per_adv_subevent_data_params.subevent_params[i].subevent_data) { + memcpy(dst->per_adv_subevent_data_params.subevent_params[i].subevent_data, src->per_adv_subevent_data_params.subevent_params[i].subevent_data, src->per_adv_subevent_data_params.subevent_params[i].subevent_data_len); + } else if (src->per_adv_subevent_data_params.subevent_params[i].subevent_data_len != 0) { + BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + } + } + } + } + break; + } + case BTC_GAP_BLE_SET_PA_RSP_DATA: { + btc_ble_5_gap_args_t *src = (btc_ble_5_gap_args_t *)p_src; + btc_ble_5_gap_args_t *dst = (btc_ble_5_gap_args_t *)p_dest; + if (src->per_adv_response_data_params.response_data && src->per_adv_response_data_params.response_data_len) { + dst->per_adv_response_data_params.response_data = osi_malloc(src->per_adv_response_data_params.response_data_len); + if (dst->per_adv_response_data_params.response_data) { + memcpy(dst->per_adv_response_data_params.response_data, src->per_adv_response_data_params.response_data, src->per_adv_response_data_params.response_data_len); + } else { + BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + } + } + break; + } + case BTC_GAP_BLE_SET_PA_SYNC_SUBEVT: { + btc_ble_5_gap_args_t *src = (btc_ble_5_gap_args_t *)p_src; + btc_ble_5_gap_args_t *dst = (btc_ble_5_gap_args_t *)p_dest; + if (src->per_sync_subevent_params.subevent && src->per_sync_subevent_params.num_subevents_to_sync) { + dst->per_sync_subevent_params.subevent = osi_malloc(src->per_sync_subevent_params.num_subevents_to_sync); + if (dst->per_sync_subevent_params.subevent) { + memcpy(dst->per_sync_subevent_params.subevent, src->per_sync_subevent_params.subevent, src->per_sync_subevent_params.num_subevents_to_sync); + } else { + BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + } + } + break; + } +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) default: BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act); break; @@ -2014,6 +2109,34 @@ void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) } break; } +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + case ESP_GAP_BLE_PERIODIC_ADV_RESPONSE_REPORT_EVT: + if (src->pa_rsp_rpt_evt.pa_rsp_info) { + dst->pa_rsp_rpt_evt.pa_rsp_info = osi_malloc(src->pa_rsp_rpt_evt.num_rsp * sizeof(esp_ble_pa_rsp_info)); + if (dst->pa_rsp_rpt_evt.pa_rsp_info) { + for (UINT8 i = 0; i < src->pa_rsp_rpt_evt.num_rsp; i++) + { + dst->pa_rsp_rpt_evt.pa_rsp_info[i].tx_power = src->pa_rsp_rpt_evt.pa_rsp_info[i].tx_power; + dst->pa_rsp_rpt_evt.pa_rsp_info[i].rssi = src->pa_rsp_rpt_evt.pa_rsp_info[i].rssi; + dst->pa_rsp_rpt_evt.pa_rsp_info[i].cte_type = src->pa_rsp_rpt_evt.pa_rsp_info[i].cte_type; + dst->pa_rsp_rpt_evt.pa_rsp_info[i].rsp_slot = src->pa_rsp_rpt_evt.pa_rsp_info[i].rsp_slot; + dst->pa_rsp_rpt_evt.pa_rsp_info[i].data_status = src->pa_rsp_rpt_evt.pa_rsp_info[i].data_status; + dst->pa_rsp_rpt_evt.pa_rsp_info[i].data_len = src->pa_rsp_rpt_evt.pa_rsp_info[i].data_len; + if (src->pa_rsp_rpt_evt.pa_rsp_info[i].data_len) { + dst->pa_rsp_rpt_evt.pa_rsp_info[i].data = osi_malloc(src->pa_rsp_rpt_evt.pa_rsp_info[i].data_len); + if (dst->pa_rsp_rpt_evt.pa_rsp_info[i].data) { + memcpy(dst->pa_rsp_rpt_evt.pa_rsp_info[i].data, src->pa_rsp_rpt_evt.pa_rsp_info[i].data, src->pa_rsp_rpt_evt.pa_rsp_info[i].data_len); + } else { + BTC_TRACE_ERROR("%s, data, no enough memory.", __func__); + } + } + } + } else { + BTC_TRACE_ERROR("%s, pa_rsp_info, no enough memory.", __func__); + } + } + break; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) default: BTC_TRACE_ERROR("%s, Unhandled deep copy %d\n", __func__, msg->act); break; @@ -2136,6 +2259,35 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg) break; } break; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + case BTC_GAP_BLE_SET_PA_SUBEVT_DATA: { + struct per_adv_subevent_data_params_args *per_adv_subevent_data_params = &((btc_ble_5_gap_args_t *)msg->arg)->per_adv_subevent_data_params; + if (per_adv_subevent_data_params->subevent_params) { + for (uint8_t i = 0; i < per_adv_subevent_data_params->num_subevents_with_data; i++) + { + if (per_adv_subevent_data_params->subevent_params[i].subevent_data) { + osi_free(per_adv_subevent_data_params->subevent_params[i].subevent_data); + } + } + osi_free(per_adv_subevent_data_params->subevent_params); + } + break; + } + case BTC_GAP_BLE_SET_PA_RSP_DATA: { + uint8_t *response_data = ((btc_ble_5_gap_args_t *)msg->arg)->per_adv_response_data_params.response_data; + if (response_data) { + osi_free(response_data); + } + break; + } + case BTC_GAP_BLE_SET_PA_SYNC_SUBEVT: { + uint8_t *subevent = ((btc_ble_5_gap_args_t *)msg->arg)->per_sync_subevent_params.subevent; + if (subevent) { + osi_free(subevent); + } + break; + } +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) default: BTC_TRACE_DEBUG("Unhandled deep free %d\n", msg->act); break; @@ -2167,6 +2319,20 @@ void btc_gap_ble_cb_deep_free(btc_msg_t *msg) } break; } +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + case ESP_GAP_BLE_PERIODIC_ADV_RESPONSE_REPORT_EVT: + esp_ble_pa_rsp_info *pa_rsp_info = ((esp_ble_gap_cb_param_t *)msg->arg)->pa_rsp_rpt_evt.pa_rsp_info; + if (pa_rsp_info) { + uint8_t num_rsp = ((esp_ble_gap_cb_param_t *)msg->arg)->pa_rsp_rpt_evt.num_rsp; + for (UINT8 i = 0; i < num_rsp; i++) { + if (pa_rsp_info[i].data) { + osi_free(pa_rsp_info[i].data); + } + } + osi_free(pa_rsp_info); + } + break; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) default: BTC_TRACE_DEBUG("Unhandled deep free %d", msg->act); break; @@ -2517,6 +2683,13 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) params.interval_min = arg_5->peridic_adv_set_params.params.interval_min; params.interval_max = arg_5->peridic_adv_set_params.params.interval_max; params.properties = arg_5->peridic_adv_set_params.params.properties; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + params.num_subevents = arg_5->peridic_adv_set_params.params.num_subevents; + params.subevent_interval = arg_5->peridic_adv_set_params.params.subevent_interval; + params.rsp_slot_delay = arg_5->peridic_adv_set_params.params.rsp_slot_delay; + params.rsp_slot_spacing = arg_5->peridic_adv_set_params.params.rsp_slot_spacing; + params.num_rsp_slots = arg_5->peridic_adv_set_params.params.num_rsp_slots; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) BTC_TRACE_DEBUG("BTC_GAP_BLE_SET_PERIODIC_ADV_PARAMS"); BTA_DmBleGapPeriodicAdvSetParams(arg_5->peridic_adv_set_params.instance, ¶ms); @@ -2725,6 +2898,18 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) BTA_DmBleGapSetHostFeature(arg_5->set_host_feature_params.bit_num, arg_5->set_host_feature_params.bit_val); break; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + case BTC_GAP_BLE_SET_PA_SUBEVT_DATA: + BTA_DmBleGapSetPASubevtData(arg_5->per_adv_subevent_data_params.adv_handle, arg_5->per_adv_subevent_data_params.num_subevents_with_data, (uint8_t *)(arg_5->per_adv_subevent_data_params.subevent_params)); + break; + case BTC_GAP_BLE_SET_PA_RSP_DATA: + BTA_DmBleGapSetPeriodicAdvRspData(arg_5->per_adv_response_data_params.sync_handle, arg_5->per_adv_response_data_params.request_event, arg_5->per_adv_response_data_params.request_subevent, + arg_5->per_adv_response_data_params.response_subevent, arg_5->per_adv_response_data_params.response_slot, arg_5->per_adv_response_data_params.response_data_len, arg_5->per_adv_response_data_params.response_data); + break; + case BTC_GAP_BLE_SET_PA_SYNC_SUBEVT: + BTA_DmBleGapSetPeriodicSyncSubevt(arg_5->per_sync_subevent_params.sync_handle, arg_5->per_sync_subevent_params.periodic_adv_properties, arg_5->per_sync_subevent_params.num_subevents_to_sync, arg_5->per_sync_subevent_params.subevent); + break; +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) default: break; } diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index 03b1e0885d..ae1b974f66 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -141,6 +141,11 @@ typedef enum { BTC_GAP_ACT_SET_HOST_FEATURE, #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) BTC_GAP_BLE_READ_CHANNEL_MAP, +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + BTC_GAP_BLE_SET_PA_SUBEVT_DATA, + BTC_GAP_BLE_SET_PA_RSP_DATA, + BTC_GAP_BLE_SET_PA_SYNC_SUBEVT, +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) } btc_gap_ble_act_t; /* btc_ble_gap_args_t */ @@ -531,9 +536,34 @@ typedef union { } subrate_req_param; #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) struct set_host_feature_arg { - uint16_t bit_num; - uint8_t bit_val; - } set_host_feature_params; + uint16_t bit_num; + uint8_t bit_val; + } set_host_feature_params; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + // BTC_GAP_BLE_SET_PA_SUBEVT_DATA + struct per_adv_subevent_data_params_args { + uint8_t adv_handle; + uint8_t num_subevents_with_data; + esp_ble_subevent_params *subevent_params; + } per_adv_subevent_data_params; + // BTC_GAP_BLE_SET_PA_RSP_DATA + struct per_adv_response_data_params_args { + uint16_t sync_handle; + uint16_t request_event; + uint8_t request_subevent; + uint8_t response_subevent; + uint8_t response_slot; + uint8_t response_data_len; + uint8_t *response_data; + } per_adv_response_data_params; + // BTC_GAP_BLE_SET_PA_SYNC_SUBEVT + struct per_sync_subevent_params_args { + uint16_t sync_handle; + uint16_t periodic_adv_properties; + uint8_t num_subevents_to_sync; + uint8_t *subevent; + } per_sync_subevent_params; +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) } btc_ble_5_gap_args_t; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) 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 16a6320dbe..e784919b57 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 @@ -364,6 +364,12 @@ #define UC_BT_BLE_FEAT_CONN_SUBRATING FALSE #endif +#ifdef CONFIG_BT_BLE_FEAT_PAWR_EN +#define UC_BT_BLE_FEAT_PAWR_EN CONFIG_BT_BLE_FEAT_PAWR_EN +#else +#define UC_BT_BLE_FEAT_PAWR_EN FALSE +#endif + #ifdef CONFIG_BT_BLE_VENDOR_HCI_EN #define UC_BT_BLE_VENDOR_HCI_EN CONFIG_BT_BLE_VENDOR_HCI_EN #else 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 6ec7ec52ba..eb2a6b92bb 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -415,6 +415,12 @@ #define BLE_FEAT_CONN_SUBRATING FALSE #endif +#if (UC_BT_BLE_FEAT_PAWR_EN == TRUE) +#define BT_BLE_FEAT_PAWR_EN TRUE +#else +#define BT_BLE_FEAT_PAWR_EN FALSE +#endif + #if (UC_BT_BLE_VENDOR_HCI_EN == TRUE) #define BLE_VENDOR_HCI_EN TRUE #else diff --git a/components/bt/host/bluedroid/device/controller.c b/components/bt/host/bluedroid/device/controller.c index 4b68eb93c8..0364ba2ca9 100644 --- a/components/bt/host/bluedroid/device/controller.c +++ b/components/bt/host/bluedroid/device/controller.c @@ -31,7 +31,7 @@ #include "osi/future.h" #include "config/stack_config.h" #if (BLE_50_FEATURE_SUPPORT == TRUE) -const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x07\xff\xff\xff\xff" }; +const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\xff\xff\xff\xff\xff" }; #else const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\x00\x06\x7f" }; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 4b3372504e..bda51c25de 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -710,11 +710,20 @@ tBTM_STATUS BTM_BlePeriodicAdvSetParams(UINT8 instance, tBTM_BLE_Periodic_Adv_Pa goto end; } - if ((err= btsnd_hcic_ble_set_periodic_adv_params(instance, params->interval_min, +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + if ((err = btsnd_hcic_ble_set_periodic_adv_params_v2(instance, params->interval_min, params->interval_max, + params->properties, params->num_subevents, params->subevent_interval, + params->rsp_slot_delay, params->rsp_slot_spacing, params->num_rsp_slots)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("LE PA SetParams_V2: cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } +#else + if ((err = btsnd_hcic_ble_set_periodic_adv_params(instance, params->interval_min, params->interval_max, params->properties)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA SetParams: cmd err=0x%x", err); status = BTM_HCI_ERROR | err; } +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) end: @@ -1740,3 +1749,67 @@ tBTM_STATUS BTM_BleSetHostFeature(uint16_t bit_num, uint8_t bit_val) return status; } #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +void BTM_BleSetPaSubeventData(UINT8 adv_handle, UINT8 num_subevents_with_data, uint8_t *subevent_params) +{ + tBTM_STATUS status = BTM_SUCCESS; + tHCI_STATUS err = HCI_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_periodic_adv_subevt_data(adv_handle, num_subevents_with_data, (ble_subevent_params *)subevent_params)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err = 0x%x", __func__, err); + status = BTM_HCI_ERROR | err; + } + + cb_params.pa_subevt_data_evt.status = status; + cb_params.pa_subevt_data_evt.adv_handle = adv_handle; + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_PERIODIC_ADV_SUBEVT_DATA_EVT, &cb_params); +} + +void BTM_BleSetPaResponseData(UINT16 sync_handle, UINT16 req_evt, UINT8 req_subevt, UINT8 rsp_subevt, UINT8 rsp_slot, UINT8 rsp_data_len, UINT8 *rsp_data) +{ + tBTM_STATUS status = BTM_SUCCESS; + tHCI_STATUS err = HCI_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_periodic_adv_rsp_data(sync_handle, req_evt, req_subevt, rsp_subevt, rsp_slot, rsp_data_len, rsp_data)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err = 0x%x", __func__, err); + status = BTM_HCI_ERROR | err; + } + + cb_params.pa_rsp_data_evt.status = status; + cb_params.pa_rsp_data_evt.sync_handle = sync_handle; + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_PERIODIC_ADV_RESPONSE_DATA_EVT, &cb_params); +} + +void BTM_BleSetPaSyncSubevt(UINT16 sync_handle, UINT16 periodic_adv_properties, UINT8 num_subevents_to_sync, UINT8 *subevt) +{ + tBTM_STATUS status = BTM_SUCCESS; + tHCI_STATUS err = HCI_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_periodic_sync_subevt(sync_handle, periodic_adv_properties, num_subevents_to_sync, subevt)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err = 0x%x", __func__, err); + status = BTM_HCI_ERROR | err; + } + + cb_params.pa_sync_subevt_evt.status = status; + cb_params.pa_sync_subevt_evt.sync_handle = sync_handle; + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_PERIODIC_SYNC_SUBEVT_EVT, &cb_params); +} + +void btm_ble_pa_subevt_data_req_evt(tBTM_BLE_PA_SUBEVT_DATA_REQ_EVT *params) +{ + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_SUBEVT_DATA_REQUEST_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)params); +} + +void btm_ble_pa_rsp_rpt_evt(tBTM_BLE_PA_RSP_REPORT_EVT *params) +{ + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_RESPONSE_REPORT_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)params); +} + +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index de25c6fa3e..e7fe12925d 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -606,6 +606,10 @@ void btm_ble_transmit_power_report_evt(tBTM_BLE_TRANS_POWER_REPORT_EVT *params); #if (BLE_FEAT_CONN_SUBRATING == TRUE) void btm_ble_subrate_change_evt(tBTM_BLE_SUBRATE_CHANGE_EVT *params); #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +void btm_ble_pa_subevt_data_req_evt(tBTM_BLE_PA_SUBEVT_DATA_REQ_EVT *params); +void btm_ble_pa_rsp_rpt_evt(tBTM_BLE_PA_RSP_REPORT_EVT *params); +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) /* #ifdef __cplusplus diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 2ff53852e0..fddfb02615 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -161,8 +161,8 @@ static void btu_ble_phy_update_complete_evt(UINT8 *p); static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len); #endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) #if (BLE_50_EXTEND_SYNC_EN == TRUE) -static void btu_ble_periodic_adv_sync_establish_evt(UINT8 *p); -static void btu_ble_periodic_adv_report_evt(UINT8 *p, UINT8 evt_len); +static void btu_ble_periodic_adv_sync_establish_evt(UINT8 *p, bool v2_evt); +static void btu_ble_periodic_adv_report_evt(UINT8 *p, UINT8 evt_len, bool v2_evt); static void btu_ble_periodic_adv_sync_lost_evt(UINT8 *p); #endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) #if (BLE_50_EXTEND_SCAN_EN == TRUE) @@ -202,7 +202,7 @@ static void btu_ble_accept_cis_req_cmd_status(UINT8 status); static void btu_ble_cis_request_evt(UINT8 *p); #endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) #if (BLE_FEAT_ISO_CIG_EN == TRUE) -static void btu_ble_cis_established_evt(UINT8 *p); +static void btu_ble_cis_established_evt(UINT8 *p, bool v2_evt); static void btu_ble_cis_disconnected(UINT16 handle, UINT8 reason); #endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) @@ -228,6 +228,11 @@ static void btu_ble_transmit_power_report_evt(UINT8 *p); static void btu_ble_subrate_change_evt(UINT8 *p); #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +static void btu_ble_pa_subevt_data_request_evt(UINT8 *p); +static void btu_ble_pa_response_report_evt(UINT8 *p); +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) + #if (BLE_42_ADV_EN == TRUE) extern osi_sem_t adv_enable_sem; extern osi_sem_t adv_data_sem; @@ -493,10 +498,16 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) #endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) #if (BLE_50_EXTEND_SYNC_EN == TRUE) case HCI_BLE_PERIOD_ADV_SYNC_ESTAB_EVT: - btu_ble_periodic_adv_sync_establish_evt(p); + btu_ble_periodic_adv_sync_establish_evt(p, false); + break; + case HCI_BLE_PERIOD_ADV_SYNC_ESTAB_EVT_V2: + btu_ble_periodic_adv_sync_establish_evt(p, true); break; case HCI_BLE_PERIOD_ADV_REPORT_EVT: - btu_ble_periodic_adv_report_evt(p, hci_evt_len); + btu_ble_periodic_adv_report_evt(p, hci_evt_len, false); + break; + case HCI_BLE_PERIOD_ADV_REPORT_EVT_V2: + btu_ble_periodic_adv_report_evt(p, hci_evt_len, true); break; case HCI_BLE_PERIOD_ADV_SYNC_LOST_EVT: btu_ble_periodic_adv_sync_lost_evt(p); @@ -527,8 +538,10 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_CIG_EN == TRUE) case HCI_BLE_CIS_ESTABLISHED_V1_EVT: + btu_ble_cis_established_evt(p, false); + break; case HCI_BLE_CIS_ESTABLISHED_V2_EVT: - btu_ble_cis_established_evt(p); + btu_ble_cis_established_evt(p, true); break; #endif // #if (BLE_FEAT_ISO_CIG_EN == TRUE) #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) @@ -586,6 +599,14 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) btu_ble_subrate_change_evt(p); break; #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + case HCI_BLE_PA_SUBEVT_DATA_REQUEST_EVT: + btu_ble_pa_subevt_data_request_evt(p); + break; + case HCI_BLE_PA_RESPONSE_REPORT_EVT: + btu_ble_pa_response_report_evt(p); + break; +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) } break; #endif /* BLE_INCLUDED */ @@ -2540,7 +2561,7 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len) #endif // #if (BLE_50_EXTEND_SCAN_EN == TRUE) #if (BLE_50_EXTEND_SYNC_EN == TRUE) -static void btu_ble_periodic_adv_sync_establish_evt(UINT8 *p) +static void btu_ble_periodic_adv_sync_establish_evt(UINT8 *p, bool v2_evt) { tBTM_BLE_PERIOD_ADV_SYNC_ESTAB sync_estab = {0}; @@ -2557,15 +2578,24 @@ static void btu_ble_periodic_adv_sync_establish_evt(UINT8 *p) STREAM_TO_UINT8(sync_estab.adv_phy, p); STREAM_TO_UINT16(sync_estab.period_adv_interval, p); STREAM_TO_UINT8(sync_estab.adv_clk_accuracy, p); +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + if (v2_evt) { + STREAM_TO_UINT8(sync_estab.num_subevt, p); + STREAM_TO_UINT8(sync_estab.subevt_interval, p); + STREAM_TO_UINT8(sync_estab.rsp_slot_delay, p); + STREAM_TO_UINT8(sync_estab.rsp_slot_spacing, p); + } +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) btm_ble_periodic_adv_sync_establish_evt(&sync_estab); } -static void btu_ble_periodic_adv_report_evt(UINT8 *p, UINT8 evt_len) +static void btu_ble_periodic_adv_report_evt(UINT8 *p, UINT8 evt_len, bool v2_evt) { tBTM_PERIOD_ADV_REPORT adv_report = {0}; /* This parameter is intended to be used in a future feature. */ UINT8 unused = 0; + UINT8 min_len = MIN_BLE_PERIODIC_ADV_REPORT_LEN; if (!p) { HCI_TRACE_ERROR("%s, Invalid params.", __func__); @@ -2581,10 +2611,17 @@ static void btu_ble_periodic_adv_report_evt(UINT8 *p, UINT8 evt_len) STREAM_TO_UINT8(adv_report.tx_power, p); STREAM_TO_UINT8(adv_report.rssi, p); STREAM_TO_UINT8(adv_report.cte_type, p); +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + if (v2_evt) { + STREAM_TO_UINT16(adv_report.periodic_evt_cnt, p); + STREAM_TO_UINT8(adv_report.subevt, p); + min_len += 3; + } +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) STREAM_TO_UINT8(adv_report.data_status, p); STREAM_TO_UINT8(adv_report.data_length, p); - if ((evt_len - MIN_BLE_PERIODIC_ADV_REPORT_LEN) != adv_report.data_length) { + if ((evt_len - min_len) != adv_report.data_length) { HCI_TRACE_ERROR("%s, Invalid ev_len = %d is less than adv len = %d", __func__, evt_len, adv_report.data_length); return; } @@ -2742,7 +2779,7 @@ static void btu_ble_cis_disconnected(UINT16 handle, UINT8 reason) btm_ble_cis_disconnected_evt(&cis_disconnected_evt); } -static void btu_ble_cis_established_evt(UINT8 *p) +static void btu_ble_cis_established_evt(UINT8 *p, bool v2_evt) { HCI_TRACE_DEBUG("%s", __func__); tBTM_BLE_CIS_ESTABLISHED_CMPL cis_estab_evt = {0}; @@ -2769,12 +2806,14 @@ static void btu_ble_cis_established_evt(UINT8 *p) STREAM_TO_UINT16(cis_estab_evt.max_pdu_p_to_c, p); STREAM_TO_UINT16(cis_estab_evt.iso_interval, p); #if (BLE_FEAT_ISO_60_EN == TRUE) - STREAM_TO_UINT24(cis_estab_evt.sub_interval, p); - STREAM_TO_UINT16(cis_estab_evt.max_sdu_c_to_p, p); - STREAM_TO_UINT16(cis_estab_evt.max_sdu_p_to_c, p); - STREAM_TO_UINT24(cis_estab_evt.sdu_int_c_to_p, p); - STREAM_TO_UINT24(cis_estab_evt.sdu_int_p_to_c, p); - STREAM_TO_UINT8(cis_estab_evt.framing, p); + if (v2_evt) { + STREAM_TO_UINT24(cis_estab_evt.sub_interval, p); + STREAM_TO_UINT16(cis_estab_evt.max_sdu_c_to_p, p); + STREAM_TO_UINT16(cis_estab_evt.max_sdu_p_to_c, p); + STREAM_TO_UINT24(cis_estab_evt.sdu_int_c_to_p, p); + STREAM_TO_UINT24(cis_estab_evt.sdu_int_p_to_c, p); + STREAM_TO_UINT8(cis_estab_evt.framing, p); + } #endif // #if (BLE_FEAT_ISO_60_EN == TRUE) btm_ble_cis_established_evt(&cis_estab_evt); @@ -3084,6 +3123,74 @@ static void btu_ble_subrate_change_evt(UINT8 *p) } #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +static void btu_ble_pa_subevt_data_request_evt(UINT8 *p) +{ + tBTM_BLE_PA_SUBEVT_DATA_REQ_EVT pa_subevt_req_evt = {0}; + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(pa_subevt_req_evt.adv_handle, p); + STREAM_TO_UINT8(pa_subevt_req_evt.subevt_start, p); + STREAM_TO_UINT8(pa_subevt_req_evt.subevt_data_count, p); + + btm_ble_pa_subevt_data_req_evt(&pa_subevt_req_evt); +} + +static void btu_ble_pa_response_report_evt(UINT8 *p) +{ + tBTM_BLE_PA_RSP_REPORT_EVT pa_rsp_rpt_evt = {0}; + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(pa_rsp_rpt_evt.adv_handle, p); + STREAM_TO_UINT8(pa_rsp_rpt_evt.subevt, p); + STREAM_TO_UINT8(pa_rsp_rpt_evt.tx_status, p); + STREAM_TO_UINT8(pa_rsp_rpt_evt.num_rsp, p); + + pa_rsp_rpt_evt.rsp_data_info = osi_malloc(pa_rsp_rpt_evt.num_rsp * sizeof(tBTM_BLE_PA_RSP_DATA_INFO)); + if (pa_rsp_rpt_evt.rsp_data_info) + { + for (UINT8 i = 0; i < pa_rsp_rpt_evt.num_rsp; i++) + { + STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].tx_power, p); + STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].rssi, p); + STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].cte_type, p); + STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].rsp_slot, p); + STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].data_status, p); + STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].data_len, p); + if (pa_rsp_rpt_evt.rsp_data_info[i].data_len) { + pa_rsp_rpt_evt.rsp_data_info[i].data = osi_malloc(pa_rsp_rpt_evt.rsp_data_info[i].data_len); + if (pa_rsp_rpt_evt.rsp_data_info[i].data) { + STREAM_TO_ARRAY(pa_rsp_rpt_evt.rsp_data_info[i].data, p, pa_rsp_rpt_evt.rsp_data_info[i].data_len); + } else { + HCI_TRACE_ERROR("%s, no enough memory.", __func__); + } + } + } + } else { + HCI_TRACE_ERROR("%s, no memory.", __func__); + } + + btm_ble_pa_rsp_rpt_evt(&pa_rsp_rpt_evt); + + if (pa_rsp_rpt_evt.rsp_data_info) + { + for (UINT8 i = 0; i < pa_rsp_rpt_evt.num_rsp; i++) + { + if (pa_rsp_rpt_evt.rsp_data_info[i].data) { + osi_free(pa_rsp_rpt_evt.rsp_data_info[i].data); + } + } + osi_free(pa_rsp_rpt_evt.rsp_data_info); + } +} +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + /********************************************** ** End of BLE Events Handler ***********************************************/ diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 5ad13216f7..7947ef557f 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -1421,10 +1421,40 @@ UINT8 btsnd_hcic_ble_clear_adv_set(void) #endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) #if (BLE_50_PERIODIC_ADV_EN == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +UINT8 btsnd_hcic_ble_set_periodic_adv_params_v2(UINT8 adv_handle, UINT16 interval_min, UINT16 interval_max, + UINT16 propertics, UINT8 num_subevents, UINT8 subevent_interval, + UINT8 rsp_slot_delay, UINT8 rsp_slot_spacing, UINT8 num_rsp_slots) +{ + BT_HDR *p; + UINT8 *pp; + HCI_TRACE_EVENT("%s, adv_handle = %d, interval_min = %d, interval_max = %d, propertics = %d num_subevents = %d subevent_interval = %d rsp_slot_delay %d rsp_slot_spacing %d num_rsp_slots %d", + __func__, adv_handle, interval_min, interval_max, propertics, num_subevents, subevent_interval, rsp_slot_delay, rsp_slot_spacing, num_rsp_slots); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_PERIODIC_ADV_PARAMS_V2); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_PERIOD_ADV_PARAMS_V2); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_PERIODIC_ADV_PARAMS_V2); + + UINT8_TO_STREAM(pp, adv_handle); + UINT16_TO_STREAM(pp, interval_min); + UINT16_TO_STREAM(pp, interval_max); + UINT16_TO_STREAM(pp, propertics); + UINT8_TO_STREAM(pp, num_subevents); + UINT8_TO_STREAM(pp, subevent_interval); + UINT8_TO_STREAM(pp, rsp_slot_delay); + UINT8_TO_STREAM(pp, rsp_slot_spacing); + UINT8_TO_STREAM(pp, num_rsp_slots); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); + +} + +#else UINT8 btsnd_hcic_ble_set_periodic_adv_params(UINT8 adv_handle, UINT16 interval_min, UINT16 interval_max, - UINT8 propertics) + UINT16 propertics) { BT_HDR *p; UINT8 *pp; @@ -1445,6 +1475,9 @@ UINT8 btsnd_hcic_ble_set_periodic_adv_params(UINT8 adv_handle, } +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) + + UINT8 btsnd_hcic_ble_set_periodic_adv_data(UINT8 adv_handle, UINT8 operation, UINT8 len, @@ -2808,3 +2841,114 @@ UINT8 btsnd_hcic_ble_set_host_feature(uint16_t bit_num, uint8_t bit_val) return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); } #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +UINT8 btsnd_hcic_ble_set_periodic_adv_subevt_data(UINT8 adv_handle, UINT8 num_subevents_with_data, ble_subevent_params *subevent_params) +{ + BT_HDR *p; + UINT8 *pp; + uint8_t param_len = 0; + + HCI_TRACE_DEBUG("hci set PA subevent data, adv_handle %d num_subevents_with_data %d", adv_handle, num_subevents_with_data); + + if (!subevent_params) { + HCI_TRACE_ERROR("%s error\n", __func__); + return HCI_ERR_ILLEGAL_PARAMETER_FMT; + } + param_len += HCIC_PARAM_SIZE_SET_PA_SUBEVT_DATA_PARAMS_LEN; + + for (UINT8 i = 0; i < num_subevents_with_data; i++) + { + HCI_TRACE_DEBUG("subevent_params: subevent %d response_slot_start %d response_slot_count %d subevent_data_len %d", + subevent_params[i].subevent, subevent_params[i].response_slot_start, subevent_params[i].response_slot_count, + subevent_params[i].subevent_data_len); + + if (subevent_params[i].subevent_data_len) { + esp_log_buffer_hex_internal("data", subevent_params[i].data, subevent_params[i].subevent_data_len, ESP_LOG_DEBUG); + } + + param_len += (4 + subevent_params->subevent_data_len); + } + + HCIC_BLE_CMD_CREATED(p, pp, param_len); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_PERIOD_ADV_SUBEVT_DATA); + UINT8_TO_STREAM(pp, param_len); + + UINT8_TO_STREAM(pp, adv_handle); + UINT8_TO_STREAM(pp, num_subevents_with_data); + for (UINT8 i = 0; i < num_subevents_with_data; i++) + { + UINT8_TO_STREAM(pp, subevent_params[i].subevent); + UINT8_TO_STREAM(pp, subevent_params[i].response_slot_start); + UINT8_TO_STREAM(pp, subevent_params[i].response_slot_count); + UINT8_TO_STREAM(pp, subevent_params[i].subevent_data_len); + if (subevent_params[i].subevent_data_len) { + ARRAY_TO_STREAM(pp, subevent_params[i].data, subevent_params[i].subevent_data_len); + } + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_set_periodic_adv_rsp_data(UINT16 sync_handle, UINT16 req_evt, UINT8 req_subevt, UINT8 rsp_subevt, UINT8 rsp_slot, UINT8 rsp_data_len, UINT8 *rsp_data) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set PA rsp data, sync_handle %d req_evt %d req_subevt %d rsp_subevt %d rsp_slot %d rsp_data_len %d", + sync_handle, req_evt, req_subevt, rsp_subevt, rsp_slot, rsp_data_len); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_PA_RESPONSE_DATA_PARAMS_LEN + rsp_data_len); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_PERIOD_ADV_RSP_DATA); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_PA_RESPONSE_DATA_PARAMS_LEN + rsp_data_len); + + UINT16_TO_STREAM(pp, sync_handle); + UINT16_TO_STREAM(pp, req_evt); + UINT8_TO_STREAM(pp, req_subevt); + UINT8_TO_STREAM(pp, rsp_subevt); + UINT8_TO_STREAM(pp, rsp_slot); + UINT8_TO_STREAM(pp, rsp_data_len); + + if (rsp_data) { + ARRAY_TO_STREAM(pp, rsp_data, rsp_data_len); + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_set_periodic_sync_subevt(UINT16 sync_handle, UINT16 periodic_adv_properties, UINT8 num_subevents_to_sync, UINT8 *subevt) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("hci set PA sync subevent, sync_handle %d periodic_adv_properties %d num_subevents_to_sync %d", + sync_handle, periodic_adv_properties, num_subevents_to_sync); + for (UINT8 i = 0; i < num_subevents_to_sync; i++) + { + HCI_TRACE_DEBUG("subevt[%d] = %d", i, subevt[i]); + } + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_PA_SYNC_SUBEVT_PARAMS_LEN + num_subevents_to_sync); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_PERIOD_SYNC_SUBEVT); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_PA_SYNC_SUBEVT_PARAMS_LEN + num_subevents_to_sync); + + UINT16_TO_STREAM(pp, sync_handle); + UINT16_TO_STREAM(pp, periodic_adv_properties); + UINT8_TO_STREAM(pp, num_subevents_to_sync); + for (UINT8 i = 0; i < num_subevents_to_sync; i++) + { + UINT8_TO_STREAM(pp, subevt[i]); + } + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) 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 e696fe65cf..5e1dcbceed 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 @@ -808,7 +808,14 @@ typedef struct { typedef struct { UINT16 interval_min; UINT16 interval_max; - UINT8 properties; + UINT16 properties; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + UINT8 num_subevents; + UINT8 subevent_interval; + UINT8 rsp_slot_delay; + UINT8 rsp_slot_spacing; + UINT8 num_rsp_slots; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) } tBTM_BLE_Periodic_Adv_Params; typedef struct { @@ -1090,7 +1097,14 @@ typedef void (tBTM_SET_VENDOR_EVT_MASK_CBACK) (tBTM_STATUS status); #if (BLE_50_FEATURE_SUPPORT == TRUE) #define BTM_BLE_GAP_SET_HOST_FEATURE_EVT 51 #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) -#define BTM_BLE_5_GAP_UNKNOWN_EVT 52 +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +#define BTM_BLE_GAP_SET_PERIODIC_ADV_SUBEVT_DATA_EVT 52 +#define BTM_BLE_GAP_SET_PERIODIC_ADV_RESPONSE_DATA_EVT 53 +#define BTM_BLE_GAP_SET_PERIODIC_SYNC_SUBEVT_EVT 54 +#define BTM_BLE_GAP_PERIODIC_ADV_SUBEVT_DATA_REQUEST_EVT 55 +#define BTM_BLE_GAP_PERIODIC_ADV_RESPONSE_REPORT_EVT 56 +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#define BTM_BLE_5_GAP_UNKNOWN_EVT 57 typedef UINT8 tBTM_BLE_5_GAP_EVENT; #if (BLE_FEAT_ISO_EN == TRUE) @@ -1332,6 +1346,10 @@ typedef struct { UINT8 tx_power; INT8 rssi; UINT8 cte_type; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + UINT16 periodic_evt_cnt; + UINT8 subevt; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) tBTM_BLE_EXT_ADV_DATA_STATUS data_status; UINT8 data_length; UINT8 *data; @@ -1350,6 +1368,12 @@ typedef struct { UINT8 adv_phy; UINT16 period_adv_interval; UINT8 adv_clk_accuracy; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + UINT8 num_subevt; + UINT8 subevt_interval; + UINT8 rsp_slot_delay; + UINT8 rsp_slot_spacing; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) } tBTM_BLE_PERIOD_ADV_SYNC_ESTAB; typedef struct { @@ -1453,6 +1477,44 @@ typedef struct { } __attribute__((packed)) tBTM_BLE_SUBRATE_CHANGE_EVT; #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +typedef struct { + UINT8 status; + UINT8 adv_handle; +} __attribute__((packed)) tBTM_BLE_PA_SUBEVT_DATA_EVT; +typedef struct { + UINT8 status; + UINT16 sync_handle; +} __attribute__((packed)) tBTM_BLE_PA_RSP_DATA_EVT; +typedef struct { + UINT8 status; + UINT16 sync_handle; +} __attribute__((packed)) tBTM_BLE_PA_SYNC_SUBEVT_DATA_EVT; +typedef struct { + UINT8 adv_handle; + UINT8 subevt_start; + UINT8 subevt_data_count; +} __attribute__((packed)) tBTM_BLE_PA_SUBEVT_DATA_REQ_EVT; + +typedef struct { + INT8 tx_power; + INT8 rssi; + UINT8 cte_type; + UINT8 rsp_slot; + UINT8 data_status; + UINT8 data_len; + UINT8 *data; +} __attribute__((packed)) tBTM_BLE_PA_RSP_DATA_INFO; + +typedef struct { + UINT8 adv_handle; + UINT8 subevt; + UINT8 tx_status; + UINT8 num_rsp; + tBTM_BLE_PA_RSP_DATA_INFO *rsp_data_info; +} __attribute__((packed)) tBTM_BLE_PA_RSP_REPORT_EVT; +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) typedef struct { @@ -1819,6 +1881,13 @@ typedef union { #if (BLE_FEAT_CONN_SUBRATING == TRUE) tBTM_BLE_SUBRATE_CHANGE_EVT subrate_change_evt; #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + tBTM_BLE_PA_SUBEVT_DATA_EVT pa_subevt_data_evt; + tBTM_BLE_PA_RSP_DATA_EVT pa_rsp_data_evt; + tBTM_BLE_PA_SYNC_SUBEVT_DATA_EVT pa_sync_subevt_evt; + tBTM_BLE_PA_SUBEVT_DATA_REQ_EVT pa_subevent_data_req_evt; + tBTM_BLE_PA_RSP_REPORT_EVT pa_rsp_rpt_evt; +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) } tBTM_BLE_5_GAP_CB_PARAMS; typedef struct { @@ -3371,7 +3440,15 @@ void BTM_BleSetDefaultSubrate(UINT16 subrate_min, UINT16 subrate_max, UINT16 max void BTM_BleSubrateRequest(UINT16 conn_handle, UINT16 subrate_min, UINT16 subrate_max, UINT16 max_latency, UINT16 continuation_number, UINT16 supervision_timeout); #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) + #if (BLE_50_FEATURE_SUPPORT == TRUE) tBTM_STATUS BTM_BleSetHostFeature(uint16_t bit_num, uint8_t bit_val); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +void BTM_BleSetPaSubeventData(UINT8 adv_handle, UINT8 num_subevents_with_data, uint8_t *subevent_params); +void BTM_BleSetPaResponseData(UINT16 sync_handle, UINT16 req_evt, UINT8 req_subevt, UINT8 rsp_subevt, UINT8 rsp_slot, UINT8 rsp_data_len, UINT8 *rsp_data); +void BTM_BleSetPaSyncSubevt(UINT16 sync_handle, UINT16 periodic_adv_properties, UINT8 num_subevents_to_sync, UINT8 *subevt); +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + #endif diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index 23f9b3e6b8..81bfbe0f43 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -443,6 +443,13 @@ #define HCI_BLE_SUBRATE_REQUEST (0x007E | HCI_GRP_BLE_CMDS) #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +#define HCI_BLE_SET_PERIOD_ADV_SUBEVT_DATA (0x0082 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_PERIOD_ADV_RSP_DATA (0x0083 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_PERIOD_SYNC_SUBEVT (0x0084 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_PERIOD_ADV_PARAMS_V2 (0x0086 | HCI_GRP_BLE_CMDS) +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + // Vendor OGF define #define HCI_VENDOR_OGF 0x3F @@ -918,6 +925,14 @@ #define HCI_BLE_SUBRATE_CHANGE_EVT 0x23 #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#define HCI_BLE_PERIOD_ADV_SYNC_ESTAB_EVT_V2 0x24 +#define HCI_BLE_PERIOD_ADV_REPORT_EVT_V2 0x25 + +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +#define HCI_BLE_PA_SUBEVT_DATA_REQUEST_EVT 0x27 +#define HCI_BLE_PA_RESPONSE_REPORT_EVT 0x28 +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + /* Definitions for LE Channel Map */ #define HCI_BLE_CHNL_MAP_SIZE 5 diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index 4ee07b4d40..9ebbebdf92 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -1013,7 +1013,7 @@ UINT8 btsnd_hcic_ble_clear_adv_set(void); UINT8 btsnd_hcic_ble_set_periodic_adv_params(UINT8 adv_handle, UINT16 interval_min, UINT16 interval_max, - UINT8 propertics); + UINT16 propertics); UINT8 btsnd_hcic_ble_set_periodic_adv_data(UINT8 adv_handle, UINT8 operation, @@ -1243,4 +1243,26 @@ UINT8 btsnd_hcic_ble_subrate_request(UINT16 conn_handle, UINT16 subrate_min, UIN UINT8 btsnd_hcic_ble_set_host_feature(uint16_t bit_num, uint8_t bit_val); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +typedef struct { + uint8_t subevent; + uint8_t response_slot_start; + uint8_t response_slot_count; + uint8_t subevent_data_len; + uint8_t data[251]; +} ble_subevent_params; + +#define HCIC_PARAM_SIZE_SET_PA_SUBEVT_DATA_PARAMS_LEN 2 +#define HCIC_PARAM_SIZE_SET_PA_RESPONSE_DATA_PARAMS_LEN 8 +#define HCIC_PARAM_SIZE_SET_PA_SYNC_SUBEVT_PARAMS_LEN 5 + +#define HCIC_PARAM_SIZE_SET_PERIODIC_ADV_PARAMS_V2 12 +UINT8 btsnd_hcic_ble_set_periodic_adv_params_v2(UINT8 adv_handle, UINT16 interval_min, UINT16 interval_max, + UINT16 propertics, UINT8 num_subevents, UINT8 subevent_interval, + UINT8 rsp_slot_delay, UINT8 rsp_slot_spacing, UINT8 num_rsp_slots); +UINT8 btsnd_hcic_ble_set_periodic_adv_subevt_data(UINT8 adv_handle, UINT8 num_subevents_with_data, ble_subevent_params *subevent_params); +UINT8 btsnd_hcic_ble_set_periodic_adv_rsp_data(UINT16 sync_handle, UINT16 req_evt, UINT8 req_subevt, UINT8 rsp_subevt, UINT8 rsp_slot, UINT8 rsp_data_len, UINT8 *rsp_data); +UINT8 btsnd_hcic_ble_set_periodic_sync_subevt(UINT16 sync_handle, UINT16 periodic_adv_properties, UINT8 num_subevents_to_sync, UINT8 *subevt); +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + #endif From cd156796d8dde09c6c08bd3c5059dfb60c6db475 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Fri, 16 May 2025 20:27:53 +0800 Subject: [PATCH 006/226] feat(ble/bluedroid): Add bluedroid host Advertising Coding Selection feature --- components/bt/host/bluedroid/Kconfig.in | 71 ++++++++++--------- .../api/include/api/esp_gap_ble_api.h | 55 ++++++++++++++ .../host/bluedroid/bta/include/bta/bta_api.h | 4 ++ .../btc/profile/std/gap/btc_gap_ble.c | 7 +- .../include/common/bluedroid_user_config.h | 6 ++ .../common/include/common/bt_target.h | 6 ++ .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 15 +++- .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 52 +++++++++++++- .../stack/include/stack/btm_ble_api.h | 4 ++ .../bluedroid/stack/include/stack/hcidefs.h | 4 ++ .../bluedroid/stack/include/stack/hcimsgs.h | 11 +++ 11 files changed, 196 insertions(+), 39 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index cb2b1dc4ba..734fe0a730 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1302,7 +1302,7 @@ config BT_BLE_RPA_TIMEOUT Default is 900 s (15 minutes). Range is 1 s to 1 hour (3600 s). menuconfig BT_BLE_50_FEATURES_SUPPORTED - bool "Enable BLE 5.0 features(please disable BLE 4.2 if enable BLE 5.0)" + 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)) default y help @@ -1366,37 +1366,6 @@ config BT_BLE_FEAT_CREATE_SYNC_ENH help Enable the create sync enhancements -menuconfig BT_BLE_42_FEATURES_SUPPORTED - bool "Enable BLE 4.2 features(please disable BLE 5.0 if enable BLE 4.2)" - depends on BT_BLE_ENABLED - default y if IDF_TARGET_ESP32 - default n - help - This enables BLE 4.2 features. - This option is universally supported by all ESP chips with BLE capabilities. - BLE 4.2 and BLE 5.0 cannot be used simultaneously. - -config BT_BLE_42_DTM_TEST_EN - bool "Enable BLE 4.2 DTM test" - depends on BT_BLE_42_FEATURES_SUPPORTED - default y - help - This enables BLE 4.2 direct test mode - -config BT_BLE_42_ADV_EN - bool "Enable BLE 4.2 advertising" - depends on BT_BLE_42_FEATURES_SUPPORTED - default y - help - This enables BLE v4.2 advertising - -config BT_BLE_42_SCAN_EN - bool "Enable BLE 4.2 scan" - depends on BT_BLE_42_FEATURES_SUPPORTED - default y - help - This enables BLE v4.2 scan - menuconfig BT_BLE_FEAT_ISO_EN bool "Enable BLE 5.2 iso feature" depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_AUDIO_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR @@ -1516,6 +1485,44 @@ config BT_BLE_FEAT_PAWR_EN help Enable BLE Periodic Advertisement with Response(PAwR) feature +config BT_BLE_FEAT_ADV_CODING_SELECTION + bool "Enable Advertising Coding Selection" + depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_ADV_CODING_SELECT_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR + default n + help + Enable Advertising Coding Selection + +menuconfig BT_BLE_42_FEATURES_SUPPORTED + bool "Enable BLE 4.2 features(please disable BLE 5.0 if enable BLE 4.2)" + depends on BT_BLE_ENABLED + default y if IDF_TARGET_ESP32 + default n + help + This enables BLE 4.2 features. + This option is universally supported by all ESP chips with BLE capabilities. + BLE 4.2 and BLE 5.0 cannot be used simultaneously. + +config BT_BLE_42_DTM_TEST_EN + bool "Enable BLE 4.2 DTM test" + depends on BT_BLE_42_FEATURES_SUPPORTED + default y + help + This enables BLE 4.2 direct test mode + +config BT_BLE_42_ADV_EN + bool "Enable BLE 4.2 advertising" + depends on BT_BLE_42_FEATURES_SUPPORTED + default y + help + This enables BLE v4.2 advertising + +config BT_BLE_42_SCAN_EN + bool "Enable BLE 4.2 scan" + depends on BT_BLE_42_FEATURES_SUPPORTED + default y + help + This enables BLE v4.2 scan + config BT_BLE_VENDOR_HCI_EN bool "Enable BLE Vendor HCI command and event" depends on BT_BLE_ENABLED diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index c23c403d3b..df0f8629f2 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -862,6 +862,12 @@ typedef uint8_t esp_ble_gap_all_phys_t; #define ESP_BLE_GAP_PRI_PHY_CODED ESP_BLE_GAP_PHY_CODED /*!< Primary Phy is LE CODED */ typedef uint8_t esp_ble_gap_pri_phy_t; // primary phy +#define ESP_BLE_GAP_RPT_PHY_1M 1 /*!< Advertiser PHY is LE 1M */ +#define ESP_BLE_GAP_RPT_PHY_2M 2 /*!< Advertiser PHY is LE 2M */ +#define ESP_BLE_GAP_RPT_PHY_S8 3 /*!< If the Advertising Coding Selection feature bit is set: Advertising PHY is LE 125K Otherwise: Advertiser PHY is LE Coded */ +#define ESP_BLE_GAP_RPT_PHY_S2 4 /*!< If the Advertising Coding Selection feature bit is set: Advertising PHY is LE 500K Otherwise: Reserved for future use */ +typedef uint8_t esp_ble_gap_rpt_phy_t; // extended Advertising report phy + #define ESP_BLE_GAP_PHY_1M_PREF_MASK (1 << 0) /*!< The Host prefers use the LE1M transmitter or receiver PHY */ #define ESP_BLE_GAP_PHY_2M_PREF_MASK (1 << 1) /*!< The Host prefers use the LE2M transmitter or receiver PHY */ #define ESP_BLE_GAP_PHY_CODED_PREF_MASK (1 << 2) /*!< The Host prefers use the LE CODED transmitter or receiver PHY */ @@ -910,6 +916,21 @@ typedef uint8_t esp_ble_gap_adv_type_t; /// max number of advertising sets to enable or disable #define EXT_ADV_NUM_SETS_MAX (10) /*!< max evt instance num */ +#if (CONFIG_BT_BLE_FEAT_ADV_CODING_SELECTION) +// The Host has no preferred or required coding when transmitting on the LE Coded PHY +#define ESP_BLE_ADV_PHY_OPTIONS_NO_PREFER_CODED (0x00) +// The Host prefers that S=2 coding be used when transmitting on the LE Coded PHY +#define ESP_BLE_ADV_PHY_OPTIONS_PREFER_CODED_S2 (0x01) +// The Host prefers that S=8 coding be used when transmitting on the LE Coded PHY +#define ESP_BLE_ADV_PHY_OPTIONS_PREFER_CODED_S8 (0x02) +// The Host requires that S=2 coding be used when transmitting on the LE Coded PHY +#define ESP_BLE_ADV_PHY_OPTIONS_REQUIRE_CODED_S2 (0x03) +// The Host requires that S=8 coding be used when transmitting on the LE Coded PHY +#define ESP_BLE_ADV_PHY_OPTIONS_REQUIRE_CODED_S8 (0x04) + +typedef uint8_t esp_ble_gap_adv_phy_options_t; +#endif //(CONFIG_BT_BLE_FEAT_ADV_CODING_SELECTION) + /** * @brief ext adv parameters */ @@ -928,6 +949,20 @@ typedef struct { esp_ble_gap_phy_t secondary_phy; /*!< ext adv secondary phy */ uint8_t sid; /*!< ext adv sid */ bool scan_req_notif; /*!< ext adv scan request event notify */ +#if (CONFIG_BT_BLE_FEAT_ADV_CODING_SELECTION) + esp_ble_gap_adv_phy_options_t primary_adv_phy_options; /*!< + 0x00: The Host has no preferred or required coding when transmitting on the LE Coded PHY + 0x01: The Host prefers that S=2 coding be used when transmitting on the LE Coded PHY + 0x02: The Host prefers that S=8 coding be used when transmitting on the LE Coded PHY + 0x03: The Host requires that S=2 coding be used when transmitting on the LE Coded PHY + 0x04: The Host requires that S=8 coding be used when transmitting on the LE Coded PHY */ + esp_ble_gap_adv_phy_options_t secondary_adv_phy_options; /*!< + 0x00: The Host has no preferred or required coding when transmitting on the LE Coded PHY + 0x01: The Host prefers that S=2 coding be used when transmitting on the LE Coded PHY + 0x02: The Host prefers that S=8 coding be used when transmitting on the LE Coded PHY + 0x03: The Host requires that S=2 coding be used when transmitting on the LE Coded PHY + 0x04: The Host requires that S=8 coding be used when transmitting on the LE Coded PHY */ +#endif // CONFIG_BT_BLE_FEAT_ADV_CODING_SELECTION } esp_ble_gap_ext_adv_params_t; /** @@ -1040,8 +1075,28 @@ typedef struct { esp_ble_gap_adv_type_t event_type; /*!< extend advertising type */ uint8_t addr_type; /*!< extend advertising address type */ esp_bd_addr_t addr; /*!< extend advertising address */ +#if (CONFIG_BT_BLE_FEAT_PAWR_EN) + esp_ble_gap_rpt_phy_t primary_phy; /*!< extend advertising primary phy + 0x01: Advertiser PHY is LE 1M + 0x03: If the Advertising Coding Selection (Host Support) feature bit is set: Advertising PHY is LE Coded with S=8 data coding + Otherwise: Advertiser PHY is LE Coded + 0x04: If the Advertising Coding Selection (Host Support) feature bit is set: Advertising PHY is LE Coded with S=2 data coding + Otherwise: Reserved for future use + */ + + esp_ble_gap_rpt_phy_t secondly_phy; /*!< extend advertising secondary phy + 0x00: No packets on the secondary advertising physical channel + 0x01: Advertiser PHY is LE 1M + 0x02: Advertiser PHY is LE 2M + 0x03: If the Advertising Coding Selection (Host Support) feature bit is set: Advertising PHY is LE Coded with S=8 data coding + Otherwise: Advertiser PHY is LE Coded + 0x04: If the Advertising Coding Selection (Host Support) feature bit is set: Advertising PHY is LE Coded with S=2 data coding + Otherwise: Reserved for future use + */ +#else esp_ble_gap_pri_phy_t primary_phy; /*!< extend advertising primary phy */ esp_ble_gap_phy_t secondly_phy; /*!< extend advertising secondary phy */ +#endif uint8_t sid; /*!< extend advertising sid */ uint8_t tx_power; /*!< extend advertising tx power */ int8_t rssi; /*!< extend advertising rssi */ diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index b87d33acf3..17e439c2ad 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1573,6 +1573,10 @@ typedef struct { tBTA_DM_BLE_GAP_PHY secondary_phy; UINT8 sid; BOOLEAN scan_req_notif; +#if (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) + uint8_t primary_adv_phy_options; + uint8_t secondary_adv_phy_options; +#endif // (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) } tBTA_DM_BLE_GAP_EXT_ADV_PARAMS; typedef struct { 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 b517dea902..f42ab484a9 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 @@ -2138,7 +2138,7 @@ void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) break; #endif // (BT_BLE_FEAT_PAWR_EN == TRUE) default: - BTC_TRACE_ERROR("%s, Unhandled deep copy %d\n", __func__, msg->act); + // BTC_TRACE_ERROR("%s, Unhandled deep copy %d\n", __func__, msg->act); break; } } @@ -2619,7 +2619,10 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) params.secondary_phy = arg_5->ext_adv_set_params.params.secondary_phy; params.sid = arg_5->ext_adv_set_params.params.sid; params.scan_req_notif = arg_5->ext_adv_set_params.params.scan_req_notif; - +#if (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) + params.primary_adv_phy_options = arg_5->ext_adv_set_params.params.primary_adv_phy_options; + params.secondary_adv_phy_options= arg_5->ext_adv_set_params.params.secondary_adv_phy_options; +#endif // (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) memcpy(params.peer_addr, arg_5->ext_adv_set_params.params.peer_addr, sizeof(BD_ADDR)); BTC_TRACE_DEBUG("BTC_GAP_BLE_SET_EXT_ADV_PARAMS"); 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 e784919b57..c2318de1d0 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 @@ -370,6 +370,12 @@ #define UC_BT_BLE_FEAT_PAWR_EN FALSE #endif +#ifdef CONFIG_BT_BLE_FEAT_ADV_CODING_SELECTION +#define UC_BT_BLE_FEAT_ADV_CODING_SELECTION CONFIG_BT_BLE_FEAT_ADV_CODING_SELECTION +#else +#define UC_BT_BLE_FEAT_ADV_CODING_SELECTION FALSE +#endif + #ifdef CONFIG_BT_BLE_VENDOR_HCI_EN #define UC_BT_BLE_VENDOR_HCI_EN CONFIG_BT_BLE_VENDOR_HCI_EN #else 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 eb2a6b92bb..4dadb8a29f 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -421,6 +421,12 @@ #define BT_BLE_FEAT_PAWR_EN FALSE #endif +#if (UC_BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) +#define BT_BLE_FEAT_ADV_CODING_SELECTION TRUE +#else +#define BT_BLE_FEAT_ADV_CODING_SELECTION FALSE +#endif + #if (UC_BT_BLE_VENDOR_HCI_EN == TRUE) #define BLE_VENDOR_HCI_EN TRUE #else diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index bda51c25de..20225ef564 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -401,7 +401,18 @@ tBTM_STATUS BTM_BleSetExtendedAdvParams(UINT8 instance, tBTM_BLE_GAP_EXT_ADV_PAR #else btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = params->own_addr_type; #endif - +#if (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) + if ((err = btsnd_hcic_ble_set_ext_adv_params_v2(instance, params->type, params->interval_min, params->interval_max, + params->channel_map, params->own_addr_type, params->peer_addr_type, + params->peer_addr, params->filter_policy, params->tx_power, + params->primary_phy, params->max_skip, + params->secondary_phy, params->sid, params->scan_req_notif, + params->primary_adv_phy_options, params->secondary_adv_phy_options)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("LE EA SetParams: cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + goto end; + } +#else if ((err = btsnd_hcic_ble_set_ext_adv_params(instance, params->type, params->interval_min, params->interval_max, params->channel_map, params->own_addr_type, params->peer_addr_type, params->peer_addr, params->filter_policy, params->tx_power, @@ -411,6 +422,7 @@ tBTM_STATUS BTM_BleSetExtendedAdvParams(UINT8 instance, tBTM_BLE_GAP_EXT_ADV_PAR status = BTM_HCI_ERROR | err; goto end; } +#endif // (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) extend_adv_cb.inst[instance].configured = true; @@ -692,7 +704,6 @@ tBTM_STATUS BTM_BlePeriodicAdvSetParams(UINT8 instance, tBTM_BLE_Periodic_Adv_Pa tBTM_STATUS status = BTM_SUCCESS; tHCI_STATUS err = HCI_SUCCESS; tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; - //ext_adv_flag = true; if (instance >= MAX_BLE_ADV_INSTANCE) { status = BTM_ILLEGAL_VALUE; diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 7947ef557f..10d0dd89d2 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -1221,7 +1221,55 @@ UINT8 btsnd_hcic_ble_set_extend_rand_address(UINT8 adv_handle, BD_ADDR rand_addr return btu_hcif_send_cmd_sync (LOCAL_BR_EDR_CONTROLLER_ID, p); } +#if (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) +UINT8 btsnd_hcic_ble_set_ext_adv_params_v2(UINT8 adv_handle, UINT16 properties, UINT32 interval_min, + UINT32 interval_max, UINT8 channel_map, UINT8 own_addr_type, + UINT8 peer_addr_type, BD_ADDR peer_addr, + UINT8 adv_filter_policy, INT8 adv_tx_power, + UINT8 primary_adv_phy, UINT8 secondary_adv_max_skip, + UINT8 secondary_adv_phy, + UINT8 adv_sid, UINT8 scan_req_ntf_enable, + UINT8 primary_adv_phy_options, UINT8 secondary_adv_phy_options) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_EVENT("%s, adv_handle = %d, properties = %d, interval_min = %d, interval_max = %d, channel_map = %d,\n\ + own_addr_type = %d, peer_addr_type = %d, adv_filter_policy = %d,\n\ + adv_tx_power = %d, primary_adv_phy = %d, secondary_adv_max_skip = %d, secondary_adv_phy = %d,\n\ + adv_sid = %d, scan_req_ntf_enable = %d, primary_phy_options %d secondary_phy_options %d", __func__, adv_handle, properties, interval_min, interval_max, + channel_map, own_addr_type, peer_addr_type, adv_filter_policy, adv_tx_power, + primary_adv_phy, secondary_adv_max_skip, secondary_adv_phy, adv_sid, scan_req_ntf_enable, + primary_adv_phy_options, secondary_adv_phy_options); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_EXT_ADV_SET_PARAMS + 2); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_EXT_ADV_PARAM_V2); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_EXT_ADV_SET_PARAMS + 2); + + UINT8_TO_STREAM(pp, adv_handle); + UINT16_TO_STREAM(pp, properties); + UINT24_TO_STREAM(pp, interval_min); + UINT24_TO_STREAM(pp, interval_max); + UINT8_TO_STREAM(pp, channel_map); + UINT8_TO_STREAM(pp, own_addr_type); + UINT8_TO_STREAM(pp, peer_addr_type); + BDADDR_TO_STREAM (pp, peer_addr); + UINT8_TO_STREAM(pp, adv_filter_policy); + INT8_TO_STREAM(pp, adv_tx_power); + UINT8_TO_STREAM(pp, primary_adv_phy); + UINT8_TO_STREAM(pp, secondary_adv_max_skip); + UINT8_TO_STREAM(pp, secondary_adv_phy); + UINT8_TO_STREAM(pp, adv_sid); + UINT8_TO_STREAM(pp, scan_req_ntf_enable); + UINT8_TO_STREAM(pp, primary_adv_phy_options); + UINT8_TO_STREAM(pp, secondary_adv_phy_options); + + return btu_hcif_send_cmd_sync (LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +#else UINT8 btsnd_hcic_ble_set_ext_adv_params(UINT8 adv_handle, UINT16 properties, UINT32 interval_min, UINT32 interval_max, UINT8 channel_map, UINT8 own_addr_type, UINT8 peer_addr_type, BD_ADDR peer_addr, @@ -1264,8 +1312,7 @@ UINT8 btsnd_hcic_ble_set_ext_adv_params(UINT8 adv_handle, UINT16 properties, UIN return btu_hcif_send_cmd_sync (LOCAL_BR_EDR_CONTROLLER_ID, p); } - -bool ext_adv_flag = false; +#endif // #if (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) UINT8 btsnd_hcic_ble_set_ext_adv_data(UINT8 adv_handle, UINT8 operation, UINT8 fragment_prefrence, @@ -1275,7 +1322,6 @@ UINT8 btsnd_hcic_ble_set_ext_adv_data(UINT8 adv_handle, UINT8 *pp; HCI_TRACE_EVENT("%s, adv_handle = %d, operation = %d, fragment_prefrence = %d,\ data_len = %d", __func__, adv_handle, operation, fragment_prefrence, data_len); - ext_adv_flag = true; HCIC_BLE_CMD_CREATED(p, pp, data_len + 4); UINT16_TO_STREAM(pp, HCI_BLE_SET_EXT_ADV_DATA); 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 5e1dcbceed..8c0460c457 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 @@ -781,6 +781,10 @@ typedef struct { tBTM_BLE_GAP_PHY secondary_phy; UINT8 sid; BOOLEAN scan_req_notif; +#if (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) + UINT8 primary_adv_phy_options; + UINT8 secondary_adv_phy_options; +#endif // (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) } tBTM_BLE_GAP_EXT_ADV_PARAMS; typedef struct { diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index 81bfbe0f43..a539b3e69d 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -443,6 +443,10 @@ #define HCI_BLE_SUBRATE_REQUEST (0x007E | HCI_GRP_BLE_CMDS) #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) +#define HCI_BLE_SET_EXT_ADV_PARAM_V2 (0x007F | HCI_GRP_BLE_CMDS) +#endif // (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) + #if (BT_BLE_FEAT_PAWR_EN == TRUE) #define HCI_BLE_SET_PERIOD_ADV_SUBEVT_DATA (0x0082 | HCI_GRP_BLE_CMDS) #define HCI_BLE_SET_PERIOD_ADV_RSP_DATA (0x0083 | HCI_GRP_BLE_CMDS) diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index 9ebbebdf92..d497ee2592 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -1265,4 +1265,15 @@ UINT8 btsnd_hcic_ble_set_periodic_adv_rsp_data(UINT16 sync_handle, UINT16 req_ev UINT8 btsnd_hcic_ble_set_periodic_sync_subevt(UINT16 sync_handle, UINT16 periodic_adv_properties, UINT8 num_subevents_to_sync, UINT8 *subevt); #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) +UINT8 btsnd_hcic_ble_set_ext_adv_params_v2(UINT8 adv_handle, UINT16 properties, UINT32 interval_min, + UINT32 interval_max, UINT8 channel_map, UINT8 own_addr_type, + UINT8 peer_addr_type, BD_ADDR peer_addr, + UINT8 adv_filter_policy, INT8 adv_tx_power, + UINT8 primary_adv_phy, UINT8 secondary_adv_max_skip, + UINT8 secondary_adv_phy, + UINT8 adv_sid, UINT8 scan_req_ntf_enable, + UINT8 primary_adv_phy_options, UINT8 secondary_adv_phy_options); +#endif // (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) + #endif From a3f994315ff78597df01b5d49e20098b99030cf7 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Tue, 10 Jun 2025 15:39:50 +0800 Subject: [PATCH 007/226] feat(ble/bluedroid): Support LE Security Levels Characteristic --- components/bt/host/bluedroid/Kconfig.in | 7 ++++++ .../include/common/bluedroid_user_config.h | 6 +++++ .../common/include/common/bt_target.h | 6 +++++ .../bt/host/bluedroid/stack/gap/gap_ble.c | 23 +++++++++++++++++++ .../bluedroid/stack/include/stack/gap_api.h | 3 +++ .../bluedroid/stack/include/stack/gattdefs.h | 4 +++- 6 files changed, 48 insertions(+), 1 deletion(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 734fe0a730..4a3ad65333 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -377,6 +377,13 @@ config BT_GATTS_APPEARANCE_WRITABLE help Enabling this option allows remote GATT clients to write appearance +config BT_GATTS_SECURITY_LEVELS_CHAR + bool "Enable LE GATT Security Levels Characteristic" + depends on BT_GATTS_ENABLE + default n + help + Enable LE GATT Security Levels Characteristic + menuconfig BT_GATTC_ENABLE bool "Include GATT client module(GATTC)" depends on BT_BLE_ENABLED 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 c2318de1d0..48d06fba6b 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 @@ -580,6 +580,12 @@ #define UC_BT_GATTS_APPEARANCE_WRITABLE FALSE #endif +#ifdef CONFIG_BT_GATTS_SECURITY_LEVELS_CHAR +#define UC_BT_GATTS_SECURITY_LEVELS_CHAR CONFIG_BT_GATTS_SECURITY_LEVELS_CHAR +#else +#define UC_BT_GATTS_SECURITY_LEVELS_CHAR FALSE +#endif + #ifdef CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN #define UC_BT_BLE_ACT_SCAN_REP_ADV_SCAN CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN #else 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 4dadb8a29f..a62caff1a2 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -798,6 +798,12 @@ #define GATTS_APPEARANCE_WRITABLE FALSE #endif +#if (UC_BT_GATTS_SECURITY_LEVELS_CHAR == TRUE) +#define BT_GATTS_SECURITY_LEVELS_CHAR TRUE +#else +#define BT_GATTS_SECURITY_LEVELS_CHAR FALSE +#endif + #ifdef UC_BT_BLE_ACT_SCAN_REP_ADV_SCAN #define BTM_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY UC_BT_BLE_ACT_SCAN_REP_ADV_SCAN #endif diff --git a/components/bt/host/bluedroid/stack/gap/gap_ble.c b/components/bt/host/bluedroid/stack/gap/gap_ble.c index bf3d97d666..5dd00e5e79 100644 --- a/components/bt/host/bluedroid/stack/gap/gap_ble.c +++ b/components/bt/host/bluedroid/stack/gap/gap_ble.c @@ -256,6 +256,12 @@ tGATT_STATUS gap_read_attr_value (UINT16 handle, tGATT_VALUE *p_value, BOOLEAN i UINT8_TO_STREAM(p, p_db_attr->attr_value.addr_resolution); p_value->len = 1; break; +#if (BT_GATTS_SECURITY_LEVELS_CHAR == TRUE) + case GATT_UUID_GAP_GATT_SECURITY_LEVELS: + UINT16_TO_STREAM(p, p_db_attr->attr_value.security_level); + p_value->len = 2; + break; +#endif // (BT_GATTS_SECURITY_LEVELS_CHAR == TRUE) } return GATT_SUCCESS; } @@ -464,6 +470,17 @@ void gap_attr_db_init(void) p_db_attr->attr_value.addr_resolution = 0; p_db_attr++; +#if (BT_GATTS_SECURITY_LEVELS_CHAR == TRUE) + /* Add LE Security Levels Characteristic */ + uuid.len = LEN_UUID_16; + uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_GATT_SECURITY_LEVELS; + p_db_attr->handle = GATTS_AddCharacteristic(service_handle, &uuid, + GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ, + NULL, NULL); + p_db_attr->attr_value.security_level = 0x0101; + p_db_attr++; +#endif // (BT_GATTS_SECURITY_LEVELS_CHAR == TRUE) + /* start service now */ memset (&app_uuid.uu.uuid128, 0x81, LEN_UUID_128); @@ -517,6 +534,12 @@ void GAP_BleAttrDBUpdate(UINT16 attr_uuid, tGAP_BLE_ATTR_VALUE *p_value) p_db_attr->attr_value.addr_resolution = p_value->addr_resolution; break; +#if (BT_GATTS_SECURITY_LEVELS_CHAR == TRUE) + case GATT_UUID_GAP_GATT_SECURITY_LEVELS: + p_db_attr->attr_value.security_level = p_value->security_level; + break; +#endif // (BT_GATTS_SECURITY_LEVELS_CHAR == TRUE) + } break; } diff --git a/components/bt/host/bluedroid/stack/include/stack/gap_api.h b/components/bt/host/bluedroid/stack/include/stack/gap_api.h index 62062d2f21..a79d9748c8 100644 --- a/components/bt/host/bluedroid/stack/include/stack/gap_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/gap_api.h @@ -119,6 +119,9 @@ typedef union { UINT16 icon; UINT8 *p_dev_name; UINT8 addr_resolution; +#if (BT_GATTS_SECURITY_LEVELS_CHAR == TRUE) + UINT16 security_level; +#endif // (BT_GATTS_SECURITY_LEVELS_CHAR == TRUE) } tGAP_BLE_ATTR_VALUE; diff --git a/components/bt/host/bluedroid/stack/include/stack/gattdefs.h b/components/bt/host/bluedroid/stack/include/stack/gattdefs.h index d8e4cb591e..2ae8cef839 100644 --- a/components/bt/host/bluedroid/stack/include/stack/gattdefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/gattdefs.h @@ -52,6 +52,8 @@ #define GATT_UUID_GAP_PREF_CONN_PARAM 0x2A04 #define GATT_UUID_GAP_CENTRAL_ADDR_RESOL 0x2AA6 +#define GATT_UUID_GAP_GATT_SECURITY_LEVELS 0x2BF5 + /* Attribute Profile Attribute UUID */ #define GATT_UUID_GATT_SRV_CHGD 0x2A05 /* Attribute Protocol Test */ @@ -81,7 +83,7 @@ #define GATT_UUID_GM_CONTROL_POINT 0x2A52 #define GATT_UUID_GM_FEATURE 0x2A51 -/* device infor characteristic */ +/* device information characteristic */ #define GATT_UUID_SYSTEM_ID 0x2A23 #define GATT_UUID_MODEL_NUMBER_STR 0x2A24 #define GATT_UUID_SERIAL_NUMBER_STR 0x2A25 From 692c2b02e59a5d960c80a5837a47410ad6d44cdd Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Mon, 23 Jun 2025 17:33:21 +0800 Subject: [PATCH 008/226] feat(ble/bluedroid): Supported BLE bluedroid host pawr connection --- .../core/bluedroid_host/adapter.c | 2 + .../bt/host/bluedroid/api/esp_gattc_api.c | 107 +++++++++++++++++- .../bluedroid/api/include/api/esp_gatt_defs.h | 15 ++- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 2 +- .../host/bluedroid/bta/gatt/bta_gattc_act.c | 15 ++- .../host/bluedroid/bta/gatt/bta_gattc_api.c | 6 + .../host/bluedroid/bta/gatt/bta_gatts_act.c | 2 +- .../bta/gatt/include/bta_gattc_int.h | 5 + .../bt/host/bluedroid/bta/hh/bta_hh_le.c | 2 +- .../bluedroid/bta/include/bta/bta_gatt_api.h | 1 + .../bt/host/bluedroid/bta/jv/bta_jv_act.c | 2 +- .../btc/profile/std/gatt/btc_gattc.c | 11 +- .../btc/profile/std/include/btc_gattc.h | 3 + .../host/bluedroid/stack/btm/btm_ble_bgconn.c | 2 +- .../bluedroid/stack/btm/include/btm_int.h | 3 + .../bt/host/bluedroid/stack/gap/gap_ble.c | 2 +- .../bt/host/bluedroid/stack/gatt/gatt_api.c | 5 +- .../bt/host/bluedroid/stack/gatt/gatt_attr.c | 14 +-- .../bt/host/bluedroid/stack/gatt/gatt_main.c | 12 +- .../bluedroid/stack/gatt/include/gatt_int.h | 4 +- .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 76 +++++++++++++ .../bluedroid/stack/include/stack/gatt_api.h | 3 +- .../bluedroid/stack/include/stack/hcidefs.h | 1 + .../bluedroid/stack/include/stack/hcimsgs.h | 8 ++ .../bluedroid/stack/include/stack/l2c_api.h | 13 ++- .../bluedroid/stack/l2cap/include/l2c_int.h | 5 + .../bt/host/bluedroid/stack/l2cap/l2c_api.c | 8 +- .../bt/host/bluedroid/stack/l2cap/l2c_ble.c | 20 +++- .../bt/host/bluedroid/stack/smp/smp_api.c | 4 +- 29 files changed, 312 insertions(+), 41 deletions(-) diff --git a/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c b/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c index e31d4186e7..a322c0ab86 100644 --- a/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c +++ b/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c @@ -1874,6 +1874,7 @@ int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, uint16_t service_uuid) BTA_GATTC_Enh_Open(bt_mesh_gattc_if, bt_mesh_gattc_info[i].addr.val, bt_mesh_gattc_info[i].addr.type, true, BTA_GATT_TRANSPORT_LE, TRUE, BLE_ADDR_UNKNOWN_TYPE, + false, 0xFF, 0xFF, BTA_BLE_PHY_1M_MASK, &conn_1m_param, NULL, NULL); #else /* CONFIG_BLE_MESH_USE_BLE_50 */ /* Min_interval: 15ms @@ -1889,6 +1890,7 @@ int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, uint16_t service_uuid) BTA_GATTC_Enh_Open(bt_mesh_gattc_if, bt_mesh_gattc_info[i].addr.val, bt_mesh_gattc_info[i].addr.type, true, BTA_GATT_TRANSPORT_LE, FALSE, BLE_ADDR_UNKNOWN_TYPE, + false, 0xFF, 0xFF, BTA_BLE_PHY_1M_MASK, &conn_1m_param, NULL, NULL); #endif /* CONFIG_BLE_MESH_USE_BLE_50 */ diff --git a/components/bt/host/bluedroid/api/esp_gattc_api.c b/components/bt/host/bluedroid/api/esp_gattc_api.c index 00c6a96e0b..f54deb8ea2 100644 --- a/components/bt/host/bluedroid/api/esp_gattc_api.c +++ b/components/bt/host/bluedroid/api/esp_gattc_api.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -88,6 +88,11 @@ esp_err_t esp_ble_gattc_enh_open(esp_gatt_if_t gattc_if, esp_ble_gatt_creat_conn arg.open.remote_addr_type = creat_conn_params->remote_addr_type; arg.open.is_direct = creat_conn_params->is_direct; arg.open.is_aux= creat_conn_params->is_aux; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + arg.open.is_pawr_synced = false; + arg.open.adv_handle = 0xFF; + arg.open.subevent = 0xFF; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) arg.open.own_addr_type = creat_conn_params->own_addr_type; arg.open.phy_mask = creat_conn_params->phy_mask; @@ -206,6 +211,106 @@ esp_err_t esp_ble_gattc_aux_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bd } #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +esp_err_t esp_ble_gattc_aux_open_with_pawr_synced(esp_gatt_if_t gattc_if, esp_ble_gatt_pawr_conn_params_t *pawr_conn_params) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + const esp_ble_conn_params_t *conn_params; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (!pawr_conn_params) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_OPEN; + arg.open.gattc_if = gattc_if; + memcpy(arg.open.remote_bda, pawr_conn_params->remote_bda, ESP_BD_ADDR_LEN); + arg.open.remote_addr_type = pawr_conn_params->remote_addr_type; + arg.open.is_direct = true; + arg.open.is_aux = true; + arg.open.is_pawr_synced = true; + arg.open.adv_handle = pawr_conn_params->adv_handle; + arg.open.subevent = pawr_conn_params->subevent; + arg.open.own_addr_type = pawr_conn_params->own_addr_type; + arg.open.phy_mask = pawr_conn_params->phy_mask; + + if (pawr_conn_params->phy_mask & ESP_BLE_PHY_1M_PREF_MASK) { + if (!pawr_conn_params->phy_1m_conn_params) { + return ESP_ERR_INVALID_ARG; + } + + 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) && + 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))) && + (conn_params->interval_min <= conn_params->interval_max)) { + memcpy(&arg.open.phy_1m_conn_params, conn_params, sizeof(esp_ble_conn_params_t)); + } else { + LOG_ERROR("%s, invalid 1M PHY connection params: min_int = %d, max_int = %d, latency = %d, timeout = %d", __func__, + conn_params->interval_min, + conn_params->interval_max, + conn_params->latency, + conn_params->supervision_timeout); + return ESP_ERR_INVALID_ARG; + } + } + + if (pawr_conn_params->phy_mask & ESP_BLE_PHY_2M_PREF_MASK) { + if (!pawr_conn_params->phy_2m_conn_params) { + return ESP_ERR_INVALID_ARG; + } + + 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) && + 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))) && + (conn_params->interval_min <= conn_params->interval_max)) { + memcpy(&arg.open.phy_2m_conn_params, conn_params, sizeof(esp_ble_conn_params_t)); + } else { + LOG_ERROR("%s, invalid 2M PHY connection params: min_int = %d, max_int = %d, latency = %d, timeout = %d", __func__, + conn_params->interval_min, + conn_params->interval_max, + conn_params->latency, + conn_params->supervision_timeout); + return ESP_ERR_INVALID_ARG; + } + } + + if (pawr_conn_params->phy_mask & ESP_BLE_PHY_CODED_PREF_MASK) { + if (!pawr_conn_params->phy_coded_conn_params) { + return ESP_ERR_INVALID_ARG; + } + + 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) && + 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))) && + (conn_params->interval_min <= conn_params->interval_max)) { + memcpy(&arg.open.phy_coded_conn_params, conn_params, sizeof(esp_ble_conn_params_t)); + } else { + LOG_ERROR("%s, invalid Coded PHY connection params: min_int = %d, max_int = %d, latency = %d, timeout = %d", __func__, + conn_params->interval_min, + conn_params->interval_max, + conn_params->latency, + conn_params->supervision_timeout); + return ESP_ERR_INVALID_ARG; + } + } + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + esp_err_t esp_ble_gattc_close (esp_gatt_if_t gattc_if, uint16_t conn_id) { btc_msg_t msg = {0}; diff --git a/components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h b/components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h index e8cc134ca7..dcbfe2f6eb 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -695,6 +695,19 @@ typedef struct { const esp_ble_conn_params_t *phy_coded_conn_params; /*!< Connection parameters for the LE Coded PHY */ } esp_ble_gatt_creat_conn_params_t; +/** @brief Represents a creat connection element. */ +typedef struct { + esp_bd_addr_t remote_bda; /*!< The Bluetooth address of the remote device */ + esp_ble_addr_type_t remote_addr_type; /*!< Address type of the remote device */ + esp_ble_addr_type_t own_addr_type; /*!< Specifies the address type used in the connection request. Set to 0xFF if the address type is unknown. */ + uint8_t adv_handle; /*!< Advertising_Handle identifying the periodic advertising train. Range: 0x00 to 0xEF or 0xFF */ + uint8_t subevent; /*!< Subevent where the connection request is to be sent. Range: 0x00 to 0x7F or 0xFF */ + esp_ble_phy_mask_t phy_mask; /*!< Indicates which PHY connection parameters will be used. When is_aux is false, only the connection params for 1M PHY can be specified */ + const esp_ble_conn_params_t *phy_1m_conn_params; /*!< Connection parameters for the LE 1M PHY */ + const esp_ble_conn_params_t *phy_2m_conn_params; /*!< Connection parameters for the LE 2M PHY */ + const esp_ble_conn_params_t *phy_coded_conn_params; /*!< Connection parameters for the LE Coded PHY */ +} esp_ble_gatt_pawr_conn_params_t; + #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 5082201278..2c35c4fa32 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6961,7 +6961,7 @@ void btm_dm_start_gatt_discovery (BD_ADDR bd_addr) } else { //TODO need to add addr_type in future BTA_GATTC_Enh_Open(bta_dm_search_cb.client_if, bd_addr, BLE_ADDR_UNKNOWN_TYPE, TRUE, - BTA_GATT_TRANSPORT_LE, FALSE, BLE_ADDR_UNKNOWN_TYPE, 0, NULL, NULL, NULL); + BTA_GATT_TRANSPORT_LE, FALSE, BLE_ADDR_UNKNOWN_TYPE, false, 0xFF, 0xFF, 0, NULL, NULL, NULL); } } diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c index f65dd43e7c..bbbc1ba09f 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c @@ -511,6 +511,10 @@ void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) tGATT_TCB *p_tcb; tBTM_SEC_DEV_REC *p_dev_rec = NULL; + BOOLEAN is_pawr_synced = FALSE; + UINT8 adv_handle = 0xFF; + UINT8 subevent = 0xFF; + if (!p_clcb || !p_data) { return; } @@ -545,10 +549,15 @@ void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) APPL_TRACE_ERROR("Unknown Device, setting rejected"); } } - +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + is_pawr_synced = p_data->api_conn.is_pawr_synced; + adv_handle = p_data->api_conn.adv_handle; + subevent = p_data->api_conn.subevent; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) /* open/hold a connection */ if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, p_data->api_conn.remote_addr_type, - TRUE, p_data->api_conn.transport, p_data->api_conn.is_aux)) { + TRUE, p_data->api_conn.transport, p_data->api_conn.is_aux, is_pawr_synced, + adv_handle, subevent)) { APPL_TRACE_ERROR("Connection open failure"); bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data); @@ -585,7 +594,7 @@ void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg /* always call open to hold a connection */ if (!GATT_Connect(p_data->client_if, p_data->remote_bda, p_data->remote_addr_type, FALSE, - p_data->transport, p_data->is_aux)) { + p_data->transport, p_data->is_aux, FALSE, 0xFF, 0xFF)) { #if (!CONFIG_BT_STACK_NO_LOG) uint8_t *bda = (uint8_t *)p_data->remote_bda; #endif diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c index 8ac0ec4c96..69738647ba 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c @@ -144,6 +144,7 @@ void BTA_GATTC_AppDeregister(tBTA_GATTC_IF client_if) *******************************************************************************/ void BTA_GATTC_Enh_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_ADDR_TYPE remote_addr_type, BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport, BOOLEAN is_aux, tBTA_ADDR_TYPE own_addr_type, + BOOLEAN is_pawr_synced, UINT8 adv_handle, UINT8 subevent, UINT8 phy_mask, tBTA_BLE_CONN_PARAMS *phy_1m_conn_params, tBTA_BLE_CONN_PARAMS *phy_2m_conn_params, tBTA_BLE_CONN_PARAMS *phy_coded_conn_params) { @@ -156,6 +157,11 @@ void BTA_GATTC_Enh_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_ADDR_T p_buf->is_direct = is_direct; p_buf->transport = transport; p_buf->is_aux = is_aux; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + p_buf->is_pawr_synced = is_pawr_synced; + p_buf->adv_handle = adv_handle; + p_buf->subevent = subevent; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) p_buf->remote_addr_type = remote_addr_type; p_buf->own_addr_type = own_addr_type; p_buf->phy_mask = phy_mask; diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c index 692c59c660..37c9a67527 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c @@ -757,7 +757,7 @@ void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg) if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if)) != NULL) { /* should always get the connection ID */ if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda, BLE_ADDR_UNKNOWN_TYPE, - p_msg->api_open.is_direct, p_msg->api_open.transport, FALSE)) { + p_msg->api_open.is_direct, p_msg->api_open.transport, FALSE, FALSE, 0xFF, 0xFF)) { status = BTA_GATT_OK; if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda, diff --git a/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h b/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h index cb877fcfc2..ac42de6973 100644 --- a/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h +++ b/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h @@ -130,6 +130,11 @@ typedef struct { tBTA_GATTC_IF client_if; BOOLEAN is_direct; BOOLEAN is_aux; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + BOOLEAN is_pawr_synced; + UINT8 adv_handle; + UINT8 subevent; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) tBTA_TRANSPORT transport; tBTA_ADDR_TYPE own_addr_type; UINT8 phy_mask; diff --git a/components/bt/host/bluedroid/bta/hh/bta_hh_le.c b/components/bt/host/bluedroid/bta/hh/bta_hh_le.c index f5697dff52..ae150a3c94 100644 --- a/components/bt/host/bluedroid/bta/hh/bta_hh_le.c +++ b/components/bt/host/bluedroid/bta/hh/bta_hh_le.c @@ -2603,7 +2603,7 @@ static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB *p_cb, BOOLEAN check_bond) !p_cb->in_bg_conn && to_add) { /* add device into BG connection to accept remote initiated connection */ BTA_GATTC_Enh_Open(bta_hh_cb.gatt_if, p_cb->addr, BLE_ADDR_UNKNOWN_TYPE, FALSE, - BTA_GATT_TRANSPORT_LE, FALSE, BLE_ADDR_UNKNOWN_TYPE, 0, NULL, NULL); + BTA_GATT_TRANSPORT_LE, FALSE, BLE_ADDR_UNKNOWN_TYPE, false, 0xFF, 0xFF, 0, NULL, NULL); p_cb->in_bg_conn = TRUE; BTA_DmBleSetBgConnType(BTA_DM_BLE_CONN_AUTO, NULL); diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h index a42d14084b..7819b8a718 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h @@ -817,6 +817,7 @@ extern void BTA_GATTC_AppDeregister (tBTA_GATTC_IF client_if); *******************************************************************************/ extern void BTA_GATTC_Enh_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_ADDR_TYPE remote_addr_type, BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport, BOOLEAN is_aux, tBTA_ADDR_TYPE own_addr_type, + BOOLEAN is_pawr_synced, UINT8 adv_handle, UINT8 subevent, UINT8 phy_mask, tBTA_BLE_CONN_PARAMS *phy_1m_conn_params, tBTA_BLE_CONN_PARAMS *phy_2m_conn_params, tBTA_BLE_CONN_PARAMS *phy_coded_conn_params); diff --git a/components/bt/host/bluedroid/bta/jv/bta_jv_act.c b/components/bt/host/bluedroid/bta/jv/bta_jv_act.c index a49cfc91a0..492c22022e 100644 --- a/components/bt/host/bluedroid/bta/jv/bta_jv_act.c +++ b/components/bt/host/bluedroid/bta/jv/bta_jv_act.c @@ -2923,7 +2923,7 @@ void bta_jv_l2cap_connect_le(tBTA_JV_MSG *p_data) id = t->id; t->init_called = FALSE; - if (L2CA_ConnectFixedChnl(t->chan, t->remote_addr, BLE_ADDR_UNKNOWN_TYPE, FALSE)) { + if (L2CA_ConnectFixedChnl(t->chan, t->remote_addr, BLE_ADDR_UNKNOWN_TYPE, FALSE, FALSE, 0xFF, 0xFF)) { evt.l2c_cl_init.status = BTA_JV_SUCCESS; evt.l2c_cl_init.handle = id; diff --git a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c index e8f7444368..9928a7ab2e 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c +++ b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c @@ -213,12 +213,21 @@ static void btc_gattc_app_unregister(btc_ble_gattc_args_t *arg) static void btc_gattc_open(btc_ble_gattc_args_t *arg) { tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE; - +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + BTA_GATTC_Enh_Open(arg->open.gattc_if, arg->open.remote_bda, + arg->open.remote_addr_type, arg->open.is_direct, + transport, arg->open.is_aux, arg->open.own_addr_type, + arg->open.is_pawr_synced, arg->open.adv_handle, arg->open.subevent, + arg->open.phy_mask, (void *)&arg->open.phy_1m_conn_params, + (void *)&arg->open.phy_2m_conn_params, (void *)&arg->open.phy_coded_conn_params); +#else BTA_GATTC_Enh_Open(arg->open.gattc_if, arg->open.remote_bda, arg->open.remote_addr_type, arg->open.is_direct, transport, arg->open.is_aux, arg->open.own_addr_type, + false, 0xff, 0xff, arg->open.phy_mask, (void *)&arg->open.phy_1m_conn_params, (void *)&arg->open.phy_2m_conn_params, (void *)&arg->open.phy_coded_conn_params); +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) } static void btc_gattc_close(btc_ble_gattc_args_t *arg) diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h index 1c8ef828b0..7580b7f17c 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h @@ -58,6 +58,9 @@ typedef union { bool is_direct; bool is_aux; esp_ble_addr_type_t own_addr_type; + bool is_pawr_synced; + uint8_t adv_handle; + uint8_t subevent; esp_ble_phy_mask_t phy_mask; esp_ble_conn_params_t phy_1m_conn_params; esp_ble_conn_params_t phy_2m_conn_params; diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c index bf9b1adbff..1eb67844f1 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c @@ -671,7 +671,7 @@ void btm_ble_initiate_select_conn(BD_ADDR bda) BTM_TRACE_EVENT ("btm_ble_initiate_select_conn"); /* use direct connection procedure to initiate connection */ - if (!L2CA_ConnectFixedChnl(L2CAP_ATT_CID, bda, BLE_ADDR_UNKNOWN_TYPE, FALSE)) { + if (!L2CA_ConnectFixedChnl(L2CAP_ATT_CID, bda, BLE_ADDR_UNKNOWN_TYPE, FALSE, FALSE, 0xFF, 0xFF)) { BTM_TRACE_ERROR("btm_ble_initiate_select_conn failed"); } } diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index e1036b9174..5afc610e80 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -702,6 +702,9 @@ struct tBTM_SEC_DEV_REC{ #if (BLE_50_FEATURE_SUPPORT == TRUE) tBTM_EXT_CONN_PARAMS ext_conn_params; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + BOOLEAN is_pawr_synced; + UINT8 adv_handle; + UINT8 subevent; #endif // btla-specific ++ diff --git a/components/bt/host/bluedroid/stack/gap/gap_ble.c b/components/bt/host/bluedroid/stack/gap/gap_ble.c index 5dd00e5e79..7e4f453278 100644 --- a/components/bt/host/bluedroid/stack/gap/gap_ble.c +++ b/components/bt/host/bluedroid/stack/gap/gap_ble.c @@ -764,7 +764,7 @@ BOOLEAN gap_ble_accept_cl_operation(BD_ADDR peer_bda, UINT16 uuid, tGAP_BLE_CMPL } /* hold the link here */ - if (!GATT_Connect(gap_cb.gatt_if, p_clcb->bda, BLE_ADDR_UNKNOWN_TYPE, TRUE, BT_TRANSPORT_LE, FALSE)) { + if (!GATT_Connect(gap_cb.gatt_if, p_clcb->bda, BLE_ADDR_UNKNOWN_TYPE, TRUE, BT_TRANSPORT_LE, FALSE, FALSE, 0xFF, 0xFF)) { return started; } diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_api.c b/components/bt/host/bluedroid/stack/gatt/gatt_api.c index 51e46e2274..db7952e95a 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_api.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_api.c @@ -1453,7 +1453,8 @@ void GATT_StartIf (tGATT_IF gatt_if) ** *******************************************************************************/ BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_addr_type, - BOOLEAN is_direct, tBT_TRANSPORT transport, BOOLEAN is_aux) + BOOLEAN is_direct, tBT_TRANSPORT transport, BOOLEAN is_aux, + BOOLEAN is_pawr_synced, UINT8 adv_handle, UINT8 subevent) { tGATT_REG *p_reg; BOOLEAN status = FALSE; @@ -1467,7 +1468,7 @@ BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_addr_ } if (is_direct) { - status = gatt_act_connect (p_reg, bd_addr, bd_addr_type, transport, is_aux); + status = gatt_act_connect (p_reg, bd_addr, bd_addr_type, transport, is_aux, is_pawr_synced, adv_handle, subevent); } else { #if (tGATT_BG_CONN_DEV == TRUE) if (transport == BT_TRANSPORT_LE) { diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_attr.c b/components/bt/host/bluedroid/stack/gatt/gatt_attr.c index 3ab573426a..27e80d605d 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_attr.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_attr.c @@ -98,7 +98,7 @@ UINT16 gatt_profile_find_conn_id_by_bd_addr(BD_ADDR remote_bda) ** ** Description find clcb by Connection ID ** -** Returns Pointer to the found link conenction control block. +** Returns Pointer to the found link connection control block. ** *******************************************************************************/ static tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_conn_id(UINT16 conn_id) @@ -119,9 +119,9 @@ static tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_conn_id(UINT16 conn_id) ** ** Function gatt_profile_find_clcb_by_bd_addr ** -** Description The function searches all LCBs with macthing bd address. +** Description The function searches all LCBs with matching bd address. ** -** Returns Pointer to the found link conenction control block. +** Returns Pointer to the found link connection control block. ** *******************************************************************************/ static tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_bd_addr(BD_ADDR bda, tBT_TRANSPORT transport) @@ -148,7 +148,7 @@ static tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_bd_addr(BD_ADDR bda, tBT_TR ** Returns NULL if not found. Otherwise pointer to the connection link block. ** *******************************************************************************/ -tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda, tBT_TRANSPORT tranport) +tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda, tBT_TRANSPORT transport) { UINT8 i_clcb = 0; tGATT_PROFILE_CLCB *p_clcb = NULL; @@ -158,7 +158,7 @@ tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda, tBT_TR p_clcb->in_use = TRUE; p_clcb->conn_id = conn_id; p_clcb->connected = TRUE; - p_clcb->transport = tranport; + p_clcb->transport = transport; memcpy (p_clcb->bda, bda, BD_ADDR_LEN); break; } @@ -435,7 +435,7 @@ static void gatt_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, ** ** Function gatt_profile_db_init ** -** Description Initializa the GATT profile attribute database. +** Description Initialize the GATT profile attribute database. ** *******************************************************************************/ void gatt_profile_db_init (void) @@ -684,7 +684,7 @@ void GATT_ConfigServiceChangeCCC (BD_ADDR remote_bda, BOOLEAN enable, tBT_TRANSP p_clcb->connected = TRUE; } /* hold the link here */ - GATT_Connect(gatt_cb.gatt_if, remote_bda, BLE_ADDR_UNKNOWN_TYPE, TRUE, transport, FALSE); + GATT_Connect(gatt_cb.gatt_if, remote_bda, BLE_ADDR_UNKNOWN_TYPE, TRUE, transport, FALSE, FALSE, 0xFF, 0xFF); p_clcb->ccc_stage = GATT_SVC_CHANGED_CONNECTING; if (!p_clcb->connected) { diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_main.c b/components/bt/host/bluedroid/stack/gatt/gatt_main.c index e5d9823712..4eaae0d302 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_main.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_main.c @@ -220,7 +220,8 @@ void gatt_free(void) ** Returns TRUE if connection is started, otherwise return FALSE. ** *******************************************************************************/ -BOOLEAN gatt_connect (BD_ADDR rem_bda, tBLE_ADDR_TYPE bd_addr_type, tGATT_TCB *p_tcb, tBT_TRANSPORT transport, BOOLEAN is_aux) +BOOLEAN gatt_connect (BD_ADDR rem_bda, tBLE_ADDR_TYPE bd_addr_type, tGATT_TCB *p_tcb, tBT_TRANSPORT transport, BOOLEAN is_aux, + BOOLEAN is_pawr_synced, UINT8 adv_handle, UINT8 subevent) { BOOLEAN gatt_ret = FALSE; @@ -230,7 +231,7 @@ BOOLEAN gatt_connect (BD_ADDR rem_bda, tBLE_ADDR_TYPE bd_addr_type, tGATT_TCB *p if (transport == BT_TRANSPORT_LE) { p_tcb->att_lcid = L2CAP_ATT_CID; - gatt_ret = L2CA_ConnectFixedChnl (L2CAP_ATT_CID, rem_bda, bd_addr_type, is_aux); + gatt_ret = L2CA_ConnectFixedChnl (L2CAP_ATT_CID, rem_bda, bd_addr_type, is_aux, is_pawr_synced, adv_handle, subevent); #if (CLASSIC_BT_GATT_INCLUDED == TRUE) } else { if ((p_tcb->att_lcid = L2CA_ConnectReq(BT_PSM_ATT, rem_bda)) != 0) { @@ -376,7 +377,8 @@ void gatt_update_app_use_link_flag (tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN ** *******************************************************************************/ BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, - tBLE_ADDR_TYPE bd_addr_type, tBT_TRANSPORT transport, BOOLEAN is_aux) + tBLE_ADDR_TYPE bd_addr_type, tBT_TRANSPORT transport, BOOLEAN is_aux, + BOOLEAN is_pawr_synced, UINT8 adv_handle, UINT8 subevent) { BOOLEAN ret = FALSE; tGATT_TCB *p_tcb; @@ -389,7 +391,7 @@ BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, /* before link down, another app try to open a GATT connection */ if (st == GATT_CH_OPEN && gatt_num_apps_hold_link(p_tcb) == 0 && transport == BT_TRANSPORT_LE ) { - if (!gatt_connect(bd_addr, bd_addr_type, p_tcb, transport, is_aux)) { + if (!gatt_connect(bd_addr, bd_addr_type, p_tcb, transport, is_aux, is_pawr_synced, adv_handle, subevent)) { ret = FALSE; } } else if (st == GATT_CH_CLOSING) { @@ -400,7 +402,7 @@ BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, } } else { if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, transport)) != NULL) { - if (!gatt_connect(bd_addr, bd_addr_type, p_tcb, transport, is_aux)) { + if (!gatt_connect(bd_addr, bd_addr_type, p_tcb, transport, is_aux, is_pawr_synced, adv_handle, subevent)) { GATT_TRACE_ERROR("gatt_connect failed"); // code enter here if create connection failed. if disconnect after connection, code will not enter here diff --git a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h index f9d3cd8e51..778e7d92bf 100644 --- a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -597,8 +597,8 @@ extern void gatt_free(void); /* from gatt_main.c */ extern BOOLEAN gatt_disconnect (tGATT_TCB *p_tcb); -extern BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_addr_type, tBT_TRANSPORT transport, BOOLEAN is_aux); -extern BOOLEAN gatt_connect (BD_ADDR rem_bda, tBLE_ADDR_TYPE bd_addr_type, tGATT_TCB *p_tcb, tBT_TRANSPORT transport, BOOLEAN is_aux); +extern BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_addr_type, tBT_TRANSPORT transport, BOOLEAN is_aux, BOOLEAN is_pawr_synced, UINT8 adv_handle, UINT8 subevent); +extern BOOLEAN gatt_connect (BD_ADDR rem_bda, tBLE_ADDR_TYPE bd_addr_type, tGATT_TCB *p_tcb, tBT_TRANSPORT transport, BOOLEAN is_aux, BOOLEAN is_pawr_synced, UINT8 adv_handle, UINT8 subevent); extern void gatt_data_process (tGATT_TCB *p_tcb, BT_HDR *p_buf); extern void gatt_update_app_use_link_flag ( tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN is_add, BOOLEAN check_acl_link); diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 10d0dd89d2..81214a9bc4 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -1697,6 +1697,82 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn) } +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +BOOLEAN btsnd_hcic_ble_create_ext_conn_v2(tHCI_CreatExtConn *p_conn) +{ + BT_HDR *p; + UINT8 *pp; + tHCI_ExtConnParams *params; + HCI_TRACE_EVENT("%s", __func__); + uint8_t size = HCIC_PARAM_SIZE_EXT_CONN_CREATE_BASE + 2; + + if (p_conn->init_phy_mask & 0x01) { + size += sizeof(tHCI_ExtConnParams); + } + + if (p_conn->init_phy_mask & 0x02) { + size += sizeof(tHCI_ExtConnParams); + } + + if (p_conn->init_phy_mask & 0x04) { + size += sizeof(tHCI_ExtConnParams); + } + + HCIC_BLE_CMD_CREATED(p, pp, size); + + UINT16_TO_STREAM(pp, HCI_BLE_EXT_CREATE_CONN_V2); + UINT8_TO_STREAM(pp, size); + UINT8_TO_STREAM(pp, p_conn->adv_handle); + UINT8_TO_STREAM(pp, p_conn->subevent); + UINT8_TO_STREAM(pp, p_conn->filter_policy); + UINT8_TO_STREAM(pp, p_conn->filter_policy); + UINT8_TO_STREAM(pp, p_conn->own_addr_type); + UINT8_TO_STREAM(pp, p_conn->peer_addr_type); + BDADDR_TO_STREAM(pp, p_conn->peer_addr); + UINT8_TO_STREAM(pp, p_conn->init_phy_mask); + + if (p_conn->init_phy_mask & 0x01) { + params = &p_conn->params[0]; + UINT16_TO_STREAM(pp, params->scan_interval); + UINT16_TO_STREAM(pp, params->scan_window); + UINT16_TO_STREAM(pp, params->conn_interval_min); + UINT16_TO_STREAM(pp, params->conn_interval_max); + UINT16_TO_STREAM(pp, params->conn_latency); + UINT16_TO_STREAM(pp, params->sup_timeout); + UINT16_TO_STREAM(pp, params->min_ce_len ? params->min_ce_len : BLE_CE_LEN_MIN); + UINT16_TO_STREAM(pp, params->max_ce_len ? params->max_ce_len : BLE_CE_LEN_MIN); + } + + if (p_conn->init_phy_mask & 0x02) { + params = &p_conn->params[1]; + UINT16_TO_STREAM(pp, params->scan_interval); + UINT16_TO_STREAM(pp, params->scan_window); + UINT16_TO_STREAM(pp, params->conn_interval_min); + UINT16_TO_STREAM(pp, params->conn_interval_max); + UINT16_TO_STREAM(pp, params->conn_latency); + UINT16_TO_STREAM(pp, params->sup_timeout); + UINT16_TO_STREAM(pp, params->min_ce_len ? params->min_ce_len : BLE_CE_LEN_MIN); + UINT16_TO_STREAM(pp, params->max_ce_len ? params->max_ce_len : BLE_CE_LEN_MIN); + } + + if (p_conn->init_phy_mask & 0x04) { + params = &p_conn->params[2]; + UINT16_TO_STREAM(pp, params->scan_interval); + UINT16_TO_STREAM(pp, params->scan_window); + UINT16_TO_STREAM(pp, params->conn_interval_min); + UINT16_TO_STREAM(pp, params->conn_interval_max); + UINT16_TO_STREAM(pp, params->conn_latency); + UINT16_TO_STREAM(pp, params->sup_timeout); + UINT16_TO_STREAM(pp, params->min_ce_len ? params->min_ce_len : BLE_CE_LEN_MIN); + UINT16_TO_STREAM(pp, params->max_ce_len ? params->max_ce_len : BLE_CE_LEN_MIN); + } + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; + +} +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) + #if (BLE_50_EXTEND_SYNC_EN == TRUE) BOOLEAN btsnd_hcic_ble_periodic_adv_create_sync(UINT8 option, UINT8 adv_sid, UINT8 adv_addr_type, BD_ADDR adv_addr, diff --git a/components/bt/host/bluedroid/stack/include/stack/gatt_api.h b/components/bt/host/bluedroid/stack/include/stack/gatt_api.h index 002cb16e33..83667e7724 100644 --- a/components/bt/host/bluedroid/stack/include/stack/gatt_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/gatt_api.h @@ -1140,7 +1140,8 @@ extern void GATT_StartIf (tGATT_IF gatt_if); ** *******************************************************************************/ extern BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_addr_type, - BOOLEAN is_direct, tBT_TRANSPORT transport, BOOLEAN is_aux); + BOOLEAN is_direct, tBT_TRANSPORT transport, BOOLEAN is_aux, + BOOLEAN is_pawr_synced, UINT8 adv_handle, UINT8 subevent); /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index a539b3e69d..8621b67458 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -451,6 +451,7 @@ #define HCI_BLE_SET_PERIOD_ADV_SUBEVT_DATA (0x0082 | HCI_GRP_BLE_CMDS) #define HCI_BLE_SET_PERIOD_ADV_RSP_DATA (0x0083 | HCI_GRP_BLE_CMDS) #define HCI_BLE_SET_PERIOD_SYNC_SUBEVT (0x0084 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_EXT_CREATE_CONN_V2 (0x0085 | HCI_GRP_BLE_CMDS) #define HCI_BLE_SET_PERIOD_ADV_PARAMS_V2 (0x0086 | HCI_GRP_BLE_CMDS) #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index d497ee2592..d0f8e20529 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -947,6 +947,10 @@ typedef struct { } tHCI_ExtConnParams; typedef struct { +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + UINT8 adv_handle; + UINT8 subevent; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) UINT8 filter_policy; UINT8 own_addr_type; UINT8 peer_addr_type; @@ -1032,6 +1036,10 @@ UINT8 btsnd_hcic_ble_ext_scan_enable(UINT8 enable, UINT8 filter_dups, BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn); +#if (BT_BLE_FEAT_PAWR_EN == TRUE) +BOOLEAN btsnd_hcic_ble_create_ext_conn_v2(tHCI_CreatExtConn *p_conn); +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) + BOOLEAN btsnd_hcic_ble_periodic_adv_create_sync(UINT8 filter_policy, UINT8 adv_sid, UINT8 adv_addr_type, BD_ADDR adv_addr, UINT16 sync_timeout, UINT8 sync_cte_type); diff --git a/components/bt/host/bluedroid/stack/include/stack/l2c_api.h b/components/bt/host/bluedroid/stack/include/stack/l2c_api.h index b985b641e8..45538ff534 100644 --- a/components/bt/host/bluedroid/stack/include/stack/l2c_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/l2c_api.h @@ -121,7 +121,7 @@ typedef UINT8 tL2CAP_CHNL_DATA_RATE; #define L2CAP_FCR_CHAN_OPT_ALL_MASK (L2CAP_FCR_CHAN_OPT_BASIC | L2CAP_FCR_CHAN_OPT_ERTM | L2CAP_FCR_CHAN_OPT_STREAM) /* Validity check for PSM. PSM values must be odd. Also, all PSM values must -** be assigned such that the least significant bit of the most sigificant +** be assigned such that the least significant bit of the most significant ** octet equals zero. */ #define L2C_INVALID_PSM(psm) (((psm) & 0x0101) != 0x0001) @@ -938,7 +938,7 @@ typedef struct { ** ** Parameters: tL2CAP_UCD_CB_INFO ** -** Return value: TRUE if successs +** Return value: TRUE if success ** *******************************************************************************/ extern BOOLEAN L2CA_UcdRegister ( UINT16 psm, tL2CAP_UCD_CB_INFO *p_cb_info ); @@ -951,7 +951,7 @@ extern BOOLEAN L2CA_UcdRegister ( UINT16 psm, tL2CAP_UCD_CB_INFO *p_cb_info ); ** ** Parameters: PSM ** -** Return value: TRUE if successs +** Return value: TRUE if success ** *******************************************************************************/ extern BOOLEAN L2CA_UcdDeregister ( UINT16 psm ); @@ -968,7 +968,7 @@ extern BOOLEAN L2CA_UcdDeregister ( UINT16 psm ); ** L2CAP_UCD_INFO_TYPE_MTU ** ** -** Return value: TRUE if successs +** Return value: TRUE if success ** *******************************************************************************/ extern BOOLEAN L2CA_UcdDiscover ( UINT16 psm, BD_ADDR rem_bda, UINT8 info_type ); @@ -1001,7 +1001,7 @@ extern UINT16 L2CA_UcdDataWrite (UINT16 psm, BD_ADDR rem_bda, BT_HDR *p_buf, UIN ** Parameters: BD Addr ** Timeout in second ** -** Return value: TRUE if successs +** Return value: TRUE if success ** *******************************************************************************/ extern BOOLEAN L2CA_UcdSetIdleTimeout ( BD_ADDR rem_bda, UINT16 timeout ); @@ -1089,7 +1089,8 @@ extern BOOLEAN L2CA_RegisterFixedChannel (UINT16 fixed_cid, tL2CAP_FIXED_CHNL_R ** Return value: TRUE if connection started ** *******************************************************************************/ -extern BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_addr_type, BOOLEAN is_aux); +extern BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_addr_type, BOOLEAN is_aux, + BOOLEAN is_pawr_synced, UINT8 adv_handle, UINT8 subevent); /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h index 88eac86b2f..d17f82f4cc 100644 --- a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h +++ b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h @@ -379,6 +379,11 @@ typedef struct t_l2c_linkcb { BOOLEAN in_use; /* TRUE when in use, FALSE when not */ tL2C_LINK_STATE link_state; BOOLEAN is_aux; /* This variable used for BLE 5.0 or higher version when do auxiliary connection */ +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + BOOLEAN is_pawr_synced; + UINT8 adv_handle; + UINT8 subevent; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) TIMER_LIST_ENT timer_entry; /* Timer list entry for timeout evt */ UINT16 handle; /* The handle used with LM */ diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c index fa01790d5f..36d636768a 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c @@ -1649,7 +1649,8 @@ BOOLEAN L2CA_RegisterFixedChannel (UINT16 fixed_cid, tL2CAP_FIXED_CHNL_REG *p_f ** Return value: TRUE if connection started ** *******************************************************************************/ -BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda, tBLE_ADDR_TYPE bd_addr_type, BOOLEAN is_aux) +BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda, tBLE_ADDR_TYPE bd_addr_type, BOOLEAN is_aux, + BOOLEAN is_pawr_synced, UINT8 adv_handle, UINT8 subevent) { tL2C_LCB *p_lcb; tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; @@ -1738,6 +1739,11 @@ BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda, tBLE_ADDR_TYPE #if (BLE_INCLUDED == TRUE) p_lcb->is_aux = is_aux; p_lcb->open_addr_type = bd_addr_type; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + p_lcb->is_pawr_synced = is_pawr_synced; + p_lcb->adv_handle = adv_handle; + p_lcb->subevent = subevent; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) #endif if (!l2cu_create_conn(p_lcb, transport)) { L2CAP_TRACE_WARNING ("%s() - create_conn failed", __func__); diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c index 3ce25ab977..88d18b08a2 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c @@ -1020,6 +1020,10 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) } tHCI_CreatExtConn aux_conn = {0}; +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + aux_conn.adv_handle = p_lcb->adv_handle; + aux_conn.subevent = p_lcb->subevent; +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) aux_conn.filter_policy = FALSE; aux_conn.own_addr_type = own_addr_type; aux_conn.peer_addr_type = peer_addr_type; @@ -1041,9 +1045,19 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) memcpy (l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN); btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, link_timeout); btm_ble_set_conn_st (BLE_DIR_CONN); - if(!btsnd_hcic_ble_create_ext_conn(&aux_conn)) { - l2cu_release_lcb (p_lcb); - L2CAP_TRACE_ERROR("initiate Aux connection failed, no resources"); +#if (BT_BLE_FEAT_PAWR_EN == TRUE) + if (p_lcb->is_pawr_synced) { + if(!btsnd_hcic_ble_create_ext_conn_v2(&aux_conn)) { + l2cu_release_lcb (p_lcb); + L2CAP_TRACE_ERROR("initiate pawr sync connection failed, no resources"); + } + } else +#endif // (BT_BLE_FEAT_PAWR_EN == TRUE) + { + if(!btsnd_hcic_ble_create_ext_conn(&aux_conn)) { + l2cu_release_lcb (p_lcb); + L2CAP_TRACE_ERROR("initiate Aux connection failed, no resources"); + } } #else L2CAP_TRACE_ERROR("BLE 5.0 not support!\n"); diff --git a/components/bt/host/bluedroid/stack/smp/smp_api.c b/components/bt/host/bluedroid/stack/smp/smp_api.c index 78e295f4f1..5ac5cd7ef4 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_api.c +++ b/components/bt/host/bluedroid/stack/smp/smp_api.c @@ -161,7 +161,7 @@ tSMP_STATUS SMP_Pair (BD_ADDR bd_addr) memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN); - if (!L2CA_ConnectFixedChnl (L2CAP_SMP_CID, bd_addr, BLE_ADDR_UNKNOWN_TYPE, FALSE)) { + if (!L2CA_ConnectFixedChnl (L2CAP_SMP_CID, bd_addr, BLE_ADDR_UNKNOWN_TYPE, FALSE, FALSE, 0xFF, 0xFF)) { SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.\n", __FUNCTION__); smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status); return status; @@ -205,7 +205,7 @@ tSMP_STATUS SMP_BR_PairWith (BD_ADDR bd_addr) memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN); - if (!L2CA_ConnectFixedChnl (L2CAP_SMP_BR_CID, bd_addr, BLE_ADDR_UNKNOWN_TYPE, FALSE)) { + if (!L2CA_ConnectFixedChnl (L2CAP_SMP_BR_CID, bd_addr, BLE_ADDR_UNKNOWN_TYPE, FALSE, FALSE, 0xFF, 0xFF)) { SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.", __FUNCTION__); smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &status); return status; From 831e9e7721a481f2fe27e082031e8fd70c90f8f6 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Tue, 10 Jun 2025 16:56:56 +0800 Subject: [PATCH 009/226] feat(ble/bluedroid): support bluedroid host channel sounding feature --- components/bt/host/bluedroid/Kconfig.in | 7 + .../bt/host/bluedroid/api/esp_gap_ble_api.c | 332 +++++++ .../api/include/api/esp_gap_ble_api.h | 890 ++++++++++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 81 ++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 161 ++++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 14 + .../bluedroid/bta/dm/include/bta_dm_int.h | 158 ++++ .../host/bluedroid/bta/include/bta/bta_api.h | 96 ++ .../btc/profile/std/gap/btc_gap_ble.c | 274 ++++++ .../btc/profile/std/include/btc_gap_ble.h | 116 +++ .../include/common/bluedroid_user_config.h | 6 + .../common/include/common/bt_target.h | 6 + .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 285 ++++++ .../bluedroid/stack/btm/include/btm_ble_int.h | 11 + .../bluedroid/stack/btm/include/btm_int.h | 8 + .../bt/host/bluedroid/stack/btu/btu_hcif.c | 278 +++++- .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 321 +++++++ .../stack/include/stack/btm_ble_api.h | 217 ++++- .../bluedroid/stack/include/stack/hcidefs.h | 25 + .../bluedroid/stack/include/stack/hcimsgs.h | 45 + 20 files changed, 3329 insertions(+), 2 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 4a3ad65333..929e539919 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1499,6 +1499,13 @@ config BT_BLE_FEAT_ADV_CODING_SELECTION help Enable Advertising Coding Selection +config BT_BLE_FEAT_CHANNEL_SOUNDING + bool "Enable BLE channel sounding" + depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_CHANNEL_SOUNDING_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR + default n + help + Enable BLE channel sounding + menuconfig BT_BLE_42_FEATURES_SUPPORTED bool "Enable BLE 4.2 features(please disable BLE 5.0 if enable BLE 4.2)" depends on BT_BLE_ENABLED 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 d90d55cebe..aa55a1399d 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -2180,3 +2180,335 @@ esp_err_t esp_ble_gap_set_periodic_sync_subevent(esp_ble_per_sync_subevent_param == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +esp_err_t esp_ble_cs_read_local_supported_capabilities(void) +{ + btc_msg_t msg = {0}; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CS_READ_LOCAL_SUPPORTED_CAPS; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cs_read_remote_supported_capabilities(uint16_t conn_handle) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CS_READ_REMOTE_SUPPORTED_CAPS; + + arg.cs_read_remote_supp_caps.conn_handle = conn_handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cs_write_cached_remote_supported_capabilities(esp_ble_cs_write_cached_remote_supp_caps_params *cached_remote_supp_caps_params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg = {0}; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!cached_remote_supp_caps_params) { + return ESP_ERR_NOT_ALLOWED; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPS; + + arg.cs_write_cached_remote_supp_caps.conn_handle = cached_remote_supp_caps_params->conn_handle; + arg.cs_write_cached_remote_supp_caps.num_config_supported = cached_remote_supp_caps_params->num_config_supported; + arg.cs_write_cached_remote_supp_caps.max_consecutive_proc_supported = cached_remote_supp_caps_params->max_consecutive_proc_supported; + arg.cs_write_cached_remote_supp_caps.num_ant_supported = cached_remote_supp_caps_params->num_ant_supported; + arg.cs_write_cached_remote_supp_caps.max_ant_paths_supported = cached_remote_supp_caps_params->max_ant_paths_supported; + arg.cs_write_cached_remote_supp_caps.modes_supported = cached_remote_supp_caps_params->modes_supported; + arg.cs_write_cached_remote_supp_caps.rtt_capability = cached_remote_supp_caps_params->rtt_capability; + arg.cs_write_cached_remote_supp_caps.rtt_aa_only_n = cached_remote_supp_caps_params->rtt_aa_only_n; + arg.cs_write_cached_remote_supp_caps.rtt_sounding_n = cached_remote_supp_caps_params->rtt_sounding_n; + arg.cs_write_cached_remote_supp_caps.rtt_random_payload_n = cached_remote_supp_caps_params->rtt_random_payload_n; + arg.cs_write_cached_remote_supp_caps.NADM_sounding_capability = cached_remote_supp_caps_params->NADM_sounding_capability; + arg.cs_write_cached_remote_supp_caps.NADM_random_capability = cached_remote_supp_caps_params->NADM_random_capability; + arg.cs_write_cached_remote_supp_caps.subfeatures_supported = cached_remote_supp_caps_params->subfeatures_supported; + arg.cs_write_cached_remote_supp_caps.T_IP1_times_supported = cached_remote_supp_caps_params->T_IP1_times_supported; + arg.cs_write_cached_remote_supp_caps.T_IP2_times_supported = cached_remote_supp_caps_params->T_IP2_times_supported; + arg.cs_write_cached_remote_supp_caps.T_FCS_times_supported = cached_remote_supp_caps_params->T_FCS_times_supported; + arg.cs_write_cached_remote_supp_caps.T_PM_times_supported = cached_remote_supp_caps_params->T_PM_times_supported; + arg.cs_write_cached_remote_supp_caps.T_SW_times_supported = cached_remote_supp_caps_params->T_SW_times_supported; + arg.cs_write_cached_remote_supp_caps.TX_SNR_capability = cached_remote_supp_caps_params->TX_SNR_capability; + if (cached_remote_supp_caps_params->initiator_role_supported) { + arg.cs_write_cached_remote_supp_caps.roles_supported |= ESP_BLE_CS_INITIATOR_ROLE_SUPPORTED; + } + if (cached_remote_supp_caps_params->reflector_role_supported) { + arg.cs_write_cached_remote_supp_caps.roles_supported |= ESP_BLE_CS_REFLECTOR_ROLE_SUPPORTED; + } + if (cached_remote_supp_caps_params->cs_sync_2m_phy_supported) { + arg.cs_write_cached_remote_supp_caps.cs_sync_phys_supported |= ESP_BLE_CS_SYNC_PHYS_2M_SUPPORTED; + } + if (cached_remote_supp_caps_params->cs_sync_2m_2bt_phy_supported) { + arg.cs_write_cached_remote_supp_caps.cs_sync_phys_supported |= ESP_BLE_CS_SYNC_PHYS_2M_2BT_SUPPORTED; + } + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cs_security_enable(uint16_t conn_handle) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CS_SECURITY_ENABLE; + + arg.cs_security_enable.conn_handle = conn_handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cs_set_default_settings(esp_ble_cs_set_default_settings_params *default_setting_params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg = {0}; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!default_setting_params) { + return ESP_ERR_NOT_ALLOWED; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CS_SET_DEFAULT_SETTINGS; + + arg.cs_set_default_settings_params.conn_handle = default_setting_params->conn_handle; + arg.cs_set_default_settings_params.cs_sync_ant_selection = default_setting_params->cs_sync_ant_selection; + arg.cs_set_default_settings_params.max_tx_power = default_setting_params->max_tx_power; + if (default_setting_params->initiator_role_enable) { + arg.cs_set_default_settings_params.role_enable |= ESP_BLE_CS_INITIATOR_ROLE_ENABLED; + } + if (default_setting_params->reflector_role_enable) { + arg.cs_set_default_settings_params.role_enable |= ESP_BLE_CS_REFLECTOR_ROLE_ENABLED; + } + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cs_read_remote_fae_table(uint16_t conn_handle) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CS_READ_REMOTE_FAE_TABLE; + + arg.cs_read_remote_tab.conn_handle = conn_handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cs_write_cached_remote_fae_table(esp_ble_cs_write_cached_remote_fae_table_params *write_cached_remote_fae_tab_params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg = {0}; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!write_cached_remote_fae_tab_params) { + return ESP_ERR_NOT_ALLOWED; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CS_WRITE_CACHED_REMOTE_FAE_TABLE; + + arg.cs_write_cached_remote_fae_table_params.conn_handle = write_cached_remote_fae_tab_params->conn_handle; + memcpy(arg.cs_write_cached_remote_fae_table_params.remote_fae_table, write_cached_remote_fae_tab_params->remote_fae_table, sizeof(arg.cs_write_cached_remote_fae_table_params.remote_fae_table)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cs_create_config(esp_ble_cs_create_config_params *create_config_params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg = {0}; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!create_config_params) { + return ESP_ERR_NOT_ALLOWED; + } + + arg.cs_create_config_params.conn_handle = create_config_params->conn_handle; + arg.cs_create_config_params.config_id = create_config_params->config_id; + arg.cs_create_config_params.create_context = create_config_params->create_context; + arg.cs_create_config_params.main_mode_type = create_config_params->main_mode_type; + arg.cs_create_config_params.sub_mode_type = create_config_params->sub_mode_type; + arg.cs_create_config_params.min_main_mode_steps = create_config_params->min_main_mode_steps; + arg.cs_create_config_params.max_main_mode_steps = create_config_params->max_main_mode_steps; + arg.cs_create_config_params.main_mode_repetition = create_config_params->main_mode_repetition; + arg.cs_create_config_params.mode_0_steps = create_config_params->mode_0_steps; + arg.cs_create_config_params.role = create_config_params->role; + arg.cs_create_config_params.rtt_type = create_config_params->rtt_type; + arg.cs_create_config_params.cs_sync_phy = create_config_params->cs_sync_phy; + memcpy(arg.cs_create_config_params.channel_map, create_config_params->channel_map, sizeof(arg.cs_create_config_params.channel_map)); + arg.cs_create_config_params.channel_map_repetition = create_config_params->channel_map_repetition; + arg.cs_create_config_params.channel_selection_type = create_config_params->channel_selection_type; + arg.cs_create_config_params.ch3c_shape = create_config_params->ch3c_shape; + arg.cs_create_config_params.ch3c_jump = create_config_params->ch3c_jump; + arg.cs_create_config_params.reserved = create_config_params->reserved; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CS_CREATE_CONFIG; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cs_remove_config(esp_ble_cs_remove_config_params *remove_config_params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!remove_config_params) { + return ESP_ERR_NOT_ALLOWED; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CS_REMOVE_CONFIG; + + arg.cs_remove_config_params.conn_handle = remove_config_params->conn_handle; + arg.cs_remove_config_params.config_id = remove_config_params->config_id; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cs_set_channel_classification(esp_ble_cs_set_channel_class_params *channel_class_params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!channel_class_params) { + return ESP_ERR_NOT_ALLOWED; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CS_SET_CAHNNEL_CLASSIFICATION; + + memcpy(arg.cs_set_channel_class_params.channel_class, channel_class_params->channel_class, sizeof(arg.cs_set_channel_class_params)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cs_set_procedure_params(esp_ble_cs_set_proc_params *procedure_params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!procedure_params) { + return ESP_ERR_NOT_ALLOWED; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CS_SET_PROCEDURE_PARAMS; + + arg.cs_set_procedure_params.conn_handle = procedure_params->conn_handle; + arg.cs_set_procedure_params.config_id = procedure_params->config_id; + arg.cs_set_procedure_params.max_procedure_len = procedure_params->max_procedure_len; + arg.cs_set_procedure_params.min_procedure_interval = procedure_params->min_procedure_interval; + arg.cs_set_procedure_params.max_procedure_interval = procedure_params->max_procedure_interval; + arg.cs_set_procedure_params.max_procedure_count = procedure_params->max_procedure_count; + arg.cs_set_procedure_params.min_subevent_len = (procedure_params->min_subevent_len & 0x00FFFFFF); + arg.cs_set_procedure_params.max_subevent_len = (procedure_params->max_subevent_len & 0x00FFFFFF); + arg.cs_set_procedure_params.tone_ant_config_selection = procedure_params->tone_ant_config_selection; + arg.cs_set_procedure_params.phy = procedure_params->phy; + arg.cs_set_procedure_params.tx_power_delta = procedure_params->tx_power_delta; + arg.cs_set_procedure_params.preferred_peer_antenna = procedure_params->preferred_peer_antenna; + arg.cs_set_procedure_params.SNR_control_initiator = procedure_params->SNR_control_initiator; + arg.cs_set_procedure_params.SNR_control_reflector = procedure_params->SNR_control_reflector; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_cs_procedure_enable(esp_ble_cs_procedure_enable_params *procedure_enable_params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!procedure_enable_params) { + return ESP_ERR_NOT_ALLOWED; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CS_PROCEDURE_ENABLE; + + arg.cs_procedure_enable_params.conn_handle = procedure_enable_params->conn_handle; + arg.cs_procedure_enable_params.config_id = procedure_enable_params->config_id; + arg.cs_procedure_enable_params.enable = procedure_enable_params->enable; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +#endif diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index df0f8629f2..02adac2041 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -254,6 +254,19 @@ typedef enum { ESP_GAP_BLE_SET_PERIODIC_SYNC_SUBEVT_EVT, /*!< When BLE update periodic sync subevent complete, the event comes */ ESP_GAP_BLE_PERIODIC_ADV_SUBEVT_DATA_REQUEST_EVT, /*!< When Controller is ready to transmit one or more subevents and is requesting the advertising data for these subevents, the event comes*/ ESP_GAP_BLE_PERIODIC_ADV_RESPONSE_REPORT_EVT, /*!< When one or more devices have responded to a periodic advertising subevent during a PAwR train, the event comes */ + ESP_GAP_BLE_CS_READ_LOCAL_SUPP_CAPS_EVT, /*!< When CS read local supported capabilities complete, the event comes */ + ESP_GAP_BLE_CS_WRITE_CACHED_REMOTE_SUPP_CAPS_EVT, /*!< When CS write cached remote supported capabilities complete, the event comes */ + ESP_GAP_BLE_CS_SET_DEFAULT_SETTINGS_EVT, /*!< When CS set default settings complete, the event comes */ + ESP_GAP_BLE_CS_WRITE_CACHED_REMOTE_FAE_TABLE_EVT, /*!< When CS write cached remote FAE table complete, the event comes */ + ESP_GAP_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT, /*!< When CS read remote supported capabilities complete, the event comes */ + ESP_GAP_BLE_CS_SET_CHANNEL_CLASS_CMPL_EVT, /*!< When CS set channel classification complete, the event comes */ + ESP_GAP_BLE_CS_SET_PROC_PARAMS_CMPL_EVT, /*!< When CS set procedure parameters complete, the event comes */ + ESP_GAP_BLE_CS_PROC_ENABLE_CMPL_EVT, /*!< When CS procedure enable complete, the event comes */ + ESP_GAP_BLE_CS_READ_REMOTE_FAE_TABLE_CMPL_EVT, /*!< When CS read remote FAE table complete, the event comes */ + ESP_GAP_BLE_CS_SECURITY_ENABLE_CMPL_EVT, /*!< When CS security enable complete, the event comes */ + ESP_GAP_BLE_CS_CONFIG_CMPL_EVT, /*!< When CS has completed the Channel Sounding Configuration procedure, the event comes */ + ESP_GAP_BLE_CS_SUBEVENT_RESULT_EVT, /*!< When CS has results to report for a CS subevent during the CS procedure, the event comes */ + ESP_GAP_BLE_CS_SUBEVENT_RESULT_CONTINUE_EVT, /*!< When CS has completed a new CS subevent measurement, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ } esp_gap_ble_cb_event_t; @@ -1368,6 +1381,349 @@ typedef struct { uint8_t *data; /*!< Periodic advertising response data formatted as defined in [Vol 3] Part C, Section 11*/ } esp_ble_pa_rsp_info; +/** Initiator role that are supported by the remote Controller */ +#define ESP_BLE_CS_INITIATOR_ROLE_SUPPORTED (1 << 0) +/** Reflector role that are supported by the remote Controller */ +#define ESP_BLE_CS_REFLECTOR_ROLE_SUPPORTED (1 << 1) + +/** The RTT_AA_Only_N field refers to the 150 ns time-of-flight precision requirement */ +#define ESP_BLE_CS_RTT_CAPABILITY_RTT_AA_ONLY_N_150NS (0 << 0) +/** The RTT_AA_Only_N field refers to the 10 ns time-of-flight precision requirement */ +#define ESP_BLE_CS_RTT_CAPABILITY_RTT_AA_ONLY_N_10NS (1 << 0) +/** The RTT_Sounding_N field refers to the 150 ns time-of-flight precision requirement */ +#define ESP_BLE_CS_RTT_CAPABILITY_RTT_SOUNDING_N_150NS (0 << 1) +/** The RTT_Sounding_N field refers to the 10 ns time-of-flight precision requirement */ +#define ESP_BLE_CS_RTT_CAPABILITY_RTT_SOUNDING_N_10NS (1 << 1) +/** The RTT_Random_Payload_N field refers to the 150 ns time-of-flight precision requirement */ +#define ESP_BLE_CS_RTT_CAPABILITY_RTT_RANDOM_PAYLOAD_N_150NS (0 << 2) +/** The RTT_Random_Payload_N field refers to the 10 ns time-of-flight precision requirement */ +#define ESP_BLE_CS_RTT_CAPABILITY_RTT_RANDOM_PAYLOAD_N_10NS (1 << 2) +typedef uint8_t esp_ble_cs_rtt_caps_opt_t; + +/** CS_SYNC 2M phy supported */ +#define ESP_BLE_CS_SYNC_PHYS_2M_SUPPORTED (1 << 1) +/** CS_SYNC 2M 2BT phy supported */ +#define ESP_BLE_CS_SYNC_PHYS_2M_2BT_SUPPORTED (1 << 2) + +/** +* @brief CS write cached remote supported capabilities parameters +*/ +typedef struct { + uint16_t conn_handle; /*!< Connection_Handle */ + uint8_t num_config_supported; /*!< The number of CS configurations that are supported by the remote Controller. Range: 0x01 to 0x04 */ + uint16_t max_consecutive_proc_supported;/*!< 0x0000: Support for both a fixed number of consecutive CS procedures and for an indefinite number of CS procedures until termination + 0x0001 to 0xFFFF: The Maximum number of consecutive CS procedures supported */ + uint8_t num_ant_supported; /*!< Number of antennas supported. Range: 0x01 to 0x04 */ + uint8_t max_ant_paths_supported; /*!< Maximum number of antenna paths supported. Range: 0x01 to 0x04 */ + bool initiator_role_supported; /*!< Initiator role that are supported by the remote Controller */ + bool reflector_role_supported; /*!< Reflector role that are supported by the remote Controller */ + uint8_t modes_supported; /*!< The optional CS modes that are supported by the remote Controller + bit 0: Mode-3 */ + esp_ble_cs_rtt_caps_opt_t rtt_capability; /*!< time-of-flight precision requirement */ + uint8_t rtt_aa_only_n; /*!< 0x00: RTT AA-only not supported. + 0x01 to 0xff: Number of CS_SYNC exchanges needed to satisfy the precision requirements */ + uint8_t rtt_sounding_n; /*!< 0x00: RTT Sounding not supported + 0x01 to 0xFF: Number of CS_SYNC exchanges needed to satisfy the precision requirements */ + uint8_t rtt_random_payload_n; /*!< 0x00: RTT Random Payload not supported + 0x01 to 0xff: Number of CS_SYNC exchanges needed to satisfy the time-of-flight precision requirements */ + uint16_t NADM_sounding_capability; /*!< Support for Phase-based Normalized Attack Detector Metric when a CS_SYNC with sounding sequence is received */ + uint16_t NADM_random_capability; /*!< Support for Phase-based Normalized Attack Detector Metric when a CS_SYNC with random sequence is received */ + bool cs_sync_2m_phy_supported; /*!< CS_SYNC 2M phy supported */ + bool cs_sync_2m_2bt_phy_supported; /*!< CS_SYNC 2M 2BT phy supported */ + uint16_t subfeatures_supported; /*!< bit 1: CS with a Frequency Actuation Error of zero relative to mode-0 transmissions in the reflector role + bit 2: CS Channel Selection Algorithm #3c + bit 3: CS phase-based ranging from an RTT sounding sequence */ + uint16_t T_IP1_times_supported; /*!< bit 0: 10 μs supported + bit 1: 20 μs supported + bit 2: 30 μs supported + bit 3: 40 μs supported + bit 4: 50 μs supported + bit 5: 60 μs supported + bit 6: 80 μs supported + */ + uint16_t T_IP2_times_supported; /*!< bit 0: 10 μs supported + bit 1: 20 μs supported + bit 2: 30 μs supported + bit 3: 40 μs supported + bit 4: 50 μs supported + bit 5: 60 μs supported + bit 6: 80 μs supported + */ + uint16_t T_FCS_times_supported; /*!< bit 0: 15 μs supported + bit 1: 20 μs supported + bit 2: 30 μs supported + bit 3: 40 μs supported + bit 4: 50 μs supported + bit 5: 60 μs supported + bit 6: 80 μs supported + bit 7: 100 μs supported + bit 8: 120 μs supported + */ + uint16_t T_PM_times_supported; /*!< bit 0: 10 μs supported + bit 1: 20 μs supported + */ + uint8_t T_SW_times_supported; /*!< Time in microseconds for the antenna switch period of the CS tones. Range: 0x00 to 0x04 or 0x0A */ + uint8_t TX_SNR_capability; /*!< bit 0: 18 dB supported + bit 1: 21 dB supported + bit 2: 24 dB supported + bit 3: 27 dB supported + bit 4: 30 dB supported + */ +} esp_ble_cs_write_cached_remote_supp_caps_params; + +/** +* @brief CS sync antenna selection options +*/ +typedef enum { + /** Use antenna identifier 1 for CS_SYNC packets by the local Controller */ + ESP_BLE_CS_ANT_SELECTION_OPT_ONE = 0x01, + /** Use antenna identifier 2 for CS_SYNC packets by the local Controller */ + ESP_BLE_CS_ANT_SELECTION_OPT_TWO = 0x02, + /** Use antenna identifier 3 for CS_SYNC packets by the local Controller */ + ESP_BLE_CS_ANT_SELECTION_OPT_THREE = 0x03, + /** Use antenna identifier 4 for CS_SYNC packets by the local Controller */ + ESP_BLE_CS_ANT_SELECTION_OPT_FOUR = 0x04, + /** Use antennas in repetitive order from 1 to 4 for CS_SYNC packets by the local Controller */ + ESP_BLE_CS_ANT_SELECTION_OPT_REPETITIVE = 0xFE, + /** No recommendation for local controller antenna selection by the local Controller */ + ESP_BLE_CS_ANT_SELECTION_OPT_NO_RECOMMENDATION = 0xFF, +} esp_ble_cs_sync_ant_selection_opt_t; + +/** Initiator role is enabled */ +#define ESP_BLE_CS_INITIATOR_ROLE_ENABLED (1 << 0) +/** Reflector role is enabled */ +#define ESP_BLE_CS_REFLECTOR_ROLE_ENABLED (1 << 1) + +/** +* @brief CS set default settings parameters +*/ +typedef struct { + uint16_t conn_handle; /*!< Connection_Handle */ + bool initiator_role_enable; /*!< Initiator role is enabled */ + bool reflector_role_enable; /*!< Reflector role is enabled */ + esp_ble_cs_sync_ant_selection_opt_t cs_sync_ant_selection; /*!< 0x01 to 0x04: Antenna identifier to be used for CS_SYNC packets by the local Controller + 0xFE: Antennas to be used, in repetitive order from 0x01 to 0x04, for CS_SYNC packets by the local Controller + 0xFF: Host does not have a recommendation + */ + int8_t max_tx_power; /*!< The maximum transmit power level to be used for all CS transmissions. Range: -127 to 20. Units: dBm */ +} esp_ble_cs_set_default_settings_params; + +/** +* @brief CS write cached remote Frequency Actuation Error table parameters +*/ +typedef struct { + uint16_t conn_handle; /*!< Connection_Handle */ + uint8_t remote_fae_table[72]; /*!< Per-channel mode-0 Frequency Actuation Error table of the local Controller */ +} esp_ble_cs_write_cached_remote_fae_table_params; + +#define ESP_BLE_CS_SYNC_PHY_1M (0x01) +#define ESP_BLE_CS_SYNC_PHY_2M (0x02) +#define ESP_BLE_CS_SYNC_PHY_2M_2BT (0x03) +typedef uint8_t esp_ble_cs_sync_phy_opt_t; + +#define ESP_BLE_CS_RTT_TYPE_RTT_AA_ONLY (0X00) +#define ESP_BLE_CS_RTT_TYPE_RTT_WITH_32BIT_SOUNDING_SEQUENCE (0X01) +#define ESP_BLE_CS_RTT_TYPE_RTT_WITH_96BIT_SOUNDING_SEQUENCE (0X02) +#define ESP_BLE_CS_RTT_TYPE_RTT_WITH_32BIT_RANDOM_SEQUENCE (0X03) +#define ESP_BLE_CS_RTT_TYPE_RTT_WITH_64BIT_RANDOM_SEQUENCE (0X04) +#define ESP_BLE_CS_RTT_TYPE_RTT_WITH_96BIT_RANDOM_SEQUENCE (0X05) +#define ESP_BLE_CS_RTT_TYPE_RTT_WITH_128BIT_RANDOM_SEQUENCE (0X06) +typedef uint8_t esp_ble_cs_rtt_type_opt_t; + +#define ESP_BLE_CS_ROLE_INITIATOR (0x00) +#define ESP_BLE_CS_ROLE_REFLECTOR (0x01) +typedef uint8_t esp_ble_cs_role_opt_t; + +#define ESP_BLE_CS_MAIN_MODE_TYPE_MODE_1 (0x01) +#define ESP_BLE_CS_MAIN_MODE_TYPE_MODE_2 (0x02) +#define ESP_BLE_CS_MAIN_MODE_TYPE_MODE_3 (0x03) +typedef uint8_t esp_ble_cs_main_mode_opt_t; + +#define ESP_BLE_CS_SUB_MODE_TYPE_MODE_1 (0x01) +#define ESP_BLE_CS_SUB_MODE_TYPE_MODE_2 (0x02) +#define ESP_BLE_CS_SUB_MODE_TYPE_MODE_3 (0x03) +#define ESP_BLE_CS_SUB_MODE_TYPE_UNUSED (0xFF) +typedef uint8_t esp_ble_cs_sub_mode_opt_t; + +#define ESP_BLE_CS_CREAT_CONTEXT_IN_LOCAL_CONTROLLER (0x00) +#define ESP_BLE_CS_CREAT_CONTEXT_IN_LOCAL_AND_REMOTE_CONTROLLER (0x01) +typedef uint8_t esp_ble_cs_create_context_opt_t; + +#define ESP_BLE_CS_CAHNNEL_SELECT_TYPE_ALGORITHM_3b (0x00) +#define ESP_BLE_CS_CAHNNEL_SELECT_TYPE_ALGORITHM_3C (0x01) +typedef uint8_t esp_ble_cs_channel_select_type_opt_t; + +#define ESP_BLE_CS_CH3C_USE_HAT_SHAPE (0x00) +#define ESP_BLE_CS_CH3C_USE_X_SHAPE (0x01) +typedef uint8_t esp_ble_cs_ch3c_shape_opt_t; + +/** +* @brief CS create configuration parameters +*/ +typedef struct { + uint16_t conn_handle; /*!< Connection_Handle */ + uint8_t config_id; /*!< CS configuration identifier. Range: 0 to 3 */ + esp_ble_cs_create_context_opt_t create_context; /*!< 0x00: Write CS configuration in local Controller only + 0x01: Write CS configuration in both local and remote Controller using Channel Sounding Configuration procedure + */ + esp_ble_cs_main_mode_opt_t main_mode_type; /*!< 0x01: Mode-1 + 0x02: Mode-2 + 0x03: Mode-3 + */ + esp_ble_cs_sub_mode_opt_t sub_mode_type; /*!< 0x01: Mode-1 + 0x02: Mode-2 + 0x03: Mode-3 + 0xFF: Unused + */ + uint8_t min_main_mode_steps; /*!< Minimum number of CS main mode steps to be executed before a submode step is executed. Range: 0x02 to 0xFF */ + uint8_t max_main_mode_steps; /*!< Maximum number of CS main mode steps to be executed before a submode step is executed. Range: 0x02 to 0xFF */ + uint8_t main_mode_repetition; /*!< The number of main mode steps taken from the end of the last CS subevent to be repeated at the beginning of + the current CS subevent directly after the last mode-0 step of that event. Range: 0x00 to 0x03 */ + uint8_t mode_0_steps; /*!< Number of CS mode-0 steps to be included at the beginning of each CS subevent. Range: 0x01 to 0x03 */ + esp_ble_cs_role_opt_t role; /*!< 0x00: Initiator + 0x01: Reflector + */ + esp_ble_cs_rtt_type_opt_t rtt_type; /*!< 0x00: RTT AA-only + 0x01: RTT with 32-bit sounding sequence + 0x02: RTT with 96-bit sounding sequence + 0x03: RTT with 32-bit random sequence + 0x04: RTT with 64-bit random sequence + 0x05: RTT with 96-bit random sequence + 0x06: RTT with 128-bit random sequence + */ + esp_ble_cs_sync_phy_opt_t cs_sync_phy; /*!< 0x01: LE 1M PHY + 0x02: LE 2M PHY + 0x03: LE 2M 2BT PHY + */ + uint8_t channel_map[10]; /*!< This parameter contains 80 1-bit fields. + The nth such field (in the range 0 to 78) contains the value for the CS channel index n. + Channel n is enabled for CS procedure = 1 + Channel n is disabled for CS procedure = 0 + Channels n = 0, 1, 23, 24, 25, 77, and 78 shall be ignored and shall be set to zero. At least 15 channels shall be enabled. + The most significant bit (bit 79) is reserved for future use + */ + uint8_t channel_map_repetition; /*!< The number of times the map represented by the Channel_Map field is to be cycled through for non-mode-0 steps within a CS procedure. Range: 0x01 to 0xFF */ + esp_ble_cs_channel_select_type_opt_t channel_selection_type;/*!< 0x00: Use Channel Selection Algorithm #3b for non-mode-0 CS steps + 0x01: Use Channel Selection Algorithm #3c for non-mode-0 CS steps + */ + esp_ble_cs_ch3c_shape_opt_t ch3c_shape; /*!< 0x00: Use Hat shape for user-specified channel sequence + 0x01: Use X shape for user-specified channel sequence + */ + uint8_t ch3c_jump; /*!< Number of channels skipped in each rising and falling sequence. Range: 0x02 to 0x08 */ + uint8_t reserved; /*!< Reserved, shall be set to 0x00 */ +} esp_ble_cs_create_config_params; + +/** +* @brief CS remove configuration parameters +*/ +typedef struct { + uint16_t conn_handle; /*!< Connection_Handle */ + uint8_t config_id; /*!< CS configuration identifier. Range: 0 to 3 */ +} esp_ble_cs_remove_config_params; + +/** +* @brief CS set channel class parameters +*/ +typedef struct { + uint8_t channel_class[10]; /*!< This parameter contains 80 1-bit fields. + The nth such field (in the range 0 to 78) contains the value for the CS channel index n. + Channel n is enabled for CS procedure = 1 + Channel n is disabled for CS procedure = 0 + Channels n = 0, 1, 23, 24, 25, 77, and 78 shall be reserved for future use and shall be set to zero. At least 15 channels shall be enabled. + The most significant bit (bit 79) is reserved for future use. + */ +} esp_ble_cs_set_channel_class_params; + +#define ESP_BLE_CS_PHY_1M (0x01) +#define ESP_BLE_CS_PHY_2M (0x02) +#define ESP_BLE_CS_PHY_S8 (0x03) +#define ESP_BLE_CS_PHY_S2 (0x04) +typedef uint8_t esp_ble_cs_phy_opt_t; + +#define ESP_BLE_CS_PREFERRED_FIRST_ORDER_ANT (1 << 0) +#define ESP_BLE_CS_PREFERRED_SECOND_ORDER_ANT (1 << 1) +#define ESP_BLE_CS_PREFERRED_THIRD_ORDER_ANT (1 << 2) +#define ESP_BLE_CS_PREFERRED_FOURTH_ORDER_ANT (1 << 3) +typedef uint8_t esp_ble_cs_preferred_peer_ant_t; + +#define ESP_BLE_CS_SNR_CONTROL_ADIJUSTMENT_18DB (0x00) +#define ESP_BLE_CS_SNR_CONTROL_ADIJUSTMENT_21DB (0x01) +#define ESP_BLE_CS_SNR_CONTROL_ADIJUSTMENT_24DB (0x02) +#define ESP_BLE_CS_SNR_CONTROL_ADIJUSTMENT_27DB (0x03) +#define ESP_BLE_CS_SNR_CONTROL_ADIJUSTMENT_30DB (0x04) +#define ESP_BLE_CS_SNR_CONTROL_NOT_APPLIED (0xFF) +typedef uint8_t esp_ble_cs_snr_control_adjustment_t; + +/** +* @brief CS set procedure parameters +*/ +typedef struct { + uint16_t conn_handle; /*!< Connection_Handle */ + uint8_t config_id; /*!< CS configuration identifier. Range: 0 to 3 */ + uint16_t max_procedure_len; /*!< Maximum duration for each CS procedure. Range: 0x0001 to 0xFFFF. Time = N × 0.625 ms */ + uint16_t min_procedure_interval; /*!< Minimum number of connection events between consecutive CS procedures. Range: 0x0001 to 0xFFFF */ + uint16_t max_procedure_interval; /*!< Maximum number of connection events between consecutive CS procedures. Range: 0x0001 to 0xFFFF */ + uint16_t max_procedure_count; /*!< 0x0000:CS procedures to continue until disabled + 0xxxxx: Maximum number of CS procedures to be scheduled + */ + uint32_t min_subevent_len; /*!< Minimum suggested duration for each CS subevent in microseconds. Range: 1250 μs to 4 s */ + uint32_t max_subevent_len; /*!< Maximum suggested duration for each CS subevent in microseconds. Range: 1250 μs to 4 s */ + uint8_t tone_ant_config_selection; /*!< Antenna Configuration Index. Range: 0x00 to 0x07 */ + esp_ble_cs_phy_opt_t phy; /*!< 0x01: LE 1M PHY + 0x02: LE 2M PHY + 0x03: LE Coded PHY with S=8 data coding + 0x04: LE Coded PHY with S=2 data coding + */ + uint8_t tx_power_delta; /*!< 0xxx: Transmit power delta, in signed dB, to indicate the recommended difference between the remote device’s power level + for the CS tones and RTT packets and the existing power level for the PHY indicated by the PHY parameter + 0x80: Host does not have a recommendation for transmit power delta + */ + esp_ble_cs_preferred_peer_ant_t preferred_peer_antenna; /*!< bit 0: Use first ordered antenna element + bit 1: Use second ordered antenna element + bit 2: Use third ordered antenna element + bit 3: Use fourth ordered antenna element + */ + esp_ble_cs_snr_control_adjustment_t SNR_control_initiator; /*!< 0x00: SNR control adjustment of 18 dB. + 0x01: SNR control adjustment of 21 dB. + 0x02: SNR control adjustment of 24 dB. + 0x03: SNR control adjustment of 27 dB. + 0x04: SNR control adjustment of 30 dB. + 0xFF: SNR control is not to be applied + */ + esp_ble_cs_snr_control_adjustment_t SNR_control_reflector; /*!< 0x00: SNR control adjustment of 18 dB. + 0x01: SNR control adjustment of 21 dB. + 0x02: SNR control adjustment of 24 dB. + 0x03: SNR control adjustment of 27 dB. + 0x04: SNR control adjustment of 30 dB. + 0xFF: SNR control is not to be applied. + */ +} esp_ble_cs_set_proc_params; + +#define ESP_BLE_CS_PROCEDURES_DISABLE (0x00) +#define ESP_BLE_CS_PROCEDURES_ENABLE (0x01) +typedef uint8_t esp_ble_cs_procedures_action_t; + +/** +* @brief CS procedure enable parameters +*/ +typedef struct { + uint16_t conn_handle; /*!< Connection_Handle */ + uint8_t config_id; /*!< CS configuration identifier. Range: 0 to 3 */ + esp_ble_cs_procedures_action_t enable; /*!< 0x00: CS procedures are to be disabled + 0x01: CS procedures are to be enabled + */ +} esp_ble_cs_procedure_enable_params; + +/** +* @brief CS step information +*/ +typedef struct { + uint8_t step_mode; /*!< 0x00 to 0x03: Mode type */ + uint8_t step_channel; /*!< 0x00 to 0x4E: CS channel index */ + uint8_t step_data_len; /*!< 0x00 to 0xFF: Length of mode- and role-specific information being reported */ + uint8_t *data; /*!< Mode- and role-specific information being reported as Mode_Role_Specific_Info object */ +} esp_ble_cs_step_info; + /** * @brief Gap callback parameters union */ @@ -2074,6 +2430,376 @@ typedef union { esp_ble_pa_rsp_info *pa_rsp_info; /*!< response information */ } pa_rsp_rpt_evt; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_RESPONSE_REPORT_EVT */ #endif // #if (CONFIG_BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + /** + * @brief ESP_GAP_BLE_CS_READ_LOCAL_SUPP_CAPS_EVT + */ + struct ble_cs_read_local_supp_caps_evt { + uint8_t status; /*!< Indicate channel sounding read local supported capabilities command successfully completed */ + uint16_t conn_handle; /*!< Connection Handle */ + uint8_t num_config_supported; /*!< Number of CS configurations supported per connection */ + uint16_t max_consecutive_proc_supported; /*!< 0x0000: Support for both a fixed number of consecutive CS procedures and for an indefinite number of CS procedures until termination + 0x0001 to 0xFFFF: Maximum number of consecutive CS procedures supported */ + uint8_t num_ant_supported; /*!< Number of antennas supported */ + uint8_t max_ant_paths_supported; /*!< Maximum number of antenna paths supported */ + uint8_t roles_supported; /*!< bit 0: Initiator + bit 1: Reflector + */ + uint8_t modes_supported; /*!< bit 0: Mode-3*/ + uint8_t rtt_capability; /*!< time-of-flight precision requirement */ + uint8_t rtt_aa_only_n; /*!< 0x00: RTT AA Only not supported + 0x01 to 0xFF: Number of CS steps of single packet exchanges needed to satisfy the precision requirements */ + uint8_t rtt_sounding_n; /*!< 0x00: RTT Sounding not supported + 0x01 to 0xFF: Number of CS steps of single packet exchanges needed to satisfy the precision requirements */ + uint8_t rtt_random_payload_n; /*!< 0x00: RTT Random Payload not supported + 0x01 to 0xFF: Number of CS steps of single packet exchanges needed to satisfy the precision requirements */ + uint16_t NADM_sounding_capability; /*!< bit 0: Support for Phase-based Normalized Attack Detector Metric when a CS_SYNC with sounding sequence is received */ + uint16_t NADM_random_capability; /*!< bit 0: Support for Phase-based Normalized Attack Detector Metric when a CS_SYNC with random sequence is received */ + uint8_t cs_sync_phys_supported; /*!< bit 1: LE 2M PHY + bit 2: LE 2M 2BT PHY + */ + uint16_t subfeatures_supported; /*!< bit 1: CS with no transmitter Frequency Actuation Error + bit 2: CS Channel Selection Algorithm #3c + bit 3: CS phase-based ranging from RTT sounding sequence + */ + uint16_t T_IP1_times_supported; /*!< bit 0: 10 μs supported + bit 1: 20 μs supported + bit 2: 30 μs supported + bit 3: 40 μs supported + bit 4: 50 μs supported + bit 5: 60 μs supported + bit 6: 80 μs supported + */ + uint16_t T_IP2_times_supported; /*!< bit 0: 10 μs supported + bit 1: 20 μs supported + bit 2: 30 μs supported + bit 3: 40 μs supported + bit 4: 50 μs supported + bit 5: 60 μs supported + bit 6: 80 μs supported + */ + uint16_t T_FCS_times_supported; /*!< bit 0: 15 μs supported + bit 1: 20 μs supported + bit 2: 30 μs supported + bit 3: 40 μs supported + bit 4: 50 μs supported + bit 5: 60 μs supported + bit 6: 80 μs supported + bit 7: 100 μs supported + bit 8: 120 μs supported */ + uint16_t T_PM_times_supported; /*!< bit 0: 10 μs supported + bit 1: 20 μs supported + */ + uint8_t T_SW_times_supported; /*!< 0x00, 0x01, 0x02, 0x04, or 0x0A: Time in microseconds for the antenna switch period of the CS tones */ + uint8_t TX_SNR_capability; /*!< bit 0: 18 dB supported + bit 1: 21 dB supported + bit 2: 24 dB supported + bit 3: 27 dB supported + bit 4: 30 dB supported + */ + } cs_read_local_supp_caps; /*!< Event parameter of ESP_GAP_BLE_CS_READ_LOCAL_SUPP_CAPS_EVT */ + /** + * @brief ESP_GAP_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT + */ + struct ble_cs_read_remote_supp_caps { + uint8_t status; /*!< 0x00: Channel sounding read remote supported capabilities command successfully completed + other: Channel sounding read remote supported capabilities command failed */ + uint16_t conn_handle; /*!< Connection Handle */ + uint8_t num_config_supported; /*!< Number of CS configurations supported per connection */ + uint16_t max_consecutive_proc_supported; /*!< Maximum number of consecutive CS procedures supported */ + uint8_t num_ant_supported; /*!< Number of antennas supported */ + uint8_t max_ant_paths_supported; /*!< Maximum number of antenna paths supported */ + uint8_t roles_supported; /*!< bit 0: Initiator + bit 1: Reflector */ + uint8_t modes_supported; /*!< bit 0: Mode-3 */ + uint8_t rtt_capability; /*!< Time-of-flight precision requirement */ + uint8_t rtt_aa_only_n; /*!< Number of CS steps of single packet exchanges needed to satisfy the precision requirements */ + uint8_t rtt_sounding_n; /*!< Number of CS steps of single packet exchanges needed to satisfy the precision requirements */ + uint8_t rtt_random_payload_n; /*!< Number of CS steps of single packet exchanges needed to satisfy the precision requirements */ + uint16_t NADM_sounding_capability; /*!< bit 0: Support for Phase-based Normalized Attack Detector Metric when a CS_SYNC with sounding sequence is received */ + uint16_t NADM_random_capability; /*!< bit 0: Support for Phase-based Normalized Attack Detector Metric when a CS_SYNC with random sequence is received*/ + uint8_t cs_sync_phys_supported; /*!< bit 1: LE 2M PHY + bit 2: LE 2M 2BT PHY */ + uint16_t subfeatures_supported; /*!< bit 1: CS with no transmitter Frequency Actuation Error + bit 2: CS Channel Selection Algorithm #3c + bit 3: CS phase-based ranging from RTT sounding sequence + */ + uint16_t T_IP1_times_supported; /*!< bit 0: 10 μs supported + bit 1: 20 μs supported + bit 2: 30 μs supported + bit 3: 40 μs supported + bit 4: 50 μs supported + bit 5: 60 μs supported + bit 6: 80 μs supported + */ + uint16_t T_IP2_times_supported; /*!< bit 0: 10 μs supported + bit 1: 20 μs supported + bit 2: 30 μs supported + bit 3: 40 μs supported + bit 4: 50 μs supported + bit 5: 60 μs supported + bit 6: 80 μs supported + */ + uint16_t T_FCS_times_supported; /*!< bit 0: 15 μs supported + bit 1: 20 μs supported + bit 2: 30 μs supported + bit 3: 40 μs supported + bit 4: 50 μs supported + bit 5: 60 μs supported + bit 6: 80 μs supported + bit 7: 100 μs supported + bit 8: 120 μs supported + */ + uint16_t T_PM_times_supported; /*!< bit 0: 10 μs supported + bit 1: 20 μs supported + */ + uint8_t T_SW_times_supported; /*!< 0x00, 0x01, 0x02, 0x04, or 0x0A: Time in microseconds for the antenna switch period of the CS tones */ + uint8_t TX_SNR_capability; /*!< bit 0: 18 dB supported + bit 1: 21 dB supported + bit 2: 24 dB supported + bit 3: 27 dB supported + bit 4: 30 dB supported + */ + } cs_read_remote_supp_caps; /*!< Event parameter of ESP_GAP_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT */ + /** + * @brief ESP_GAP_BLE_CS_WRITE_CACHED_REMOTE_SUPP_CAPS_EVT + */ + struct ble_cs_write_cached_remote_supp_caps { + uint8_t status; /*!< 0x00: Channel sounding write cached remote FAE table command succeeded + 0x01: Channel sounding write cached remote FAE table command failed */ + uint16_t conn_handle; /*!< Connection Handle */ + } cs_write_cached_remote_supp_caps; /*!< Event parameter of ESP_GAP_BLE_CS_WRITE_CACHED_REMOTE_SUPP_CAPS_EVT */ + /** + * @brief ESP_GAP_BLE_CS_SECURITY_ENABLE_CMPL_EVT + */ + struct ble_cs_security_enable { + uint8_t status; /*!< 0x00: Channel sounding security parameters successfully exchanged + other: Channel sounding CS security parameter exchange failed */ + uint16_t conn_handle; /*!< Connection Handle */ + } cs_security_enable; /*!< Event parameter of ESP_GAP_BLE_CS_SECURITY_ENABLE_CMPL_EVT */ + /** + * @brief ESP_GAP_BLE_CS_SET_DEFAULT_SETTINGS_EVT + */ + struct ble_cs_set_default_settings { + uint8_t status; /*!< 0x00: Channel sounding set default settings command successfully completed + other: Channel sounding set default settings command failed*/ + uint16_t conn_handle; /*!< Connection Handle */ + } cs_set_default_settings; /*!< Event parameter of ESP_GAP_BLE_CS_SET_DEFAULT_SETTINGS_EVT */ + /** + * @brief ESP_GAP_BLE_CS_READ_REMOTE_FAE_TABLE_CMPL_EVT + */ + struct ble_cs_read_remote_fae_tab { + uint8_t status; /*!< 0x00: Channel sounding read remote FAE Table command successfully completed + other: Channel sounding read remote FAE Table command failed*/ + uint16_t conn_handle; /*!< Connection Handle */ + uint8_t remote_fae_table[72]; /*!< Per-channel mode-0 Frequency Actuation Error table of the remote Controller */ + } cs_read_remote_fae_tab; /*!< Event parameter of ESP_GAP_BLE_CS_READ_REMOTE_FAE_TABLE_CMPL_EVT */ + /** + * @brief ESP_GAP_BLE_CS_WRITE_CACHED_REMOTE_FAE_TABLE_EVT + */ + struct ble_cs_write_cached_remote_fae_tab { + uint8_t status; /*!< 0x00: Channel sounding write cached remote FAE table command succeeded + other: Channel sounding write cached remote FAE table command failed */ + uint16_t conn_handle; /*!< Connection Handle */ + } cs_write_cached_remote_fae_tab; /*!< Event parameter of ESP_GAP_BLE_CS_WRITE_CACHED_REMOTE_FAE_TABLE_EVT */ + /** + * @brief ESP_GAP_BLE_CS_CONFIG_CMPL_EVT + */ + struct ble_cs_config_udpate { + uint8_t status; /*!< 0x00: Channel Sounding Configuration procedure succeeded + other: Channel Sounding Configuration procedure failed */ + uint16_t conn_handle; /*!< Connection Handle */ + uint8_t config_id; /*!< CS configuration identifier */ + uint8_t action; /*!< 0x00: CS configuration is removed + 0x01: CS configuration is created */ + uint8_t main_mode_type; /*!< 0x01: Mode-1 + 0x02: Mode-2 + 0x03: Mode-3 + */ + uint8_t sub_mode_type; /*!< 0x01: Mode-1 + 0x02: Mode-2 + 0x03: Mode-3 + 0xFF: Unused + */ + uint8_t min_main_mode_steps; /*!< Minimum number of CS main mode steps to be executed before a submode step is executed */ + uint8_t max_main_mode_steps; /*!< Maximum number of CS main mode steps to be executed before a submode step is executed */ + uint8_t main_mode_repetition; /*!< Number of main mode steps taken from the end of the last CS subevent to be repeated at + the beginning of the current CS subevent directly after the last mode-0 step of that event + */ + uint8_t mode_0_steps; /*!< Number of CS mode-0 steps to be included at the beginning of each CS subevent */ + uint8_t role; /*!< 0x00: Initiator + 0x01: Reflector + */ + uint8_t rtt_type; /*!< 0x00: RTT AA Only + 0x01: RTT with 32-bit sounding sequence + 0x02: RTT with 96-bit sounding sequence + 0x03: RTT with 32-bit random sequence + 0x04: RTT with 64-bit random sequence + 0x05: RTT with 96-bit random sequence + 0x06: RTT with 128-bit random sequence + */ + uint8_t cs_sync_phy; /*!< 0x01: LE 1M PHY + 0x02: LE 2M PHY + 0x03: LE 2M 2BT PHY + */ + uint8_t channel_map[10]; /*!< This parameter contains 80 1-bit fields. + The nth such field (in the range 0 to 78) contains the value for the CS channel index n. + Channel n is enabled for CS procedure = 1 + Channel n is disabled for CS procedure = 0 + Channels n = 0, 1, 23, 24, 25, 77, and 78 shall be ignored and shall be set to zero. At least 15 channels shall be enabled. + The most significant bit (bit 79) is reserved for future use. + */ + uint8_t channel_map_repetition; /*!< The number of times the Channel_Map field will be cycled through for non-mode-0 steps within a CS procedure*/ + uint8_t channel_selection_type; /*!< 0x00: Use Channel Selection Algorithm #3b for non-mode-0 CS steps + 0x01: Use Channel Selection Algorithm #3c for non-mode-0 CS steps + */ + uint8_t ch3c_shape; /*!< 0x00: Use Hat shape for user-specified channel sequence + 0x01: Use X shape for user-specified channel sequence + */ + uint8_t ch3c_jump; /*!< Number of channels skipped in each rising and falling sequence */ + uint8_t reserved; /*!< Reserved, shall be set to 0x00 */ + uint8_t t_ip1_time; /*!< 0x0A, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x50, or 0x91: Interlude time in microseconds between the RTT packets */ + uint8_t t_ip2_time; /*!< 0x0A, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x50, or 0x91: nterlude time in microseconds between the CS tones */ + uint8_t t_fcs_time; /*!< 0x0F, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x50, 0x64, 0x78, or 0x96: Time in microseconds for frequency changes */ + uint8_t t_pm_time; /*!< 0x0A, 0x14, or 0x28: Time in microseconds for the phase measurement period of the CS tones */ + } cs_config_update; /*!< Event parameter of ESP_GAP_BLE_CS_CONFIG_CMPL_EVT */ + /** + * @brief ESP_GAP_BLE_CS_SET_PROC_PARAMS_CMPL_EVT + */ + struct ble_cs_set_proc_params { + uint8_t status; /*!< 0x00: Channel sounding set procedure_Parameters command successful + other: Channel sounding set procedure_Parameters command failed */ + uint16_t conn_handle; /*!< Connection Handle */ + } cs_set_proc_params; /*!< Event parameter of ESP_GAP_BLE_CS_SET_PROC_PARAMS_CMPL_EVT */ + /** + * @brief ESP_GAP_BLE_CS_SET_CHANNEL_CLASS_CMPL_EVT + */ + struct ble_cs_set_channel_class { + uint8_t status; /*!< 0x00: Channel sounding set channel classification command successful + other: Channel sounding set channel classification command failed */ + } cs_set_channel_class; /*!< Event parameter of ESP_GAP_BLE_CS_SET_CHANNEL_CLASS_CMPL_EVT */ + /** + * @brief ESP_GAP_BLE_CS_PROC_ENABLE_CMPL_EVT + */ + struct ble_cs_proc_enable { + uint8_t status; /*!< 0x00: Channel sounding procedure enable command successful + other: Channel sounding procedure enable command failed */ + uint16_t conn_handle; /*!< Connection Handle */ + uint8_t config_id; /*!< CS configuration identifier */ + uint8_t state; /*!< 0x00: CS procedures are disabled + 0x01: CS procedures are enabled + */ + uint8_t tone_Ant_config_select; /*!< Antenna Configuration Index. Range:0x00 to 0x07*/ + int8_t select_tx_power; /*!< Transmit power level used for CS procedure. Range: -127 to 20. Units: dBm */ + uint32_t subevent_Len; /*!< Duration for each CS subevent in microseconds. Range: 1250 μs to 4 s */ + uint8_t subevents_per_event; /*!< Number of CS subevents anchored off the same ACL connection event. Range: 0x01 to 0x20 */ + uint16_t subevent_interval; /*!< Time between consecutive CS subevents anchored off the same ACL connection event. Units: 0.625 ms */ + uint16_t event_interval; /*!< Number of ACL connection events between consecutive CS event anchor points */ + uint16_t procedure_interval; /*!< Number of ACL connection events between consecutive CS procedure anchor points */ + uint16_t procedure_count; /*!< 0x0000: CS procedures to continue until disabled + other: Number of CS procedures to be scheduled */ + uint16_t max_procedure_len; /*!< Maximum duration for each CS procedure. Range: 0x0001 to 0xFFFF. Time = N × 0.625 ms. Time range: 0.625 ms to 40.959375 s */ + } cs_proc_enable; /*!< Event parameter of ESP_GAP_BLE_CS_PROC_ENABLE_CMPL_EVT */ + /** + * @brief ESP_GAP_BLE_CS_SUBEVENT_RESULT_EVT + */ + struct ble_cs_subevt_result { + uint16_t conn_handle; /*!< 0x0000 to 0x0EFF: Connection Handle + 0x0FFF: CS test + */ + uint8_t config_id; /*!< CS configuration identifier. Range: 0 to 3 */ + uint16_t start_acl_conn_event_counter; /*!< Starting ACL connection event counter for the results reported in the event */ + uint16_t procedure_counter; /*!< CS procedure count since completion of the Channel Sounding Security Start procedure. Range: 0x0000 to 0xFFFF */ + int16_t frequency_compensation; /*!< 0xC000: Frequency compensation value is not available, or the role is not initiator + other: Frequency compensation value in units of 0.01 ppm (15-bit signed integer). Range: -100 ppm (0x58F0) to +100 ppm (0x2710). Units: 0.01 ppm */ + int8_t reference_power_level; /*!< 0x7F: Reference power level is not applicable + other: Reference power level. Range: -127 to 20. Units: dBm */ + uint8_t procedure_done_status; /*!< bit 0 to 3: + 0x0 = All results complete for the CS procedure + 0x1 = Partial results with more to follow for the CS procedure + 0xF = All subsequent CS procedures aborted + All other values = Reserved for future use + bit 4 to 7: + Reserved for future use + */ + uint8_t subevent_done_status; /*!< bit 0 to 3: + 0x0 = All results complete for the CS subevent + 0x1 = Partial results with more to follow for the CS subevent + 0xF = Current CS subevent aborted + All other values = Reserved for future use + bit 4 to 7: + Reserved for future use + */ + uint8_t abort_reason; /*!< bit 0 to 3: + Indicates the abort reason when Procedure_Done_Status is set to 0xF, otherwise the default value is set to zero. + 0x0 = Report with no abort + 0x1 = Abort because of local Host or remote request + 0x2 = Abort because filtered channel map has less than 15 channels + 0x3 = Abort because the channel map update instant has passed + 0xF = Abort because of unspecified reasons + All other values = Reserved for future use + bit 4 to 7: + Indicates the abort reason when Subevent_Done_Status is set to 0xF, otherwise the default value is set to zero. + 0x0 = Report with no abort + 0x1 = Abort because of local Host or remote request + 0x2 = Abort because no CS_SYNC (mode-0) received + 0x3 = Abort because of scheduling conflicts or limited resources + 0xF = Abort because of unspecified reasons + All other values = Reserved for future use + */ + uint8_t num_ant_paths; /*!< 0x00: Ignored because phase measurement does not occur during the CS step + 0x01 to 0x04: Number of antenna paths used during the phase measurement stage of the CS step */ + uint8_t num_steps_reported; /*!< 0x00 to 0xA0: Number of steps in the CS subevent for which results are reported */ + esp_ble_cs_step_info *step_info; /*!< steps information in the CS subevent */ + } cs_subevt_result; /*!< Event parameter of ESP_GAP_BLE_CS_SUBEVENT_RESULT_EVT */ + /** + * @brief ESP_GAP_BLE_CS_SUBEVENT_RESULT_CONTINUE_EVT + */ + struct ble_cs_subevt_result_continue { + uint16_t conn_handle; /*!< 0x0000 to 0x0EFF: Connection Handle + 0x0FFF: CS test + */ + uint8_t config_id; /*!< CS configuration identifier. Range: 0 to 3 */ + uint8_t proc_done_status; /*!< bit 0 to 3: + 0x0 = All results complete for the CS procedure + 0x1 = Partial results with more to follow for the CS procedure + 0xF = All subsequent CS procedures aborted + All other values = Reserved for future use + bit 4 to 7: + Reserved for future use + */ + uint8_t subevt_done_status; /*!< bit 0 to 3: + 0x0 = All results complete for the CS subevent + 0x1 = Partial results with more to follow for the CS subevent + 0xF = Current CS subevent aborted + All other values = Reserved for future use + bit 4 to 7: + Reserved for future use + */ + uint8_t abort_reason; /*!< bit 0 to 3: + Indicates the abort reason when Procedure_Done_Status is set to 0xF, otherwise the default value is set to zero. + 0x0 = Report with no abort + 0x1 = Abort because of local Host or remote request + 0x2 = Abort because filtered channel map has less than 15 channels + 0x3 = Abort because the channel map update instant has passed + 0xF = Abort because of unspecified reasons + All other values = Reserved for future use + bit 4 to 7: + Indicates the abort reason when Subevent_Done_Status is set to 0xF, otherwise the default value is set to zero. + 0x0 = Report with no abort + 0x1 = Abort because of local Host or remote request + 0x2 = Abort because no CS_SYNC (mode-0) received + 0x3 = Abort because of scheduling conflicts or limited resources + 0xF = Abort because of unspecified reasons + All other values = Reserved for future use + */ + uint8_t num_ant_paths; /*!< 0x00: Ignored because phase measurement does not occur during the CS step + 0x01 to 0x04: Number of antenna paths used during the phase measurement stage of the CS step + */ + uint8_t num_steps_reported; /*!< Number of steps in the CS subevent for which results are reported, Range: 0x00 to 0xA0 */ + esp_ble_cs_step_info *step_info; /*!< steps information in the CS subevent */ + } cs_subevt_result_continue; /*!< Event parameter of ESP_GAP_BLE_CS_SUBEVENT_RESULT_CONTINUE_EVT */ +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) } esp_ble_gap_cb_param_t; /** @@ -3555,6 +4281,170 @@ esp_err_t esp_ble_gap_set_periodic_adv_response_data(esp_ble_per_adv_response_da */ esp_err_t esp_ble_gap_set_periodic_sync_subevent(esp_ble_per_sync_subevent_params *sync_subevent_params); +/** + * @brief This function is used to read the CS capabilities that are supported by the local Controller + * + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_cs_read_local_supported_capabilities(void); + +/** + * @brief This function is used to query the CS capabilities that are supported by the remote Controller + * + * + * + * @param[in] conn_handle: connection handle. + * + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_cs_read_remote_supported_capabilities(uint16_t conn_handle); + +/** + * @brief This function is used to write the cached copy of the CS capabilities that are supported by the remote Controller + * + * + * + * @param[in] cached_remote_supp_caps_params: CS write cached remote supported capabilities parameters + * + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_cs_write_cached_remote_supported_capabilities(esp_ble_cs_write_cached_remote_supp_caps_params *cached_remote_supp_caps_params); + +/** + * @brief This function is used to start or restart the Channel Sounding Security Start procedure in the local Controller + * + * + * + * @param[in] conn_handle: the ACL connection identified + * + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_cs_security_enable(uint16_t conn_handle); + +/** + * @brief This function is used to set default CS settings in the local Controller + * + * + * + * @param[in] default_setting_params: CS set default settings parameters + * + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_cs_set_default_settings(esp_ble_cs_set_default_settings_params *default_setting_params); + +/** + * @brief This function is used to read the per-channel mode-0 Frequency Actuation Error table of the remote Controller + * + * + * + * @param[in] conn_handle: the ACL connection identified + * + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_cs_read_remote_fae_table(uint16_t conn_handle); + +/** + * @brief This function is used to write a cached copy of the per-channel mode-0 Frequency Actuation Error table of the remote device in the local Controller + * + * + * + * @param[in] write_cached_remote_fae_tab_params: CS write cached remote FAE table parameters + * + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_cs_write_cached_remote_fae_table(esp_ble_cs_write_cached_remote_fae_table_params *write_cached_remote_fae_tab_params); + +/** + * @brief This function is used to create a new CS configuration or update an existing CS configuration in the local and/or the remote Controller + * + * + * + * @param[in] create_config_params: CS create config parameters + * + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_cs_create_config(esp_ble_cs_create_config_params *create_config_params); + +/** + * @brief This function is used to remove a CS configuration from the local Controller + * + * + * + * @param[in] remove_config_params: CS remove config parameters + * + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_cs_remove_config(esp_ble_cs_remove_config_params *remove_config_params); + +/** + * @brief This function is used to update the channel classification based on its local information + * + * + * + * @param[in] channel_class_params: CS set channel classification parameters + * + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_cs_set_channel_classification(esp_ble_cs_set_channel_class_params *channel_class_params); + +/** + * @brief This function is used to set the parameters for the scheduling of one or more CS procedures by the local Controller + * + * + * + * @param[in] procedure_params: CS set channel procedure parameters + * + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_cs_set_procedure_params(esp_ble_cs_set_proc_params *procedure_params); + +/** + * @brief This function is used to enable or disable the scheduling of CS procedures by the local Controller + * + * + * + * @param[in] procedure_enable_params: CS procedure enable parameters + * + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_cs_procedure_enable(esp_ble_cs_procedure_enable_params *procedure_enable_params); + #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 2c35c4fa32..724ea7c67a 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6366,6 +6366,87 @@ void bta_dm_api_set_periodic_sync_subevt(tBTA_DM_MSG *p_data) } #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +void bta_dm_api_cs_read_local_supported_caps(tBTA_DM_MSG *p_data) +{ + BTM_BleCSReadLocalSuppCaps(); +} + +void bta_dm_api_cs_read_remote_supported_caps(tBTA_DM_MSG *p_data) +{ + BTM_BleCSReadRemoteSuppCaps(p_data->read_remote_supp_caps.conn_handle); +} + +void bta_dm_api_cs_write_cached_remote_supported_caps(tBTA_DM_MSG *p_data) +{ + tBTA_DM_API_CS_WRITE_CACHED_REMOTE_SUPP_CAPS *p = &p_data->write_cached_remote_caps; + BTM_BleGapWriteCachedRemoteSupportedCaps(p->conn_handle, p->num_config_supported, p->max_consecutive_proc_supported, + p->num_ant_supported, p->max_ant_paths_supported, p->roles_supported, + p->modes_supported, p->rtt_capability, p->rtt_aa_only_n, + p->rtt_sounding_n, p->rtt_random_payload_n, p->NADM_sounding_capability, + p->NADM_random_capability, p->cs_sync_phys_supported, p->subfeatures_supported, + p->T_IP1_times_supported, p->T_IP2_times_supported, p->T_FCS_times_supported, + p->T_PM_times_supported, p->T_SW_times_supported, p->TX_SNR_capability); +} + +void bta_dm_api_cs_security_enable(tBTA_DM_MSG *p_data) +{ + BTM_BleGapCsSecurityEnable(p_data->security_enable.conn_handle); +} + +void bta_dm_api_cs_set_default_settings(tBTA_DM_MSG *p_data) +{ + BTM_BleGapCsSetDefaultSetting(p_data->set_default_setting_params.conn_handle, p_data->set_default_setting_params.role_enable, + p_data->set_default_setting_params.cs_sync_ant_selection, p_data->set_default_setting_params.max_tx_power); +} + +void bta_dm_api_cs_read_remote_fae_table(tBTA_DM_MSG *p_data) +{ + BTM_BleGapCsReadRemoteFaeTable(p_data->read_remote_tab.conn_handle); +} + +void bta_dm_api_cs_write_cached_remote_fae_table(tBTA_DM_MSG *p_data) +{ + BTM_BleGapWriteCachedRemoteFaeTable(p_data->write_cached_remote_fae_tab_params.conn_handle, p_data->write_cached_remote_fae_tab_params.remote_fae_table); +} + +void bta_dm_api_cs_create_config(tBTA_DM_MSG *p_data) +{ + tBTA_DM_API_CS_CREATE_CONFIG_PARAMS *p = &p_data->create_config_params; + BTM_BleGapCsCreateConfig(p->conn_handle, p->config_id, p->create_context, + p->main_mode_type, p->sub_mode_type, p->min_main_mode_steps, + p->max_main_mode_steps, p->main_mode_repetition, p->mode_0_steps, + p->role, p->rtt_type, p->cs_sync_phy, &p->channel_map[0], + p->channel_map_repetition, p->channel_selection_type, p->ch3c_shape, + p->ch3c_jump, p->reserved); +} + +void bta_dm_api_cs_remove_config(tBTA_DM_MSG *p_data) +{ + BTM_BleGapCsRemoveConfig(p_data->remove_config_params.conn_handle, p_data->remove_config_params.config_id); +} + +void bta_dm_api_cs_set_channel_classification(tBTA_DM_MSG *p_data) +{ + BTM_BleGapCsSetChannelClass(p_data->set_channel_class_params.channel_class); +} +void bta_dm_api_cs_set_procedure_params(tBTA_DM_MSG *p_data) +{ + tBTA_DM_API_CS_SET_PROC_PARAMS *p = &p_data->set_proc_params; + BTM_BleGapCsSetProcPatams(p->conn_handle, p->config_id, p->max_procedure_len, + p->min_procedure_interval, p->max_procedure_interval, + p->max_procedure_count, p->min_subevent_len, + p->max_subevent_len, p->tone_ant_config_selection, + p->phy, p->tx_power_delta, p->preferred_peer_antenna, + p->SNR_control_initiator, p->SNR_control_reflector); +} + +void bta_dm_api_cs_procedure_enable(tBTA_DM_MSG *p_data) +{ + BTM_BleGapCsProcEnable(p_data->proc_enable_params.conn_handle, p_data->proc_enable_params.config_id, p_data->proc_enable_params.enable); +} +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 65f564ac08..7ffdabfa82 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -3240,6 +3240,167 @@ void BTA_DmBleGapSetPeriodicSyncSubevt(uint16_t sync_handle, uint16_t periodic_a #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +void BTA_DmBleGapReadLocalSupportedCaps(void) +{ + tBTA_DM_API_CS_READ_LOCAL_SUPP_CAPS *p_msg; + + if ((p_msg = (tBTA_DM_API_CS_READ_LOCAL_SUPP_CAPS *)osi_malloc(sizeof(tBTA_DM_API_CS_READ_LOCAL_SUPP_CAPS))) != NULL) { + p_msg->hdr.event = BTA_DM_API_CS_READ_LOCAL_SUPPORTED_CAPS; + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleGapReadRemoteSupportedCaps(uint16_t conn_handle) +{ + tBTA_DM_API_CS_READ_REMOTE_SUPP_CAPS *p_msg; + + if ((p_msg = (tBTA_DM_API_CS_READ_REMOTE_SUPP_CAPS *)osi_malloc(sizeof(tBTA_DM_API_CS_READ_REMOTE_SUPP_CAPS))) != NULL) { + p_msg->hdr.event = BTA_DM_API_CS_READ_REMOTE_SUPPORTED_CAPS; + p_msg->conn_handle = conn_handle; + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleGapWriteCachedRemoteSupportedCaps(tBTA_DM_CS_WRITE_CACHED_REMOTE_SUPP_CAPS *write_cachedremote_supp_caps) +{ + tBTA_DM_API_CS_WRITE_CACHED_REMOTE_SUPP_CAPS *p_msg; + + if ((p_msg = (tBTA_DM_API_CS_WRITE_CACHED_REMOTE_SUPP_CAPS *)osi_malloc(sizeof(tBTA_DM_API_CS_WRITE_CACHED_REMOTE_SUPP_CAPS))) != NULL) { + p_msg->hdr.event = BTA_DM_API_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPS; + memcpy(&p_msg->conn_handle, &write_cachedremote_supp_caps->conn_handle, sizeof(tBTA_DM_CS_WRITE_CACHED_REMOTE_SUPP_CAPS)); + // p_msg->conn_handle = write_cachedremote_supp_caps->conn_handle; + // p_msg->num_config_supported = write_cachedremote_supp_caps->num_config_supported; + // p_msg->max_consecutive_proc_supported = write_cachedremote_supp_caps->max_consecutive_proc_supported; + // p_msg->num_ant_supported = write_cachedremote_supp_caps->num_ant_supported; + // p_msg->max_ant_paths_supported = write_cachedremote_supp_caps->max_ant_paths_supported; + // p_msg->roles_supported = write_cachedremote_supp_caps->roles_supported; + // p_msg->modes_supported = write_cachedremote_supp_caps->modes_supported; + // p_msg->rtt_capability = write_cachedremote_supp_caps->rtt_capability; + // p_msg->rtt_aa_only_n = write_cachedremote_supp_caps->rtt_aa_only_n; + // p_msg->rtt_sounding_n = write_cachedremote_supp_caps->rtt_sounding_n; + // p_msg->rtt_random_payload_n = write_cachedremote_supp_caps->rtt_random_payload_n; + // p_msg->NADM_sounding_capability = write_cachedremote_supp_caps->NADM_sounding_capability; + // p_msg->NADM_random_capability = write_cachedremote_supp_caps->NADM_random_capability; + // p_msg->cs_sync_phys_supported = write_cachedremote_supp_caps->cs_sync_phys_supported; + // p_msg->subfeatures_supported = write_cachedremote_supp_caps->subfeatures_supported; + // p_msg->T_IP1_times_supported = write_cachedremote_supp_caps->T_IP1_times_supported; + // p_msg->T_IP2_times_supported = write_cachedremote_supp_caps->T_IP2_times_supported; + // p_msg->T_FCS_times_supported = write_cachedremote_supp_caps->T_FCS_times_supported; + // p_msg->T_PM_times_supported = write_cachedremote_supp_caps->T_PM_times_supported; + // p_msg->T_SW_times_supported = write_cachedremote_supp_caps->T_SW_times_supported; + // p_msg->TX_SNR_capability = write_cachedremote_supp_caps->TX_SNR_capability; + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleGapCsSecurityEnable(uint16_t conn_handle) +{ + tBTA_DM_API_CS_SECURITY_ENABLE *p_msg; + + if ((p_msg = (tBTA_DM_API_CS_SECURITY_ENABLE *)osi_malloc(sizeof(tBTA_DM_API_CS_SECURITY_ENABLE))) != NULL) { + p_msg->hdr.event = BTA_DM_API_CS_SECURITY_ENABLE; + p_msg->conn_handle = conn_handle; + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleGapCsSetDefaultSetting(uint16_t conn_handle, uint8_t role_enable, uint8_t cs_sync_ant_selection, int8_t max_tx_power) +{ + tBTA_DM_API_CS_SET_DEFAULT_SETTING_PARAMS *p_msg; + + if ((p_msg = (tBTA_DM_API_CS_SET_DEFAULT_SETTING_PARAMS *)osi_malloc(sizeof(tBTA_DM_API_CS_SET_DEFAULT_SETTING_PARAMS))) != NULL) { + p_msg->hdr.event = BTA_DM_API_CS_SET_DEFAULT_SETTINGS; + p_msg->conn_handle = conn_handle; + p_msg->role_enable = role_enable; + p_msg->cs_sync_ant_selection = cs_sync_ant_selection; + p_msg->max_tx_power = max_tx_power; + bta_sys_sendmsg(p_msg); + } +} +void BTA_DmBleGapCsReadRemoteFaeTable(uint16_t conn_handle) +{ + tBTA_DM_API_CS_READ_REMOTE_TAB *p_msg; + + if ((p_msg = (tBTA_DM_API_CS_READ_REMOTE_TAB *)osi_malloc(sizeof(tBTA_DM_API_CS_READ_REMOTE_TAB))) != NULL) { + p_msg->hdr.event = BTA_DM_API_CS_READ_REMOTE_FAE_TABLE; + p_msg->conn_handle = conn_handle; + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleGapWriteCachedRemoteFaeTable(uint16_t conn_handle, uint8_t *remote_fae_table, uint8_t table_len) +{ + tBTA_DM_API_CS_WRITE_CACHED_REMOTE_FAE_TAB_PARAMS *p_msg; + + if ((p_msg = (tBTA_DM_API_CS_WRITE_CACHED_REMOTE_FAE_TAB_PARAMS *)osi_malloc(sizeof(tBTA_DM_API_CS_WRITE_CACHED_REMOTE_FAE_TAB_PARAMS))) != NULL) { + p_msg->hdr.event = BTA_DM_API_CS_WRITE_CACHED_REMOTE_FAE_TABLE; + p_msg->conn_handle = conn_handle; + memcpy(&p_msg->remote_fae_table[0], remote_fae_table, table_len); + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleGapCsCreateConfig(tBTA_DM_CS_CREATE_CONFIG_PARAMS *create_config_params) +{ + tBTA_DM_API_CS_CREATE_CONFIG_PARAMS *p_msg; + + if ((p_msg = (tBTA_DM_API_CS_CREATE_CONFIG_PARAMS *)osi_malloc(sizeof(tBTA_DM_API_CS_CREATE_CONFIG_PARAMS))) != NULL) { + p_msg->hdr.event = BTA_DM_API_CS_CREATE_CONFIG; + memcpy(&p_msg->conn_handle, &create_config_params->conn_handle, sizeof(tBTA_DM_CS_CREATE_CONFIG_PARAMS)); + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleGapCsRemoveConfig(uint16_t conn_handle, uint8_t config_id) +{ + tBTA_DM_API_CS_REMOVE_CONFIG_PARAMS *p_msg; + + if ((p_msg = (tBTA_DM_API_CS_REMOVE_CONFIG_PARAMS *)osi_malloc(sizeof(tBTA_DM_API_CS_REMOVE_CONFIG_PARAMS))) != NULL) { + p_msg->hdr.event = BTA_DM_API_CS_REMOVE_CONFIG; + p_msg->conn_handle = conn_handle; + p_msg->config_id = config_id; + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleGapCsSetChannelClass(uint8_t *channel_class, uint8_t channl_len) +{ + tBTA_DM_API_CS_SET_CHANNEL_CLASS_PARAMS *p_msg; + + if ((p_msg = (tBTA_DM_API_CS_SET_CHANNEL_CLASS_PARAMS *)osi_malloc(sizeof(tBTA_DM_API_CS_SET_CHANNEL_CLASS_PARAMS))) != NULL) { + p_msg->hdr.event = BTA_DM_API_CS_SET_CAHNNEL_CLASSIFICATION; + memcpy(&p_msg->channel_class[0], channel_class, channl_len); + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleGapCsSetProcPatams(tBTA_DM_CS_SET_PROC_PARAMS *set_proc_params) +{ + tBTA_DM_API_CS_SET_PROC_PARAMS *p_msg; + + if ((p_msg = (tBTA_DM_API_CS_SET_PROC_PARAMS *)osi_malloc(sizeof(tBTA_DM_API_CS_SET_PROC_PARAMS))) != NULL) { + p_msg->hdr.event = BTA_DM_API_CS_SET_PROCEDURE_PARAMS; + memcpy(&p_msg->conn_handle, &set_proc_params->conn_handle, sizeof(tBTA_DM_CS_SET_PROC_PARAMS)); + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleGapCsProcEnable(uint16_t conn_handle, uint8_t config_id, uint8_t enable) +{ + tBTA_DM_API_CS_PROC_ENABLE_PARAMS *p_msg; + + if ((p_msg = (tBTA_DM_API_CS_PROC_ENABLE_PARAMS *)osi_malloc(sizeof(tBTA_DM_API_CS_PROC_ENABLE_PARAMS))) != NULL) { + p_msg->hdr.event = BTA_DM_API_CS_PROCEDURE_ENABLE; + p_msg->conn_handle = conn_handle; + p_msg->config_id = config_id; + p_msg->enable = enable; + bta_sys_sendmsg(p_msg); + } +} + +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + /******************************************************************************* ** ** Function BTA_VendorInit diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 362795cd32..77bc60a7f2 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -349,6 +349,20 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_api_set_periodic_adv_response_data, /* BTA_DM_API_SET_PA_RSP_DATA */ bta_dm_api_set_periodic_sync_subevt, /* BTA_DM_API_SET_PA_SYNC_SUBEVT */ #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + bta_dm_api_cs_read_local_supported_caps, /* BTA_DM_API_CS_READ_LOCAL_SUPPORTED_CAPS */ + bta_dm_api_cs_read_remote_supported_caps, /* BTA_DM_API_CS_READ_REMOTE_SUPPORTED_CAPS */ + bta_dm_api_cs_write_cached_remote_supported_caps, /* BTA_DM_API_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPS */ + bta_dm_api_cs_security_enable, /* BTA_DM_API_CS_SECURITY_ENABLE */ + bta_dm_api_cs_set_default_settings, /* BTA_DM_API_CS_SET_DEFAULT_SETTINGS */ + bta_dm_api_cs_read_remote_fae_table, /* BTA_DM_API_CS_READ_REMOTE_FAE_TABLE */ + bta_dm_api_cs_write_cached_remote_fae_table, /* BTA_DM_API_CS_WRITE_CACHED_REMOTE_FAE_TABLE */ + bta_dm_api_cs_create_config, /* BTA_DM_API_CS_CREATE_CONFIG */ + bta_dm_api_cs_remove_config, /* BTA_DM_API_CS_REMOVE_CONFIG */ + bta_dm_api_cs_set_channel_classification, /* BTA_DM_API_CS_SET_CAHNNEL_CLASSIFICATION */ + bta_dm_api_cs_set_procedure_params, /* BTA_DM_API_CS_SET_PROCEDURE_PARAMS */ + bta_dm_api_cs_procedure_enable, /* BTA_DM_API_CS_PROCEDURE_ENABLE */ +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) }; diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 32b7e40a61..9ef189a26f 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -340,6 +340,20 @@ enum { BTA_DM_API_SET_PA_RSP_DATA, BTA_DM_API_SET_PA_SYNC_SUBEVT, #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + BTA_DM_API_CS_READ_LOCAL_SUPPORTED_CAPS, + BTA_DM_API_CS_READ_REMOTE_SUPPORTED_CAPS, + BTA_DM_API_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPS, + BTA_DM_API_CS_SECURITY_ENABLE, + BTA_DM_API_CS_SET_DEFAULT_SETTINGS, + BTA_DM_API_CS_READ_REMOTE_FAE_TABLE, + BTA_DM_API_CS_WRITE_CACHED_REMOTE_FAE_TABLE, + BTA_DM_API_CS_CREATE_CONFIG, + BTA_DM_API_CS_REMOVE_CONFIG, + BTA_DM_API_CS_SET_CAHNNEL_CLASSIFICATION, + BTA_DM_API_CS_SET_PROCEDURE_PARAMS, + BTA_DM_API_CS_PROCEDURE_ENABLE, +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) BTA_DM_MAX_EVT }; @@ -1206,6 +1220,122 @@ typedef struct { } tBTA_DM_API_BLE_PA_SYNC_SUBEVT; #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +typedef struct { + BT_HDR hdr; +} tBTA_DM_API_CS_READ_LOCAL_SUPP_CAPS; +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; +} tBTA_DM_API_CS_READ_REMOTE_SUPP_CAPS; +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; + UINT8 num_config_supported; + UINT16 max_consecutive_proc_supported; + UINT8 num_ant_supported; + UINT8 max_ant_paths_supported; + UINT8 roles_supported; + UINT8 modes_supported; + UINT8 rtt_capability; + UINT8 rtt_aa_only_n; + UINT8 rtt_sounding_n; + UINT8 rtt_random_payload_n; + UINT16 NADM_sounding_capability; + UINT16 NADM_random_capability; + UINT8 cs_sync_phys_supported; + UINT16 subfeatures_supported; + UINT16 T_IP1_times_supported; + UINT16 T_IP2_times_supported; + UINT16 T_FCS_times_supported; + UINT16 T_PM_times_supported; + UINT8 T_SW_times_supported; + UINT8 TX_SNR_capability; +} tBTA_DM_API_CS_WRITE_CACHED_REMOTE_SUPP_CAPS; + +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; +} tBTA_DM_API_CS_SECURITY_ENABLE; + +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; + UINT8 role_enable; + UINT8 cs_sync_ant_selection; + INT8 max_tx_power; +} tBTA_DM_API_CS_SET_DEFAULT_SETTING_PARAMS; + +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; +} tBTA_DM_API_CS_READ_REMOTE_TAB; + +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; + UINT8 remote_fae_table[72]; +} tBTA_DM_API_CS_WRITE_CACHED_REMOTE_FAE_TAB_PARAMS; + +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; + UINT8 config_id; + UINT8 create_context; + UINT8 main_mode_type; + UINT8 sub_mode_type; + UINT8 min_main_mode_steps; + UINT8 max_main_mode_steps; + UINT8 main_mode_repetition; + UINT8 mode_0_steps; + UINT8 role; + UINT8 rtt_type; + UINT8 cs_sync_phy; + UINT8 channel_map[10]; + UINT8 channel_map_repetition; + UINT8 channel_selection_type; + UINT8 ch3c_shape; + UINT8 ch3c_jump; + UINT8 reserved; +} tBTA_DM_API_CS_CREATE_CONFIG_PARAMS; + +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; + UINT8 config_id; +} tBTA_DM_API_CS_REMOVE_CONFIG_PARAMS; + +typedef struct { + BT_HDR hdr; + UINT8 channel_class[10]; +} tBTA_DM_API_CS_SET_CHANNEL_CLASS_PARAMS; + +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; + UINT8 config_id; + UINT16 max_procedure_len; + UINT16 min_procedure_interval; + UINT16 max_procedure_interval; + UINT16 max_procedure_count; + UINT32 min_subevent_len; + UINT32 max_subevent_len; + UINT8 tone_ant_config_selection; + UINT8 phy; + UINT8 tx_power_delta; + UINT8 preferred_peer_antenna; + UINT8 SNR_control_initiator; + UINT8 SNR_control_reflector; +} tBTA_DM_API_CS_SET_PROC_PARAMS; + +typedef struct { + BT_HDR hdr; + UINT16 conn_handle; + UINT8 config_id; + UINT8 enable; +} tBTA_DM_API_CS_PROC_ENABLE_PARAMS; +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + #endif /* BLE_INCLUDED */ #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) @@ -1931,6 +2061,20 @@ typedef union { tBTA_DM_API_BLE_PA_RSP_DATA pa_rsp_data; tBTA_DM_API_BLE_PA_SYNC_SUBEVT pa_sync_subevt; #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + tBTA_DM_API_CS_READ_LOCAL_SUPP_CAPS read_local_supp_caps; + tBTA_DM_API_CS_READ_REMOTE_SUPP_CAPS read_remote_supp_caps; + tBTA_DM_API_CS_WRITE_CACHED_REMOTE_SUPP_CAPS write_cached_remote_caps; + tBTA_DM_API_CS_SECURITY_ENABLE security_enable; + tBTA_DM_API_CS_SET_DEFAULT_SETTING_PARAMS set_default_setting_params; + tBTA_DM_API_CS_READ_REMOTE_TAB read_remote_tab; + tBTA_DM_API_CS_WRITE_CACHED_REMOTE_FAE_TAB_PARAMS write_cached_remote_fae_tab_params; + tBTA_DM_API_CS_CREATE_CONFIG_PARAMS create_config_params; + tBTA_DM_API_CS_REMOVE_CONFIG_PARAMS remove_config_params; + tBTA_DM_API_CS_SET_CHANNEL_CLASS_PARAMS set_channel_class_params; + tBTA_DM_API_CS_SET_PROC_PARAMS set_proc_params; + tBTA_DM_API_CS_PROC_ENABLE_PARAMS proc_enable_params; +#endif } tBTA_DM_MSG; @@ -2603,4 +2747,18 @@ void bta_dm_api_set_periodic_adv_subevt_data(tBTA_DM_MSG *p_data); void bta_dm_api_set_periodic_adv_response_data(tBTA_DM_MSG *p_data); void bta_dm_api_set_periodic_sync_subevt(tBTA_DM_MSG *p_data); #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +void bta_dm_api_cs_read_local_supported_caps(tBTA_DM_MSG *p_data); +void bta_dm_api_cs_read_remote_supported_caps(tBTA_DM_MSG *p_data); +void bta_dm_api_cs_write_cached_remote_supported_caps(tBTA_DM_MSG *p_data); +void bta_dm_api_cs_security_enable(tBTA_DM_MSG *p_data); +void bta_dm_api_cs_set_default_settings(tBTA_DM_MSG *p_data); +void bta_dm_api_cs_read_remote_fae_table(tBTA_DM_MSG *p_data); +void bta_dm_api_cs_write_cached_remote_fae_table(tBTA_DM_MSG *p_data); +void bta_dm_api_cs_create_config(tBTA_DM_MSG *p_data); +void bta_dm_api_cs_remove_config(tBTA_DM_MSG *p_data); +void bta_dm_api_cs_set_channel_classification(tBTA_DM_MSG *p_data); +void bta_dm_api_cs_set_procedure_params(tBTA_DM_MSG *p_data); +void bta_dm_api_cs_procedure_enable(tBTA_DM_MSG *p_data); +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) #endif /* BTA_DM_INT_H */ diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 17e439c2ad..23bf8915d9 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1228,6 +1228,71 @@ typedef struct { tBTA_DM_SEARCH *p_data; /* Union of all search callback structures */ } tBTA_DM_SEARCH_PARAM; +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +typedef struct { + UINT16 conn_handle; + UINT8 num_config_supported; + UINT16 max_consecutive_proc_supported; + UINT8 num_ant_supported; + UINT8 max_ant_paths_supported; + UINT8 roles_supported; + UINT8 modes_supported; + UINT8 rtt_capability; + UINT8 rtt_aa_only_n; + UINT8 rtt_sounding_n; + UINT8 rtt_random_payload_n; + UINT16 NADM_sounding_capability; + UINT16 NADM_random_capability; + UINT8 cs_sync_phys_supported; + UINT16 subfeatures_supported; + UINT16 T_IP1_times_supported; + UINT16 T_IP2_times_supported; + UINT16 T_FCS_times_supported; + UINT16 T_PM_times_supported; + UINT8 T_SW_times_supported; + UINT8 TX_SNR_capability; +} tBTA_DM_CS_WRITE_CACHED_REMOTE_SUPP_CAPS; + +typedef struct { + UINT16 conn_handle; + UINT8 config_id; + UINT8 create_context; + UINT8 main_mode_type; + UINT8 sub_mode_type; + UINT8 min_main_mode_steps; + UINT8 max_main_mode_steps; + UINT8 main_mode_repetition; + UINT8 mode_0_steps; + UINT8 role; + UINT8 rtt_type; + UINT8 cs_sync_phy; + UINT8 channel_map[10]; + UINT8 channel_map_repetition; + UINT8 channel_selection_type; + UINT8 ch3c_shape; + UINT8 ch3c_jump; + UINT8 reserved; +} tBTA_DM_CS_CREATE_CONFIG_PARAMS; + +typedef struct { + UINT16 conn_handle; + UINT8 config_id; + UINT16 max_procedure_len; + UINT16 min_procedure_interval; + UINT16 max_procedure_interval; + UINT16 max_procedure_count; + uint32_t min_subevent_len; + uint32_t max_subevent_len; + UINT8 tone_ant_config_selection; + UINT8 phy; + UINT8 tx_power_delta; + UINT8 preferred_peer_antenna; + UINT8 SNR_control_initiator; + UINT8 SNR_control_reflector; +} tBTA_DM_CS_SET_PROC_PARAMS; + +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + /* Search callback */ typedef void (tBTA_DM_SEARCH_CBACK)(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data); @@ -1720,6 +1785,22 @@ typedef struct { #define BTA_BLE_GAP_PERIODIC_ADV_RESPONSE_REPORT_EVT BTM_BLE_GAP_PERIODIC_ADV_RESPONSE_REPORT_EVT #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#define BTA_BLE_GAP_CS_READ_LOCAL_SUPP_CAPS_EVT BTM_BLE_GAP_CS_READ_LOCAL_SUPP_CAPS_EVT +#define BTA_BLE_GAP_CS_WRITE_CACHED_REMOTE_SUPP_CAPS_EVT BTM_BLE_GAP_CS_WRITE_CACHED_REMOTE_SUPP_CAPS_EVT +#define BTA_BLE_GAP_CS_SET_DEFAULT_SETTINGS_EVT BTM_BLE_GAP_CS_SET_DEFAULT_SETTINGS_EVT +#define BTA_BLE_GAP_CS_WRITE_CACHED_REMOTE_FAE_TAB_EVT BTM_BLE_GAP_CS_WRITE_CACHED_REMOTE_FAE_TAB_EVT +#define BTA_BLE_GAP_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT BTM_BLE_GAP_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT +#define BTA_BLE_GAP_CS_SET_CHANNEL_CLASS_CMPL_EVT BTM_BLE_GAP_CS_SET_CHANNEL_CLASS_CMPL_EVT +#define BTA_BLE_GAP_CS_PROC_PARAMS_CMPL_EVT BTM_BLE_GAP_CS_PROC_PARAMS_CMPL_EVT +#define BTA_BLE_GAP_CS_PROC_ENABLE_CMPL_EVT BTM_BLE_GAP_CS_PROC_ENABLE_CMPL_EVT +#define BTA_BLE_GAP_CS_READ_REMOTE_FAE_TABLE_CMPL_EVT BTM_BLE_GAP_CS_READ_REMOTE_FAE_TABLE_CMPL_EVT +#define BTA_BLE_GAP_CS_SECURITY_ENABLE_CMPL_EVT BTM_BLE_GAP_CS_SECURITY_ENABLE_CMPL_EVT +#define BTA_BLE_GAP_CS_CONFIG_CMPL_EVT BTM_BLE_GAP_CS_CONFIG_CMPL_EVT +#define BTA_BLE_GAP_CS_SUBEVENT_RESULT_EVT BTM_BLE_GAP_CS_SUBEVENT_RESULT_EVT +#define BTA_BLE_GAP_CS_SUBEVENT_RESULT_CONTINUE_EVT BTM_BLE_GAP_CS_SUBEVENT_RESULT_CONTINUE_EVT +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + #define BTA_DM_BLE_5_GAP_UNKNOWN_EVT BTM_BLE_5_GAP_UNKNOWN_EVT typedef tBTM_BLE_5_GAP_EVENT tBTA_DM_BLE_5_GAP_EVENT; @@ -3120,6 +3201,21 @@ void BTA_DmBleGapSetPeriodicAdvRspData(uint16_t sync_handle, uint16_t request_ev void BTA_DmBleGapSetPeriodicSyncSubevt(uint16_t sync_handle, uint16_t periodic_adv_properties, uint8_t num_subevents_to_sync, uint8_t *subevent); #endif// (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +void BTA_DmBleGapReadLocalSupportedCaps(void); +void BTA_DmBleGapReadRemoteSupportedCaps(uint16_t conn_handle); +void BTA_DmBleGapWriteCachedRemoteSupportedCaps(tBTA_DM_CS_WRITE_CACHED_REMOTE_SUPP_CAPS *write_cachedremote_supp_caps); +void BTA_DmBleGapCsSecurityEnable(uint16_t conn_handle); +void BTA_DmBleGapCsSetDefaultSetting(uint16_t conn_handle, uint8_t role_enable, uint8_t cs_sync_ant_selection, int8_t max_tx_power); +void BTA_DmBleGapCsReadRemoteFaeTable(uint16_t conn_handle); +void BTA_DmBleGapWriteCachedRemoteFaeTable(uint16_t conn_handle, uint8_t *remote_fae_table, uint8_t table_len); +void BTA_DmBleGapCsCreateConfig(tBTA_DM_CS_CREATE_CONFIG_PARAMS *create_config_params); +void BTA_DmBleGapCsRemoveConfig(uint16_t conn_handle, uint8_t config_id); +void BTA_DmBleGapCsSetChannelClass(uint8_t *channel_class, uint8_t channl_len); +void BTA_DmBleGapCsSetProcPatams(tBTA_DM_CS_SET_PROC_PARAMS *set_proc_params); +void BTA_DmBleGapCsProcEnable(uint16_t conn_handle, uint8_t config_id, uint8_t enable); +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + /******************************************************************************* ** ** Function BTA_DmBleSetStorageParams 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 f42ab484a9..7a22f2fa5a 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 @@ -1328,6 +1328,161 @@ void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, param.pa_rsp_rpt_evt.pa_rsp_info = (esp_ble_pa_rsp_info *)params->pa_rsp_rpt_evt.rsp_data_info; break; #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + case BTA_BLE_GAP_CS_READ_LOCAL_SUPP_CAPS_EVT: + msg.act = ESP_GAP_BLE_CS_READ_LOCAL_SUPP_CAPS_EVT; + param.cs_read_local_supp_caps.status = params->cs_read_local_supp_caps.status; + param.cs_read_local_supp_caps.conn_handle = params->cs_read_local_supp_caps.conn_handle; + param.cs_read_local_supp_caps.num_config_supported = params->cs_read_local_supp_caps.num_config_supported; + param.cs_read_local_supp_caps.max_consecutive_proc_supported = params->cs_read_local_supp_caps.max_consecutive_proc_supported; + param.cs_read_local_supp_caps.num_ant_supported = params->cs_read_local_supp_caps.num_ant_supported; + param.cs_read_local_supp_caps.max_ant_paths_supported= params->cs_read_local_supp_caps.max_ant_paths_supported; + param.cs_read_local_supp_caps.roles_supported = params->cs_read_local_supp_caps.roles_supported; + param.cs_read_local_supp_caps.modes_supported = params->cs_read_local_supp_caps.modes_supported; + param.cs_read_local_supp_caps.rtt_capability = params->cs_read_local_supp_caps.rtt_capability; + param.cs_read_local_supp_caps.rtt_aa_only_n = params->cs_read_local_supp_caps.rtt_aa_only_n; + param.cs_read_local_supp_caps.rtt_sounding_n = params->cs_read_local_supp_caps.rtt_sounding_n; + param.cs_read_local_supp_caps.rtt_random_payload_n = params->cs_read_local_supp_caps.rtt_random_payload_n; + param.cs_read_local_supp_caps.NADM_sounding_capability = params->cs_read_local_supp_caps.NADM_sounding_capability; + param.cs_read_local_supp_caps.NADM_random_capability = params->cs_read_local_supp_caps.NADM_random_capability; + param.cs_read_local_supp_caps.cs_sync_phys_supported = params->cs_read_local_supp_caps.cs_sync_phys_supported; + param.cs_read_local_supp_caps.subfeatures_supported = params->cs_read_local_supp_caps.subfeatures_supported; + param.cs_read_local_supp_caps.T_IP1_times_supported = params->cs_read_local_supp_caps.T_IP1_times_supported; + param.cs_read_local_supp_caps.T_IP2_times_supported = params->cs_read_local_supp_caps.T_IP2_times_supported; + param.cs_read_local_supp_caps.T_FCS_times_supported = params->cs_read_local_supp_caps.T_FCS_times_supported; + param.cs_read_local_supp_caps.T_PM_times_supported = params->cs_read_local_supp_caps.T_PM_times_supported; + param.cs_read_local_supp_caps.T_SW_times_supported = params->cs_read_local_supp_caps.T_SW_times_supported; + param.cs_read_local_supp_caps.TX_SNR_capability = params->cs_read_local_supp_caps.TX_SNR_capability; + break; + case BTA_BLE_GAP_CS_WRITE_CACHED_REMOTE_SUPP_CAPS_EVT: + msg.act = ESP_GAP_BLE_CS_WRITE_CACHED_REMOTE_SUPP_CAPS_EVT; + param.cs_write_cached_remote_supp_caps.status = params->cs_write_cached_remote_supp_caps.status; + param.cs_write_cached_remote_supp_caps.conn_handle = params->cs_write_cached_remote_supp_caps.conn_handle; + break; + case BTA_BLE_GAP_CS_SET_DEFAULT_SETTINGS_EVT: + msg.act = ESP_GAP_BLE_CS_SET_DEFAULT_SETTINGS_EVT; + param.cs_set_default_settings.status = params->cs_set_default_settings.status; + param.cs_set_default_settings.conn_handle = params->cs_set_default_settings.conn_handle; + break; + case BTA_BLE_GAP_CS_WRITE_CACHED_REMOTE_FAE_TAB_EVT: + msg.act = ESP_GAP_BLE_CS_WRITE_CACHED_REMOTE_FAE_TABLE_EVT; + param.cs_write_cached_remote_fae_tab.status = params->cs_write_cached_remote_fae_tab.status; + param.cs_write_cached_remote_fae_tab.conn_handle = params->cs_write_cached_remote_fae_tab.conn_handle; + break; + case BTA_BLE_GAP_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT: + msg.act = ESP_GAP_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT; + param.cs_read_remote_supp_caps.status = params->cs_read_remote_supp_caps.status; + param.cs_read_remote_supp_caps.conn_handle = params->cs_read_remote_supp_caps.conn_handle; + param.cs_read_remote_supp_caps.num_config_supported = params->cs_read_remote_supp_caps.num_config_supported; + param.cs_read_remote_supp_caps.max_consecutive_proc_supported = params->cs_read_remote_supp_caps.max_consecutive_proc_supported; + param.cs_read_remote_supp_caps.num_ant_supported = params->cs_read_remote_supp_caps.num_ant_supported; + param.cs_read_remote_supp_caps.max_ant_paths_supported = params->cs_read_remote_supp_caps.max_ant_paths_supported; + param.cs_read_remote_supp_caps.roles_supported = params->cs_read_remote_supp_caps.roles_supported; + param.cs_read_remote_supp_caps.modes_supported = params->cs_read_remote_supp_caps.modes_supported; + param.cs_read_remote_supp_caps.rtt_capability = params->cs_read_remote_supp_caps.rtt_capability; + param.cs_read_remote_supp_caps.rtt_aa_only_n = params->cs_read_remote_supp_caps.rtt_aa_only_n; + param.cs_read_remote_supp_caps.rtt_sounding_n = params->cs_read_remote_supp_caps.rtt_sounding_n; + param.cs_read_remote_supp_caps.rtt_random_payload_n = params->cs_read_remote_supp_caps.rtt_random_payload_n; + param.cs_read_remote_supp_caps.NADM_sounding_capability = params->cs_read_remote_supp_caps.NADM_sounding_capability; + param.cs_read_remote_supp_caps.NADM_random_capability = params->cs_read_remote_supp_caps.NADM_random_capability; + param.cs_read_remote_supp_caps.cs_sync_phys_supported = params->cs_read_remote_supp_caps.cs_sync_phys_supported; + param.cs_read_remote_supp_caps.subfeatures_supported = params->cs_read_remote_supp_caps.subfeatures_supported; + param.cs_read_remote_supp_caps.T_IP1_times_supported = params->cs_read_remote_supp_caps.T_IP1_times_supported; + param.cs_read_remote_supp_caps.T_IP2_times_supported = params->cs_read_remote_supp_caps.T_IP2_times_supported; + param.cs_read_remote_supp_caps.T_FCS_times_supported = params->cs_read_remote_supp_caps.T_FCS_times_supported; + param.cs_read_remote_supp_caps.T_PM_times_supported = params->cs_read_remote_supp_caps.T_PM_times_supported; + param.cs_read_remote_supp_caps.T_SW_times_supported = params->cs_read_remote_supp_caps.T_SW_times_supported; + param.cs_read_remote_supp_caps.TX_SNR_capability = params->cs_read_remote_supp_caps.TX_SNR_capability; + break; + case BTA_BLE_GAP_CS_SET_CHANNEL_CLASS_CMPL_EVT: + msg.act = ESP_GAP_BLE_CS_SET_CHANNEL_CLASS_CMPL_EVT; + param.cs_set_channel_class.status = params->status; + break; + case BTA_BLE_GAP_CS_PROC_PARAMS_CMPL_EVT: + msg.act = ESP_GAP_BLE_CS_SET_PROC_PARAMS_CMPL_EVT; + param.cs_set_proc_params.status = params->cs_set_proc_params.status; + param.cs_set_proc_params.conn_handle = params->cs_set_proc_params.conn_handle; + break; + case BTA_BLE_GAP_CS_PROC_ENABLE_CMPL_EVT: + msg.act = ESP_GAP_BLE_CS_PROC_ENABLE_CMPL_EVT; + param.cs_proc_enable.status = params->cs_proc_en.status; + param.cs_proc_enable.conn_handle = params->cs_proc_en.conn_handle; + param.cs_proc_enable.config_id = params->cs_proc_en.config_id; + param.cs_proc_enable.state = params->cs_proc_en.state; + param.cs_proc_enable.tone_Ant_config_select = params->cs_proc_en.tone_Ant_config_select; + param.cs_proc_enable.select_tx_power = params->cs_proc_en.select_tx_power; + param.cs_proc_enable.subevent_Len = params->cs_proc_en.subevent_Len; + param.cs_proc_enable.subevents_per_event = params->cs_proc_en.subevents_per_event; + param.cs_proc_enable.subevent_interval = params->cs_proc_en.subevent_interval; + param.cs_proc_enable.event_interval = params->cs_proc_en.event_interval; + param.cs_proc_enable.procedure_interval = params->cs_proc_en.procedure_interval; + param.cs_proc_enable.procedure_count = params->cs_proc_en.procedure_count; + param.cs_proc_enable.max_procedure_len = params->cs_proc_en.max_procedure_len; + break; + case BTA_BLE_GAP_CS_READ_REMOTE_FAE_TABLE_CMPL_EVT: + msg.act = ESP_GAP_BLE_CS_READ_REMOTE_FAE_TABLE_CMPL_EVT; + param.cs_read_remote_fae_tab.status = params->cs_read_remote_fae_tab.status; + param.cs_read_remote_fae_tab.conn_handle = params->cs_read_remote_fae_tab.conn_handle; + memcpy(param.cs_read_remote_fae_tab.remote_fae_table, params->cs_read_remote_fae_tab.remote_fae_table, 72); + break; + case BTA_BLE_GAP_CS_SECURITY_ENABLE_CMPL_EVT: + msg.act = ESP_GAP_BLE_CS_SECURITY_ENABLE_CMPL_EVT; + param.cs_security_enable.status = params->cs_security_enable.status; + param.cs_security_enable.conn_handle = params->cs_security_enable.conn_handle; + break; + case BTA_BLE_GAP_CS_CONFIG_CMPL_EVT: + msg.act = ESP_GAP_BLE_CS_CONFIG_CMPL_EVT; + param.cs_config_update.status = params->cs_config_update.status; + param.cs_config_update.conn_handle = params->cs_config_update.conn_handle; + param.cs_config_update.config_id = params->cs_config_update.config_id; + param.cs_config_update.action = params->cs_config_update.action; + param.cs_config_update.main_mode_type = params->cs_config_update.main_mode_type; + param.cs_config_update.sub_mode_type = params->cs_config_update.sub_mode_type; + param.cs_config_update.min_main_mode_steps = params->cs_config_update.min_main_mode_steps; + param.cs_config_update.max_main_mode_steps = params->cs_config_update.max_main_mode_steps; + param.cs_config_update.main_mode_repetition = params->cs_config_update.main_mode_repetition; + param.cs_config_update.mode_0_steps = params->cs_config_update.mode_0_steps; + param.cs_config_update.role = params->cs_config_update.role; + param.cs_config_update.rtt_type = params->cs_config_update.rtt_type; + param.cs_config_update.cs_sync_phy = params->cs_config_update.cs_sync_phy; + memcpy(param.cs_config_update.channel_map, params->cs_config_update.channel_map, 10); + param.cs_config_update.channel_map_repetition = params->cs_config_update.channel_map_repetition; + param.cs_config_update.channel_selection_type = params->cs_config_update.channel_selection_type; + param.cs_config_update.ch3c_shape = params->cs_config_update.ch3c_shape; + param.cs_config_update.ch3c_jump = params->cs_config_update.ch3c_jump; + param.cs_config_update.reserved = params->cs_config_update.reserved; + param.cs_config_update.t_ip1_time = params->cs_config_update.t_ip1_time; + param.cs_config_update.t_ip2_time = params->cs_config_update.t_ip2_time; + param.cs_config_update.t_fcs_time = params->cs_config_update.t_fcs_time; + param.cs_config_update.t_pm_time = params->cs_config_update.t_pm_time; + break; + case BTA_BLE_GAP_CS_SUBEVENT_RESULT_EVT: + msg.act = ESP_GAP_BLE_CS_SUBEVENT_RESULT_EVT; + param.cs_subevt_result.conn_handle = params->cs_subevt_result.conn_handle; + param.cs_subevt_result.config_id = params->cs_subevt_result.config_id; + param.cs_subevt_result.start_acl_conn_event_counter = params->cs_subevt_result.start_acl_conn_event_counter; + param.cs_subevt_result.procedure_counter = params->cs_subevt_result.procedure_counter; + param.cs_subevt_result.frequency_compensation = params->cs_subevt_result.frequency_compensation; + param.cs_subevt_result.reference_power_level = params->cs_subevt_result.reference_power_level; + param.cs_subevt_result.procedure_done_status = params->cs_subevt_result.procedure_done_status; + param.cs_subevt_result.subevent_done_status = params->cs_subevt_result.subevent_done_status; + param.cs_subevt_result.abort_reason = params->cs_subevt_result.abort_reason; + param.cs_subevt_result.num_ant_paths = params->cs_subevt_result.num_ant_paths; + param.cs_subevt_result.num_steps_reported = params->cs_subevt_result.num_steps_reported; + param.cs_subevt_result.step_info = (esp_ble_cs_step_info *)params->cs_subevt_result.step_info; + break; + case BTA_BLE_GAP_CS_SUBEVENT_RESULT_CONTINUE_EVT: + msg.act = ESP_GAP_BLE_CS_SUBEVENT_RESULT_CONTINUE_EVT; + param.cs_subevt_result_continue.conn_handle = params->cs_subevt_result_continue.conn_handle; + param.cs_subevt_result_continue.config_id = params->cs_subevt_result_continue.config_id; + param.cs_subevt_result_continue.proc_done_status = params->cs_subevt_result_continue.proc_done_status; + param.cs_subevt_result_continue.subevt_done_status = params->cs_subevt_result_continue.subevt_done_status; + param.cs_subevt_result_continue.abort_reason = params->cs_subevt_result_continue.abort_reason; + param.cs_subevt_result_continue.num_ant_paths = params->cs_subevt_result_continue.num_ant_paths; + param.cs_subevt_result_continue.num_steps_reported = params->cs_subevt_result_continue.num_steps_reported; + param.cs_subevt_result_continue.step_info = (esp_ble_cs_step_info *)params->cs_subevt_result_continue.step_info; + break; +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) default: break; } @@ -2137,6 +2292,54 @@ void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) } break; #endif // (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + case BTA_BLE_GAP_CS_SUBEVENT_RESULT_EVT: + if (src->cs_subevt_result.step_info) { + dst->cs_subevt_result.step_info = osi_malloc(src->cs_subevt_result.num_steps_reported * sizeof(esp_ble_cs_step_info)); + if (dst->cs_subevt_result.step_info) { + for (UINT8 i = 0; i < src->cs_subevt_result.num_steps_reported; i++) + { + dst->cs_subevt_result.step_info[i].step_mode = src->cs_subevt_result.step_info[i].step_mode; + dst->cs_subevt_result.step_info[i].step_channel = src->cs_subevt_result.step_info[i].step_channel; + dst->cs_subevt_result.step_info[i].step_data_len = src->cs_subevt_result.step_info[i].step_data_len; + if (src->cs_subevt_result.step_info[i].step_data_len) { + dst->cs_subevt_result.step_info[i].data = osi_malloc(src->cs_subevt_result.step_info[i].step_data_len); + if (dst->cs_subevt_result.step_info[i].data) { + memcpy(dst->cs_subevt_result.step_info[i].data, src->cs_subevt_result.step_info[i].data, src->cs_subevt_result.step_info[i].step_data_len); + } else { + BTC_TRACE_ERROR("%s, data, no enough memory.", __func__); + } + } + } + } else { + BTC_TRACE_ERROR("%s, pa_rsp_info, no enough memory.", __func__); + } + } + break; + case BTA_BLE_GAP_CS_SUBEVENT_RESULT_CONTINUE_EVT: + if (src->cs_subevt_result_continue.step_info) { + dst->cs_subevt_result_continue.step_info = osi_malloc(src->cs_subevt_result_continue.num_steps_reported * sizeof(esp_ble_cs_step_info)); + if (dst->cs_subevt_result_continue.step_info) { + for (UINT8 i = 0; i < src->cs_subevt_result_continue.num_steps_reported; i++) + { + dst->cs_subevt_result_continue.step_info[i].step_mode = src->cs_subevt_result_continue.step_info[i].step_mode; + dst->cs_subevt_result_continue.step_info[i].step_channel = src->cs_subevt_result_continue.step_info[i].step_channel; + dst->cs_subevt_result_continue.step_info[i].step_data_len = src->cs_subevt_result_continue.step_info[i].step_data_len; + if (src->cs_subevt_result_continue.step_info[i].step_data_len) { + dst->cs_subevt_result_continue.step_info[i].data = osi_malloc(src->cs_subevt_result_continue.step_info[i].step_data_len); + if (dst->cs_subevt_result_continue.step_info[i].data) { + memcpy(dst->cs_subevt_result_continue.step_info[i].data, src->cs_subevt_result_continue.step_info[i].data, src->cs_subevt_result.step_info[i].step_data_len); + } else { + BTC_TRACE_ERROR("%s, data, no enough memory.", __func__); + } + } + } + } else { + BTC_TRACE_ERROR("%s, pa_rsp_info, no enough memory.", __func__); + } + } + break; +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) default: // BTC_TRACE_ERROR("%s, Unhandled deep copy %d\n", __func__, msg->act); break; @@ -2333,6 +2536,38 @@ void btc_gap_ble_cb_deep_free(btc_msg_t *msg) } break; #endif // (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + case BTA_BLE_GAP_CS_SUBEVENT_RESULT_EVT: + { + esp_ble_cs_step_info *step_info = ((esp_ble_gap_cb_param_t *)msg->arg)->cs_subevt_result.step_info; + if (step_info) { + uint8_t num_step = ((esp_ble_gap_cb_param_t *)msg->arg)->cs_subevt_result.num_steps_reported; + for (uint8_t i = 0; i < num_step; i++) + { + if (step_info[i].data) { + osi_free(step_info[i].data); + } + } + osi_free(step_info); + } + } + break; + case BTA_BLE_GAP_CS_SUBEVENT_RESULT_CONTINUE_EVT: + { + esp_ble_cs_step_info *step_info = ((esp_ble_gap_cb_param_t *)msg->arg)->cs_subevt_result_continue.step_info; + if (step_info) { + uint8_t num_step = ((esp_ble_gap_cb_param_t *)msg->arg)->cs_subevt_result_continue.num_steps_reported; + for (uint8_t i = 0; i < num_step; i++) + { + if (step_info[i].data) { + osi_free(step_info[i].data); + } + } + osi_free(step_info); + } + } + break; +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) default: BTC_TRACE_DEBUG("Unhandled deep free %d", msg->act); break; @@ -2913,6 +3148,45 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) BTA_DmBleGapSetPeriodicSyncSubevt(arg_5->per_sync_subevent_params.sync_handle, arg_5->per_sync_subevent_params.periodic_adv_properties, arg_5->per_sync_subevent_params.num_subevents_to_sync, arg_5->per_sync_subevent_params.subevent); break; #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + case BTC_GAP_BLE_CS_READ_LOCAL_SUPPORTED_CAPS: + BTA_DmBleGapReadLocalSupportedCaps(); + break; + case BTC_GAP_BLE_CS_READ_REMOTE_SUPPORTED_CAPS: + BTA_DmBleGapReadRemoteSupportedCaps(arg_5->cs_read_remote_supp_caps.conn_handle); + break; + case BTC_GAP_BLE_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPS: + BTA_DmBleGapWriteCachedRemoteSupportedCaps((tBTA_DM_CS_WRITE_CACHED_REMOTE_SUPP_CAPS *)&arg_5->cs_write_cached_remote_supp_caps); + break; + case BTC_GAP_BLE_CS_SECURITY_ENABLE: + BTA_DmBleGapCsSecurityEnable(arg_5->cs_security_enable.conn_handle); + break; + case BTC_GAP_BLE_CS_SET_DEFAULT_SETTINGS: + BTA_DmBleGapCsSetDefaultSetting(arg_5->cs_set_default_settings_params.conn_handle, arg_5->cs_set_default_settings_params.role_enable, + arg_5->cs_set_default_settings_params.cs_sync_ant_selection, arg_5->cs_set_default_settings_params.max_tx_power); + break; + case BTC_GAP_BLE_CS_READ_REMOTE_FAE_TABLE: + BTA_DmBleGapCsReadRemoteFaeTable(arg_5->cs_read_remote_tab.conn_handle); + break; + case BTC_GAP_BLE_CS_WRITE_CACHED_REMOTE_FAE_TABLE: + BTA_DmBleGapWriteCachedRemoteFaeTable(arg_5->cs_write_cached_remote_fae_table_params.conn_handle, &arg_5->cs_write_cached_remote_fae_table_params.remote_fae_table[0], 72); + break; + case BTC_GAP_BLE_CS_CREATE_CONFIG: + BTA_DmBleGapCsCreateConfig((tBTA_DM_CS_CREATE_CONFIG_PARAMS*)&arg_5->cs_create_config_params); + break; + case BTC_GAP_BLE_CS_REMOVE_CONFIG: + BTA_DmBleGapCsRemoveConfig(arg_5->cs_remove_config_params.conn_handle, arg_5->cs_remove_config_params.config_id); + break; + case BTC_GAP_BLE_CS_SET_CAHNNEL_CLASSIFICATION: + BTA_DmBleGapCsSetChannelClass(&arg_5->cs_set_channel_class_params.channel_class[0], 10); + break; + case BTC_GAP_BLE_CS_SET_PROCEDURE_PARAMS: + BTA_DmBleGapCsSetProcPatams((tBTA_DM_CS_SET_PROC_PARAMS *)&arg_5->cs_set_procedure_params); + break; + case BTC_GAP_BLE_CS_PROCEDURE_ENABLE: + BTA_DmBleGapCsProcEnable(arg_5->cs_procedure_enable_params.conn_handle, arg_5->cs_procedure_enable_params.config_id, arg_5->cs_procedure_enable_params.enable); + break; +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) default: break; } diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index ae1b974f66..8f844a50b8 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -146,6 +146,20 @@ typedef enum { BTC_GAP_BLE_SET_PA_RSP_DATA, BTC_GAP_BLE_SET_PA_SYNC_SUBEVT, #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + BTC_GAP_BLE_CS_READ_LOCAL_SUPPORTED_CAPS, + BTC_GAP_BLE_CS_READ_REMOTE_SUPPORTED_CAPS, + BTC_GAP_BLE_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPS, + BTC_GAP_BLE_CS_SECURITY_ENABLE, + BTC_GAP_BLE_CS_SET_DEFAULT_SETTINGS, + BTC_GAP_BLE_CS_READ_REMOTE_FAE_TABLE, + BTC_GAP_BLE_CS_WRITE_CACHED_REMOTE_FAE_TABLE, + BTC_GAP_BLE_CS_CREATE_CONFIG, + BTC_GAP_BLE_CS_REMOVE_CONFIG, + BTC_GAP_BLE_CS_SET_CAHNNEL_CLASSIFICATION, + BTC_GAP_BLE_CS_SET_PROCEDURE_PARAMS, + BTC_GAP_BLE_CS_PROCEDURE_ENABLE, +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) } btc_gap_ble_act_t; /* btc_ble_gap_args_t */ @@ -564,6 +578,108 @@ typedef union { uint8_t *subevent; } per_sync_subevent_params; #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + struct cs_read_remote_supp_caps_args { + uint16_t conn_handle; + } cs_read_remote_supp_caps; + + struct cs_write_cached_remote_supp_caps_args { + uint16_t conn_handle; + uint8_t num_config_supported; + uint16_t max_consecutive_proc_supported; + uint8_t num_ant_supported; + uint8_t max_ant_paths_supported; + uint8_t roles_supported; + uint8_t modes_supported; + uint8_t rtt_capability; + uint8_t rtt_aa_only_n; + uint8_t rtt_sounding_n; + uint8_t rtt_random_payload_n; + uint16_t NADM_sounding_capability; + uint16_t NADM_random_capability; + uint8_t cs_sync_phys_supported; + uint16_t subfeatures_supported; + uint16_t T_IP1_times_supported; + uint16_t T_IP2_times_supported; + uint16_t T_FCS_times_supported; + uint16_t T_PM_times_supported; + uint8_t T_SW_times_supported; + uint8_t TX_SNR_capability; + } cs_write_cached_remote_supp_caps; + + struct cs_security_enable_args { + uint16_t conn_handle; + } cs_security_enable; + + struct cs_set_default_settings_params_args { + uint16_t conn_handle; + uint8_t role_enable; + uint8_t cs_sync_ant_selection; + int8_t max_tx_power; + } cs_set_default_settings_params; + + struct cs_read_remote_tab_args { + uint16_t conn_handle; + } cs_read_remote_tab; + + struct cs_write_cached_remote_fae_table_params_args { + uint16_t conn_handle; + uint8_t remote_fae_table[72]; + } cs_write_cached_remote_fae_table_params; + + struct cs_create_config_params_args { + uint16_t conn_handle; + uint8_t config_id; + uint8_t create_context; + uint8_t main_mode_type; + uint8_t sub_mode_type; + uint8_t min_main_mode_steps; + uint8_t max_main_mode_steps; + uint8_t main_mode_repetition; + uint8_t mode_0_steps; + uint8_t role; + uint8_t rtt_type; + uint8_t cs_sync_phy; + uint8_t channel_map[10]; + uint8_t channel_map_repetition; + uint8_t channel_selection_type; + uint8_t ch3c_shape; + uint8_t ch3c_jump; + uint8_t reserved; + } cs_create_config_params; + + struct cs_remove_config_params_args { + uint16_t conn_handle; + uint8_t config_id; + } cs_remove_config_params; + + struct cs_set_channel_class_params_args { + uint8_t channel_class[10]; + } cs_set_channel_class_params; + + struct cs_set_procedure_params_args { + uint16_t conn_handle; + uint8_t config_id; + uint16_t max_procedure_len; + uint16_t min_procedure_interval; + uint16_t max_procedure_interval; + uint16_t max_procedure_count; + uint32_t min_subevent_len; + uint32_t max_subevent_len; + uint8_t tone_ant_config_selection; + uint8_t phy; + uint8_t tx_power_delta; + uint8_t preferred_peer_antenna; + uint8_t SNR_control_initiator; + uint8_t SNR_control_reflector; + } cs_set_procedure_params; + + struct cs_procedure_enable_params_args { + uint16_t conn_handle; + uint8_t config_id; + uint8_t enable; + } cs_procedure_enable_params; +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) } btc_ble_5_gap_args_t; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) 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 48d06fba6b..70e967b44b 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 @@ -376,6 +376,12 @@ #define UC_BT_BLE_FEAT_ADV_CODING_SELECTION FALSE #endif +#ifdef CONFIG_BT_BLE_FEAT_CHANNEL_SOUNDING +#define UC_BT_BLE_FEAT_CHANNEL_SOUNDING CONFIG_BT_BLE_FEAT_CHANNEL_SOUNDING +#else +#define UC_BT_BLE_FEAT_CHANNEL_SOUNDING FALSE +#endif + #ifdef CONFIG_BT_BLE_VENDOR_HCI_EN #define UC_BT_BLE_VENDOR_HCI_EN CONFIG_BT_BLE_VENDOR_HCI_EN #else 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 a62caff1a2..412ca9dd06 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -427,6 +427,12 @@ #define BT_BLE_FEAT_ADV_CODING_SELECTION FALSE #endif +#if (UC_BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#define BT_BLE_FEAT_CHANNEL_SOUNDING TRUE +#else +#define BT_BLE_FEAT_CHANNEL_SOUNDING FALSE +#endif + #if (UC_BT_BLE_VENDOR_HCI_EN == TRUE) #define BLE_VENDOR_HCI_EN TRUE #else diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 20225ef564..b87c9d35f6 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -1824,3 +1824,288 @@ void btm_ble_pa_rsp_rpt_evt(tBTM_BLE_PA_RSP_REPORT_EVT *params) } #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +void BTM_BleCSReadLocalSuppCaps(void) +{ + btsnd_hcic_ble_cs_read_local_supported_caps(); +} + +void btm_ble_cs_read_local_supp_caps_cmpl_evt(uint8_t *p) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + STREAM_TO_UINT8(cb_params.cs_read_local_supp_caps.status, p); + if (cb_params.cs_read_local_supp_caps.status != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err = 0x%x", __func__, cb_params.cs_read_local_supp_caps.status); + cb_params.cs_read_local_supp_caps.status |= BTM_HCI_ERROR; + goto _error; + } + + STREAM_TO_UINT16(cb_params.cs_read_local_supp_caps.conn_handle, p); + STREAM_TO_UINT8(cb_params.cs_read_local_supp_caps.num_config_supported, p); + STREAM_TO_UINT16(cb_params.cs_read_local_supp_caps.max_consecutive_proc_supported, p); + STREAM_TO_UINT8(cb_params.cs_read_local_supp_caps.num_ant_supported, p); + STREAM_TO_UINT8(cb_params.cs_read_local_supp_caps.max_ant_paths_supported, p); + STREAM_TO_UINT8(cb_params.cs_read_local_supp_caps.roles_supported, p); + STREAM_TO_UINT8(cb_params.cs_read_local_supp_caps.modes_supported, p); + STREAM_TO_UINT8(cb_params.cs_read_local_supp_caps.rtt_capability, p); + STREAM_TO_UINT8(cb_params.cs_read_local_supp_caps.rtt_aa_only_n, p); + STREAM_TO_UINT8(cb_params.cs_read_local_supp_caps.rtt_sounding_n, p); + STREAM_TO_UINT8(cb_params.cs_read_local_supp_caps.rtt_random_payload_n, p); + STREAM_TO_UINT16(cb_params.cs_read_local_supp_caps.NADM_sounding_capability, p); + STREAM_TO_UINT16(cb_params.cs_read_local_supp_caps.NADM_random_capability, p); + STREAM_TO_UINT8(cb_params.cs_read_local_supp_caps.cs_sync_phys_supported, p); + STREAM_TO_UINT16(cb_params.cs_read_local_supp_caps.subfeatures_supported, p); + STREAM_TO_UINT16(cb_params.cs_read_local_supp_caps.T_IP1_times_supported, p); + STREAM_TO_UINT16(cb_params.cs_read_local_supp_caps.T_IP2_times_supported, p); + STREAM_TO_UINT16(cb_params.cs_read_local_supp_caps.T_FCS_times_supported, p); + STREAM_TO_UINT16(cb_params.cs_read_local_supp_caps.T_PM_times_supported, p); + STREAM_TO_UINT8(cb_params.cs_read_local_supp_caps.T_SW_times_supported, p); + STREAM_TO_UINT8(cb_params.cs_read_local_supp_caps.TX_SNR_capability, p); + +_error: + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_READ_LOCAL_SUPP_CAPS_EVT, &cb_params); +} + +void BTM_BleCSReadRemoteSuppCaps(UINT16 conn_handle) +{ + btsnd_hcic_ble_cs_read_remote_supported_capabilities(conn_handle); +} + +void btm_ble_cs_read_remote_supp_caps_cmd_status(UINT8 status) +{ + if (status != HCI_SUCCESS) { + tBTM_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT cs_read_remote_supp_caps = {0}; + cs_read_remote_supp_caps.status = (status | BTM_HCI_ERROR); + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)&cs_read_remote_supp_caps); + } +} + +void BTM_BleGapWriteCachedRemoteSupportedCaps(UINT16 conn_handle, UINT8 num_config_supported, UINT16 max_consecutive_proc_supported, + UINT8 num_ant_supported, UINT8 max_ant_paths_supported, UINT8 roles_supported, + UINT8 modes_supported, UINT8 rtt_capability, UINT8 rtt_aa_only_n, + UINT8 rtt_sounding_n, UINT8 rtt_random_payload_n, UINT16 NADM_sounding_capability, + UINT16 NADM_random_capability, UINT8 cs_sync_phys_supported, UINT16 subfeatures_supported, + UINT16 T_IP1_times_supported, UINT16 T_IP2_times_supported, UINT16 T_FCS_times_supported, + UINT16 T_PM_times_supported, UINT8 T_SW_times_supported, UINT8 TX_SNR_capability) +{ + tBTM_STATUS status = BTM_SUCCESS; + tHCI_STATUS err = HCI_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_cs_write_cached_remote_supported_capabilities(conn_handle, num_config_supported, max_consecutive_proc_supported, + num_ant_supported, max_ant_paths_supported, roles_supported, + modes_supported, rtt_capability, rtt_aa_only_n, + rtt_sounding_n, rtt_random_payload_n, NADM_sounding_capability, + NADM_random_capability, cs_sync_phys_supported, subfeatures_supported, + T_IP1_times_supported, T_IP2_times_supported, T_FCS_times_supported, + T_PM_times_supported, T_SW_times_supported, TX_SNR_capability)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cs write cached remote support caps, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cs_write_cached_remote_supp_caps.status = status; + cb_params.cs_write_cached_remote_supp_caps.conn_handle = conn_handle; + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_WRITE_CACHED_REMOTE_SUPP_CAPS_EVT, &cb_params); +} + +void BTM_BleGapCsSecurityEnable(UINT16 conn_handle) +{ + btsnd_hcic_ble_cs_security_enable(conn_handle); +} + +void btm_ble_cs_security_enable_cmd_status(UINT8 status) +{ + tBTM_BLE_CS_SEC_ENABLE_CMPL_EVT cs_security_enable = {0}; + if (status != HCI_SUCCESS) { + cs_security_enable.status = (status | BTM_HCI_ERROR); + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_SECURITY_ENABLE_CMPL_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)&cs_security_enable); + } +} + +void BTM_BleGapCsSetDefaultSetting(UINT16 conn_handle, UINT8 role_enable, UINT8 cs_sync_ant_selection, INT8 max_tx_power) +{ + tBTM_STATUS status = BTM_SUCCESS; + tHCI_STATUS err = HCI_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_cs_set_default_settings(conn_handle, role_enable, cs_sync_ant_selection, max_tx_power)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cs set default setting, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cs_set_default_settings.status = status; + cb_params.cs_set_default_settings.conn_handle = conn_handle; + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_SET_DEFAULT_SETTINGS_EVT, &cb_params); +} + +void BTM_BleGapCsReadRemoteFaeTable(UINT16 conn_handle) +{ + btsnd_hcic_ble_cs_read_remote_fae_table(conn_handle); +} + +void btm_ble_cs_read_remote_fae_table_cmd_status(UINT8 status) +{ + tBTM_BLE_CS_READ_REMOTE_FAE_TAB_CMPL_EVT cs_read_remote_fae_tab = {0}; + if (status != HCI_SUCCESS) { + cs_read_remote_fae_tab.status = (status | BTM_HCI_ERROR); + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_READ_REMOTE_FAE_TABLE_CMPL_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)&cs_read_remote_fae_tab); + } +} + +void BTM_BleGapWriteCachedRemoteFaeTable(UINT16 conn_handle, UINT8 *remote_fae_table) +{ + tBTM_STATUS status = BTM_SUCCESS; + tHCI_STATUS err = HCI_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_cs_write_cached_remote_fae_table(conn_handle, remote_fae_table)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cs write cached remote fae tab, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cs_write_cached_remote_fae_tab.status = status; + cb_params.cs_write_cached_remote_fae_tab.conn_handle = conn_handle; + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_WRITE_CACHED_REMOTE_FAE_TAB_EVT, &cb_params); +} + +void BTM_BleGapCsCreateConfig(UINT16 conn_handle, UINT8 config_id, UINT8 create_context, + UINT8 main_mode_type, UINT8 sub_mode_type, UINT8 min_main_mode_steps, + UINT8 max_main_mode_steps, UINT8 main_mode_repetition, UINT8 mode_0_steps, + UINT8 role, UINT8 rtt_type, UINT8 cs_sync_phy, UINT8 *channel_map, + UINT8 channel_map_repetition, UINT8 channel_selection_type, UINT8 ch3c_shape, + UINT8 ch3c_jump,UINT8 reserved) +{ + btsnd_hcic_ble_cs_create_config(conn_handle, config_id, create_context, + main_mode_type, sub_mode_type, min_main_mode_steps, + max_main_mode_steps, main_mode_repetition, mode_0_steps, + role, rtt_type, cs_sync_phy, channel_map, + channel_map_repetition, channel_selection_type, ch3c_shape, + ch3c_jump, reserved); +} + +void BTM_BleGapCsRemoveConfig(UINT16 conn_handle, UINT8 config_id) +{ + btsnd_hcic_ble_cs_remove_config(conn_handle, config_id); +} + +void btm_ble_cs_update_config_cmd_status(UINT8 status, BOOLEAN create) +{ + tBTM_BLE_CS_CONFIG_CMPL_EVT config_cmpl = {0}; + if (status != HCI_SUCCESS) { + config_cmpl.status = (status | BTM_HCI_ERROR); + config_cmpl.action = (create? 0x01:0x00); + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_CONFIG_CMPL_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)&config_cmpl); + } +} + +void BTM_BleGapCsSetChannelClass(UINT8 *channel_class) +{ + tBTM_STATUS status = BTM_SUCCESS; + tHCI_STATUS err = HCI_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_cs_set_channel_classification(channel_class)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cs set channel class, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.status = status; + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_SET_CHANNEL_CLASS_CMPL_EVT, &cb_params); +} + +void BTM_BleGapCsSetProcPatams(UINT16 conn_handle, UINT8 config_id, UINT16 max_procedure_len, + UINT16 min_procedure_interval, UINT16 max_procedure_interval, + UINT16 max_procedure_count, UINT32 min_subevent_len, + UINT32 max_subevent_len, UINT8 tone_ant_config_selection, + UINT8 phy, UINT8 tx_power_delta, UINT8 preferred_peer_antenna, + UINT8 SNR_control_initiator, UINT8 SNR_control_reflector) +{ + tBTM_STATUS status = BTM_SUCCESS; + tHCI_STATUS err = HCI_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_cs_set_procedure_params(conn_handle, config_id, max_procedure_len, + min_procedure_interval, max_procedure_interval, + max_procedure_count, min_subevent_len, + max_subevent_len, tone_ant_config_selection, + phy, tx_power_delta, preferred_peer_antenna, + SNR_control_initiator, SNR_control_reflector)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("cs set procedure params, cmd err=0x%x", err); + status = BTM_HCI_ERROR | err; + } + + cb_params.cs_set_proc_params.status = status; + cb_params.cs_set_proc_params.conn_handle = conn_handle; + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_PROC_PARAMS_CMPL_EVT, &cb_params); +} + +void BTM_BleGapCsProcEnable(UINT16 conn_handle, UINT8 config_id, UINT8 enable) +{ + btsnd_hcic_ble_cs_procedure_enable(conn_handle, config_id, enable); +} + +void btm_ble_cs_read_remote_supp_caps_cmpl_evt(tBTM_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT *cs_read_remote_supp_caps) +{ + if (cs_read_remote_supp_caps->status != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err = 0x%x", __func__, cs_read_remote_supp_caps->status); + cs_read_remote_supp_caps->status |= BTM_HCI_ERROR; + } + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)cs_read_remote_supp_caps); +} + +void btm_ble_cs_read_remote_fae_tab_cmpl_evt(tBTM_BLE_CS_READ_REMOTE_FAE_TAB_CMPL_EVT *cs_read_remote_fae_tab) +{ + if (cs_read_remote_fae_tab->status != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err = 0x%x", __func__, cs_read_remote_fae_tab->status); + cs_read_remote_fae_tab->status |= BTM_HCI_ERROR; + } + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_READ_REMOTE_FAE_TABLE_CMPL_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)cs_read_remote_fae_tab); +} + +void btm_ble_cs_securuty_enable_cmpl_evt(tBTM_BLE_CS_SEC_ENABLE_CMPL_EVT *cs_security_enable) +{ + if (cs_security_enable->status != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err = 0x%x", __func__, cs_security_enable->status); + cs_security_enable->status |= BTM_HCI_ERROR; + } + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_SECURITY_ENABLE_CMPL_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)cs_security_enable); +} + +void btm_ble_cs_config_cmpl_evt(tBTM_BLE_CS_CONFIG_CMPL_EVT *config_cmpl) +{ + if (config_cmpl->status != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err = 0x%x", __func__, config_cmpl->status); + config_cmpl->status |= BTM_HCI_ERROR; + } + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_CONFIG_CMPL_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)config_cmpl); +} + +void btm_ble_cs_proc_enable_cmpl_evt(tBTM_BLE_CS_PROC_ENABLE_CMPL_EVT *proc_en) +{ + if (proc_en->status != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err = 0x%x", __func__, proc_en->status); + proc_en->status |= BTM_HCI_ERROR; + } + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_PROC_ENABLE_CMPL_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)proc_en); +} + +void btm_ble_cs_subevt_result_evt(tBTM_BLE_CS_SUBEVT_RESULT_CMPL_EVT *subevt_result) +{ + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_SUBEVENT_RESULT_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)subevt_result); +} + +void btm_ble_cs_subevt_continue_result_evt(tBTM_BLE_CS_SUBEVT_RESULT_CONTINUE_EVT *subevt_result_continue) +{ + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_SUBEVENT_RESULT_CONTINUE_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)subevt_result_continue); +} + +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index e7fe12925d..c8181086f7 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -611,6 +611,17 @@ void btm_ble_pa_subevt_data_req_evt(tBTM_BLE_PA_SUBEVT_DATA_REQ_EVT *params); void btm_ble_pa_rsp_rpt_evt(tBTM_BLE_PA_RSP_REPORT_EVT *params); #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +void btm_ble_cs_read_remote_supp_caps_cmpl_evt(tBTM_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT *cs_read_remote_supp_caps); +void btm_ble_cs_read_remote_fae_tab_cmpl_evt(tBTM_BLE_CS_READ_REMOTE_FAE_TAB_CMPL_EVT *cs_read_remote_fae_tab); +void btm_ble_cs_securuty_enable_cmpl_evt(tBTM_BLE_CS_SEC_ENABLE_CMPL_EVT *cs_security_enable); +void btm_ble_cs_config_cmpl_evt(tBTM_BLE_CS_CONFIG_CMPL_EVT *config_cmpl); +void btm_ble_cs_proc_enable_cmpl_evt(tBTM_BLE_CS_PROC_ENABLE_CMPL_EVT *proc_en); +void btm_ble_cs_subevt_result_evt(tBTM_BLE_CS_SUBEVT_RESULT_CMPL_EVT *subevt_result); +void btm_ble_cs_subevt_continue_result_evt(tBTM_BLE_CS_SUBEVT_RESULT_CONTINUE_EVT *subevt_continue_result); +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + + /* #ifdef __cplusplus } diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index 5afc610e80..d4d96c81a9 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -1137,6 +1137,14 @@ void btm_read_remote_trans_pwr_level_cmpl(UINT8 status); void btm_subrate_req_cmd_status(UINT8 status); #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +void btm_ble_cs_read_local_supp_caps_cmpl_evt(UINT8 *p); +void btm_ble_cs_read_remote_supp_caps_cmd_status(UINT8 status); +void btm_ble_cs_security_enable_cmd_status(UINT8 status); +void btm_ble_cs_read_remote_fae_table_cmd_status(UINT8 status); +void btm_ble_cs_update_config_cmd_status(UINT8 status, BOOLEAN create); +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + /* Internal functions provided by btm_sco.c ******************************************** */ diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index fddfb02615..e79b7be050 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -233,6 +233,16 @@ static void btu_ble_pa_subevt_data_request_evt(UINT8 *p); static void btu_ble_pa_response_report_evt(UINT8 *p); #endif // (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +static void btu_ble_cs_read_remote_supp_caps_evt(UINT8 *p); +static void btu_ble_cs_read_remote_fae_tab_evt(UINT8 *p); +static void btu_ble_cs_security_enable_cmpl_evt(UINT8 *p); +static void btu_ble_cs_config_cmpl_evt(UINT8 *p); +static void btu_ble_cs_proc_enable_cmpl_evt(UINT8 *p); +static void btu_ble_cs_subevt_result_evt(UINT8 *p); +static void btu_ble_cs_subevt_result_continue_evt(UINT8 *p); +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + #if (BLE_42_ADV_EN == TRUE) extern osi_sem_t adv_enable_sem; extern osi_sem_t adv_data_sem; @@ -607,6 +617,29 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) btu_ble_pa_response_report_evt(p); break; #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + case HCI_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT: + btu_ble_cs_read_remote_supp_caps_evt(p); + break; + case HCI_BLE_CS_READ_REMOTE_FAE_TAB_CMPL_EVT: + btu_ble_cs_read_remote_fae_tab_evt(p); + break; + case HCI_BLE_CS_SECURITY_ENABLE_CMPL_EVT: + btu_ble_cs_security_enable_cmpl_evt(p); + break; + case HCI_BLE_CS_CONFIG_CMPL_EVT: + btu_ble_cs_config_cmpl_evt(p); + break; + case HCI_BLE_CS_PROC_ENABLE_CMPL_EVT: + btu_ble_cs_proc_enable_cmpl_evt(p); + break; + case HCI_BLE_CS_SUBEVENT_RESULT_EVT: + btu_ble_cs_subevt_result_evt(p); + break; + case HCI_BLE_CS_SUBEVENT_RESULT_CONTINUE_EVT: + btu_ble_cs_subevt_result_continue_evt(p); + break; +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) } break; #endif /* BLE_INCLUDED */ @@ -1411,7 +1444,11 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l btm_enh_read_trans_pwr_level_cmpl_evt(p); break; #endif //#if (BLE_FEAT_POWER_CONTROL_EN == TRUE) - +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + case HCI_BLE_CS_READ_LOCAL_SUPP_CAPS: + btm_ble_cs_read_local_supp_caps_cmpl_evt(p); + break; +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) #endif /* (BLE_INCLUDED == TRUE) */ default: { @@ -1619,6 +1656,23 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c btm_subrate_req_cmd_status(status); break; #endif // #if (BLE_FEAT_CONN_SUBRATING == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + case HCI_BLE_CS_READ_REMOTE_SUPP_CAPS: + btm_ble_cs_read_remote_supp_caps_cmd_status(status); + break; + case HCI_BLE_CS_SECURITY_ENABLE: + btm_ble_cs_security_enable_cmd_status(status); + break; + case HCI_BLE_CS_READ_REMOTE_FAE_TABLE: + btm_ble_cs_read_remote_fae_table_cmd_status(status); + break; + case HCI_BLE_CS_CREATE_CONFIG: + btm_ble_cs_update_config_cmd_status(status, true); + break; + case HCI_BLE_CS_REMOVE_CONFIG: + btm_ble_cs_update_config_cmd_status(status, false); + break; +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) default: /* If command failed to start, we may need to tell BTM */ if (status != HCI_SUCCESS) { @@ -3191,6 +3245,228 @@ static void btu_ble_pa_response_report_evt(UINT8 *p) } #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +static void btu_ble_cs_read_remote_supp_caps_evt(UINT8 *p) +{ + tBTM_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT cs_read_remote_supp_caps = {0}; + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(cs_read_remote_supp_caps.status, p); + STREAM_TO_UINT16(cs_read_remote_supp_caps.conn_handle, p); + STREAM_TO_UINT8(cs_read_remote_supp_caps.num_config_supported, p); + STREAM_TO_UINT16(cs_read_remote_supp_caps.max_consecutive_proc_supported, p); + STREAM_TO_UINT8(cs_read_remote_supp_caps.num_ant_supported, p); + STREAM_TO_UINT8(cs_read_remote_supp_caps.max_ant_paths_supported, p); + STREAM_TO_UINT8(cs_read_remote_supp_caps.roles_supported, p); + STREAM_TO_UINT8(cs_read_remote_supp_caps.modes_supported, p); + STREAM_TO_UINT8(cs_read_remote_supp_caps.rtt_capability, p); + STREAM_TO_UINT8(cs_read_remote_supp_caps.rtt_aa_only_n, p); + STREAM_TO_UINT8(cs_read_remote_supp_caps.rtt_sounding_n, p); + STREAM_TO_UINT8(cs_read_remote_supp_caps.rtt_random_payload_n, p); + STREAM_TO_UINT16(cs_read_remote_supp_caps.NADM_sounding_capability, p); + STREAM_TO_UINT16(cs_read_remote_supp_caps.NADM_random_capability, p); + STREAM_TO_UINT8(cs_read_remote_supp_caps.cs_sync_phys_supported, p); + STREAM_TO_UINT16(cs_read_remote_supp_caps.subfeatures_supported, p); + STREAM_TO_UINT16(cs_read_remote_supp_caps.T_IP1_times_supported, p); + STREAM_TO_UINT16(cs_read_remote_supp_caps.T_IP2_times_supported, p); + STREAM_TO_UINT16(cs_read_remote_supp_caps.T_FCS_times_supported, p); + STREAM_TO_UINT16(cs_read_remote_supp_caps.T_PM_times_supported, p); + STREAM_TO_UINT8(cs_read_remote_supp_caps.T_SW_times_supported, p); + STREAM_TO_UINT8(cs_read_remote_supp_caps.TX_SNR_capability, p); + + btm_ble_cs_read_remote_supp_caps_cmpl_evt(&cs_read_remote_supp_caps); +} + +static void btu_ble_cs_read_remote_fae_tab_evt(UINT8 *p) +{ + tBTM_BLE_CS_READ_REMOTE_FAE_TAB_CMPL_EVT cs_read_remote_fae_tab = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(cs_read_remote_fae_tab.status, p); + STREAM_TO_UINT16(cs_read_remote_fae_tab.conn_handle, p); + STREAM_TO_ARRAY(cs_read_remote_fae_tab.remote_fae_table, p, 72); + + btm_ble_cs_read_remote_fae_tab_cmpl_evt(&cs_read_remote_fae_tab); +} + +static void btu_ble_cs_security_enable_cmpl_evt(UINT8 *p) +{ + tBTM_BLE_CS_SEC_ENABLE_CMPL_EVT cs_security_enable = {0}; + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + STREAM_TO_UINT8(cs_security_enable.status, p); + STREAM_TO_UINT16(cs_security_enable.conn_handle, p); + + btm_ble_cs_securuty_enable_cmpl_evt(&cs_security_enable); +} + +static void btu_ble_cs_config_cmpl_evt(UINT8 *p) +{ + tBTM_BLE_CS_CONFIG_CMPL_EVT config_cmpl = {0}; + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + STREAM_TO_UINT8(config_cmpl.status, p); + STREAM_TO_UINT16(config_cmpl.conn_handle, p); + STREAM_TO_UINT8(config_cmpl.config_id, p); + STREAM_TO_UINT8(config_cmpl.action, p);; + STREAM_TO_UINT8(config_cmpl.main_mode_type, p); + STREAM_TO_UINT8(config_cmpl.sub_mode_type, p); + STREAM_TO_UINT8(config_cmpl.min_main_mode_steps, p); + STREAM_TO_UINT8(config_cmpl.max_main_mode_steps, p); + STREAM_TO_UINT8(config_cmpl.main_mode_repetition, p); + STREAM_TO_UINT8(config_cmpl.mode_0_steps, p); + STREAM_TO_UINT8(config_cmpl.role, p); + STREAM_TO_UINT8(config_cmpl.rtt_type, p); + STREAM_TO_UINT8(config_cmpl.cs_sync_phy, p); + STREAM_TO_ARRAY(config_cmpl.channel_map, p, 10); + STREAM_TO_UINT8(config_cmpl.channel_map_repetition, p); + STREAM_TO_UINT8(config_cmpl.channel_selection_type, p); + STREAM_TO_UINT8(config_cmpl.ch3c_shape, p); + STREAM_TO_UINT8(config_cmpl.ch3c_jump, p); + STREAM_TO_UINT8(config_cmpl.reserved, p); + STREAM_TO_UINT8(config_cmpl.t_ip1_time, p); + STREAM_TO_UINT8(config_cmpl.t_ip2_time, p); + STREAM_TO_UINT8(config_cmpl.t_fcs_time, p); + STREAM_TO_UINT8(config_cmpl.t_pm_time, p); + + btm_ble_cs_config_cmpl_evt(&config_cmpl); +} + +static void btu_ble_cs_proc_enable_cmpl_evt(UINT8 *p) +{ + tBTM_BLE_CS_PROC_ENABLE_CMPL_EVT proc_en = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(proc_en.status, p); + STREAM_TO_UINT16(proc_en.conn_handle, p); + STREAM_TO_UINT8(proc_en.config_id, p); + STREAM_TO_UINT8(proc_en.state, p); + STREAM_TO_UINT8(proc_en.tone_Ant_config_select, p); + STREAM_TO_UINT8(proc_en.select_tx_power, p); + STREAM_TO_UINT24(proc_en.subevent_Len, p); + STREAM_TO_UINT8(proc_en.subevents_per_event, p); + STREAM_TO_UINT16(proc_en.subevent_interval, p); + STREAM_TO_UINT16(proc_en.event_interval, p); + STREAM_TO_UINT16(proc_en.procedure_interval, p); + STREAM_TO_UINT16(proc_en.procedure_count, p); + STREAM_TO_UINT16(proc_en.max_procedure_len, p); + + btm_ble_cs_proc_enable_cmpl_evt(&proc_en); +} + +static void btu_ble_cs_subevt_result_evt(UINT8 *p) +{ + tBTM_BLE_CS_SUBEVT_RESULT_CMPL_EVT subevt_result = {0}; + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + STREAM_TO_UINT16(subevt_result.conn_handle, p); + STREAM_TO_UINT8(subevt_result.config_id, p); + STREAM_TO_UINT16(subevt_result.start_acl_conn_event_counter, p); + STREAM_TO_UINT16(subevt_result.procedure_counter, p); + STREAM_TO_UINT16(subevt_result.frequency_compensation, p); + STREAM_TO_UINT8(subevt_result.reference_power_level, p); + STREAM_TO_UINT8(subevt_result.procedure_done_status, p); + STREAM_TO_UINT8(subevt_result.subevent_done_status, p); + STREAM_TO_UINT8(subevt_result.abort_reason, p); + STREAM_TO_UINT8(subevt_result.num_ant_paths, p); + STREAM_TO_UINT8(subevt_result.num_steps_reported, p); + + subevt_result.step_info = osi_malloc(subevt_result.num_steps_reported * sizeof(tBTM_BLE_CS_STEP_INFO)); + if (subevt_result.step_info) { + for (uint8_t i = 0; i < subevt_result.num_steps_reported; i++) + { + STREAM_TO_UINT8(subevt_result.step_info[i].step_mode, p); + STREAM_TO_UINT8(subevt_result.step_info[i].step_channel, p); + STREAM_TO_UINT8(subevt_result.step_info[i].step_data_len, p); + subevt_result.step_info[i].data = osi_malloc(subevt_result.step_info[i].step_data_len); + if (subevt_result.step_info[i].data) { + STREAM_TO_ARRAY(subevt_result.step_info[i].data, p, subevt_result.step_info[i].step_data_len); + } else if (subevt_result.step_info[i].step_data_len) { + HCI_TRACE_ERROR("%s, no memory.", __func__); + } + } + } + + btm_ble_cs_subevt_result_evt(&subevt_result); + + if (subevt_result.step_info) + { + for (UINT8 i = 0; i < subevt_result.num_steps_reported; i++) + { + if (subevt_result.step_info[i].data) { + osi_free(subevt_result.step_info[i].data); + } + } + osi_free(subevt_result.step_info); + } + +} + +static void btu_ble_cs_subevt_result_continue_evt(UINT8 *p) +{ + tBTM_BLE_CS_SUBEVT_RESULT_CONTINUE_EVT subevt_continue_result = {0}; + + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT16(subevt_continue_result.conn_handle, p); + STREAM_TO_UINT8(subevt_continue_result.config_id, p); + STREAM_TO_UINT8(subevt_continue_result.proc_done_status, p); + STREAM_TO_UINT8(subevt_continue_result.subevt_done_status, p); + STREAM_TO_UINT8(subevt_continue_result.abort_reason, p); + STREAM_TO_UINT8(subevt_continue_result.num_ant_paths, p); + STREAM_TO_UINT8(subevt_continue_result.num_steps_reported, p); + + subevt_continue_result.step_info = osi_malloc(subevt_continue_result.num_steps_reported * sizeof(tBTM_BLE_CS_STEP_INFO)); + if (subevt_continue_result.step_info) { + for (uint8_t i = 0; i < subevt_continue_result.num_steps_reported; i++) { + STREAM_TO_UINT8(subevt_continue_result.step_info[i].step_mode, p); + STREAM_TO_UINT8(subevt_continue_result.step_info[i].step_channel, p); + STREAM_TO_UINT8(subevt_continue_result.step_info[i].step_data_len, p); + subevt_continue_result.step_info[i].data = osi_malloc(subevt_continue_result.step_info[i].step_data_len); + if (subevt_continue_result.step_info[i].data) { + STREAM_TO_ARRAY(subevt_continue_result.step_info[i].data, p, subevt_continue_result.step_info[i].step_data_len); + } else if (subevt_continue_result.step_info[i].step_data_len) { + HCI_TRACE_ERROR("%s, no memory.", __func__); + } + } + } + + btm_ble_cs_subevt_continue_result_evt(&subevt_continue_result); + + if (subevt_continue_result.step_info) + { + for (UINT8 i = 0; i < subevt_continue_result.num_steps_reported; i++) + { + if (subevt_continue_result.step_info[i].data) { + osi_free(subevt_continue_result.step_info[i].data); + } + } + osi_free(subevt_continue_result.step_info); + } + +} +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + /********************************************** ** End of BLE Events Handler ***********************************************/ diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 81214a9bc4..af75e6ac5a 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -3074,3 +3074,324 @@ UINT8 btsnd_hcic_ble_set_periodic_sync_subevt(UINT16 sync_handle, UINT16 periodi return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); } #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) + +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +UINT8 btsnd_hcic_ble_cs_read_local_supported_caps(void) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("cs read local supported caps"); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_READ_LOCAL_SUPP_CAPS_PARAMS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CS_READ_LOCAL_SUPP_CAPS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_LOCAL_SUPP_CAPS_PARAMS_LEN); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return (TRUE); +} + +UINT8 btsnd_hcic_ble_cs_read_remote_supported_capabilities(UINT16 conn_handle) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_ERROR("cs read remote supported caps, conn_handle %d", conn_handle); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_READ_REMOTE_SUPP_CAPS_PARAMS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CS_READ_REMOTE_SUPP_CAPS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_REMOTE_SUPP_CAPS_PARAMS_LEN); + UINT16_TO_STREAM(pp, conn_handle); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return (TRUE); +} + +UINT8 btsnd_hcic_ble_cs_write_cached_remote_supported_capabilities(UINT16 conn_handle, UINT8 num_config_supported, UINT16 max_consecutive_proc_supported, + UINT8 num_ant_supported, UINT8 max_ant_paths_supported, UINT8 roles_supported, + UINT8 modes_supported, UINT8 rtt_capability, UINT8 rtt_aa_only_n, + UINT8 rtt_sounding_n, UINT8 rtt_random_payload_n, UINT16 NADM_sounding_capability, + UINT16 NADM_random_capability, UINT8 cs_sync_phys_supported, UINT16 subfeatures_supported, + UINT16 T_IP1_times_supported, UINT16 T_IP2_times_supported, UINT16 T_FCS_times_supported, + UINT16 T_PM_times_supported, UINT8 T_SW_times_supported, UINT8 TX_SNR_capability) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("cs write cached remote supported caps"); + HCI_TRACE_DEBUG("conn_handle %d num_config_supported %d max_consecutive_proc_supported %d, num_ant_supported %d max_ant_paths_supported %d roles_supported %d,\ + modes_supported %d, rtt_capability %d, rtt_aa_only_n %d, rtt_sounding_n %d, rtt_random_payload_n %d, NADM_sounding_capability %d, NADM_random_capability %d\ + ,cs_sync_phys_supported %d, subfeatures_supported %d, T_IP1_times_supported %d, T_IP2_times_supported %d, T_FCS_times_supported %d, T_PM_times_supported %d\ + ,T_SW_times_supported %d, TX_SNR_capability %d", + conn_handle, num_config_supported, max_consecutive_proc_supported, num_ant_supported, max_ant_paths_supported, roles_supported, + modes_supported, rtt_capability, rtt_aa_only_n, rtt_sounding_n, rtt_random_payload_n, NADM_sounding_capability, + NADM_random_capability, cs_sync_phys_supported, subfeatures_supported, T_IP1_times_supported, T_IP2_times_supported, T_FCS_times_supported, + T_PM_times_supported, T_SW_times_supported, TX_SNR_capability); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_WRITE_CACHE_REMOTE_SUPP_CAPS_PARAMS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CS_WRITE_CACHED_REMOTE_SUPP_CAPS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_CACHE_REMOTE_SUPP_CAPS_PARAMS_LEN); + UINT16_TO_STREAM(pp, conn_handle); + UINT8_TO_STREAM(pp, num_config_supported); + UINT16_TO_STREAM(pp, max_consecutive_proc_supported); + UINT8_TO_STREAM(pp, num_ant_supported); + UINT8_TO_STREAM(pp, max_ant_paths_supported); + UINT8_TO_STREAM(pp, roles_supported); + UINT8_TO_STREAM(pp, modes_supported); + UINT8_TO_STREAM(pp, rtt_capability); + UINT8_TO_STREAM(pp, rtt_aa_only_n); + UINT8_TO_STREAM(pp, rtt_sounding_n); + UINT8_TO_STREAM(pp, rtt_random_payload_n); + UINT16_TO_STREAM(pp, NADM_sounding_capability); + UINT16_TO_STREAM(pp, NADM_random_capability); + UINT8_TO_STREAM(pp, cs_sync_phys_supported); + UINT16_TO_STREAM(pp, subfeatures_supported); + UINT16_TO_STREAM(pp, T_IP1_times_supported); + UINT16_TO_STREAM(pp, T_IP2_times_supported); + UINT16_TO_STREAM(pp, T_FCS_times_supported); + UINT16_TO_STREAM(pp, T_PM_times_supported); + UINT8_TO_STREAM(pp, T_SW_times_supported); + UINT8_TO_STREAM(pp, TX_SNR_capability); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); + +} + +UINT8 btsnd_hcic_ble_cs_security_enable(UINT16 conn_handle) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("cs security enable conn_handle %d", conn_handle); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SECURITY_ENABLE_PARAMS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CS_SECURITY_ENABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SECURITY_ENABLE_PARAMS_LEN); + UINT16_TO_STREAM(pp, conn_handle); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return (TRUE); +} + +UINT8 btsnd_hcic_ble_cs_set_default_settings(UINT16 conn_handle, UINT8 role_enable, UINT8 cs_sync_ant_selection, INT8 max_tx_power) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("cs set default settings, conn_handle %d role_enable %d cs_sync_ant_selection %d max_tx_power %d", conn_handle, role_enable, cs_sync_ant_selection, max_tx_power); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_DEFAULT_SETTINGS_PARAMS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CS_SET_DEFAULT_SETTINGS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_DEFAULT_SETTINGS_PARAMS_LEN); + UINT16_TO_STREAM(pp, conn_handle); + UINT8_TO_STREAM(pp, role_enable); + UINT8_TO_STREAM(pp, cs_sync_ant_selection); + INT8_TO_STREAM(pp, max_tx_power); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_cs_read_remote_fae_table(UINT16 conn_handle) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("cs read remote fae table, conn_handle %d", conn_handle); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_READ_REMOTE_FAE_TAB_PARAMS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CS_READ_REMOTE_FAE_TABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_REMOTE_FAE_TAB_PARAMS_LEN); + UINT16_TO_STREAM(pp, conn_handle); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return (TRUE); +} + +UINT8 btsnd_hcic_ble_cs_write_cached_remote_fae_table(UINT16 conn_handle, UINT8 *remote_fae_table) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("cs write cached remote fae table, conn_handle %d", conn_handle); + esp_log_buffer_hex_internal("remote_fae_table", remote_fae_table, 72, ESP_LOG_DEBUG); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_WRITE_CACHED_REMOTE_FAE_TAB_PARAMS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CS_WRITE_CACHED_REMOTE_FAE_TABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_CACHED_REMOTE_FAE_TAB_PARAMS_LEN); + UINT16_TO_STREAM(pp, conn_handle); + ARRAY_TO_STREAM(pp, remote_fae_table, 72); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_cs_create_config(UINT16 conn_handle, UINT8 config_id, UINT8 create_context, + UINT8 main_mode_type, UINT8 sub_mode_type, UINT8 min_main_mode_steps, + UINT8 max_main_mode_steps, UINT8 main_mode_repetition, UINT8 mode_0_steps, + UINT8 role, UINT8 rtt_type, UINT8 cs_sync_phy, UINT8 *channel_map, + UINT8 channel_map_repetition, UINT8 channel_selection_type, UINT8 ch3c_shape, + UINT8 ch3c_jump,UINT8 reserved) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("cs create config"); + HCI_TRACE_DEBUG("conn_handle %d config_id %d create_context %d main_mode_type %d sub_mode_type %d min_main_mode_steps %d max_main_mode_steps\ + %d main_mode_repetition %d mode_0_steps %d role %d rtt_type %d cs_sync_phy %d, channel_map_repetition %d, channel_selection_type %d\ + ch3c_shape %d ch3c_jump %d,reserved %d", conn_handle, config_id, create_context, main_mode_type, sub_mode_type, min_main_mode_steps, max_main_mode_steps,\ + main_mode_repetition, mode_0_steps, role, rtt_type, cs_sync_phy, channel_map_repetition, channel_selection_type\ + ,ch3c_shape, ch3c_jump, reserved); + esp_log_buffer_hex_internal("channel_map", channel_map, 10, ESP_LOG_DEBUG); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_CREATE_CONFIG_PARAMS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CS_CREATE_CONFIG); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CREATE_CONFIG_PARAMS_LEN); + UINT16_TO_STREAM(pp, conn_handle); + UINT8_TO_STREAM(pp, config_id); + UINT8_TO_STREAM(pp, create_context); + UINT8_TO_STREAM(pp, main_mode_type); + UINT8_TO_STREAM(pp, sub_mode_type); + UINT8_TO_STREAM(pp, min_main_mode_steps); + UINT8_TO_STREAM(pp, max_main_mode_steps); + UINT8_TO_STREAM(pp, main_mode_repetition); + UINT8_TO_STREAM(pp, mode_0_steps); + UINT8_TO_STREAM(pp, role); + UINT8_TO_STREAM(pp, rtt_type); + UINT8_TO_STREAM(pp, cs_sync_phy); + ARRAY_TO_STREAM(pp, channel_map, 10); + UINT8_TO_STREAM(pp, channel_map_repetition); + UINT8_TO_STREAM(pp, channel_selection_type); + UINT8_TO_STREAM(pp, ch3c_shape); + UINT8_TO_STREAM(pp, ch3c_jump); + UINT8_TO_STREAM(pp, reserved); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return (TRUE); +} + +UINT8 btsnd_hcic_ble_cs_remove_config(UINT16 conn_handle, UINT8 config_id) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_ERROR("cs remove config, conn_handle %d config_id %d", conn_handle, config_id); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_REMOVE_CONFIG_PARAMS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CS_REMOVE_CONFIG); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_REMOVE_CONFIG_PARAMS_LEN); + UINT16_TO_STREAM(pp, conn_handle); + UINT8_TO_STREAM(pp, config_id); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + + return TRUE; +} + +UINT8 btsnd_hcic_ble_cs_set_channel_classification(UINT8 *channel_class) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("cs set channel class"); + esp_log_buffer_hex_internal("channel", channel_class, 10, ESP_LOG_DEBUG); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_CHANNEL_CLASS_PARAMS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CS_SET_CAHNNEL_CLASS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CHANNEL_CLASS_PARAMS_LEN); + ARRAY_TO_STREAM(pp, channel_class, 10); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_cs_set_procedure_params(UINT16 conn_handle, UINT8 config_id, UINT16 max_procedure_len, + UINT16 min_procedure_interval, UINT16 max_procedure_interval, + UINT16 max_procedure_count, UINT32 min_subevent_len, + UINT32 max_subevent_len, UINT8 tone_ant_config_selection, + UINT8 phy, UINT8 tx_power_delta, UINT8 preferred_peer_antenna, + UINT8 SNR_control_initiator, UINT8 SNR_control_reflector) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("cs set procedure params"); + HCI_TRACE_DEBUG("conn_handle %d config_id %d max_procedure_len %d min_procedure_interval %d max_procedure_interval %d\ + max_procedure_count %d min_subevent_len %d max_subevent_len %d tone_ant_config_selection %d phy %d tx_power_delta %d,\ + preferred_peer_antenna %d SNR_control_initiator %d SNR_control_reflector %d\n", + conn_handle, config_id, max_procedure_len, min_procedure_interval, max_procedure_interval, max_procedure_count, min_subevent_len, max_subevent_len, + tone_ant_config_selection, phy, tx_power_delta, preferred_peer_antenna, SNR_control_initiator, SNR_control_reflector); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_PROCEDURE_PARAMS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CS_SET_PROCEDURE_PARAMS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_PROCEDURE_PARAMS_LEN); + UINT16_TO_STREAM(pp, conn_handle); + UINT8_TO_STREAM(pp, config_id); + UINT16_TO_STREAM(pp, max_procedure_len); + UINT16_TO_STREAM(pp, min_procedure_interval); + UINT16_TO_STREAM(pp, max_procedure_interval); + UINT16_TO_STREAM(pp, max_procedure_count); + UINT24_TO_STREAM(pp, min_subevent_len); + UINT24_TO_STREAM(pp, max_subevent_len); + UINT8_TO_STREAM(pp, tone_ant_config_selection); + UINT8_TO_STREAM(pp, phy); + UINT8_TO_STREAM(pp, tx_power_delta); + UINT8_TO_STREAM(pp, preferred_peer_antenna); + UINT8_TO_STREAM(pp, SNR_control_initiator); + UINT8_TO_STREAM(pp, SNR_control_reflector); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_cs_procedure_enable(UINT16 conn_handle, UINT8 config_id, UINT8 enable) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("cs set procedure enable, conn_handle %d config_id %d enable %d", conn_handle, config_id, enable); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_PROCEDURE_ENABLE_PARAMS_LEN); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_CS_SET_PROCEDURE_ENABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_PROCEDURE_ENABLE_PARAMS_LEN); + UINT16_TO_STREAM(pp, conn_handle); + UINT8_TO_STREAM(pp, config_id); + UINT8_TO_STREAM(pp, enable); + + btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); + + return TRUE; +} +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) 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 8c0460c457..22de09f434 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 @@ -1108,7 +1108,22 @@ typedef void (tBTM_SET_VENDOR_EVT_MASK_CBACK) (tBTM_STATUS status); #define BTM_BLE_GAP_PERIODIC_ADV_SUBEVT_DATA_REQUEST_EVT 55 #define BTM_BLE_GAP_PERIODIC_ADV_RESPONSE_REPORT_EVT 56 #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) -#define BTM_BLE_5_GAP_UNKNOWN_EVT 57 +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#define BTM_BLE_GAP_CS_READ_LOCAL_SUPP_CAPS_EVT 57 +#define BTM_BLE_GAP_CS_WRITE_CACHED_REMOTE_SUPP_CAPS_EVT 58 +#define BTM_BLE_GAP_CS_SET_DEFAULT_SETTINGS_EVT 59 +#define BTM_BLE_GAP_CS_WRITE_CACHED_REMOTE_FAE_TAB_EVT 60 +#define BTM_BLE_GAP_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT 61 +#define BTM_BLE_GAP_CS_SET_CHANNEL_CLASS_CMPL_EVT 62 +#define BTM_BLE_GAP_CS_PROC_PARAMS_CMPL_EVT 63 +#define BTM_BLE_GAP_CS_PROC_ENABLE_CMPL_EVT 64 +#define BTM_BLE_GAP_CS_READ_REMOTE_FAE_TABLE_CMPL_EVT 65 +#define BTM_BLE_GAP_CS_SECURITY_ENABLE_CMPL_EVT 66 +#define BTM_BLE_GAP_CS_CONFIG_CMPL_EVT 67 +#define BTM_BLE_GAP_CS_SUBEVENT_RESULT_EVT 68 +#define BTM_BLE_GAP_CS_SUBEVENT_RESULT_CONTINUE_EVT 69 +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#define BTM_BLE_5_GAP_UNKNOWN_EVT 70 typedef UINT8 tBTM_BLE_5_GAP_EVENT; #if (BLE_FEAT_ISO_EN == TRUE) @@ -1519,6 +1534,161 @@ typedef struct { } __attribute__((packed)) tBTM_BLE_PA_RSP_REPORT_EVT; #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_CS_WRITE_CACHED_SUPPORT_CAPS_EVT; +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_CS_SET_DEFAULT_SETTINGS_EVT; +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_CS_WRITE_CACHED_REMOTE_FAE_TAB_EVT; +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_CS_SET_PAROC_PARAMS_EVT; +typedef struct { + UINT8 status; + UINT16 conn_handle; + UINT8 num_config_supported; + UINT16 max_consecutive_proc_supported; + UINT8 num_ant_supported; + UINT8 max_ant_paths_supported; + UINT8 roles_supported; + UINT8 modes_supported; + UINT8 rtt_capability; + UINT8 rtt_aa_only_n; + UINT8 rtt_sounding_n; + UINT8 rtt_random_payload_n; + UINT16 NADM_sounding_capability; + UINT16 NADM_random_capability; + UINT8 cs_sync_phys_supported; + UINT16 subfeatures_supported; + UINT16 T_IP1_times_supported; + UINT16 T_IP2_times_supported; + UINT16 T_FCS_times_supported; + UINT16 T_PM_times_supported; + UINT8 T_SW_times_supported; + UINT8 TX_SNR_capability; +} __attribute__((packed)) tBTM_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT; + +typedef struct { + UINT8 status; + UINT16 conn_handle; + UINT8 remote_fae_table[72]; +} __attribute__((packed)) tBTM_BLE_CS_READ_REMOTE_FAE_TAB_CMPL_EVT; + +typedef struct { + UINT8 status; + UINT16 conn_handle; +} __attribute__((packed)) tBTM_BLE_CS_SEC_ENABLE_CMPL_EVT; + +typedef struct { + UINT8 status; + UINT16 conn_handle; + UINT8 config_id; + UINT8 action; + UINT8 main_mode_type; + UINT8 sub_mode_type; + UINT8 min_main_mode_steps; + UINT8 max_main_mode_steps; + UINT8 main_mode_repetition; + UINT8 mode_0_steps; + UINT8 role; + UINT8 rtt_type; + UINT8 cs_sync_phy; + UINT8 channel_map[10]; + UINT8 channel_map_repetition; + UINT8 channel_selection_type; + UINT8 ch3c_shape; + UINT8 ch3c_jump; + UINT8 reserved; + UINT8 t_ip1_time; + UINT8 t_ip2_time; + UINT8 t_fcs_time; + UINT8 t_pm_time; +}__attribute__((packed)) tBTM_BLE_CS_CONFIG_CMPL_EVT; + +typedef struct { + UINT8 status; + UINT16 conn_handle; + UINT8 config_id; + UINT8 state; + UINT8 tone_Ant_config_select; + INT8 select_tx_power; + UINT32 subevent_Len; + UINT8 subevents_per_event; + UINT16 subevent_interval; + UINT16 event_interval; + UINT16 procedure_interval; + UINT16 procedure_count; + UINT16 max_procedure_len; +}__attribute__((packed)) tBTM_BLE_CS_PROC_ENABLE_CMPL_EVT; + +typedef struct { + UINT8 step_mode; + UINT8 step_channel; + UINT8 step_data_len; + UINT8 *data; +} __attribute__((packed)) tBTM_BLE_CS_STEP_INFO; + +typedef struct { + UINT16 conn_handle; + UINT8 config_id; + UINT16 start_acl_conn_event_counter; + UINT16 procedure_counter; + INT16 frequency_compensation; + INT8 reference_power_level; + UINT8 procedure_done_status; + UINT8 subevent_done_status; + UINT8 abort_reason; + UINT8 num_ant_paths; + UINT8 num_steps_reported; + tBTM_BLE_CS_STEP_INFO *step_info; +}__attribute__((packed)) tBTM_BLE_CS_SUBEVT_RESULT_CMPL_EVT; + +typedef struct { + UINT16 conn_handle; + UINT8 config_id; + UINT8 proc_done_status; + UINT8 subevt_done_status; + UINT8 abort_reason; + UINT8 num_ant_paths; + UINT8 num_steps_reported; + tBTM_BLE_CS_STEP_INFO *step_info; +}__attribute__((packed)) tBTM_BLE_CS_SUBEVT_RESULT_CONTINUE_EVT; + +typedef struct { + UINT8 status; + UINT16 conn_handle; + UINT8 num_config_supported; + UINT16 max_consecutive_proc_supported; + UINT8 num_ant_supported; + UINT8 max_ant_paths_supported; + UINT8 roles_supported; + UINT8 modes_supported; + UINT8 rtt_capability; + UINT8 rtt_aa_only_n; + UINT8 rtt_sounding_n; + UINT8 rtt_random_payload_n; + UINT16 NADM_sounding_capability; + UINT16 NADM_random_capability; + UINT8 cs_sync_phys_supported; + UINT16 subfeatures_supported; + UINT16 T_IP1_times_supported; + UINT16 T_IP2_times_supported; + UINT16 T_FCS_times_supported; + UINT16 T_PM_times_supported; + UINT8 T_SW_times_supported; + UINT8 TX_SNR_capability; +} __attribute__((packed)) tBTM_BLE_CS_READ_LOCAL_SUPP_CAPS_CMPL_EVT; + +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) typedef struct { @@ -1892,6 +2062,20 @@ typedef union { tBTM_BLE_PA_SUBEVT_DATA_REQ_EVT pa_subevent_data_req_evt; tBTM_BLE_PA_RSP_REPORT_EVT pa_rsp_rpt_evt; #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + tBTM_BLE_CS_WRITE_CACHED_SUPPORT_CAPS_EVT cs_write_cached_remote_supp_caps; + tBTM_BLE_CS_SET_DEFAULT_SETTINGS_EVT cs_set_default_settings; + tBTM_BLE_CS_WRITE_CACHED_REMOTE_FAE_TAB_EVT cs_write_cached_remote_fae_tab; + tBTM_BLE_CS_SET_PAROC_PARAMS_EVT cs_set_proc_params; + tBTM_BLE_CS_READ_LOCAL_SUPP_CAPS_CMPL_EVT cs_read_local_supp_caps; + tBTM_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT cs_read_remote_supp_caps; + tBTM_BLE_CS_READ_REMOTE_FAE_TAB_CMPL_EVT cs_read_remote_fae_tab; + tBTM_BLE_CS_SEC_ENABLE_CMPL_EVT cs_security_enable; + tBTM_BLE_CS_PROC_ENABLE_CMPL_EVT cs_proc_en; + tBTM_BLE_CS_CONFIG_CMPL_EVT cs_config_update; + tBTM_BLE_CS_SUBEVT_RESULT_CMPL_EVT cs_subevt_result; + tBTM_BLE_CS_SUBEVT_RESULT_CONTINUE_EVT cs_subevt_result_continue; +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) } tBTM_BLE_5_GAP_CB_PARAMS; typedef struct { @@ -3455,4 +3639,35 @@ void BTM_BleSetPaResponseData(UINT16 sync_handle, UINT16 req_evt, UINT8 req_sube void BTM_BleSetPaSyncSubevt(UINT16 sync_handle, UINT16 periodic_adv_properties, UINT8 num_subevents_to_sync, UINT8 *subevt); #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +void BTM_BleCSReadLocalSuppCaps(void); +void BTM_BleCSReadRemoteSuppCaps(UINT16 conn_handle); +void BTM_BleGapWriteCachedRemoteSupportedCaps(UINT16 conn_handle, UINT8 num_config_supported, UINT16 max_consecutive_proc_supported, + UINT8 num_ant_supported, UINT8 max_ant_paths_supported, UINT8 roles_supported, + UINT8 modes_supported, UINT8 rtt_capability, UINT8 rtt_aa_only_n, + UINT8 rtt_sounding_n, UINT8 rtt_random_payload_n, UINT16 NADM_sounding_capability, + UINT16 NADM_random_capability, UINT8 cs_sync_phys_supported, UINT16 subfeatures_supported, + UINT16 T_IP1_times_supported, UINT16 T_IP2_times_supported, UINT16 T_FCS_times_supported, + UINT16 T_PM_times_supported, UINT8 T_SW_times_supported, UINT8 TX_SNR_capability); +void BTM_BleGapCsSecurityEnable(UINT16 conn_handle); +void BTM_BleGapCsSetDefaultSetting(UINT16 conn_handle, UINT8 role_enable, UINT8 cs_sync_ant_selection, INT8 max_tx_power); +void BTM_BleGapCsReadRemoteFaeTable(UINT16 conn_handle); +void BTM_BleGapWriteCachedRemoteFaeTable(UINT16 conn_handle, UINT8 *remote_fae_table); +void BTM_BleGapCsCreateConfig(UINT16 conn_handle, UINT8 config_id, UINT8 create_context, + UINT8 main_mode_type, UINT8 sub_mode_type, UINT8 min_main_mode_steps, + UINT8 max_main_mode_steps, UINT8 main_mode_repetition, UINT8 mode_0_steps, + UINT8 role, UINT8 rtt_type, UINT8 cs_sync_phy, UINT8 *channel_map, + UINT8 channel_map_repetition, UINT8 channel_selection_type, UINT8 ch3c_shape, + UINT8 ch3c_jump,UINT8 reserved); +void BTM_BleGapCsRemoveConfig(UINT16 conn_handle, UINT8 config_id); +void BTM_BleGapCsSetChannelClass(UINT8 *channel_class); +void BTM_BleGapCsSetProcPatams(UINT16 conn_handle, UINT8 config_id, UINT16 max_procedure_len, + UINT16 min_procedure_interval, UINT16 max_procedure_interval, + UINT16 max_procedure_count, UINT32 min_subevent_len, + UINT32 max_subevent_len, UINT8 tone_ant_config_selection, + UINT8 phy, UINT8 tx_power_delta, UINT8 preferred_peer_antenna, + UINT8 SNR_control_initiator, UINT8 SNR_control_reflector); +void BTM_BleGapCsProcEnable(UINT16 conn_handle, UINT8 config_id, UINT8 enable); +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + #endif diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index 8621b67458..9365de9d54 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -455,6 +455,21 @@ #define HCI_BLE_SET_PERIOD_ADV_PARAMS_V2 (0x0086 | HCI_GRP_BLE_CMDS) #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#define HCI_BLE_CS_READ_LOCAL_SUPP_CAPS (0x0089 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_CS_READ_REMOTE_SUPP_CAPS (0x008A | HCI_GRP_BLE_CMDS) +#define HCI_BLE_CS_WRITE_CACHED_REMOTE_SUPP_CAPS (0x008B | HCI_GRP_BLE_CMDS) +#define HCI_BLE_CS_SECURITY_ENABLE (0x008C | HCI_GRP_BLE_CMDS) +#define HCI_BLE_CS_SET_DEFAULT_SETTINGS (0x008D | HCI_GRP_BLE_CMDS) +#define HCI_BLE_CS_READ_REMOTE_FAE_TABLE (0x008E | HCI_GRP_BLE_CMDS) +#define HCI_BLE_CS_WRITE_CACHED_REMOTE_FAE_TABLE (0x008F | HCI_GRP_BLE_CMDS) +#define HCI_BLE_CS_CREATE_CONFIG (0x0090 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_CS_REMOVE_CONFIG (0x0091 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_CS_SET_CAHNNEL_CLASS (0x0092 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_CS_SET_PROCEDURE_PARAMS (0x0093 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_CS_SET_PROCEDURE_ENABLE (0x0094 | HCI_GRP_BLE_CMDS) +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + // Vendor OGF define #define HCI_VENDOR_OGF 0x3F @@ -938,6 +953,16 @@ #define HCI_BLE_PA_RESPONSE_REPORT_EVT 0x28 #endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#define HCI_BLE_CS_READ_REMOTE_SUPP_CAPS_CMPL_EVT 0x2C +#define HCI_BLE_CS_READ_REMOTE_FAE_TAB_CMPL_EVT 0x2D +#define HCI_BLE_CS_SECURITY_ENABLE_CMPL_EVT 0x2E +#define HCI_BLE_CS_CONFIG_CMPL_EVT 0x2F +#define HCI_BLE_CS_PROC_ENABLE_CMPL_EVT 0x30 +#define HCI_BLE_CS_SUBEVENT_RESULT_EVT 0x31 +#define HCI_BLE_CS_SUBEVENT_RESULT_CONTINUE_EVT 0x32 +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + /* Definitions for LE Channel Map */ #define HCI_BLE_CHNL_MAP_SIZE 5 diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index d0f8e20529..c4da454d0f 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -1284,4 +1284,49 @@ UINT8 btsnd_hcic_ble_set_ext_adv_params_v2(UINT8 adv_handle, UINT16 properties, UINT8 primary_adv_phy_options, UINT8 secondary_adv_phy_options); #endif // (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE) +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#define HCIC_PARAM_SIZE_READ_LOCAL_SUPP_CAPS_PARAMS_LEN 0 +#define HCIC_PARAM_SIZE_READ_REMOTE_SUPP_CAPS_PARAMS_LEN 2 +#define HCIC_PARAM_SIZE_WRITE_CACHE_REMOTE_SUPP_CAPS_PARAMS_LEN 30 +#define HCIC_PARAM_SIZE_SECURITY_ENABLE_PARAMS_LEN 2 +#define HCIC_PARAM_SIZE_SET_DEFAULT_SETTINGS_PARAMS_LEN 5 +#define HCIC_PARAM_SIZE_READ_REMOTE_FAE_TAB_PARAMS_LEN 2 +#define HCIC_PARAM_SIZE_WRITE_CACHED_REMOTE_FAE_TAB_PARAMS_LEN 74 +#define HCIC_PARAM_SIZE_CREATE_CONFIG_PARAMS_LEN 28 +#define HCIC_PARAM_SIZE_REMOVE_CONFIG_PARAMS_LEN 3 +#define HCIC_PARAM_SIZE_SET_CHANNEL_CLASS_PARAMS_LEN 10 +#define HCIC_PARAM_SIZE_SET_PROCEDURE_PARAMS_LEN 21 +#define HCIC_PARAM_SIZE_SET_PROCEDURE_ENABLE_PARAMS_LEN 4 + +UINT8 btsnd_hcic_ble_cs_read_local_supported_caps(void); +UINT8 btsnd_hcic_ble_cs_read_remote_supported_capabilities(UINT16 conn_handle); +UINT8 btsnd_hcic_ble_cs_write_cached_remote_supported_capabilities(UINT16 conn_handle, UINT8 num_config_supported, UINT16 max_consecutive_proc_supported, + UINT8 num_ant_supported, UINT8 max_ant_paths_supported, UINT8 roles_supported, + UINT8 modes_supported, UINT8 rtt_capability, UINT8 rtt_aa_only_n, + UINT8 rtt_sounding_n, UINT8 rtt_random_payload_n, UINT16 NADM_sounding_capability, + UINT16 NADM_random_capability, UINT8 cs_sync_phys_supported, UINT16 subfeatures_supported, + UINT16 T_IP1_times_supported, UINT16 T_IP2_times_supported, UINT16 T_FCS_times_supported, + UINT16 T_PM_times_supported, UINT8 T_SW_times_supported, UINT8 TX_SNR_capability); + +UINT8 btsnd_hcic_ble_cs_security_enable(UINT16 conn_handle); +UINT8 btsnd_hcic_ble_cs_set_default_settings(UINT16 conn_handle, UINT8 role_enable, UINT8 cs_sync_ant_selection, INT8 max_tx_power); +UINT8 btsnd_hcic_ble_cs_read_remote_fae_table(UINT16 conn_handle); +UINT8 btsnd_hcic_ble_cs_write_cached_remote_fae_table(UINT16 conn_handle, UINT8 *remote_fae_table); +UINT8 btsnd_hcic_ble_cs_create_config(UINT16 conn_handle, UINT8 config_id, UINT8 create_context, + UINT8 main_mode_type, UINT8 sub_mode_type, UINT8 min_main_mode_steps, + UINT8 max_main_mode_steps, UINT8 main_mode_repetition, UINT8 mode_0_steps, + UINT8 role, UINT8 rtt_type, UINT8 cs_sync_phy, UINT8 *channel_map, + UINT8 channel_map_repetition, UINT8 channel_selection_type, UINT8 ch3c_shape, + UINT8 ch3c_jump,UINT8 reserved); +UINT8 btsnd_hcic_ble_cs_remove_config(UINT16 conn_handle, UINT8 config_id); +UINT8 btsnd_hcic_ble_cs_set_channel_classification(UINT8 *channel_class); +UINT8 btsnd_hcic_ble_cs_set_procedure_params(UINT16 conn_handle, UINT8 config_id, UINT16 max_procedure_len, + UINT16 min_procedure_interval, UINT16 max_procedure_interval, + UINT16 max_procedure_count, UINT32 min_subevent_len, + UINT32 max_subevent_len, UINT8 tone_ant_config_selection, + UINT8 phy, UINT8 tx_power_delta, UINT8 preferred_peer_antenna, + UINT8 SNR_control_initiator, UINT8 SNR_control_reflector); +UINT8 btsnd_hcic_ble_cs_procedure_enable(UINT16 conn_handle, UINT8 config_id, UINT8 enable); +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + #endif From 2c88b12e160809746d048ebf4845ae1af15e4336 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Wed, 20 Aug 2025 20:07:22 +0800 Subject: [PATCH 010/226] fix(ble/bluedroid): Fixed big event status error --- components/bt/host/bluedroid/stack/btu/btu_hcif.c | 1 + 1 file changed, 1 insertion(+) diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index e79b7be050..d7890ce71a 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -2900,6 +2900,7 @@ void btu_ble_create_big_cmd_status(UINT8 status) { if (status != HCI_SUCCESS) { tBTM_BLE_BIG_CREATE_CMPL big_cmpl = {0}; + big_cmpl.status = status; btm_ble_big_create_cmpl_evt(&big_cmpl); } } From c432820a5ebf77ce6691e65be65aa67cb87e76fa Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Tue, 9 Sep 2025 19:17:53 +0800 Subject: [PATCH 011/226] fix(ble/bluedroid): Optimize some bluedroid code --- .../bt/host/bluedroid/api/esp_gap_ble_api.c | 4 ++ .../api/include/api/esp_gap_ble_api.h | 61 ++++++++----------- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 21 ------- .../btc/profile/std/gap/btc_gap_ble.c | 2 +- .../bt/host/bluedroid/stack/btu/btu_hcif.c | 40 ++++++------ .../bluedroid/stack/gap/include/gap_int.h | 2 +- .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 4 +- .../stack/include/stack/btm_ble_api.h | 2 +- 8 files changed, 57 insertions(+), 79 deletions(-) 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 aa55a1399d..906e1280ba 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -2097,6 +2097,10 @@ esp_err_t esp_ble_gap_set_periodic_adv_subevent_data(esp_ble_per_adv_subevent_da return ESP_ERR_NOT_ALLOWED; } + if ((subevent_data_params->num_subevents_with_data > 0x0F) || (!subevent_data_params->num_subevents_with_data)) { + return ESP_ERR_NOT_ALLOWED; + } + for (uint8_t i = 0; i < subevent_data_params->num_subevents_with_data; i++) { if (subevent_data_params->subevent_params[i].subevent_data_len && (subevent_data_params->subevent_params[i].subevent_data == NULL)) { diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 02adac2041..102fdfd66b 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -963,18 +963,8 @@ typedef struct { uint8_t sid; /*!< ext adv sid */ bool scan_req_notif; /*!< ext adv scan request event notify */ #if (CONFIG_BT_BLE_FEAT_ADV_CODING_SELECTION) - esp_ble_gap_adv_phy_options_t primary_adv_phy_options; /*!< - 0x00: The Host has no preferred or required coding when transmitting on the LE Coded PHY - 0x01: The Host prefers that S=2 coding be used when transmitting on the LE Coded PHY - 0x02: The Host prefers that S=8 coding be used when transmitting on the LE Coded PHY - 0x03: The Host requires that S=2 coding be used when transmitting on the LE Coded PHY - 0x04: The Host requires that S=8 coding be used when transmitting on the LE Coded PHY */ - esp_ble_gap_adv_phy_options_t secondary_adv_phy_options; /*!< - 0x00: The Host has no preferred or required coding when transmitting on the LE Coded PHY - 0x01: The Host prefers that S=2 coding be used when transmitting on the LE Coded PHY - 0x02: The Host prefers that S=8 coding be used when transmitting on the LE Coded PHY - 0x03: The Host requires that S=2 coding be used when transmitting on the LE Coded PHY - 0x04: The Host requires that S=8 coding be used when transmitting on the LE Coded PHY */ + esp_ble_gap_adv_phy_options_t primary_adv_phy_options; /*!< The Host's preference or requirement concerning coding scheme */ + esp_ble_gap_adv_phy_options_t secondary_adv_phy_options; /*!< The Host's preference or requirement concerning coding scheme(including for periodic advertising) */ #endif // CONFIG_BT_BLE_FEAT_ADV_CODING_SELECTION } esp_ble_gap_ext_adv_params_t; @@ -1097,7 +1087,7 @@ typedef struct { Otherwise: Reserved for future use */ - esp_ble_gap_rpt_phy_t secondly_phy; /*!< extend advertising secondary phy + esp_ble_gap_rpt_phy_t secondary_phy; /*!< extend advertising secondary phy 0x00: No packets on the secondary advertising physical channel 0x01: Advertiser PHY is LE 1M 0x02: Advertiser PHY is LE 2M @@ -1405,6 +1395,9 @@ typedef uint8_t esp_ble_cs_rtt_caps_opt_t; /** CS_SYNC 2M 2BT phy supported */ #define ESP_BLE_CS_SYNC_PHYS_2M_2BT_SUPPORTED (1 << 2) +/**The length of Channel Sounding channel map */ +#define ESP_BLE_CS_CHAN_MAP_LEN 10 + /** * @brief CS write cached remote supported capabilities parameters */ @@ -1584,24 +1577,24 @@ typedef struct { 0x01: Reflector */ esp_ble_cs_rtt_type_opt_t rtt_type; /*!< 0x00: RTT AA-only - 0x01: RTT with 32-bit sounding sequence - 0x02: RTT with 96-bit sounding sequence - 0x03: RTT with 32-bit random sequence - 0x04: RTT with 64-bit random sequence - 0x05: RTT with 96-bit random sequence - 0x06: RTT with 128-bit random sequence + 0x01: RTT with 32-bit sounding sequence + 0x02: RTT with 96-bit sounding sequence + 0x03: RTT with 32-bit random sequence + 0x04: RTT with 64-bit random sequence + 0x05: RTT with 96-bit random sequence + 0x06: RTT with 128-bit random sequence */ esp_ble_cs_sync_phy_opt_t cs_sync_phy; /*!< 0x01: LE 1M PHY 0x02: LE 2M PHY 0x03: LE 2M 2BT PHY */ - uint8_t channel_map[10]; /*!< This parameter contains 80 1-bit fields. - The nth such field (in the range 0 to 78) contains the value for the CS channel index n. - Channel n is enabled for CS procedure = 1 - Channel n is disabled for CS procedure = 0 - Channels n = 0, 1, 23, 24, 25, 77, and 78 shall be ignored and shall be set to zero. At least 15 channels shall be enabled. - The most significant bit (bit 79) is reserved for future use - */ + uint8_t channel_map[ESP_BLE_CS_CHAN_MAP_LEN]; /*!< This parameter contains 80 1-bit fields. + The nth such field (in the range 0 to 78) contains the value for the CS channel index n. + Channel n is enabled for CS procedure = 1 + Channel n is disabled for CS procedure = 0 + Channels n = 0, 1, 23, 24, 25, 77, and 78 shall be ignored and shall be set to zero. At least 15 channels shall be enabled. + The most significant bit (bit 79) is reserved for future use + */ uint8_t channel_map_repetition; /*!< The number of times the map represented by the Channel_Map field is to be cycled through for non-mode-0 steps within a CS procedure. Range: 0x01 to 0xFF */ esp_ble_cs_channel_select_type_opt_t channel_selection_type;/*!< 0x00: Use Channel Selection Algorithm #3b for non-mode-0 CS steps 0x01: Use Channel Selection Algorithm #3c for non-mode-0 CS steps @@ -2642,13 +2635,13 @@ typedef union { 0x02: LE 2M PHY 0x03: LE 2M 2BT PHY */ - uint8_t channel_map[10]; /*!< This parameter contains 80 1-bit fields. - The nth such field (in the range 0 to 78) contains the value for the CS channel index n. - Channel n is enabled for CS procedure = 1 - Channel n is disabled for CS procedure = 0 - Channels n = 0, 1, 23, 24, 25, 77, and 78 shall be ignored and shall be set to zero. At least 15 channels shall be enabled. - The most significant bit (bit 79) is reserved for future use. - */ + uint8_t channel_map[ESP_BLE_CS_CHAN_MAP_LEN]; /*!< This parameter contains 80 1-bit fields. + The nth such field (in the range 0 to 78) contains the value for the CS channel index n. + Channel n is enabled for CS procedure = 1 + Channel n is disabled for CS procedure = 0 + Channels n = 0, 1, 23, 24, 25, 77, and 78 shall be ignored and shall be set to zero. At least 15 channels shall be enabled. + The most significant bit (bit 79) is reserved for future use. + */ uint8_t channel_map_repetition; /*!< The number of times the Channel_Map field will be cycled through for non-mode-0 steps within a CS procedure*/ uint8_t channel_selection_type; /*!< 0x00: Use Channel Selection Algorithm #3b for non-mode-0 CS steps 0x01: Use Channel Selection Algorithm #3c for non-mode-0 CS steps @@ -2689,7 +2682,7 @@ typedef union { uint8_t state; /*!< 0x00: CS procedures are disabled 0x01: CS procedures are enabled */ - uint8_t tone_Ant_config_select; /*!< Antenna Configuration Index. Range:0x00 to 0x07*/ + uint8_t tone_ant_config_select; /*!< Antenna Configuration Index. Range:0x00 to 0x07*/ int8_t select_tx_power; /*!< Transmit power level used for CS procedure. Range: -127 to 20. Units: dBm */ uint32_t subevent_Len; /*!< Duration for each CS subevent in microseconds. Range: 1250 μs to 4 s */ uint8_t subevents_per_event; /*!< Number of CS subevents anchored off the same ACL connection event. Range: 0x01 to 0x20 */ diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 7ffdabfa82..cd06eb4fd1 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -3269,27 +3269,6 @@ void BTA_DmBleGapWriteCachedRemoteSupportedCaps(tBTA_DM_CS_WRITE_CACHED_REMOTE_S if ((p_msg = (tBTA_DM_API_CS_WRITE_CACHED_REMOTE_SUPP_CAPS *)osi_malloc(sizeof(tBTA_DM_API_CS_WRITE_CACHED_REMOTE_SUPP_CAPS))) != NULL) { p_msg->hdr.event = BTA_DM_API_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPS; memcpy(&p_msg->conn_handle, &write_cachedremote_supp_caps->conn_handle, sizeof(tBTA_DM_CS_WRITE_CACHED_REMOTE_SUPP_CAPS)); - // p_msg->conn_handle = write_cachedremote_supp_caps->conn_handle; - // p_msg->num_config_supported = write_cachedremote_supp_caps->num_config_supported; - // p_msg->max_consecutive_proc_supported = write_cachedremote_supp_caps->max_consecutive_proc_supported; - // p_msg->num_ant_supported = write_cachedremote_supp_caps->num_ant_supported; - // p_msg->max_ant_paths_supported = write_cachedremote_supp_caps->max_ant_paths_supported; - // p_msg->roles_supported = write_cachedremote_supp_caps->roles_supported; - // p_msg->modes_supported = write_cachedremote_supp_caps->modes_supported; - // p_msg->rtt_capability = write_cachedremote_supp_caps->rtt_capability; - // p_msg->rtt_aa_only_n = write_cachedremote_supp_caps->rtt_aa_only_n; - // p_msg->rtt_sounding_n = write_cachedremote_supp_caps->rtt_sounding_n; - // p_msg->rtt_random_payload_n = write_cachedremote_supp_caps->rtt_random_payload_n; - // p_msg->NADM_sounding_capability = write_cachedremote_supp_caps->NADM_sounding_capability; - // p_msg->NADM_random_capability = write_cachedremote_supp_caps->NADM_random_capability; - // p_msg->cs_sync_phys_supported = write_cachedremote_supp_caps->cs_sync_phys_supported; - // p_msg->subfeatures_supported = write_cachedremote_supp_caps->subfeatures_supported; - // p_msg->T_IP1_times_supported = write_cachedremote_supp_caps->T_IP1_times_supported; - // p_msg->T_IP2_times_supported = write_cachedremote_supp_caps->T_IP2_times_supported; - // p_msg->T_FCS_times_supported = write_cachedremote_supp_caps->T_FCS_times_supported; - // p_msg->T_PM_times_supported = write_cachedremote_supp_caps->T_PM_times_supported; - // p_msg->T_SW_times_supported = write_cachedremote_supp_caps->T_SW_times_supported; - // p_msg->TX_SNR_capability = write_cachedremote_supp_caps->TX_SNR_capability; bta_sys_sendmsg(p_msg); } } 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 7a22f2fa5a..ff1f63cba8 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 @@ -1409,7 +1409,7 @@ void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, param.cs_proc_enable.conn_handle = params->cs_proc_en.conn_handle; param.cs_proc_enable.config_id = params->cs_proc_en.config_id; param.cs_proc_enable.state = params->cs_proc_en.state; - param.cs_proc_enable.tone_Ant_config_select = params->cs_proc_en.tone_Ant_config_select; + param.cs_proc_enable.tone_ant_config_select = params->cs_proc_en.tone_ant_config_select; param.cs_proc_enable.select_tx_power = params->cs_proc_en.select_tx_power; param.cs_proc_enable.subevent_Len = params->cs_proc_en.subevent_Len; param.cs_proc_enable.subevents_per_event = params->cs_proc_en.subevents_per_event; diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index d7890ce71a..cf1503d269 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -3207,28 +3207,30 @@ static void btu_ble_pa_response_report_evt(UINT8 *p) STREAM_TO_UINT8(pa_rsp_rpt_evt.tx_status, p); STREAM_TO_UINT8(pa_rsp_rpt_evt.num_rsp, p); - pa_rsp_rpt_evt.rsp_data_info = osi_malloc(pa_rsp_rpt_evt.num_rsp * sizeof(tBTM_BLE_PA_RSP_DATA_INFO)); - if (pa_rsp_rpt_evt.rsp_data_info) - { - for (UINT8 i = 0; i < pa_rsp_rpt_evt.num_rsp; i++) + if (pa_rsp_rpt_evt.num_rsp) { + pa_rsp_rpt_evt.rsp_data_info = osi_malloc(pa_rsp_rpt_evt.num_rsp * sizeof(tBTM_BLE_PA_RSP_DATA_INFO)); + if (pa_rsp_rpt_evt.rsp_data_info) { - STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].tx_power, p); - STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].rssi, p); - STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].cte_type, p); - STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].rsp_slot, p); - STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].data_status, p); - STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].data_len, p); - if (pa_rsp_rpt_evt.rsp_data_info[i].data_len) { - pa_rsp_rpt_evt.rsp_data_info[i].data = osi_malloc(pa_rsp_rpt_evt.rsp_data_info[i].data_len); - if (pa_rsp_rpt_evt.rsp_data_info[i].data) { - STREAM_TO_ARRAY(pa_rsp_rpt_evt.rsp_data_info[i].data, p, pa_rsp_rpt_evt.rsp_data_info[i].data_len); - } else { - HCI_TRACE_ERROR("%s, no enough memory.", __func__); + for (UINT8 i = 0; i < pa_rsp_rpt_evt.num_rsp; i++) + { + STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].tx_power, p); + STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].rssi, p); + STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].cte_type, p); + STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].rsp_slot, p); + STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].data_status, p); + STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].data_len, p); + if (pa_rsp_rpt_evt.rsp_data_info[i].data_len) { + pa_rsp_rpt_evt.rsp_data_info[i].data = osi_malloc(pa_rsp_rpt_evt.rsp_data_info[i].data_len); + if (pa_rsp_rpt_evt.rsp_data_info[i].data) { + STREAM_TO_ARRAY(pa_rsp_rpt_evt.rsp_data_info[i].data, p, pa_rsp_rpt_evt.rsp_data_info[i].data_len); + } else { + HCI_TRACE_ERROR("%s, no enough memory.", __func__); + } } } + } else { + HCI_TRACE_ERROR("%s, no memory.", __func__); } - } else { - HCI_TRACE_ERROR("%s, no memory.", __func__); } btm_ble_pa_rsp_rpt_evt(&pa_rsp_rpt_evt); @@ -3357,7 +3359,7 @@ static void btu_ble_cs_proc_enable_cmpl_evt(UINT8 *p) STREAM_TO_UINT16(proc_en.conn_handle, p); STREAM_TO_UINT8(proc_en.config_id, p); STREAM_TO_UINT8(proc_en.state, p); - STREAM_TO_UINT8(proc_en.tone_Ant_config_select, p); + STREAM_TO_UINT8(proc_en.tone_ant_config_select, p); STREAM_TO_UINT8(proc_en.select_tx_power, p); STREAM_TO_UINT24(proc_en.subevent_Len, p); STREAM_TO_UINT8(proc_en.subevents_per_event, p); diff --git a/components/bt/host/bluedroid/stack/gap/include/gap_int.h b/components/bt/host/bluedroid/stack/gap/include/gap_int.h index 8a3ae0e2f0..175a27e695 100644 --- a/components/bt/host/bluedroid/stack/gap/include/gap_int.h +++ b/components/bt/host/bluedroid/stack/gap/include/gap_int.h @@ -93,7 +93,7 @@ typedef struct { #if BLE_INCLUDED == TRUE -#define GAP_MAX_CHAR_NUM 4 +#define GAP_MAX_CHAR_NUM 5 typedef struct { UINT16 handle; diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index af75e6ac5a..c44e974fff 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -3099,7 +3099,7 @@ UINT8 btsnd_hcic_ble_cs_read_remote_supported_capabilities(UINT16 conn_handle) BT_HDR *p; UINT8 *pp; - HCI_TRACE_ERROR("cs read remote supported caps, conn_handle %d", conn_handle); + HCI_TRACE_DEBUG("cs read remote supported caps, conn_handle %d", conn_handle); HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_READ_REMOTE_SUPP_CAPS_PARAMS_LEN); @@ -3297,7 +3297,7 @@ UINT8 btsnd_hcic_ble_cs_remove_config(UINT16 conn_handle, UINT8 config_id) BT_HDR *p; UINT8 *pp; - HCI_TRACE_ERROR("cs remove config, conn_handle %d config_id %d", conn_handle, config_id); + HCI_TRACE_DEBUG("cs remove config, conn_handle %d config_id %d", conn_handle, config_id); HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_REMOVE_CONFIG_PARAMS_LEN); 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 22de09f434..8961197865 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 @@ -1618,7 +1618,7 @@ typedef struct { UINT16 conn_handle; UINT8 config_id; UINT8 state; - UINT8 tone_Ant_config_select; + UINT8 tone_ant_config_select; INT8 select_tx_power; UINT32 subevent_Len; UINT8 subevents_per_event; From b209fae993d795255827ce6b2b0d6942a377f5d4 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Fri, 14 Nov 2025 11:16:15 +0530 Subject: [PATCH 012/226] fix(esp_wifi): Fix invalid memory accesses in supplicant code --- .../wifi_apps/roaming_app/src/roaming_app.c | 1 + .../src/crypto/crypto_mbedtls-bignum.c | 25 ------- .../esp_supplicant/src/esp_common.c | 3 + .../esp_supplicant/src/esp_dpp.c | 73 +++++++++++++------ .../esp_supplicant/src/esp_hostap.c | 3 +- .../esp_supplicant/src/esp_wpa3.c | 8 ++ .../esp_supplicant/src/esp_wps.c | 31 +++++++- components/wpa_supplicant/src/crypto/crypto.h | 11 --- 8 files changed, 92 insertions(+), 63 deletions(-) diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c index 20dcc08366..40bf63a087 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c +++ b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c @@ -698,6 +698,7 @@ static void periodic_scan_roam(struct timeval *now) roaming_app_get_ap_info(&g_roaming_app.current_bss.ap); ESP_LOGD(ROAMING_TAG, "Connected AP's RSSI=%d", g_roaming_app.current_bss.ap.rssi); if (g_roaming_app.current_bss.ap.rssi > g_roaming_app.config.scan_rssi_threshold) { + ESP_LOGD(ROAMING_TAG, "Not going for scan, Scan RSSI threshold=%d", g_roaming_app.config.scan_rssi_threshold); return; } diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-bignum.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-bignum.c index 6328136a91..61f8840729 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-bignum.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-bignum.c @@ -252,31 +252,6 @@ cleanup: return res; } -int crypto_bignum_to_string(const struct crypto_bignum *a, - u8 *buf, size_t buflen, size_t padlen) -{ - int num_bytes, offset; - size_t outlen; - - if (padlen > buflen) { - return -1; - } - - num_bytes = mbedtls_mpi_size((mbedtls_mpi *) a); - - if (padlen > (size_t) num_bytes) { - offset = padlen - num_bytes; - } else { - offset = 0; - } - - os_memset(buf, 0, offset); - mbedtls_mpi_write_string((mbedtls_mpi *) a, 16, (char *)(buf + offset), - mbedtls_mpi_size((mbedtls_mpi *)a), &outlen); - - return outlen; -} - int crypto_bignum_addmod(const struct crypto_bignum *a, const struct crypto_bignum *b, const struct crypto_bignum *c, diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_common.c b/components/wpa_supplicant/esp_supplicant/src/esp_common.c index 04a9a9a27a..2187e28cb8 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_common.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_common.c @@ -168,6 +168,9 @@ static int handle_assoc_frame(u8 *frame, size_t len, u8 *sender, int8_t rssi, u8 channel) { if (gWpaSm.key_mgmt == WPA_KEY_MGMT_FT_PSK) { + if (len < 6) { /* Cap info + status code */ + return -1; + } if (gWpaSm.ft_protocol) { if (wpa_ft_validate_reassoc_resp(&gWpaSm, frame + 6, len - 6, sender)) { wpa_sm_set_ft_params(&gWpaSm, NULL, 0); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index bd8e11a44f..818412ba38 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -408,6 +408,10 @@ static esp_err_t esp_dpp_rx_peer_disc_resp(struct action_rx_param *rx_param) return ESP_ERR_INVALID_ARG; } + if (rx_param->vendor_data_len < 2) { + wpa_printf(MSG_INFO, "DPP: Too short vendor specific data"); + return ESP_FAIL; + } size_t len = rx_param->vendor_data_len - 2; buf = rx_param->action_frm->u.public_action.v.pa_vendor_spec.vendor_data; @@ -542,28 +546,38 @@ static esp_err_t gas_query_resp_rx(struct action_rx_param *rx_param) { struct dpp_authentication *auth = s_dpp_ctx.dpp_auth; uint8_t *pos = rx_param->action_frm->u.public_action.v.pa_gas_resp.data; - uint8_t *resp = &pos[10]; + uint8_t *resp = &pos[10]; /* first byte of DPP attributes */ + size_t vendor_len = rx_param->vendor_data_len; int i, res; - if (pos[1] == WLAN_EID_VENDOR_SPECIFIC && pos[2] == 5 && - WPA_GET_BE24(&pos[3]) == OUI_WFA && pos[6] == 0x1a && pos[7] == 1 && auth) { + /* Basic structural checks on the Advertisement Protocol payload */ + if (!(pos[1] == WLAN_EID_VENDOR_SPECIFIC && pos[2] == 5 && + WPA_GET_BE24(&pos[3]) == OUI_WFA && pos[6] == 0x1a && pos[7] == 1 && auth)) { + wpa_hexdump(MSG_INFO, "DPP: Failed, Configuration Response adv_proto", pos, 8); + return ESP_OK; + } - eloop_cancel_timeout(gas_query_timeout, NULL, auth); - if (dpp_conf_resp_rx(auth, resp, rx_param->vendor_data_len - 2) < 0) { - wpa_printf(MSG_INFO, "DPP: Configuration attempt failed"); + /* DPP attribute length = vendor_data_len - 2, caller validated vendor_data_len + * (we skip the 2-byte length field and pass only the attributes). */ + size_t dpp_data_len = vendor_len - 2; + + eloop_cancel_timeout(gas_query_timeout, NULL, auth); + + if (dpp_conf_resp_rx(auth, resp, dpp_data_len) < 0) { + wpa_printf(MSG_INFO, "DPP: Configuration attempt failed"); + goto fail; + } + + for (i = 0; i < auth->num_conf_obj; i++) { + res = esp_dpp_handle_config_obj(auth, &auth->conf_obj[i]); + if (res < 0) { + wpa_printf(MSG_INFO, "DPP: Configuration parsing failed"); goto fail; } - - for (i = 0; i < auth->num_conf_obj; i++) { - res = esp_dpp_handle_config_obj(auth, &auth->conf_obj[i]); - if (res < 0) { - wpa_printf(MSG_INFO, "DPP: Configuration parsing failed"); - goto fail; - } - } } return ESP_OK; + fail: return ESP_FAIL; } @@ -853,11 +867,17 @@ static char *esp_dpp_parse_chan_list(const char *chan_list) } char *uri_ptr = uri_channels; + size_t current_offset = 0; // Use an offset to track current position params->num_chan = 0; /* Append " chan=" at the beginning of the URI */ - strcpy(uri_ptr, " chan="); - uri_ptr += strlen(" chan="); + int written = os_snprintf(uri_ptr + current_offset, max_uri_len - current_offset, " chan="); + if (written < 0 || written >= max_uri_len - current_offset) { // Check for error or truncation + wpa_printf(MSG_ERROR, "DPP: URI buffer too small for initial string"); + os_free(uri_channels); + return NULL; + } + current_offset += written; while (*chan_list && params->num_chan < ESP_DPP_MAX_CHAN_COUNT) { int channel = 0; @@ -892,16 +912,23 @@ static char *esp_dpp_parse_chan_list(const char *chan_list) /* Add the valid channel to the list */ params->chan_list[params->num_chan++] = channel; - /* Check if there's space left in uri_channels buffer */ - size_t remaining_space = max_uri_len - (uri_ptr - uri_channels); - if (remaining_space <= 8) { // Oper class + "/" + channel + "," + null terminator - wpa_printf(MSG_ERROR, "DPP: Not enough space in URI buffer"); + // Calculate space needed for current channel string (e.g., "81/1,") + int needed_for_channel = os_snprintf(NULL, 0, "%d/%d,", oper_class, channel); + + if (current_offset + needed_for_channel + 1 > max_uri_len) { // +1 for null terminator + wpa_printf(MSG_ERROR, "DPP: Not enough space in URI buffer for channel %d", channel); os_free(uri_channels); return NULL; } /* Append the operating class and channel to the URI */ - uri_ptr += sprintf(uri_ptr, "%d/%d,", oper_class, channel); + written = os_snprintf(uri_ptr + current_offset, max_uri_len - current_offset, "%d/%d,", oper_class, channel); + if (written < 0 || written >= max_uri_len - current_offset) { // Check for error or truncation + wpa_printf(MSG_ERROR, "DPP: Error writing channel %d to URI buffer", channel); + os_free(uri_channels); + return NULL; + } + current_offset += written; /* Skip any delimiters (comma or space) */ while (*chan_list == ',' || *chan_list == ' ') { @@ -916,8 +943,8 @@ static char *esp_dpp_parse_chan_list(const char *chan_list) } /* Replace the last comma with a space if there was content added */ - if (uri_ptr > uri_channels && *(uri_ptr - 1) == ',') { - *(uri_ptr - 1) = ' '; + if (current_offset > strlen(" chan=") && uri_ptr[current_offset - 1] == ',') { + uri_ptr[current_offset - 1] = ' '; } return uri_channels; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c index da162f0ee5..d1d107a3fe 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c @@ -199,7 +199,8 @@ void *hostap_init(void) } #endif /* CONFIG_SAE */ - os_memcpy(hapd->conf->ssid.wpa_passphrase, esp_wifi_ap_get_prof_password_internal(), strlen((char *)esp_wifi_ap_get_prof_password_internal())); + os_snprintf(hapd->conf->ssid.wpa_passphrase, WIFI_PASSWORD_LEN_MAX, + "%s", esp_wifi_ap_get_prof_password_internal()); hapd->conf->ssid.wpa_passphrase[WIFI_PASSWORD_LEN_MAX - 1] = '\0'; hapd->conf->max_num_sta = esp_wifi_ap_get_max_sta_conn(); auth_conf->transition_disable = esp_wifi_ap_get_transition_disable_internal(); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c index c9b09881ee..21a7c4e379 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c @@ -333,8 +333,16 @@ static int wpa3_parse_sae_commit(u8 *buf, u32 len, u16 status) wpa_printf(MSG_ERROR, "Invalid SAE anti-clogging token container header"); return ESP_FAIL; } + if (len < 5) { + wpa_printf(MSG_ERROR, "Invalid SAE anti-clogging token length"); + return ESP_FAIL; + } g_sae_token = wpabuf_alloc_copy(buf + 5, len - 5); } else { + if (len < 2) { + wpa_printf(MSG_ERROR, "Invalid SAE anti-clogging token length"); + return ESP_FAIL; + } g_sae_token = wpabuf_alloc_copy(buf + 2, len - 2); } return ESP_OK; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c index 186571237a..26413edc29 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c @@ -389,8 +389,8 @@ static int wps_enrollee_process_msg_frag(struct wpabuf **buf, int tot_len, u8 *f identifier = sm->current_identifier; if (*buf == NULL) { - if (0 == (flag & WPS_MSG_FLAG_LEN) || tot_len < frag_len) { - wpa_printf(MSG_ERROR, "WPS: %s: Invalid fragment flag: 0x%02x", __FUNCTION__, flag); + if (frag_len < 0 || tot_len < frag_len) { + wpa_printf(MSG_ERROR, "WPS: Invalid first fragment length"); return ESP_FAIL; } @@ -405,9 +405,17 @@ static int wps_enrollee_process_msg_frag(struct wpabuf **buf, int tot_len, u8 *f if (flag & WPS_MSG_FLAG_LEN) { wpa_printf(MSG_ERROR, "WPS: %s: Invalid fragment flag: 0x%02x", __func__, flag); + wpabuf_free(*buf); + *buf = NULL; return ESP_FAIL; } + if (frag_len < 0 || wpabuf_len(*buf) + frag_len > tot_len) { + wpa_printf(MSG_ERROR, "WPS: Invalid subsequent fragment length"); + wpabuf_free(*buf); + *buf = NULL; + return ESP_FAIL; + } wpabuf_put_data(*buf, frag_data, frag_len); if (flag & WPS_MSG_FLAG_MORE) { @@ -445,6 +453,10 @@ static int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res) return ESP_FAIL; } + if (len < (int)(sizeof(struct eap_expand) + 1)) { + wpa_printf(MSG_ERROR, "WPS: Truncated EAP-Expanded header"); + return ESP_FAIL; + } expd = (struct eap_expand *) ubuf; wpa_printf(MSG_DEBUG, "WPS: Processing WSC message (len=%d, total_len=%d)", len, tlen); @@ -463,7 +475,11 @@ static int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res) flag = *(u8 *)(ubuf + sizeof(struct eap_expand)); if (flag & WPS_MSG_FLAG_LEN) { - tbuf = ubuf + sizeof(struct eap_expand) + 1 + 2;//two bytes total length + if (len < (int)(sizeof(struct eap_expand) + 1 + 2)) { + wpa_printf(MSG_ERROR, "WPS: Missing total length field"); + return ESP_FAIL; + } + tbuf = ubuf + sizeof(struct eap_expand) + 1 + 2; // includes 2-byte total length frag_len = len - (sizeof(struct eap_expand) + 1 + 2); be_tot_len = *(u16 *)(ubuf + sizeof(struct eap_expand) + 1); tlen = ((be_tot_len & 0xff) << 8) | ((be_tot_len >> 8) & 0xff); @@ -473,6 +489,15 @@ static int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res) tlen = frag_len; } + if (frag_len < 0 || tlen < 0 || ((flag & WPS_MSG_FLAG_LEN) && tlen < frag_len)) { + wpa_printf(MSG_ERROR, "WPS: Invalid fragment sizes"); + if (wps_buf) { + wpabuf_free(wps_buf); + wps_buf = NULL; + } + return ESP_FAIL; + } + if (tlen > 50000) { wpa_printf(MSG_ERROR, "WPS: Invalid EAP-WSC message length"); return ESP_FAIL; diff --git a/components/wpa_supplicant/src/crypto/crypto.h b/components/wpa_supplicant/src/crypto/crypto.h index 7946e6be16..b65b00809b 100644 --- a/components/wpa_supplicant/src/crypto/crypto.h +++ b/components/wpa_supplicant/src/crypto/crypto.h @@ -1141,17 +1141,6 @@ void crypto_free_buffer(unsigned char *buf); */ int crypto_ec_get_priv_key_der(struct crypto_ec_key *key, unsigned char **key_data, int *key_len); -/** - * crypto_bignum_to_string: get big number in ascii format - * @a: big number - * @buf: buffer in which number will written to - * @buflen: buffer length - * @padlen: padding length - * Return : 0 if success - */ -int crypto_bignum_to_string(const struct crypto_bignum *a, - u8 *buf, size_t buflen, size_t padlen); - struct crypto_ecdh; void crypto_ecdh_deinit(struct crypto_ecdh *ecdh); From 383bedae883c8737abf60a0a4171f77d42be9042 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Thu, 6 Nov 2025 12:00:51 +0800 Subject: [PATCH 013/226] fix(ble/bluedroid): Fixed CTE IQ sample data copy error --- components/bt/host/bluedroid/stack/btu/btu_hcif.c | 8 ++++++++ components/bt/host/bluedroid/stack/l2cap/l2c_api.c | 4 ++-- components/bt/host/bluedroid/stack/smp/smp_api.c | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index cf1503d269..4aa1701294 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -3067,6 +3067,10 @@ static void btu_ble_cte_connless_iq_report_evt(UINT8 *p) for (uint8_t i = 0; i < connless_iq_rpt.sample_count; i++) { STREAM_TO_UINT8(connless_iq_rpt.i_sample[i], p); + } + + for (uint8_t i = 0; i < connless_iq_rpt.sample_count; i++) + { STREAM_TO_UINT8(connless_iq_rpt.q_sample[i], p); } @@ -3098,6 +3102,10 @@ static void btu_ble_cte_conn_iq_report_evt(UINT8 *p) for (uint8_t i = 0; i < conn_iq_rpt.sample_count; i++) { STREAM_TO_UINT8(conn_iq_rpt.i_sample[i], p); + } + + for (uint8_t i = 0; i < conn_iq_rpt.sample_count; i++) + { STREAM_TO_UINT8(conn_iq_rpt.q_sample[i], p); } diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c index 36d636768a..8030df8078 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c @@ -215,7 +215,7 @@ UINT16 L2CA_ConnectReq (UINT16 psm, BD_ADDR p_bd_addr) ** ** Parameters: PSM: L2CAP PSM for the connection ** BD address of the peer -** Enhaced retransmission mode configurations +** Enhanced retransmission mode configurations ** Returns the CID of the connection, or 0 if it failed to start ** @@ -760,7 +760,7 @@ bool L2CA_GetIdentifiers(uint16_t lcid, uint16_t *rcid, uint16_t *handle) ** ** NOTE This timeout takes effect after at least 1 channel has been ** established and removed. L2CAP maintains its own timer from -** whan a connection is established till the first channel is +** when a connection is established till the first channel is ** set up. *******************************************************************************/ BOOLEAN L2CA_SetIdleTimeout (UINT16 cid, UINT16 timeout, BOOLEAN is_global) diff --git a/components/bt/host/bluedroid/stack/smp/smp_api.c b/components/bt/host/bluedroid/stack/smp/smp_api.c index 5ac5cd7ef4..b99c94abd8 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_api.c +++ b/components/bt/host/bluedroid/stack/smp/smp_api.c @@ -524,10 +524,10 @@ void SMP_SecureConnectionOobDataReply(UINT8 *p_data) ** Description This function is called to encrypt the data with the specified ** key ** -** Parameters: key - Pointer to key key[0] conatins the MSB +** Parameters: key - Pointer to key key[0] contains the MSB ** key_len - key length ** plain_text - Pointer to data to be encrypted -** plain_text[0] conatins the MSB +** plain_text[0] contains the MSB ** pt_len - plain text length ** p_out - output of the encrypted texts ** From e763455cd905e820d5366465c2f775643c09afb7 Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Tue, 30 Dec 2025 13:13:23 +0800 Subject: [PATCH 014/226] change(ble): [AUTO_MR] Update lib_esp32c2 to 9f051857 (cherry picked from commit 7ebf1c8d158a1e1ce60a870170adb34c02eb18f1) Co-authored-by: Zhou Xiao --- components/bt/controller/lib_esp32c2/esp32c2-bt-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib index 7c104a8d09..6db3a4abe6 160000 --- a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib +++ b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib @@ -1 +1 @@ -Subproject commit 7c104a8d09e35f3244636fcf01004d5c767f12c2 +Subproject commit 6db3a4abe6f2f9ec60067a61732c8ef32557e821 From 661652c9ab1b134df01593ecbc4d036a0bf07393 Mon Sep 17 00:00:00 2001 From: Luo Xu Date: Thu, 20 Nov 2025 17:43:26 +0800 Subject: [PATCH 015/226] refactor(ble): modularize compressed log scripts for better maintainability (cherry picked from commit 0cf6f50179d41e68d29d4377d6017b9c51ea42ca) Co-authored-by: luoxu --- components/bt/CMakeLists.txt | 2 +- .../extension/log_compression/CMakeLists.txt | 105 ++++++++--- .../scripts/ble_log_compress.py | 178 ++++++------------ .../scripts/configs/module_info.yml.in | 10 + .../log_compression/scripts/inttypes_map.py | 1 + .../ble_mesh/make_mesh_log_macro.py | 71 +++++++ .../bluedroid/make_bluedroid_log_macro.py | 61 ++++++ 7 files changed, 279 insertions(+), 149 deletions(-) create mode 100644 components/bt/common/ble_log/extension/log_compression/scripts/module_scripts/ble_mesh/make_mesh_log_macro.py create mode 100644 components/bt/common/ble_log/extension/log_compression/scripts/module_scripts/bluedroid/make_bluedroid_log_macro.py diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index a215bd4e8e..6fc6c2a03b 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -975,7 +975,7 @@ set(bt_priv_requires ) if(CONFIG_BLE_COMPRESSED_LOG_ENABLE) - set(BT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}") + set(CODE_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}") # When log compression is enabled, selected logs are replaced # by auto-generated macros that emit pre-encoded data. # This eliminates the original format strings, reducing firmware size and diff --git a/components/bt/common/ble_log/extension/log_compression/CMakeLists.txt b/components/bt/common/ble_log/extension/log_compression/CMakeLists.txt index 967b0e9b8e..15ae73550a 100644 --- a/components/bt/common/ble_log/extension/log_compression/CMakeLists.txt +++ b/components/bt/common/ble_log/extension/log_compression/CMakeLists.txt @@ -1,6 +1,6 @@ - set(LOG_COMPRESSED_MODULE "") set(LOG_COMPRESSED_MODULE_CODE_PATH "") +set(BT_ROOT_PATH $ENV{IDF_PATH}/components/bt) set(LOG_COMPRESSED_SRCS_DIR "${CMAKE_BINARY_DIR}/ble_log/.compressed_srcs") # default config value for ble mesh module @@ -17,32 +17,62 @@ set(BLE_HOST_TAGS_PRESERVE "") if(CONFIG_BLE_MESH_COMPRESSED_LOG_ENABLE) list(APPEND LOG_COMPRESSED_MODULE "BLE_MESH") - if(NOT EXISTS "${CMAKE_BINARY_DIR}/ble_log/include/mesh_log_index.h") - file(WRITE "${CMAKE_BINARY_DIR}/ble_log/include/mesh_log_index.h" "") - endif() - list(APPEND LOG_COMPRESSED_MODULE_CODE_PATH "esp_ble_mesh") # update config file set(BLE_MESH_CODE_PATH "esp_ble_mesh") set(BLE_MESH_LOG_INDEX_HEADER "mesh_log_index.h") + set(BLE_MESH_LOG_SCRIPT_PATH + "${CMAKE_CURRENT_LIST_DIR}/scripts/module_scripts/ble_mesh/make_mesh_log_macro.py") # update BLE_MESH_TAGS and BLE_MESH_TAGS_PRESERVE include(${CMAKE_CURRENT_LIST_DIR}/cmake/ble_mesh_log_tags.cmake) - + if(NOT EXISTS "${CMAKE_BINARY_DIR}/ble_log/include/${BLE_MESH_LOG_INDEX_HEADER}") + file(WRITE "${CMAKE_BINARY_DIR}/ble_log/include/${BLE_MESH_LOG_INDEX_HEADER}" "") + endif() + list(APPEND LOG_COMPRESSED_MODULE_CODE_PATH ${BLE_MESH_CODE_PATH}) endif() + if(CONFIG_BLE_HOST_COMPRESSED_LOG_ENABLE AND CONFIG_BT_BLUEDROID_ENABLED) list(APPEND LOG_COMPRESSED_MODULE "BLE_HOST") - list(APPEND LOG_COMPRESSED_MODULE_CODE_PATH "host/bluedroid/stack") - if(NOT EXISTS "${CMAKE_BINARY_DIR}/ble_log/include/host_log_index.h") - file(WRITE "${CMAKE_BINARY_DIR}/ble_log/include/host_log_index.h" "") - endif() + # update config file set(HOST_CODE_PATH "host/bluedroid/stack") set(HOST_LOG_INDEX_HEADER "host_log_index.h") + set(BLE_HOST_LOG_SCRIPT_PATH + "${CMAKE_CURRENT_LIST_DIR}/scripts/module_scripts/bluedroid/make_bluedroid_log_macro.py") + include(${CMAKE_CURRENT_LIST_DIR}/cmake/ble_host_bluedroid_tags.cmake) + if(NOT EXISTS "${CMAKE_BINARY_DIR}/ble_log/include/${HOST_LOG_INDEX_HEADER}") + file(WRITE "${CMAKE_BINARY_DIR}/ble_log/include/${HOST_LOG_INDEX_HEADER}" "") + endif() + list(APPEND LOG_COMPRESSED_MODULE_CODE_PATH ${HOST_CODE_PATH}) endif() + +if(BLE_COMPRESSED_LIB_LOG_BUILD) + if(NOT (BLE_COMPRESSED_LIB_NAME AND BLE_COMPRESSED_LIB_CODE_DIR AND BLE_COMPRESSED_LIB_LOG_TAGS)) + message(FATAL_ERROR "Invalid settings") + else() + message("Building compressed log for ${BLE_COMPRESSED_LIB_NAME}") + endif() + list(APPEND LOG_COMPRESSED_MODULE ${BLE_COMPRESSED_LIB_NAME}) + if(NOT EXISTS "${CMAKE_BINARY_DIR}/ble_log/include/${BLE_COMPRESSED_LIB_LOG_INDEX_HEADER}") + file(WRITE "${CMAKE_BINARY_DIR}/ble_log/include/${BLE_COMPRESSED_LIB_LOG_INDEX_HEADER}" "") + endif() + list(APPEND LOG_COMPRESSED_MODULE_CODE_PATH ${BLE_COMPRESSED_LIB_CODE_DIR}) + + string(REPLACE ";" "," BLE_COMPRESSED_LIB_CODE_DIR "${BLE_COMPRESSED_LIB_CODE_DIR}") + string(REPLACE ";" "," BLE_COMPRESSED_LIB_LOG_TAGS "${BLE_COMPRESSED_LIB_LOG_TAGS}") + string(REPLACE ";" "," BLE_COMPRESSED_LIB_LOG_TAGS_PRESERVE "${BLE_COMPRESSED_LIB_LOG_TAGS_PRESERVE}") +else() + set(BLE_COMPRESSED_LIB_NAME "placeholder") +endif() + + if(LOG_COMPRESSED_MODULE) - list(APPEND srcs "common/ble_log/extension/log_compression/ble_log_compression.c") - list(APPEND include_dirs "${CMAKE_BINARY_DIR}/ble_log/include") + # When building the library, ble_log_compression.c and its dependencies are not needed + if(NOT BLE_COMPRESSED_LIB_LOG_BUILD) + list(APPEND srcs "common/ble_log/extension/log_compression/ble_log_compression.c") + list(APPEND include_dirs "${CMAKE_BINARY_DIR}/ble_log/include") + endif() if(NOT CMAKE_VERSION VERSION_LESS 3.15.0) set(Python3_FIND_STRATEGY LOCATION) find_package(Python3 COMPONENTS Interpreter) @@ -111,19 +141,39 @@ if(LOG_COMPRESSED_MODULE) "host/nimble/nimble/nimble/host/store/config/src") endif() - add_custom_target(ble_log_compression ALL - COMMAND ${BLE_PYTHON_EXECUTABLE} ${PYTHON_SCRIPT} - compress - --compressed_srcs_path "${LOG_COMPRESSED_SRCS_DIR}" - --build_path "${CMAKE_BINARY_DIR}" - --module "'${LOG_COMPRESSED_MODULE}'" - --bt_path "${BT_ROOT_PATH}" - --srcs "'${compressed_srcs}'" - DEPENDS ${compressed_srcs_with_abs_path} ${PYTHON_SCRIPT} - COMMENT "Log compression is being performed, please wait..." - WORKING_DIRECTORY ${BT_ROOT_PATH} - USES_TERMINAL - ) + if(BLE_COMPRESSED_LIB_LOG_BUILD) + execute_process(COMMAND ${BLE_PYTHON_EXECUTABLE} ${PYTHON_SCRIPT} + compress + --compressed_srcs_path "${LOG_COMPRESSED_SRCS_DIR}" + --build_path "${CMAKE_BINARY_DIR}" + --module "${LOG_COMPRESSED_MODULE}" + --code_base_path "${CODE_BASE_PATH}" + --srcs "${compressed_srcs}" + RESULT_VARIABLE result + OUTPUT_VARIABLE out + ERROR_VARIABLE err) + if(NOT ${result} EQUAL 0) + message(WARNING "${err}") + message(WARNING "Exit this log compression due to failure of compression") + set(LOG_COMPRESS_INCLUDE_DIRS ${include_dirs} PARENT_SCOPE) + set(LOG_COMPRESSION_TARGET "" PARENT_SCOPE) + return() + endif() + else() + add_custom_target(ble_log_compression ALL + COMMAND ${BLE_PYTHON_EXECUTABLE} ${PYTHON_SCRIPT} + compress + --compressed_srcs_path "${LOG_COMPRESSED_SRCS_DIR}" + --build_path "${CMAKE_BINARY_DIR}" + --module "'${LOG_COMPRESSED_MODULE}'" + --code_base_path "${CODE_BASE_PATH}" + --srcs "'${compressed_srcs}'" + DEPENDS ${compressed_srcs_with_abs_path} ${PYTHON_SCRIPT} + COMMENT "Log compression is being performed, please wait..." + WORKING_DIRECTORY ${BT_ROOT_PATH} + USES_TERMINAL + ) + endif() function(add_flags_if_in_list file file_list compile_flags) set(PROCESSED OFF PARENT_SCOPE) @@ -190,7 +240,10 @@ if(LOG_COMPRESSED_MODULE) set(LOG_COMPRESSION_TARGET ble_log_compression PARENT_SCOPE) # set(LOG_COMPRESSION_TARGET "" PARENT_SCOPE) set(LOG_COMPRESS_SRCS "${compressed_srcs_with_abs_path};${uncompressed_srcs}" PARENT_SCOPE) - list(APPEND include_dirs "common/ble_log/extension/log_compression/include") + if(NOT BLE_COMPRESSED_LIB_LOG_BUILD) + list(APPEND include_dirs "common/ble_log/extension/log_compression/include") + endif() + list(APPEND include_dirs "${CMAKE_BINARY_DIR}/ble_log/include") set(LOG_COMPRESS_INCLUDE_DIRS ${include_dirs} PARENT_SCOPE) else() set(LOG_COMPRESSION_TARGET "" PARENT_SCOPE) diff --git a/components/bt/common/ble_log/extension/log_compression/scripts/ble_log_compress.py b/components/bt/common/ble_log/extension/log_compression/scripts/ble_log_compress.py index cb4e40bd57..2398036d8c 100644 --- a/components/bt/common/ble_log/extension/log_compression/scripts/ble_log_compress.py +++ b/components/bt/common/ble_log/extension/log_compression/scripts/ble_log_compress.py @@ -19,6 +19,7 @@ This script processes Bluetooth source files to compress logging statements. import argparse import enum +import importlib.util import logging import os import re @@ -33,6 +34,7 @@ from typing import Dict from typing import List from typing import Tuple from typing import Union +from typing import cast import tree_sitter_c as tsc import yaml @@ -72,10 +74,16 @@ CLANG_PARSER: Union[Parser, None] = None SOURCE_ENUM_MAP = { 'BLE_HOST': 0, 'BLE_MESH': 1, + 'BLE_MESH_LIB': 2, } # Functions that require hex formatting -HEX_FUNCTIONS = ['bt_hex'] # Used in Mesh and Audio modules +HEX_FUNCTIONS = { + # func_name: (arg_cnt, buf_idx, buf_len) + # Negative buf_len indicates constant buffer size + 'bt_hex': (2, 0, 1), # Used in Mesh and Audio modules + 'MAC2STR': (1, 0, -6), # Used in Bluedroid Host +} # C keywords to exclude from function names C_KEYWORDS = { @@ -119,15 +127,6 @@ LINE_MACROS = { '__LINE__', } -BLUEDROID_LOG_MODE_LEVEL_GET = { - 'BTM': 'btm_cb.trace_level', - 'L2CAP': 'l2cb.l2cap_trace_level', - 'GAP': 'gap_cb.trace_level', - 'GATT': 'gatt_cb.trace_level', - 'SMP': 'smp_cb.trace_level', - 'APPL': 'appl_trace_level', -} - class ARG_SIZE_TYPE(enum.IntEnum): U32 = 0 @@ -174,11 +173,12 @@ class LogCompressor: """Main class for BLE log compression.""" def __init__(self) -> None: - self.bt_component_path = Path() + self.code_base_path = Path() self.build_dir = Path() self.bt_compressed_srcs_path = Path() self.config: dict[str, Any] = {} self.module_info: dict[str, Any] = {} + self.module_mod: dict[str, Any] = {} def init_parser(self) -> Parser: """Initialize tree-sitter parser for C.""" @@ -371,15 +371,20 @@ class LogCompressor: if ( arg_node.type == 'call_expression' and arg_node.child_by_field_name('function') - and arg_node.child_by_field_name('function').text.decode('utf-8') in HEX_FUNCTIONS + and arg_node.child_by_field_name('function').text.decode('utf-8') in HEX_FUNCTIONS.keys() ): # Extract arguments of the hex function + hex_func_name = arg_node.child_by_field_name('function').text.decode('utf-8') hex_args = arg_node.child_by_field_name('arguments') - if hex_args and hex_args.named_child_count >= 2: - buf_node = hex_args.named_children[0] - len_node = hex_args.named_children[1] + hex_func_info = HEX_FUNCTIONS[hex_func_name] + if hex_args and hex_args.named_child_count == hex_func_info[0]: + buf_node = hex_args.named_children[hex_func_info[1]].text.decode('utf-8') + if hex_func_info[2] < 0: + len_node = abs(hex_func_info[2]) + else: + len_node = hex_args.named_children[hex_func_info[2]].text.decode('utf-8') token_list = list(token) - token_list[6] = f'@hex_func@{buf_node.text.decode("utf-8")}@{len_node.text.decode("utf-8")}' + token_list[6] = f'@hex_func@{buf_node}@{len_node}' tokens[tokens_tuple_map[i]] = tuple(token_list) log_info['argu_tokens'] = tokens @@ -419,7 +424,7 @@ class LogCompressor: if ( node.type == 'call_expression' and node.child_by_field_name('function') - and node.child_by_field_name('function').text.decode('utf-8') in HEX_FUNCTIONS + and node.child_by_field_name('function').text.decode('utf-8') in HEX_FUNCTIONS.keys() ): return True @@ -462,53 +467,6 @@ class LogCompressor: if not log_idx: return '' - def generate_mesh_log_prefix(source: str, tag: str, print_statm: str) -> str: - level = tag.split('_')[-1] - mod = tag.split('_')[0] - if level == 'ERR': - level = 'ERROR' - log_level = 'BLE_MESH_LOG_LEVEL_ERROR' - elif level == 'WARN': - level = 'WARN' - log_level = 'BLE_MESH_LOG_LEVEL_WARN' - elif level == 'INFO': - level = 'INFO' - log_level = 'BLE_MESH_LOG_LEVEL_INFO' - elif level == 'DBG': - level = 'DEBUG' - log_level = 'BLE_MESH_LOG_LEVEL_DEBUG' - else: - LOGGER.error(f'Invalid log level {level}') - return '' - if mod == 'NET': - used_log_levl = 'BLE_MESH_NET_BUF_LOG_LEVEL' - used_log_mod = 'BLE_MESH_NET_BUF' - else: - used_log_levl = 'BLE_MESH_LOG_LEVEL' - used_log_mod = 'BLE_MESH' - return ( - f'{{do {{ if (({used_log_levl} >= {log_level}) &&' - f' BLE_MESH_LOG_LEVEL_CHECK({used_log_mod}, {level})) {print_statm};}} while (0);}}\\\n' - ) - - def generate_bluedroid_log_prefix(source: str, tag: str, print_statm: str) -> str: - tag_info = tag.split('_') - mod = tag_info[0] - - return ( - f'{{if ({BLUEDROID_LOG_MODE_LEVEL_GET[mod]} >= BT_TRACE_LEVEL_{tag_info[-1]} &&' - f' BT_LOG_LEVEL_CHECK({mod}, {tag_info[-1]})) {print_statm};}}\\\n' - ) - - def generate_log_lvl_prefix(source: str, tag: str, print_statm: str) -> str: - if source == 'BLE_MESH': - return ' ' + generate_mesh_log_prefix(source, tag, print_statm) - elif source == 'BLE_HOST': # only bluedroid host supported for now - return ' ' + generate_bluedroid_log_prefix(source, tag, print_statm) - else: - LOGGER.error(f'Unknown source {source}') - return '' - source_value = SOURCE_ENUM_MAP.get(source.upper()) if source_value is None: raise ValueError(f'Invalid source: {source}') @@ -551,41 +509,22 @@ class LogCompressor: else: sizes.append(f'{int(ARG_SIZE_TYPE.U32)}') - if arg_count > 0: - size_str = ', '.join(sizes) - arg_str = ', '.join(arguments).replace('\n', '') - macro += generate_log_lvl_prefix( - source, - tag, - (f'BLE_LOG_COMPRESSED_HEX_PRINT({source_value}, {log_idx}, {arg_count}, {size_str}, {arg_str})'), - ) + stmt = self.module_mod[source].gen_compressed_stmt( + log_idx, + source_value, + tag, + log_info['arguments'][0], + [{'name': arg, 'size_type': size_type} for arg, size_type in zip(arguments, sizes)], + [ + { + 'buffer': hex_str.split('@')[2], + 'length': hex_str.split('@')[3], + } + for hex_str in hex_func + ], + ) + macro += cast(str, stmt) - for idx, item in enumerate(hex_func): - # hex_func format: @hex_func@buf@len - parts = item.split('@') - if len(parts) >= 4: - buf = parts[2] - buf_len = parts[3] - macro += generate_log_lvl_prefix( - source, - tag, - (f'BLE_LOG_COMPRESSED_HEX_PRINT_BUF({source_value}, {log_idx}, {idx}, {buf}, {buf_len})'), - ) - else: - macro += generate_log_lvl_prefix( - source, tag, f'BLE_LOG_COMPRESSED_HEX_PRINT_WITH_ZERO_ARGUMENTS({source_value}, {log_idx})' - ) - for idx, item in enumerate(hex_func): - # hex_func format: @hex_func@buf@len - parts = item.split('@') - if len(parts) >= 4: - buf = parts[2] - buf_len = parts[3] - macro += generate_log_lvl_prefix( - source, - tag, - (f'BLE_LOG_COMPRESSED_HEX_PRINT_BUF({source_value}, {log_idx}, {idx}, {buf}, {buf_len})'), - ) if ( 'tags_with_preserve' in self.module_info[source] and tag in self.module_info[source]['tags_with_preserve'] @@ -593,8 +532,7 @@ class LogCompressor: macro += f' {tag}(fmt, ##__VA_ARGS__);\\\n' else: # Non-hexified log - print_fmt = print_fmt or 'NULL' - macro += f' BLE_LOG_COMPRESSED_PRINT({source_value}, {log_idx}, "{print_fmt}", ##__VA_ARGS__); \\\n' + raise ValueError('Hexify convert failed') macro += '}\n' return macro @@ -716,7 +654,7 @@ class LogCompressor: total_cnt = 0 for src in srcs: if pattern.match(src): - src_path = self.bt_component_path / src + src_path = self.code_base_path / src dest_path = self.bt_compressed_srcs_path / src temp_path = f'{dest_path}.tmp' total_cnt += 1 @@ -754,7 +692,7 @@ class LogCompressor: module: Module name macros: List of (log_id, macro_definition) """ - # header_path = self.bt_component_path / self.module_info[module]['log_index_path'] + # header_path = self.code_base_path / self.module_info[module]['log_index_path'] header_path = self.build_dir / Path('ble_log') / Path('include') / self.module_info[module]['log_index_file'] # Create directory if needed header_path.parent.mkdir(parents=True, exist_ok=True) @@ -764,8 +702,7 @@ class LogCompressor: return elif update_state == self.db_manager.SOURCE_LOG_UPDATE_FULL: # Header template - header_content = ( - textwrap.dedent(f""" + header_content = textwrap.dedent(f""" /* * SPDX-FileCopyrightText: {datetime.now().year} Espressif Systems (Shanghai) CO LTD * @@ -778,22 +715,11 @@ class LogCompressor: #include #include - // Compression function declarations - extern int ble_log_compressed_hex_print - (uint32_t source, uint32_t log_index, size_t args_size_cnt, ...); - extern int ble_log_compressed_hex_print_buf - (uint8_t source, uint32_t log_index, uint8_t buf_idx, const uint8_t *buf, size_t len); - - // Compression macros - #define BLE_LOG_COMPRESSED_HEX_PRINT(source, log_index, args_cnt, ...) \\ - ble_log_compressed_hex_print(source, log_index, args_cnt, ##__VA_ARGS__) - #define BLE_LOG_COMPRESSED_HEX_PRINT_BUF(source, log_index, buf_idx, buf, len) \\ - ble_log_compressed_hex_print_buf(source, log_index, buf_idx, (const uint8_t *)buf, len) - #define BLE_LOG_COMPRESSED_HEX_PRINT_WITH_ZERO_ARGUMENTS(source, log_index) \\ - ble_log_compressed_hex_print(source, log_index, 0) """).strip() - + '\n\n' - ) + + header_content += self.module_mod[module].gen_header_head() + header_content += '\n\n' + # Add sorted macros for log_id, macro_def in sorted(macros, key=lambda x: x[0]): header_content += macro_def + '\n' @@ -852,6 +778,14 @@ class LogCompressor: for module in module_names: if module in modules: self.module_info[module] = modules[module] + module_script_path = self.module_info[module]['script'] + spec = self.module_mod[module] = importlib.util.spec_from_file_location(module, module_script_path) + if spec and spec.loader: + self.module_mod[module] = importlib.util.module_from_spec(spec) + spec.loader.exec_module(self.module_mod[module]) + else: + LOGGER.error(f"Failed to load module '{module}' script") + raise ImportError(' Failed to load module script') print(f'Found module {module} for compression\n', flush=True, end='', file=sys.stdout) else: LOGGER.warning(f"Skipping module '{module}' - config not found") @@ -863,7 +797,7 @@ class LogCompressor: compress_parser = subparsers.add_parser('compress') compress_parser.add_argument('--srcs', required=True, help='Semicolon-separated source file paths') - compress_parser.add_argument('--bt_path', required=True, help='Bluetooth component root path') + compress_parser.add_argument('--code_base_path', required=True, help='Component base path') compress_parser.add_argument('--module', required=True, help='Semicolon-separated module names') compress_parser.add_argument('--build_path', required=True, help='Build output directory') compress_parser.add_argument('--compressed_srcs_path', required=True, help='Directory for processed sources') @@ -871,7 +805,7 @@ class LogCompressor: args = parser.parse_args() # Setup paths - self.bt_component_path = Path(args.bt_path) + self.code_base_path = Path(args.code_base_path) self.build_dir = Path(args.build_path) self.bt_compressed_srcs_path = Path(args.compressed_srcs_path) @@ -947,7 +881,7 @@ class LogCompressor: # Mark files as processed for module, info in self.module_info.items(): for temp_path in info['files_to_process']: - src_path = self.bt_component_path / os.path.relpath(temp_path[:-4], self.bt_compressed_srcs_path) + src_path = self.code_base_path / os.path.relpath(temp_path[:-4], self.bt_compressed_srcs_path) db_manager.mark_file_processed(module, src_path, temp_path) for root, _, files in os.walk(self.bt_compressed_srcs_path): for name in files: diff --git a/components/bt/common/ble_log/extension/log_compression/scripts/configs/module_info.yml.in b/components/bt/common/ble_log/extension/log_compression/scripts/configs/module_info.yml.in index 853dcd4748..5201f57503 100644 --- a/components/bt/common/ble_log/extension/log_compression/scripts/configs/module_info.yml.in +++ b/components/bt/common/ble_log/extension/log_compression/scripts/configs/module_info.yml.in @@ -6,6 +6,7 @@ log_config: description: "BLE Mesh" code_path: [@BLE_MESH_CODE_PATH@] log_index_file: @BLE_MESH_LOG_INDEX_HEADER@ + script: @BLE_MESH_LOG_SCRIPT_PATH@ tags: [@BLE_MESH_TAGS@] tags_with_preserve: [@BLE_MESH_TAGS_PRESERVE@] @@ -13,5 +14,14 @@ log_config: description: "BLE Host" code_path: [@HOST_CODE_PATH@] log_index_file: @HOST_LOG_INDEX_HEADER@ + script: @BLE_HOST_LOG_SCRIPT_PATH@ tags: [@BLE_HOST_TAGS@] tags_with_preserve: [@BLE_HOST_TAGS_PRESERVE@] + + @BLE_COMPRESSED_LIB_NAME@: + description: "@BLE_COMPRESSED_LIB_DESC@" + code_path: [@BLE_COMPRESSED_LIB_CODE_DIR@] + log_index_file: @BLE_COMPRESSED_LIB_LOG_INDEX_HEADER@ + script: @BLE_COMPRESSED_LIB_LOG_SCRIPT_PATH@ + tags: [@BLE_COMPRESSED_LIB_LOG_TAGS@] + tags_with_preserve: [@BLE_COMPRESSED_LIB_LOG_TAGS_PRESERVE@] diff --git a/components/bt/common/ble_log/extension/log_compression/scripts/inttypes_map.py b/components/bt/common/ble_log/extension/log_compression/scripts/inttypes_map.py index 9e95a18cff..44f193ac22 100644 --- a/components/bt/common/ble_log/extension/log_compression/scripts/inttypes_map.py +++ b/components/bt/common/ble_log/extension/log_compression/scripts/inttypes_map.py @@ -163,4 +163,5 @@ TYPES_MACRO_MAP = { 'SCNoPTR': __PRIPTR_PREFIX + 'o', 'SCNuPTR': __PRIPTR_PREFIX + 'u', 'SCNxPTR': __PRIPTR_PREFIX + 'x', + 'MACSTR': '%s', } diff --git a/components/bt/common/ble_log/extension/log_compression/scripts/module_scripts/ble_mesh/make_mesh_log_macro.py b/components/bt/common/ble_log/extension/log_compression/scripts/module_scripts/ble_mesh/make_mesh_log_macro.py new file mode 100644 index 0000000000..791de5f8ab --- /dev/null +++ b/components/bt/common/ble_log/extension/log_compression/scripts/module_scripts/ble_mesh/make_mesh_log_macro.py @@ -0,0 +1,71 @@ +# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +import textwrap + + +def generate_mesh_log_prefix(tag: str, print_statm: str) -> str: + level = tag.split('_')[-1] + mod = tag.split('_')[0] + if level == 'ERR': + level = 'ERROR' + log_level = 'BLE_MESH_LOG_LEVEL_ERROR' + elif level == 'WARN': + level = 'WARN' + log_level = 'BLE_MESH_LOG_LEVEL_WARN' + elif level == 'INFO': + level = 'INFO' + log_level = 'BLE_MESH_LOG_LEVEL_INFO' + elif level == 'DBG': + level = 'DEBUG' + log_level = 'BLE_MESH_LOG_LEVEL_DEBUG' + else: + return '' + if mod == 'NET': + used_log_levl = 'BLE_MESH_NET_BUF_LOG_LEVEL' + used_log_mod = 'BLE_MESH_NET_BUF' + else: + used_log_levl = 'BLE_MESH_LOG_LEVEL' + used_log_mod = 'BLE_MESH' + return ( + f'{{do {{ if (({used_log_levl} >= {log_level}) &&' + f' BLE_MESH_LOG_LEVEL_CHECK({used_log_mod}, {level})) {print_statm};}} while (0);}}\\\n' + ) + + +def gen_header_head() -> str: + head = textwrap.dedent(""" + // Compression function declarations + extern int ble_log_compressed_hex_print + (uint8_t source, uint32_t log_index, size_t args_size_cnt, ...); + extern int ble_log_compressed_hex_print_buf + (uint8_t source, uint32_t log_index, uint8_t buf_idx, const uint8_t *buf, size_t len); + """) + return head + + +def gen_compressed_stmt( + log_index: int, module_id: int, func_name: str, fmt: str, args: list[dict], buffer_args: list[dict] +) -> str: + if len(args) == 0: + stmt = f' ble_log_compressed_hex_print({module_id}, {log_index}, 0);' + for idx, buffer_arg in enumerate(buffer_args): + stmt += '\\\n' + stmt += ( + f' ble_log_compressed_hex_print_buf(' + f'{module_id}, {log_index}, {idx}, ' + f'(const uint8_t *){buffer_arg["buffer"]}, {buffer_arg["length"]});' + ) + stmt += '\\\n' + return ' ' + generate_mesh_log_prefix(func_name, stmt) + size_str = ', '.join([arg['size_type'] for arg in args]) + args_str = ', '.join([arg['name'] for arg in args]).replace('\n', '') + stmt = f' ble_log_compressed_hex_print({module_id}, {log_index}, {len(args)}, {size_str}, {args_str});' + for idx, buffer_arg in enumerate(buffer_args): + stmt += '\\\n' + stmt += ( + f' ble_log_compressed_hex_print_buf(' + f'{module_id}, {log_index}, {idx}, ' + f'(const uint8_t *){buffer_arg["buffer"]}, {buffer_arg["length"]});' + ) + stmt += '\\\n' + return ' ' + generate_mesh_log_prefix(func_name, stmt) diff --git a/components/bt/common/ble_log/extension/log_compression/scripts/module_scripts/bluedroid/make_bluedroid_log_macro.py b/components/bt/common/ble_log/extension/log_compression/scripts/module_scripts/bluedroid/make_bluedroid_log_macro.py new file mode 100644 index 0000000000..72be38c081 --- /dev/null +++ b/components/bt/common/ble_log/extension/log_compression/scripts/module_scripts/bluedroid/make_bluedroid_log_macro.py @@ -0,0 +1,61 @@ +# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +import textwrap + +BLUEDROID_LOG_MODE_LEVEL_GET = { + 'BTM': 'btm_cb.trace_level', + 'L2CAP': 'l2cb.l2cap_trace_level', + 'GAP': 'gap_cb.trace_level', + 'GATT': 'gatt_cb.trace_level', + 'SMP': 'smp_cb.trace_level', + 'APPL': 'appl_trace_level', +} + + +def generate_bluedroid_log_prefix(tag: str, print_statm: str) -> str: + tag_info = tag.split('_') + mod = tag_info[0] + + return ( + f'{{if ({BLUEDROID_LOG_MODE_LEVEL_GET[mod]} >= BT_TRACE_LEVEL_{tag_info[-1]} &&' + f' BT_LOG_LEVEL_CHECK({mod}, {tag_info[-1]})) {print_statm};}}\\\n' + ) + + +def gen_header_head() -> str: + head = textwrap.dedent(""" + // Compression function declarations + extern int ble_log_compressed_hex_print + (uint8_t source, uint32_t log_index, size_t args_size_cnt, ...); + extern int ble_log_compressed_hex_print_buf + (uint8_t source, uint32_t log_index, uint8_t buf_idx, const uint8_t *buf, size_t len); + """) + return head + + +def gen_compressed_stmt( + log_index: int, module_id: int, func_name: str, fmt: str, args: list[dict], buffer_args: list[dict] +) -> str: + if len(args) == 0: + stmt = f' ble_log_compressed_hex_print({module_id},{log_index}, 0);' + for idx, buffer_arg in enumerate(buffer_args): + stmt += '\\\n' + stmt += ( + f' ble_log_compressed_hex_print_buf(' + f'{module_id}, {log_index}, {idx}, ' + f'(const uint8_t *){buffer_arg["buffer"]}, {buffer_arg["length"]});' + ) + stmt += '\\\n' + return ' ' + generate_bluedroid_log_prefix(func_name, stmt) + size_str = ', '.join([arg['size_type'] for arg in args]) + args_str = ', '.join([arg['name'] for arg in args]).replace('\n', '') + stmt = f' ble_log_compressed_hex_print({module_id},{log_index}, {len(args)}, {size_str}, {args_str});' + for idx, buffer_arg in enumerate(buffer_args): + stmt += '\\\n' + stmt += ( + f' ble_log_compressed_hex_print_buf(' + f'{module_id}, {log_index}, {idx}, ' + f'(const uint8_t *){buffer_arg["buffer"]}, {buffer_arg["length"]});' + ) + stmt += '\\\n' + return ' ' + generate_bluedroid_log_prefix(func_name, stmt) From cba983628d4ea38bb5ebd3574ab49c158a5164d6 Mon Sep 17 00:00:00 2001 From: yangfeng Date: Wed, 24 Dec 2025 19:25:21 +0800 Subject: [PATCH 016/226] fix(bt/bluedroid): Fix index boundary check and function return in SEP registration Closes https://github.com/espressif/esp-idf/issues/18041 --- components/bt/host/bluedroid/bta/av/bta_av_main.c | 4 ++-- components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/components/bt/host/bluedroid/bta/av/bta_av_main.c b/components/bt/host/bluedroid/bta/av/bta_av_main.c index 7ccd3423a4..cf634f2525 100644 --- a/components/bt/host/bluedroid/bta/av/bta_av_main.c +++ b/components/bt/host/bluedroid/bta/av/bta_av_main.c @@ -763,7 +763,7 @@ static void bta_av_api_reg_sep(tBTA_AV_DATA *p_data) sep_reg.seid = p_data->api_reg_sep.seid; sep_reg.reg_state = BTA_AV_FAIL; - if (index > BTA_AV_MAX_SEPS || p_data->hdr.layer_specific != BTA_AV_CHNL_AUDIO) { + if (index >= BTA_AV_MAX_SEPS || p_data->hdr.layer_specific != BTA_AV_CHNL_AUDIO) { (*bta_av_cb.p_cback)(BTA_AV_SEP_REG_EVT, (tBTA_AV *)&sep_reg); APPL_TRACE_WARNING("%s invalid parameter: seid %d, ch %d", __FUNCTION__, index, p_data->hdr.layer_specific); return; @@ -815,6 +815,7 @@ static void bta_av_api_reg_sep(tBTA_AV_DATA *p_data) p_scb->seps[index].codec_type = codec_type; p_scb->seps[index].tsep = cs.tsep; p_scb->seps[index].p_app_data_cback = p_data->api_reg_sep.p_data_cback; + sep_reg.reg_state = BTA_AV_SUCCESS; } else { APPL_TRACE_WARNING("%s fail to create sep", __FUNCTION__); break; @@ -826,7 +827,6 @@ static void bta_av_api_reg_sep(tBTA_AV_DATA *p_data) } } - sep_reg.reg_state = BTA_AV_SUCCESS; (*bta_av_cb.p_cback)(BTA_AV_SEP_REG_EVT, (tBTA_AV *)&sep_reg); #endif } diff --git a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c index 1fd74b6ada..e52102a845 100644 --- a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c +++ b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c @@ -1459,6 +1459,7 @@ static void btc_av_reg_sep(uint8_t tsep, uint8_t seid, esp_a2d_mcc_t *mcc) param.a2d_sep_reg_stat.reg_state = ESP_A2D_SEP_REG_INVALID_STATE; btc_a2d_cb_to_app(ESP_A2D_SEP_REG_STATE_EVT, ¶m); BTC_TRACE_WARNING("%s: try to reg sep when a2dp not init or connected", __func__); + return; } if (mcc->type == ESP_A2D_MCT_SBC) { From 7887b65d0298aa32c8242b34e25415758b22de73 Mon Sep 17 00:00:00 2001 From: Jin Chen Date: Wed, 3 Dec 2025 11:40:47 +0800 Subject: [PATCH 017/226] fix(ble): fix pawr set subevent data length error (cherry picked from commit 17462a379bb3931285f6886b7554a7959bd7dcd4) Co-authored-by: cjin --- components/bt/host/nimble/nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 9551ac31af..32e8ddac58 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 9551ac31af0348d7de6cbe7527de3e5ba205460d +Subproject commit 32e8ddac58211e87cca910a08e025ab5f84fb4d4 From 6d0e282513e8ebdc3cf85b7d4005902cffc98fed Mon Sep 17 00:00:00 2001 From: Jin Chen Date: Wed, 3 Dec 2025 11:40:47 +0800 Subject: [PATCH 018/226] fix(ble): fix hci log malloc failure crash (cherry picked from commit 734031311ad8554b600718bf8add68836121f72b) Co-authored-by: cjin --- components/bt/common/hci_log/bt_hci_log.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/bt/common/hci_log/bt_hci_log.c b/components/bt/common/hci_log/bt_hci_log.c index fa3de907d6..fef3760b3f 100644 --- a/components/bt/common/hci_log/bt_hci_log.c +++ b/components/bt/common/hci_log/bt_hci_log.c @@ -225,6 +225,10 @@ esp_err_t IRAM_ATTR bt_hci_log_record_data(bt_hci_log_t *p_hci_log_ctl, char *st ts = esp_timer_get_time(); temp_buf = (uint8_t *)malloc(data_len + 8); + if (!temp_buf) { + return ESP_ERR_NO_MEM; + } + memset(temp_buf, 0x0, data_len + 8); memcpy(temp_buf, &ts, 8); From 6940ade505d1a32d5ee1f813f1eb00fce4f57040 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Thu, 27 Nov 2025 12:22:18 +0530 Subject: [PATCH 019/226] fix(nimble): Add missing header file to fix compilation issue --- components/bt/host/nimble/nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 32e8ddac58..686728c09e 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 32e8ddac58211e87cca910a08e025ab5f84fb4d4 +Subproject commit 686728c09ec94a86afeeb58a936a9f6a4ab5fd83 From e362f90277023ff16f438003b282c337956ec6bd Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 3 Sep 2025 17:25:44 +0530 Subject: [PATCH 020/226] feat(nimble): Add support for static passkey --- components/bt/host/nimble/Kconfig.in | 7 ++++++- components/bt/host/nimble/nimble | 2 +- components/bt/host/nimble/port/include/esp_nimble_cfg.h | 8 ++++++++ examples/bluetooth/nimble/blecent/README.md | 8 ++++++++ examples/bluetooth/nimble/blecent/main/main.c | 4 ++++ examples/bluetooth/nimble/bleprph/README.md | 8 ++++++++ examples/bluetooth/nimble/bleprph/main/main.c | 4 ++++ 7 files changed, 39 insertions(+), 2 deletions(-) diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index cc3b71a8f8..c3fe16e729 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -1249,7 +1249,12 @@ menu "Extra Features" help Enable connection subrate change feature - + config BT_NIMBLE_STATIC_PASSKEY + bool "Enable support for Static Passkey" + default n + depends on BT_NIMBLE_ENABLED && BT_NIMBLE_SECURITY_ENABLE + help + Enable support for user defined static passkey for SMP endmenu menu "NimBLE Mesh" diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 686728c09e..445bdeb281 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 686728c09ec94a86afeeb58a936a9f6a4ab5fd83 +Subproject commit 445bdeb281ca49d324232c9f53bc30b7a4784ef9 diff --git a/components/bt/host/nimble/port/include/esp_nimble_cfg.h b/components/bt/host/nimble/port/include/esp_nimble_cfg.h index 445c0e2957..4fad474a43 100644 --- a/components/bt/host/nimble/port/include/esp_nimble_cfg.h +++ b/components/bt/host/nimble/port/include/esp_nimble_cfg.h @@ -2230,4 +2230,12 @@ #endif #endif +#ifndef MYNEWT_VAL_STATIC_PASSKEY +#ifdef CONFIG_BT_NIMBLE_STATIC_PASSKEY +#define MYNEWT_VAL_STATIC_PASSKEY CONFIG_BT_NIMBLE_STATIC_PASSKEY +#else +#define CONFIG_BT_NIMBLE_STATIC_PASSKEY (0) +#endif +#endif + #endif diff --git a/examples/bluetooth/nimble/blecent/README.md b/examples/bluetooth/nimble/blecent/README.md index 28ab5061ff..f0efe0eb95 100644 --- a/examples/bluetooth/nimble/blecent/README.md +++ b/examples/bluetooth/nimble/blecent/README.md @@ -61,6 +61,14 @@ idf.py menuconfig In the `Example Configuration` menu: * Change the `Peer Address` option if needed. +* Optional: enable static passkey support via `Component config -> Bluetooth -> NimBLE -> Enable support for Static Passkey`. + +Static passkey mode is useful for demos where you want to avoid interactive passkey entry. +When enabled, the example calls `ble_sm_configure_static_passkey(456789, true)` and NimBLE +automatically injects the passkey during pairing. Update the passkey in +`examples/bluetooth/nimble/blecent/main/main.c` if you want a different value. +Both devices must use the same 6-digit passkey, and you should only use a fixed +passkey for development or controlled environments. ### Build and Flash diff --git a/examples/bluetooth/nimble/blecent/main/main.c b/examples/bluetooth/nimble/blecent/main/main.c index b73ebe974f..652cbe05fe 100644 --- a/examples/bluetooth/nimble/blecent/main/main.c +++ b/examples/bluetooth/nimble/blecent/main/main.c @@ -1098,6 +1098,10 @@ app_main(void) ble_hs_cfg.store_status_cb = ble_store_util_status_rr; #if NIMBLE_BLE_CONNECT +#if MYNEWT_VAL(STATIC_PASSKEY) + ble_sm_configure_static_passkey(456789, true); +#endif + int rc; /* Initialize data structures to track connected peers. */ #if MYNEWT_VAL(BLE_INCL_SVC_DISCOVERY) || MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) diff --git a/examples/bluetooth/nimble/bleprph/README.md b/examples/bluetooth/nimble/bleprph/README.md index 390cbbc8d5..b1b64f47f9 100644 --- a/examples/bluetooth/nimble/bleprph/README.md +++ b/examples/bluetooth/nimble/bleprph/README.md @@ -41,6 +41,14 @@ In the `Example Configuration` menu: * Select I/O capabilities of device from `Example Configuration --> I/O Capability`, default is `Just_works`. * Enable/Disable other security related parameters `Bonding, MITM option, secure connection(SM SC)`. +* Optional: enable static passkey support via `Component config -> Bluetooth -> NimBLE -> Enable support for Static Passkey`. + +Static passkey mode is useful for demos where you want to avoid interactive passkey entry. +When enabled, the example calls `ble_sm_configure_static_passkey(456789, true)` and NimBLE +automatically injects the passkey during pairing. Update the passkey in +`examples/bluetooth/nimble/bleprph/main/main.c` if you want a different value. +Both devices must use the same 6-digit passkey, and you should only use a fixed +passkey for development or controlled environments. ### Build and Flash diff --git a/examples/bluetooth/nimble/bleprph/main/main.c b/examples/bluetooth/nimble/bleprph/main/main.c index d0eb370709..8b705fbd68 100644 --- a/examples/bluetooth/nimble/bleprph/main/main.c +++ b/examples/bluetooth/nimble/bleprph/main/main.c @@ -599,6 +599,10 @@ app_main(void) ble_hs_cfg.sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ID; #endif +#if MYNEWT_VAL(STATIC_PASSKEY) && NIMBLE_BLE_CONNECT + ble_sm_configure_static_passkey(456789, true); +#endif + #if MYNEWT_VAL(BLE_GATTS) rc = gatt_svr_init(); assert(rc == 0); From eaddb805e757c1db19fbb8a4991bb7f225bb3d96 Mon Sep 17 00:00:00 2001 From: Astha Verma Date: Fri, 26 Sep 2025 18:56:11 +0530 Subject: [PATCH 021/226] fix(nimble): Modify GATT data storage structure in NVS during gatt caching --- components/bt/host/nimble/nimble | 2 +- components/bt/host/nimble/port/src/nvs_port.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 445bdeb281..450d35aae0 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 445bdeb281ca49d324232c9f53bc30b7a4784ef9 +Subproject commit 450d35aae01161d271c6eb2cddc6444519baee67 diff --git a/components/bt/host/nimble/port/src/nvs_port.c b/components/bt/host/nimble/port/src/nvs_port.c index 19d89a063c..02a22afc5b 100644 --- a/components/bt/host/nimble/port/src/nvs_port.c +++ b/components/bt/host/nimble/port/src/nvs_port.c @@ -32,9 +32,11 @@ link_storage_fn(void *storage_cb) struct cache_fn_mapping cache_fn; cache_fn.open = nvs_open_custom; cache_fn.close = nvs_close; + cache_fn.erase_key_item = nvs_erase_key; cache_fn.erase_all = nvs_erase_all; cache_fn.write = nvs_set_blob; cache_fn.read = nvs_get_blob; + cache_fn.commit = nvs_commit; return cache_fn; } #endif From d6da79db085ff13b8cd5cff61c5962acc003a01e Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 26 Nov 2025 12:22:27 +0530 Subject: [PATCH 022/226] fix(nimble): Memory optimization + dynamic memory support --- components/bt/CMakeLists.txt | 4 + components/bt/host/nimble/Kconfig.in | 477 +++++++++++------- .../host/nimble/esp-hci/src/esp_nimble_hci.c | 20 +- components/bt/host/nimble/nimble | 2 +- .../host/nimble/port/include/esp_nimble_cfg.h | 132 ++++- .../host/nimble/port/include/esp_nimble_mem.h | 47 +- components/bt/porting/include/bt_osi_mem.h | 79 +++ components/bt/porting/mem/bt_osi_mem.c | 276 +++++++++- components/bt/porting/mem/os_msys_init.c | 13 +- .../npl/freertos/src/npl_os_freertos.c | 7 + .../bt/porting/transport/src/hci_transport.c | 2 + 11 files changed, 841 insertions(+), 218 deletions(-) diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index a215bd4e8e..76e28d48b7 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -676,6 +676,10 @@ if(CONFIG_BT_ENABLED) "porting/transport/src/hci_transport.c" ) + list(APPEND include_dirs + host/nimble/port/include + ) + if(CONFIG_BT_CONTROLLER_DISABLED) list(APPEND srcs "host/nimble/nimble/porting/nimble/src/hal_uart.c" diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index c3fe16e729..dc82f62561 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -80,28 +80,28 @@ menu "Roles and Profiles" depends on BT_NIMBLE_ENABLED default y help - Enables central role + Enables BLE Central role config BT_NIMBLE_ROLE_PERIPHERAL bool "Enable BLE Peripheral role" depends on BT_NIMBLE_ENABLED default y help - Enable peripheral role + Enable BLE Peripheral role config BT_NIMBLE_ROLE_BROADCASTER bool "Enable BLE Broadcaster role" depends on BT_NIMBLE_ENABLED default y help - Enables broadcaster role + Enables BLE broadcaster role config BT_NIMBLE_ROLE_OBSERVER bool "Enable BLE Observer role" depends on BT_NIMBLE_ENABLED default y help - Enables observer role + Enables BLE Observer role config BT_NIMBLE_GATT_CLIENT bool "Enable BLE GATT Client support" @@ -127,57 +127,84 @@ menu "Security (SMP)" help Enable BLE sm feature - config BT_NIMBLE_SM_LEGACY - bool "Security manager legacy pairing" - depends on BT_NIMBLE_SECURITY_ENABLE - default y - help - Enable security manager legacy pairing + if BT_NIMBLE_SECURITY_ENABLE + config BT_NIMBLE_SM_LEGACY + bool "Security manager legacy pairing" + default y + help + Enable security manager legacy pairing - config BT_NIMBLE_SM_SC - bool "Security manager secure connections (4.2)" - depends on BT_NIMBLE_SECURITY_ENABLE - default y - help - Enable security manager secure connections + config BT_NIMBLE_SM_SC + bool "Security manager secure connections (4.2)" + default y + help + Enable security manager secure connections - config BT_NIMBLE_SM_SC_DEBUG_KEYS - bool "Use predefined public-private key pair" - default n - depends on BT_NIMBLE_SECURITY_ENABLE && BT_NIMBLE_SM_SC - help - If this option is enabled, SM uses predefined DH key pair as described - in Core Specification, Vol. 3, Part H, 2.3.5.6.1. This allows to - decrypt air traffic easily and thus should only be used for debugging. + config BT_NIMBLE_SM_SC_DEBUG_KEYS + bool "Use predefined public-private key pair" + default n + depends on BT_NIMBLE_SM_SC + help + If this option is enabled, SM uses predefined DH key pair as described + in Core Specification, Vol. 3, Part H, 2.3.5.6.1. This allows to + decrypt air traffic easily and thus should only be used for debugging. - config BT_NIMBLE_LL_CFG_FEAT_LE_ENCRYPTION - bool "Enable LE encryption" - depends on BT_NIMBLE_SECURITY_ENABLE && BT_NIMBLE_ENABLED - default y - help - Enable encryption connection + config BT_NIMBLE_LL_CFG_FEAT_LE_ENCRYPTION + bool "Enable LE encryption" + default y + help + Enable encryption connection - config BT_NIMBLE_SM_LVL - int "Security level" - depends on BT_NIMBLE_SECURITY_ENABLE - default 0 - help - LE Security Mode 1 Levels: - 1. No Security - 2. Unauthenticated pairing with encryption - 3. Authenticated pairing with encryption - 4. Authenticated LE Secure Connections pairing with encryption using a 128-bit strength encryption key. + config BT_NIMBLE_SM_LVL + int "Security level" + default 0 + help + LE Security Mode 1 Levels: + 1. No Security + 2. Unauthenticated pairing with encryption + 3. Authenticated pairing with encryption + 4. Authenticated LE Secure Connections pairing with encryption using a 128-bit strength encryption key. - config BT_NIMBLE_SM_SC_ONLY - int "Enable Secure Connections Only Mode" - depends on BT_NIMBLE_SECURITY_ENABLE - default 0 - help - Enable Secure Connections Only Mode + config BT_NIMBLE_SM_SC_ONLY + int "Enable Secure Connections Only Mode" + default 0 + help + Enable Secure Connections Only Mode + config BT_NIMBLE_SMP_ID_RESET + bool "Reset device identity when all bonding records are deleted" + default n + help + There are tracking risks associated with using a fixed or static IRK. + If enabled this option, NimBLE will assign a new randomly-generated IRK + when all pairing and bonding records are deleted. This would decrease the ability + of a previously paired peer to be used to determine whether a device + with which it previously shared an IRK is within range. + + config BT_NIMBLE_NVS_PERSIST + bool "Persist the BLE Bonding keys in NVS" + default n + help + Enable this flag to make bonding persistent across device reboots + + config BT_NIMBLE_MAX_BONDS + int "Maximum number of bonds to save across reboots" + default 3 + help + Defines maximum number of bonds to save for peer security and our security + + config BT_NIMBLE_HANDLE_REPEAT_PAIRING_DELETION + bool "Enable stack handling of repeat pairing" + default n + help + Use this option to let stack internally handle the request for repeat pairing. + Enabling this option will delete the pairing of the device and stack will NOT post any event + to application. If this option is disabled, application will get BLE_GAP_EVENT_REPEAT_PAIRING + event. + endif endmenu #SMP -menu "GAP / GATT / Device Settings" +menu "GAP" config BT_NIMBLE_RPA_TIMEOUT int "RPA timeout in seconds" range 1 41400 @@ -193,15 +220,15 @@ menu "GAP / GATT / Device Settings" range 1 15 default 12 help - BLE list size + BLE Whitelist size config BT_NIMBLE_ENABLE_CONN_REATTEMPT bool "Enable connection reattempts on connection establishment error" default y if (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || SOC_ESP_NIMBLE_CONTROLLER) default n if IDF_TARGET_ESP32 help - Enable to make the NimBLE host to reattempt GAP connection on connection - establishment failure. + Enable to make the NimBLE host to reattempt GAP connection attempt in case of + connection establishment failure due to reason 0x3E. config BT_NIMBLE_MAX_CONN_REATTEMPT int "Maximum number connection reattempts" @@ -211,23 +238,23 @@ menu "GAP / GATT / Device Settings" help Defines maximum number of connection reattempts. - config BT_NIMBLE_HANDLE_REPEAT_PAIRING_DELETION - bool "Enable stack handling of repeat pairing" - default n + config BT_NIMBLE_HS_PVCY + bool "Enable privacy related APIs" + default y depends on BT_NIMBLE_ENABLED help - Use this option to let stack internally handle the request for repeat pairing. - Enabling this option will delete the pairing of the device and stack will NOT post any event - to application. If this option is disabled, application will get BLE_GAP_EVENT_REPEAT_PAIRING - event. + Enable this option to include host-side APIs related to BLE privacy. + Disable it if your application does not require privacy features (such as + RPA generation, resolving, or privacy-based pairing). Disabling this option + excludes privacy-related code from the host to reduce memory usage. config BT_NIMBLE_HOST_BASED_PRIVACY bool "Enable host based privacy for random address." default n - depends on BT_NIMBLE_ENABLED && IDF_TARGET_ESP32 + depends on BT_NIMBLE_ENABLED && BT_NIMBLE_HS_PVCY && IDF_TARGET_ESP32 help Use this option to do host based Random Private Address resolution. - If this option is disabled then controller based privacy is used. + This option is valid only for ESP32 config BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN bool "Allow Connections with scanning in progress" @@ -246,6 +273,7 @@ menu "GAP / GATT / Device Settings" config BT_NIMBLE_MAX_CONNECTIONS int "Maximum number of concurrent connections" + depends on BT_NIMBLE_ROLE_CENTRAL || BT_NIMBLE_ROLE_PERIPHERAL range 1 2 if IDF_TARGET_ESP32C2 range 1 70 if SOC_ESP_NIMBLE_CONTROLLER range 1 9 @@ -259,60 +287,13 @@ menu "GAP / GATT / Device Settings" configure BT_CTRL_BLE_MAX_ACT from controller menu. For ESP32C2, ESP32C6 and ESP32H2, each connection will take about 1k DRAM. - config BT_NIMBLE_MAX_BONDS - int "Maximum number of bonds to save across reboots" - default 3 - depends on BT_NIMBLE_ENABLED - help - Defines maximum number of bonds to save for peer security and our security - config BT_NIMBLE_MAX_CCCDS int "Maximum number of CCC descriptors to save across reboots" default 8 - depends on BT_NIMBLE_ENABLED + depends on BT_NIMBLE_ENABLED && BT_NIMBLE_NVS_PERSIST help Defines maximum number of CCC descriptors to save - - config BT_NIMBLE_NVS_PERSIST - bool "Persist the BLE Bonding keys in NVS" - depends on BT_NIMBLE_ENABLED - default n - help - Enable this flag to make bonding persistent across device reboots - - config BT_NIMBLE_SMP_ID_RESET - bool "Reset device identity when all bonding records are deleted" - default n - help - There are tracking risks associated with using a fixed or static IRK. - If enabled this option, NimBLE will assign a new randomly-generated IRK - when all pairing and bonding records are deleted. This would decrease the ability - of a previously paired peer to be used to determine whether a device - with which it previously shared an IRK is within range. - - config BT_NIMBLE_ATT_PREFERRED_MTU - int "Preferred MTU size in octets" - depends on BT_NIMBLE_ENABLED - default 256 - help - This is the default value of ATT MTU indicated by the device during an ATT MTU exchange. - This value can be changed using API ble_att_set_preferred_mtu() - - config BT_NIMBLE_ATT_MAX_PREP_ENTRIES - int "Max Prepare write entries" - depends on BT_NIMBLE_ENABLED - default 64 - help - This is the default value of ATT Maximum prepare entries - - config BT_NIMBLE_GATT_MAX_PROCS - int "Maximum number of GATT client procedures" - depends on BT_NIMBLE_ENABLED - default 4 - help - Maximum number of GATT client procedures that can be executed. - config BT_NIMBLE_CRYPTO_STACK_MBEDTLS bool "Override TinyCrypt with mbedTLS for crypto computations" default y @@ -329,19 +310,12 @@ menu "GAP / GATT / Device Settings" help BLE Host stop procedure timeout in milliseconds. - config BT_NIMBLE_USE_ESP_TIMER bool "Enable Esp Timer for Nimble" default y help Set this option to use Esp Timer which has higher priority timer instead of FreeRTOS timer - config BT_NIMBLE_BLE_GATT_BLOB_TRANSFER - bool "Blob transfer" - help - This option is used when data to be sent is more than 512 bytes. For peripheral role, - BT_NIMBLE_MSYS_1_BLOCK_COUNT needs to be increased according to the need. - config BT_NIMBLE_HS_FLOW_CTRL bool "Enable Host Flow control" depends on BT_NIMBLE_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER @@ -376,6 +350,113 @@ menu "GAP / GATT / Device Settings" endmenu #GAP +menu "GATT / ATT" + config BT_NIMBLE_ATT_PREFERRED_MTU + int "Preferred MTU size in octets" + depends on BT_NIMBLE_GATT_CLIENT || BT_NIMBLE_GATT_SERVER + default 256 + help + This is the default value of ATT MTU indicated by the device during an ATT MTU exchange. + This value can be changed using API ble_att_set_preferred_mtu() + + config BT_NIMBLE_ATT_MAX_PREP_ENTRIES + int "Max Prepare write entries" + depends on BT_NIMBLE_GATT_CLIENT || BT_NIMBLE_GATT_SERVER + default 64 + help + This is the default value of ATT Maximum prepare entries + + config BT_NIMBLE_GATT_MAX_PROCS + int "Maximum number of GATT client procedures" + depends on BT_NIMBLE_GATT_CLIENT || BT_NIMBLE_GATT_SERVER + default 4 + help + Maximum number of GATT client procedures that can be executed. + + config BT_NIMBLE_BLE_GATT_BLOB_TRANSFER + bool "Blob transfer" + depends on BT_NIMBLE_GATT_CLIENT || BT_NIMBLE_GATT_SERVER + help + This option is used when data to be sent is more than 512 bytes. For peripheral role, + BT_NIMBLE_MSYS_1_BLOCK_COUNT needs to be increased according to the need. + + + menuconfig BT_NIMBLE_GATT_CACHING + bool "Enable GATT caching" + depends on BT_NIMBLE_ENABLED + select BT_NIMBLE_DYNAMIC_SERVICE + help + Enable GATT caching + + config BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES + bool "Include services in GATT caching" + depends on BT_NIMBLE_GATT_CACHING + default n + help + Enable this option to include *included services* (e.g., services referenced by other services) + in the GATT database cache. Disabling this will skip caching of included service entries. + + config BT_NIMBLE_INCL_SVC_DISCOVERY + bool + default y if BT_NIMBLE_GATT_CACHING && BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES + default n if BT_NIMBLE_GATT_CACHING && !BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES + default n if !BT_NIMBLE_GATT_CACHING + prompt "Enable Included service discovery" if !BT_NIMBLE_GATT_CACHING + help + Enable this option to start discovery for included service. + + config BT_NIMBLE_GATT_CACHING_MAX_CONNS + int "Maximum connections to be cached" + depends on BT_NIMBLE_GATT_CACHING + default BT_NIMBLE_MAX_CONNECTIONS + help + Set this option to set the upper limit on number of connections to be cached. + + config BT_NIMBLE_GATT_CACHING_MAX_SVCS + int "Maximum number of services per connection" + depends on BT_NIMBLE_GATT_CACHING + default 64 + help + Set this option to set the upper limit on number of services per connection to be cached. + + config BT_NIMBLE_GATT_CACHING_MAX_INCL_SVCS + int "Maximum number of included services per connection" + depends on BT_NIMBLE_GATT_CACHING + default 64 + help + Set this option to set the upper limit on number of included services per connection to be cached. + + config BT_NIMBLE_GATT_CACHING_MAX_CHRS + int "Maximum number of characteristics per connection" + depends on BT_NIMBLE_GATT_CACHING + default 64 + help + Set this option to set the upper limit on number of characteristics per connection to be cached. + + config BT_NIMBLE_GATT_CACHING_MAX_DSCS + int "Maximum number of descriptors per connection" + depends on BT_NIMBLE_GATT_CACHING + default 64 + help + Set this option to set the upper limit on number of descriptors per connection to be cached. + + config BT_NIMBLE_GATT_CACHING_DISABLE_AUTO + bool "Do not start discovery procedure automatically upon receiving Out of Sync" + depends on BT_NIMBLE_GATT_CACHING + default n + help + When client receives ATT out-of-sync error message, it will not automatically start the discovery procedure + to correct the invalid cache. + + config BT_NIMBLE_GATT_CACHING_ASSOC_ENABLE + bool "Enable association-based GATT caching" + depends on BT_NIMBLE_GATT_CACHING + default n + help + Enable this option to use associated address caching instead of performing service discovery. + +endmenu #GATT/ATT + menu "L2CAP" config BT_NIMBLE_L2CAP_COC_MAX_NUM int "Maximum number of connection oriented channels" @@ -388,7 +469,7 @@ menu "L2CAP" config BT_NIMBLE_L2CAP_ENHANCED_COC bool "L2CAP Enhanced Connection Oriented Channel" depends on BT_NIMBLE_ENABLED && (BT_NIMBLE_L2CAP_COC_MAX_NUM >= 1) - default 0 + default n help Enable Enhanced Credit Based Flow Control Mode @@ -416,7 +497,7 @@ menu "Memory Settings" int "MSYS_2 Block Count" default 24 help - Dynamic memory count + Dynamic memory count for block 2 config BT_NIMBLE_MSYS_2_BLOCK_SIZE int "MSYS_2 Block Size" @@ -735,7 +816,7 @@ menu "BLE 6.x Features" depends on BT_NIMBLE_ENABLED && (SOC_BLE_60_SUPPORTED || BT_CONTROLLER_DISABLED) default n help - Enable BLE 6 feature + Enable BLE 6.x feature support if BT_NIMBLE_60_FEATURE_SUPPORT config BT_NIMBLE_CHANNEL_SOUNDING @@ -1123,80 +1204,6 @@ menu "Extra Features" help This enables user to add/remove Gatt services at runtime - menuconfig BT_NIMBLE_GATT_CACHING - bool "Enable GATT caching" - depends on BT_NIMBLE_ENABLED - select BT_NIMBLE_DYNAMIC_SERVICE - help - Enable GATT caching - - config BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES - bool "Include services in GATT caching" - depends on BT_NIMBLE_GATT_CACHING - default n - help - Enable this option to include *included services* (e.g., services referenced by other services) - in the GATT database cache. Disabling this will skip caching of included service entries. - - config BT_NIMBLE_INCL_SVC_DISCOVERY - bool - default y if BT_NIMBLE_GATT_CACHING && BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES - default n if BT_NIMBLE_GATT_CACHING && !BT_NIMBLE_GATT_CACHING_INCLUDE_SERVICES - default n if !BT_NIMBLE_GATT_CACHING - prompt "Enable Included service discovery" if !BT_NIMBLE_GATT_CACHING - help - Enable this option to start discovery for included service. - - config BT_NIMBLE_GATT_CACHING_MAX_CONNS - int "Maximum connections to be cached" - depends on BT_NIMBLE_GATT_CACHING - default BT_NIMBLE_MAX_CONNECTIONS - help - Set this option to set the upper limit on number of connections to be cached. - - config BT_NIMBLE_GATT_CACHING_MAX_SVCS - int "Maximum number of services per connection" - depends on BT_NIMBLE_GATT_CACHING - default 64 - help - Set this option to set the upper limit on number of services per connection to be cached. - - config BT_NIMBLE_GATT_CACHING_MAX_INCL_SVCS - int "Maximum number of included services per connection" - depends on BT_NIMBLE_GATT_CACHING - default 64 - help - Set this option to set the upper limit on number of included services per connection to be cached. - - config BT_NIMBLE_GATT_CACHING_MAX_CHRS - int "Maximum number of characteristics per connection" - depends on BT_NIMBLE_GATT_CACHING - default 64 - help - Set this option to set the upper limit on number of characteristics per connection to be cached. - - config BT_NIMBLE_GATT_CACHING_MAX_DSCS - int "Maximum number of descriptors per connection" - depends on BT_NIMBLE_GATT_CACHING - default 64 - help - Set this option to set the upper limit on number of descriptors per connection to be cached. - - config BT_NIMBLE_GATT_CACHING_DISABLE_AUTO - bool "Do not start discovery procedure automatically upon receiving Out of Sync" - depends on BT_NIMBLE_GATT_CACHING - default n - help - When client receives ATT out-of-sync error message, it will not automatically start the discovery procedure - to correct the invalid cache. - - config BT_NIMBLE_GATT_CACHING_ASSOC_ENABLE - bool "Enable association-based GATT caching" - depends on BT_NIMBLE_GATT_CACHING - default n - help - Enable this option to use associated address caching instead of performing service discovery. - config BT_NIMBLE_BLUFI_ENABLE bool "Enable blufi functionality" depends on BT_NIMBLE_ENABLED @@ -1234,7 +1241,6 @@ menu "Extra Features" error suggests insufficient security, then the central will initiate pairing and retry the service request. - config BT_NIMBLE_EATT_CHAN_NUM int "Maximum number of EATT channels" default 0 @@ -1255,6 +1261,58 @@ menu "Extra Features" depends on BT_NIMBLE_ENABLED && BT_NIMBLE_SECURITY_ENABLE help Enable support for user defined static passkey for SMP + + config BT_NIMBLE_DTM_MODE_TEST + bool "Enable DTM related test procedure support" + default y + depends on BT_NIMBLE_ENABLED + help + Enable DTM related test procedure support + + config BT_NIMBLE_MEM_OPTIMIZATION + bool "Enable memory optimization" + depends on BT_NIMBLE_ENABLED + default y + help + This option enables memory optimizations in the NimBLE stack. + + config BT_NIMBLE_STATIC_TO_DYNAMIC + bool "Use Dynamic Memory allocations instead of static" + depends on BT_NIMBLE_ENABLED + default y + help + This option enables use of dynamic memory allocation instead of static + allocation for variable global / local variable. This helps in improving + memory footprint + + config BT_NIMBLE_SM_SIGN_CNT + bool "Enable Sign counter operations" + default y + depends on BT_NIMBLE_ENABLED + help + Enable Sign counter operations + + config BT_NIMBLE_CPFD_CAFD + bool "Enable CPFD/CAPD support" + default y + depends on BT_NIMBLE_ENABLED + help + Enable CPFD and CAPD gatt descriptors support + + config BT_NIMBLE_RECONFIG_MTU + bool "Reconfig L2CAP MTU support" + default y + depends on BT_NIMBLE_ENABLED + help + Enable Support to reconfigure L2CAP MTU / MPS + + config BT_NIMBLE_LOW_SPEED_MODE + bool "Reduce DRAM/IRAM usage by moving GATT/GAP/NPL functions to FLASH" + default n + help + Disabling IRAM-optimized paths will place functions in FLASH (.irom.text) + instead of DRAM (.iram.text/.text in internal RAM). Suitable for low-speed + GAP/GATT operations to reduce RAM usage. endmenu menu "NimBLE Mesh" @@ -1474,6 +1532,16 @@ menu "Host-controller Transport" endmenu #Transport menu "Debugging/Testing" + config BT_NIMBLE_MEM_DEBUG + bool "NimBLE memory debug" + depends on BT_NIMBLE_ENABLED && !BT_NIMBLE_ISO + default n + help + Enable NimBLE memory debug to track memory allocations and deallocations. + This feature records the function name, line number, and size of each allocation, + and provides APIs to display memory usage statistics, find memory leaks, and + monitor peak memory usage. + choice BT_NIMBLE_LOG_LEVEL prompt "NimBLE Host log verbosity" depends on BT_NIMBLE_ENABLED @@ -1552,3 +1620,28 @@ menu "Vendor / Optimization" help This enable BLE high duty advertising interval feature endmenu #Vendor + +menu "Helper Utils" + config BT_NIMBLE_CHK_HOST_STATUS + bool "Enable host status query support" + default y + depends on BT_NIMBLE_ENABLED + help + Enable support to query host status + + config BT_NIMBLE_UTIL_API + bool "Enable helper APIs" + default y + depends on BT_NIMBLE_ENABLED + help + Enable support for misc APIs like set data addr change, read local resolv addr + and set host feature + + config BT_NIMBLE_EXTRA_ADV_FIELDS + bool "Enable extra Adv report fields parsing" + default y + depends on BT_NIMBLE_ENABLED + help + Enable support for parsing of more adv fields as per spec + +endmenu diff --git a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c index bffd7ee140..6dded0363b 100644 --- a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c +++ b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c @@ -35,8 +35,10 @@ static ble_hci_trans_rx_cmd_fn *ble_hci_rx_cmd_hs_cb; static void *ble_hci_rx_cmd_hs_arg; +#if NIMBLE_BLE_CONNECT static ble_hci_trans_rx_acl_fn *ble_hci_rx_acl_hs_cb; static void *ble_hci_rx_acl_hs_arg; +#endif /* * The MBUF payload size must accommodate the HCI data header size plus the @@ -54,8 +56,9 @@ const static char *TAG = "NimBLE"; int os_msys_buf_alloc(void); void os_msys_buf_free(void); +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) extern uint8_t ble_hs_enabled_state; - +#endif void ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb, void *cmd_arg, ble_hci_trans_rx_acl_fn *acl_cb, @@ -63,8 +66,10 @@ void ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb, { ble_hci_rx_cmd_hs_cb = cmd_cb; ble_hci_rx_cmd_hs_arg = cmd_arg; +#if NIMBLE_BLE_CONNECT ble_hci_rx_acl_hs_cb = acl_cb; ble_hci_rx_acl_hs_arg = acl_arg; +#endif } void esp_vhci_host_send_packet_wrapper(uint8_t *data, uint16_t len) @@ -112,6 +117,7 @@ int ble_hci_trans_ll_evt_tx(uint8_t *hci_ev) return rc; } +#if NIMBLE_BLE_CONNECT int ble_hci_trans_hs_acl_tx(struct os_mbuf *om) { uint16_t len = 0; @@ -141,6 +147,7 @@ int ble_hci_trans_hs_acl_tx(struct os_mbuf *om) return rc; } +#endif int ble_hci_trans_ll_acl_tx(struct os_mbuf *om) { @@ -160,7 +167,7 @@ int ble_hci_trans_reset(void) return 0; } - +#if NIMBLE_BLE_CONNECT static void ble_hci_rx_acl(uint8_t *data, uint16_t len) { struct os_mbuf *m = NULL; @@ -203,6 +210,7 @@ static void ble_hci_rx_acl(uint8_t *data, uint16_t len) ble_transport_to_hs_acl(m); OS_EXIT_CRITICAL(sr); } +#endif /* * @brief: BT controller callback function, used to notify the upper layer that @@ -255,7 +263,11 @@ static int host_rcv_pkt(uint8_t *data, uint16_t len) bt_record_hci_data(data, len); - if(!ble_hs_enabled_state) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (!ble_hs_get_enabled_state()) { +#else + if (!ble_hs_enabled_state) { +#endif /* If host is not enabled, drop the packet */ esp_rom_printf("Host not enabled. Dropping the packet!"); return 0; @@ -299,7 +311,9 @@ static int host_rcv_pkt(uint8_t *data, uint16_t len) rc = ble_hci_trans_ll_evt_tx(evbuf); assert(rc == 0); } else if (data[0] == BLE_HCI_UART_H4_ACL) { +#if NIMBLE_BLE_CONNECT ble_hci_rx_acl(data + 1, len - 1); +#endif } return 0; } diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 450d35aae0..e2f8239def 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 450d35aae01161d271c6eb2cddc6444519baee67 +Subproject commit e2f8239def9fc39b03dd5c719f6c794b1d675c23 diff --git a/components/bt/host/nimble/port/include/esp_nimble_cfg.h b/components/bt/host/nimble/port/include/esp_nimble_cfg.h index 4fad474a43..8155a2a6d0 100644 --- a/components/bt/host/nimble/port/include/esp_nimble_cfg.h +++ b/components/bt/host/nimble/port/include/esp_nimble_cfg.h @@ -125,10 +125,12 @@ #define BLE_SCAN_RSP_DATA_MAX_LEN_N (MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE) #endif -#ifndef CONFIG_BT_NIMBLE_MAX_PERIODIC_SYNCS -#define MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS (0) -#else +#ifndef MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS +#ifdef CONFIG_BT_NIMBLE_MAX_PERIODIC_SYNCS #define MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS (CONFIG_BT_NIMBLE_MAX_PERIODIC_SYNCS) +#else +#define MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS (0) +#endif #endif #ifndef CONFIG_BT_NIMBLE_MAX_PERIODIC_ADVERTISER_LIST @@ -279,6 +281,7 @@ #else #define MYNEWT_VAL_BLE_CONN_SUBRATING (CONFIG_BT_NIMBLE_SUBRATE) #endif + #ifndef CONFIG_BT_NIMBLE_PERIODIC_ADV_ENH #define MYNEWT_VAL_BLE_PERIODIC_ADV_ENH (0) #else @@ -951,13 +954,31 @@ #endif #if CONFIG_IDF_TARGET_ESP32 + +#define MYNEWT_VAL_BLE_HS_PVCY (1) #define MYNEWT_VAL_BLE_HOST_BASED_PRIVACY (1) + #else + #ifndef MYNEWT_VAL_BLE_HOST_BASED_PRIVACY +#if CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY #define MYNEWT_VAL_BLE_HOST_BASED_PRIVACY (CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY) +#else +#define MYNEWT_VAL_BLE_HOST_BASED_PRIVACY (0) #endif #endif +#ifndef MYNEWT_VAL_BLE_HS_PVCY +#ifdef CONFIG_BT_NIMBLE_HS_PVCY +#define MYNEWT_VAL_BLE_HS_PVCY CONFIG_BT_NIMBLE_HS_PVCY +#else +#define MYNEWT_VAL_BLE_HS_PVCY (0) +#endif +#endif + + +#endif + #ifndef MYNEWT_VAL_BLE_RPA_TIMEOUT #define MYNEWT_VAL_BLE_RPA_TIMEOUT (CONFIG_BT_NIMBLE_RPA_TIMEOUT) #endif @@ -1040,15 +1061,27 @@ #endif #ifndef MYNEWT_VAL_BLE_STORE_MAX_BONDS +#ifdef CONFIG_BT_NIMBLE_MAX_BONDS #define MYNEWT_VAL_BLE_STORE_MAX_BONDS CONFIG_BT_NIMBLE_MAX_BONDS +#else +#define MYNEWT_VAL_BLE_STORE_MAX_BONDS (0) +#endif #endif #ifndef MYNEWT_VAL_BLE_STORE_MAX_CCCDS +#ifdef CONFIG_BT_NIMBLE_MAX_CCCDS #define MYNEWT_VAL_BLE_STORE_MAX_CCCDS CONFIG_BT_NIMBLE_MAX_CCCDS +#else +#define MYNEWT_VAL_BLE_STORE_MAX_CCCDS (0) +#endif #endif #ifndef MYNEWT_VAL_BLE_STORE_MAX_CSFCS +#ifdef CONFIG_BT_NIMBLE_MAX_BONDS #define MYNEWT_VAL_BLE_STORE_MAX_CSFCS CONFIG_BT_NIMBLE_MAX_BONDS +#else +#define MYNEWT_VAL_BLE_STORE_MAX_CSFCS (0) +#endif #endif #ifdef CONFIG_BT_NIMBLE_MAX_EADS @@ -2186,11 +2219,11 @@ #endif #endif -#ifndef MYNEWT_VAL_BLE_ERR_CHECK -#ifdef CONFIG_BT_NIMBLE_PRINT_ERR_NAME -#define MYNEWT_VAL_BLE_ERR_CHECK CONFIG_BT_NIMBLE_PRINT_ERR_NAME +#ifndef MYNEWT_VAL_BT_NIMBLE_MEM_OPTIMIZATION +#ifdef CONFIG_BT_NIMBLE_MEM_OPTIMIZATION +#define MYNEWT_VAL_BT_NIMBLE_MEM_OPTIMIZATION CONFIG_BT_NIMBLE_MEM_OPTIMIZATION #else -#define MYNEWT_VAL_BLE_ERR_CHECK (0) +#define MYNEWT_VAL_BT_NIMBLE_MEM_OPTIMIZATION (0) #endif #endif @@ -2214,6 +2247,91 @@ #endif #endif +#ifndef MYNEWT_VAL_BLE_DTM_MODE_TEST +#ifdef CONFIG_BT_NIMBLE_DTM_MODE_TEST +#define MYNEWT_VAL_BLE_DTM_MODE_TEST CONFIG_BT_NIMBLE_DTM_MODE_TEST +#else +#define MYNEWT_VAL_BLE_DTM_MODE_TEST (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_HOST_STATUS +#ifdef CONFIG_BT_NIMBLE_CHK_HOST_STATUS +#define MYNEWT_VAL_BLE_HOST_STATUS CONFIG_BT_NIMBLE_CHK_HOST_STATUS +#else +#define MYNEWT_VAL_BLE_HOST_STATUS (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_SM_SIGN_CNT +#ifdef CONFIG_BT_NIMBLE_SM_SIGN_CNT +#define MYNEWT_VAL_BLE_SM_SIGN_CNT CONFIG_BT_NIMBLE_SM_SIGN_CNT +#else +#define MYNEWT_VAL_BLE_SM_SIGN_CNT (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_CPFD_CAFD +#ifdef CONFIG_BT_NIMBLE_CPFD_CAFD +#define MYNEWT_VAL_BLE_CPFD_CAFD CONFIG_BT_NIMBLE_CPFD_CAFD +#else +#define MYNEWT_VAL_BLE_CPFD_CAFD (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_RECONFIG_MTU +#ifdef CONFIG_BT_NIMBLE_RECONFIG_MTU +#define MYNEWT_VAL_BLE_RECONFIG_MTU CONFIG_BT_NIMBLE_RECONFIG_MTU +#else +#define MYNEWT_VAL_BLE_RECONFIG_MTU (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_ERR_NAME +#ifdef CONFIG_BT_NIMBLE_PRINT_ERR_NAME +#define MYNEWT_VAL_BLE_ERR_NAME CONFIG_BT_NIMBLE_PRINT_ERR_NAME +#else +#define MYNEWT_VAL_BLE_ERR_NAME (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_UTIL_API +#ifdef CONFIG_BT_NIMBLE_UTIL_API +#define MYNEWT_VAL_BLE_UTIL_API CONFIG_BT_NIMBLE_UTIL_API +#else +#define MYNEWT_VAL_BLE_UTIL_API (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_EXTRA_ADV_FIELDS +#ifdef CONFIG_BT_NIMBLE_EXTRA_ADV_FIELDS +#define MYNEWT_VAL_BLE_EXTRA_ADV_FIELDS CONFIG_BT_NIMBLE_EXTRA_ADV_FIELDS +#else +#define CONFIG_BT_NIMBLE_EXTRA_ADV_FIELDS (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_LOW_SPEED_MODE +#ifdef CONFIG_BT_NIMBLE_LOW_SPEED_MODE +#define MYNEWT_VAL_BLE_LOW_SPEED_MODE CONFIG_BT_NIMBLE_LOW_SPEED_MODE +#else +#define MYNEWT_VAL_BLE_LOW_SPEED_MODE (0) +#endif +#endif + + +#ifndef MYNEWT_VAL_BLE_STATIC_TO_DYNAMIC +#ifdef CONFIG_BT_NIMBLE_STATIC_TO_DYNAMIC +#define MYNEWT_VAL_BLE_STATIC_TO_DYNAMIC CONFIG_BT_NIMBLE_STATIC_TO_DYNAMIC +#else +#define MYNEWT_VAL_BLE_STATIC_TO_DYNAMIC (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_RESTART_PAIR +#define MYNEWT_VAL_BLE_RESTART_PAIR (1) +#endif + #ifndef MYNEWT_VAL_MP_RUNTIME_ALLOC #ifdef CONFIG_BT_NIMBLE_MEMPOOL_RUNTIME_ALLOC #define MYNEWT_VAL_MP_RUNTIME_ALLOC (1) diff --git a/components/bt/host/nimble/port/include/esp_nimble_mem.h b/components/bt/host/nimble/port/include/esp_nimble_mem.h index 0b5e5aae74..d0c5a75185 100644 --- a/components/bt/host/nimble/port/include/esp_nimble_mem.h +++ b/components/bt/host/nimble/port/include/esp_nimble_mem.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,10 +16,55 @@ extern "C" { // #pragma message "This file should be replaced with bt_osi_mem.h, used here for compatibility" #include "bt_osi_mem.h" + +#if CONFIG_BT_NIMBLE_MEM_DEBUG + +#define nimble_platform_mem_malloc(size) \ +({ \ + void *p; \ + do { \ + p = bt_osi_mem_malloc(size); \ + nimble_mem_dbg_record(p, size, __func__, __LINE__); \ + } while (0); \ + p; \ +}) + +#define nimble_platform_mem_calloc(count, size) \ +({ \ + void *p; \ + do { \ + p = bt_osi_mem_calloc(count, size); \ + nimble_mem_dbg_record(p, (count) * (size), __func__, __LINE__); \ + } while (0); \ + p; \ +}) + +#define nimble_platform_mem_realloc(ptr, new_size) \ +({ \ + void *p; \ + do { \ + p = nimble_mem_dbg_realloc(ptr, new_size, __func__, __LINE__); \ + } while (0); \ + p; \ +}) + +#define nimble_platform_mem_free(ptr) \ +do { \ + void *tmp_ptr = (void *)(ptr); \ + nimble_mem_dbg_clean(tmp_ptr, __func__, __LINE__); \ + bt_osi_mem_free(tmp_ptr); \ +} while (0) + +#else + #define nimble_platform_mem_malloc bt_osi_mem_malloc #define nimble_platform_mem_calloc bt_osi_mem_calloc +#define nimble_platform_mem_realloc realloc #define nimble_platform_mem_free bt_osi_mem_free +#endif // CONFIG_BT_NIMBLE_MEM_DEBUG + + #ifdef __cplusplus } #endif diff --git a/components/bt/porting/include/bt_osi_mem.h b/components/bt/porting/include/bt_osi_mem.h index a97165d707..8a8c448b1d 100644 --- a/components/bt/porting/include/bt_osi_mem.h +++ b/components/bt/porting/include/bt_osi_mem.h @@ -29,3 +29,82 @@ void bt_osi_mem_count_limit_set(uint16_t count_limit); size_t bt_osi_mem_internal_used_size_get(void); size_t bt_osi_mem_used_size_get(void); #endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + +#if CONFIG_BT_NIMBLE_MEM_DEBUG +/** + * @brief Initialize NimBLE memory debug module + */ +void nimble_mem_dbg_init(void); + +/** + * @brief Record memory allocation information + * + * @param p Pointer to allocated memory + * @param size Size of allocation + * @param func Function name where allocation occurred + * @param line Line number where allocation occurred + */ +void nimble_mem_dbg_record(void *p, int size, const char *func, int line); + +/** + * @brief Clean up memory allocation record + * + * @param p Pointer to memory being freed + * @param func Function name where free occurred + * @param line Line number where free occurred + */ +void nimble_mem_dbg_clean(void *p, const char *func, int line); + +/** + * @brief Display all memory debug information + */ +void nimble_mem_dbg_show(void); + +/** + * @brief Get maximum memory size used + * + * @return Maximum memory size in bytes + */ +uint32_t nimble_mem_dbg_get_max_size(void); + +/** + * @brief Get current memory size in use + * + * @return Current memory size in bytes + */ +uint32_t nimble_mem_dbg_get_current_size(void); + +/** + * @brief Start tracking memory usage for a specific section + * + * @param index Section index (0 to NIMBLE_MEM_DBG_MAX_SECTION_NUM-1) + */ +void nimble_mem_dbg_set_section_start(uint8_t index); + +/** + * @brief Stop tracking memory usage for a specific section + * + * @param index Section index (0 to NIMBLE_MEM_DBG_MAX_SECTION_NUM-1) + */ +void nimble_mem_dbg_set_section_end(uint8_t index); + +/** + * @brief Get maximum memory size used in a specific section + * + * @param index Section index (0 to NIMBLE_MEM_DBG_MAX_SECTION_NUM-1) + * @return Maximum memory size in bytes for this section + */ +uint32_t nimble_mem_dbg_get_max_size_section(uint8_t index); + +/** + * @brief Reallocate memory with debug tracking + * + * @param ptr Pointer to memory to reallocate + * @param new_size New size of allocation + * @param func Function name where realloc occurred + * @param line Line number where realloc occurred + * @return Pointer to reallocated memory + */ +void *nimble_mem_dbg_realloc(void *ptr, size_t new_size, const char *func, int line); + +#endif // CONFIG_BT_NIMBLE_MEM_DEBUG diff --git a/components/bt/porting/mem/bt_osi_mem.c b/components/bt/porting/mem/bt_osi_mem.c index 306ec8290e..e020abbf77 100644 --- a/components/bt/porting/mem/bt_osi_mem.c +++ b/components/bt/porting/mem/bt_osi_mem.c @@ -19,7 +19,248 @@ static size_t host_mem_used_size = 0; static uint16_t mem_count_limit = 0; static uint16_t curr_mem_count; #endif // CONFIG_BT_LE_MEM_CHECK_ENABLED -IRAM_ATTR void *bt_osi_mem_malloc(size_t size) + +#if CONFIG_BT_NIMBLE_MEM_DEBUG + +#define NIMBLE_MEM_DBG_INFO_MAX 1024*3 +typedef struct { + void *p; + int size; + const char *func; + int line; +} nimble_mem_dbg_info_t; + +static uint32_t nimble_mem_dbg_count = 0; +static nimble_mem_dbg_info_t nimble_mem_dbg_info[NIMBLE_MEM_DBG_INFO_MAX]; +static uint32_t nimble_mem_dbg_current_size = 0; +static uint32_t nimble_mem_dbg_max_size = 0; + +#define NIMBLE_MEM_DBG_MAX_SECTION_NUM 5 +typedef struct { + bool used; + uint32_t max_size; +} nimble_mem_dbg_max_size_section_t; +static nimble_mem_dbg_max_size_section_t nimble_mem_dbg_max_size_section[NIMBLE_MEM_DBG_MAX_SECTION_NUM]; + +void nimble_mem_dbg_init(void) +{ + int i; + + for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) { + nimble_mem_dbg_info[i].p = NULL; + nimble_mem_dbg_info[i].size = 0; + nimble_mem_dbg_info[i].func = NULL; + nimble_mem_dbg_info[i].line = 0; + } + nimble_mem_dbg_count = 0; + nimble_mem_dbg_current_size = 0; + nimble_mem_dbg_max_size = 0; + + for (i = 0; i < NIMBLE_MEM_DBG_MAX_SECTION_NUM; i++){ + nimble_mem_dbg_max_size_section[i].used = false; + nimble_mem_dbg_max_size_section[i].max_size = 0; + } +} + +void nimble_mem_dbg_record(void *p, int size, const char *func, int line) +{ + int i; + + if (!p || size == 0) { + ESP_LOGE("BT_NIMBLE_MEM", "%s invalid !!\n", __func__); + return; + } + + for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) { + if (nimble_mem_dbg_info[i].p == NULL) { + nimble_mem_dbg_info[i].p = p; + nimble_mem_dbg_info[i].size = size; + nimble_mem_dbg_info[i].func = func; + nimble_mem_dbg_info[i].line = line; + nimble_mem_dbg_count++; + break; + } + } + + if (i >= NIMBLE_MEM_DBG_INFO_MAX) { + ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line); + } + + nimble_mem_dbg_current_size += size; + if(nimble_mem_dbg_max_size < nimble_mem_dbg_current_size) { + nimble_mem_dbg_max_size = nimble_mem_dbg_current_size; + } + + for (i = 0; i < NIMBLE_MEM_DBG_MAX_SECTION_NUM; i++){ + if (nimble_mem_dbg_max_size_section[i].used) { + if(nimble_mem_dbg_max_size_section[i].max_size < nimble_mem_dbg_current_size) { + nimble_mem_dbg_max_size_section[i].max_size = nimble_mem_dbg_current_size; + } + } + } +} + +void nimble_mem_dbg_clean(void *p, const char *func, int line) +{ + int i; + + if (!p) { + ESP_LOGE("BT_NIMBLE_MEM", "%s %d free->%p invalid\n", func, line, p); + return; + } + + for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) { + if (nimble_mem_dbg_info[i].p == p) { + nimble_mem_dbg_current_size -= nimble_mem_dbg_info[i].size; + nimble_mem_dbg_info[i].p = NULL; + nimble_mem_dbg_info[i].size = 0; + nimble_mem_dbg_info[i].func = NULL; + nimble_mem_dbg_info[i].line = 0; + nimble_mem_dbg_count--; + break; + } + } + + if (i >= NIMBLE_MEM_DBG_INFO_MAX) { + ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line); + } +} + +void nimble_mem_dbg_show(void) +{ + int i; + + for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) { + if (nimble_mem_dbg_info[i].p || nimble_mem_dbg_info[i].size != 0 ) { + ESP_LOGE("BT_NIMBLE_MEM", "--> p %p, s %d, f %s, l %d\n", + nimble_mem_dbg_info[i].p, nimble_mem_dbg_info[i].size, + nimble_mem_dbg_info[i].func, nimble_mem_dbg_info[i].line); + } + } + ESP_LOGE("BT_NIMBLE_MEM", "--> count %ld\n", nimble_mem_dbg_count); + ESP_LOGE("BT_NIMBLE_MEM", "--> size %ldB\n--> max size %ldB\n", + nimble_mem_dbg_current_size, nimble_mem_dbg_max_size); +} + +uint32_t nimble_mem_dbg_get_max_size(void) +{ + return nimble_mem_dbg_max_size; +} + +uint32_t nimble_mem_dbg_get_current_size(void) +{ + return nimble_mem_dbg_current_size; +} + +void nimble_mem_dbg_set_section_start(uint8_t index) +{ + if (index >= NIMBLE_MEM_DBG_MAX_SECTION_NUM) { + ESP_LOGE("BT_NIMBLE_MEM", "Then range of index should be between 0 and %d, current index is %d.\n", + NIMBLE_MEM_DBG_MAX_SECTION_NUM - 1, index); + return; + } + + if (nimble_mem_dbg_max_size_section[index].used) { + ESP_LOGW("BT_NIMBLE_MEM", "This index(%d) has been started, restart it.\n", index); + } + + nimble_mem_dbg_max_size_section[index].used = true; + nimble_mem_dbg_max_size_section[index].max_size = nimble_mem_dbg_current_size; +} + +void nimble_mem_dbg_set_section_end(uint8_t index) +{ + if (index >= NIMBLE_MEM_DBG_MAX_SECTION_NUM) { + ESP_LOGE("BT_NIMBLE_MEM", "Then range of index should be between 0 and %d, current index is %d.\n", + NIMBLE_MEM_DBG_MAX_SECTION_NUM - 1, index); + return; + } + + if (!nimble_mem_dbg_max_size_section[index].used) { + ESP_LOGE("BT_NIMBLE_MEM", "This index(%d) has not been started.\n", index); + return; + } + + nimble_mem_dbg_max_size_section[index].used = false; +} + +uint32_t nimble_mem_dbg_get_max_size_section(uint8_t index) +{ + if (index >= NIMBLE_MEM_DBG_MAX_SECTION_NUM){ + ESP_LOGE("BT_NIMBLE_MEM", "Then range of index should be between 0 and %d, current index is %d.\n", + NIMBLE_MEM_DBG_MAX_SECTION_NUM - 1, index); + return 0; + } + + return nimble_mem_dbg_max_size_section[index].max_size; +} + +void *nimble_mem_dbg_realloc(void *ptr, size_t new_size, const char *func, int line) +{ + size_t old_size = 0; + int i; + + void *new_ptr = realloc(ptr, new_size); + if (new_ptr == NULL && new_size > 0) { + // realloc failed, keep old ptr record + return NULL; + } + + // Find and clean old record if ptr is not NULL + if (ptr != NULL) { + for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) { + if (nimble_mem_dbg_info[i].p == ptr) { + old_size = nimble_mem_dbg_info[i].size; + nimble_mem_dbg_current_size -= old_size; + + nimble_mem_dbg_info[i].p = NULL; + nimble_mem_dbg_info[i].size = 0; + nimble_mem_dbg_info[i].func = NULL; + nimble_mem_dbg_info[i].line = 0; + nimble_mem_dbg_count--; + break; + } + } + } + + // Record the new allocation if new_size > 0 + if (new_ptr != NULL && new_size > 0) { + for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) { + if (nimble_mem_dbg_info[i].p == NULL) { + nimble_mem_dbg_info[i].p = new_ptr; + nimble_mem_dbg_info[i].size = new_size; + nimble_mem_dbg_info[i].func = func; + nimble_mem_dbg_info[i].line = line; + nimble_mem_dbg_count++; + break; + } + } + + if (i >= NIMBLE_MEM_DBG_INFO_MAX) { + ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line); + } + + nimble_mem_dbg_current_size += new_size; + if (nimble_mem_dbg_max_size < nimble_mem_dbg_current_size) { + nimble_mem_dbg_max_size = nimble_mem_dbg_current_size; + } + + for (i = 0; i < NIMBLE_MEM_DBG_MAX_SECTION_NUM; i++) { + if (nimble_mem_dbg_max_size_section[i].used && + nimble_mem_dbg_max_size_section[i].max_size < nimble_mem_dbg_current_size) { + nimble_mem_dbg_max_size_section[i].max_size = nimble_mem_dbg_current_size; + } + } + } + + return new_ptr; +} +#endif // CONFIG_BT_NIMBLE_MEM_DEBUG + +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void *bt_osi_mem_malloc(size_t size) { void *mem = NULL; #ifdef CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL @@ -47,7 +288,10 @@ IRAM_ATTR void *bt_osi_mem_malloc(size_t size) return mem; } -IRAM_ATTR void *bt_osi_mem_calloc(size_t n, size_t size) +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void *bt_osi_mem_calloc(size_t n, size_t size) { void *mem = NULL; #ifdef CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL @@ -67,7 +311,10 @@ IRAM_ATTR void *bt_osi_mem_calloc(size_t n, size_t size) return mem; } -IRAM_ATTR void *bt_osi_mem_malloc_internal(size_t size) +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void *bt_osi_mem_malloc_internal(size_t size) { void *mem_ptr; #if CONFIG_BT_LE_MEM_CHECK_ENABLED @@ -87,7 +334,10 @@ IRAM_ATTR void *bt_osi_mem_malloc_internal(size_t size) return mem_ptr; } -IRAM_ATTR void *bt_osi_mem_calloc_internal(size_t n, size_t size) +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void *bt_osi_mem_calloc_internal(size_t n, size_t size) { void *mem_ptr; #if CONFIG_BT_LE_MEM_CHECK_ENABLED @@ -107,7 +357,10 @@ IRAM_ATTR void *bt_osi_mem_calloc_internal(size_t n, size_t size) return mem_ptr; } -IRAM_ATTR void bt_osi_mem_free_internal(void *ptr) +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void bt_osi_mem_free_internal(void *ptr) { #if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED if (ptr) { @@ -116,10 +369,15 @@ IRAM_ATTR void bt_osi_mem_free_internal(void *ptr) controller_mem_used_size -= alloc_size; } #endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED - heap_caps_free(ptr); + if (ptr) { + heap_caps_free(ptr); + } } -IRAM_ATTR void bt_osi_mem_free(void *ptr) +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void bt_osi_mem_free(void *ptr) { #if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED if (ptr) { @@ -128,7 +386,9 @@ IRAM_ATTR void bt_osi_mem_free(void *ptr) host_mem_used_size -= alloc_size; } #endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED - heap_caps_free(ptr); + if (ptr) { + heap_caps_free(ptr); + } } #if CONFIG_BT_LE_MEM_CHECK_ENABLED diff --git a/components/bt/porting/mem/os_msys_init.c b/components/bt/porting/mem/os_msys_init.c index 1a121e6d0b..b0340f42cf 100644 --- a/components/bt/porting/mem/os_msys_init.c +++ b/components/bt/porting/mem/os_msys_init.c @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2019-2025 Espressif Systems (Shanghai) CO LTD */ #include @@ -12,6 +12,7 @@ #include "mem_api.h" #include "bt_osi_mem.h" #include "esp_err.h" +#include "esp_nimble_mem.h" #if CONFIG_BT_NIMBLE_ENABLED #include "syscfg/syscfg.h" @@ -168,17 +169,17 @@ int os_msys_buf_alloc(void) { #if OS_MSYS_1_BLOCK_COUNT > 0 - os_msys_init_1_data = (os_membuf_t *)bt_osi_mem_calloc(1, (sizeof(os_membuf_t) * SYSINIT_MSYS_1_MEMPOOL_SIZE)); + os_msys_init_1_data = (os_membuf_t *)nimble_platform_mem_calloc(1, (sizeof(os_membuf_t) * SYSINIT_MSYS_1_MEMPOOL_SIZE)); if (!os_msys_init_1_data) { return ESP_ERR_NO_MEM; } #endif #if OS_MSYS_2_BLOCK_COUNT > 0 - os_msys_init_2_data = (os_membuf_t *)bt_osi_mem_calloc(1, (sizeof(os_membuf_t) * SYSINIT_MSYS_2_MEMPOOL_SIZE)); + os_msys_init_2_data = (os_membuf_t *)nimble_platform_mem_calloc(1, (sizeof(os_membuf_t) * SYSINIT_MSYS_2_MEMPOOL_SIZE)); if (!os_msys_init_2_data) { #if OS_MSYS_1_BLOCK_COUNT > 0 - bt_osi_mem_free(os_msys_init_1_data); + nimble_platform_mem_free(os_msys_init_1_data); os_msys_init_1_data = NULL; #endif return ESP_ERR_NO_MEM; @@ -192,12 +193,12 @@ void os_msys_buf_free(void) { #if OS_MSYS_1_BLOCK_COUNT > 0 - bt_osi_mem_free(os_msys_init_1_data); + nimble_platform_mem_free(os_msys_init_1_data); os_msys_init_1_data = NULL; #endif #if OS_MSYS_2_BLOCK_COUNT > 0 - bt_osi_mem_free(os_msys_init_2_data); + nimble_platform_mem_free(os_msys_init_2_data); os_msys_init_2_data = NULL; #endif diff --git a/components/bt/porting/npl/freertos/src/npl_os_freertos.c b/components/bt/porting/npl/freertos/src/npl_os_freertos.c index 4103e62042..1e98cf8933 100644 --- a/components/bt/porting/npl/freertos/src/npl_os_freertos.c +++ b/components/bt/porting/npl/freertos/src/npl_os_freertos.c @@ -165,6 +165,13 @@ npl_freertos_eventq_deinit(struct ble_npl_eventq *evq) { struct ble_npl_eventq_freertos *eventq = (struct ble_npl_eventq_freertos *)evq->eventq; +#if CONFIG_BT_NIMBLE_STATIC_TO_DYNAMIC + /* Deinit can be invoked twice without init . Handle this case */ + if (eventq == NULL) { + return; + } +#endif + BLE_LL_ASSERT(eventq); vQueueDelete(eventq->q); #if OS_MEM_ALLOC diff --git a/components/bt/porting/transport/src/hci_transport.c b/components/bt/porting/transport/src/hci_transport.c index 29c2e00131..9d2e0a1204 100644 --- a/components/bt/porting/transport/src/hci_transport.c +++ b/components/bt/porting/transport/src/hci_transport.c @@ -26,9 +26,11 @@ hci_transport_controller_packet_rx(hci_driver_data_type_t data_type, uint8_t *da r_ble_hci_trans_hs_cmd_tx(data); } +#if CONFIG_BT_BLUEDROID_ENABLED || (CONFIG_BT_NIMBLE_ENABLED && (CONFIG_BT_NIMBLE_ROLE_CENTRAL || CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)) if (data_type == HCI_DRIVER_TYPE_ACL) { r_ble_hci_trans_hs_acl_tx((struct os_mbuf *) data); } +#endif return 0; } From 93bb32df7503a84de1bc423c83c91209927a1c10 Mon Sep 17 00:00:00 2001 From: yangfeng Date: Thu, 14 Aug 2025 14:55:39 +0800 Subject: [PATCH 023/226] refactor(examples/classic_bt): Refactor A2DP sink and AVRCP examples - Add avrcp_ct_metadata example - Add avrcp_absolute_volume example - Add the example components about common code for a2dp sink and avrcp --- .../classic_bt/a2dp_sink/main/CMakeLists.txt | 5 - .../classic_bt/a2dp_sink/main/bt_app_av.c | 717 ------------------ .../classic_bt/a2dp_sink/main/bt_app_av.h | 59 -- .../classic_bt/a2dp_sink/main/bt_app_core.c | 266 ------- .../classic_bt/a2dp_sink/main/main.c | 265 ------- .../CMakeLists.txt | 2 +- .../{a2dp_sink => a2dp_sink_stream}/README.md | 37 +- .../a2dp_sink_stream/main/CMakeLists.txt | 10 + .../a2dp_sink_stream/main/Kconfig.projbuild | 15 + .../a2dp_sink_stream/main/idf_component.yml | 11 + .../classic_bt/a2dp_sink_stream/main/main.c | 177 +++++ .../sdkconfig.ci.ca_dis | 3 - .../sdkconfig.ci.test | 0 .../sdkconfig.defaults | 3 - .../tutorial/Example_A2DP_Sink.md | 92 +-- .../avrcp_absolute_volume/CMakeLists.txt | 8 + .../avrcp_absolute_volume/README.md | 70 ++ .../avrcp_absolute_volume/main/CMakeLists.txt | 12 + .../main/Kconfig.projbuild | 23 + .../main/idf_component.yml | 15 + .../avrcp_absolute_volume/main/main.c | 251 ++++++ .../avrcp_absolute_volume/sdkconfig.ci.test | 1 + .../avrcp_absolute_volume/sdkconfig.defaults | 8 + .../avrcp_ct_metadata/CMakeLists.txt | 8 + .../classic_bt/avrcp_ct_metadata/README.md | 67 ++ .../avrcp_ct_metadata/main/CMakeLists.txt | 12 + .../avrcp_ct_metadata/main/Kconfig.projbuild | 23 + .../avrcp_ct_metadata/main/idf_component.yml | 15 + .../classic_bt/avrcp_ct_metadata/main/main.c | 295 +++++++ .../pytest_classic_bt_metadata_test.py | 12 + .../avrcp_ct_metadata/sdkconfig.defaults | 8 + .../bluedroid/classic_bt/common/README.md | 44 ++ .../a2dp_sink_common_utils/CMakeLists.txt | 3 + .../a2dp_sink_common_utils.c | 118 +++ .../a2dp_sink_common_utils.h | 20 + .../a2dp_sink_ext_codec_utils/CMakeLists.txt | 3 + .../a2dp_sink_ext_codec_utils.c | 116 +++ .../a2dp_sink_ext_codec_utils.h | 29 + .../a2dp_sink_int_codec_utils/CMakeLists.txt | 6 + .../Kconfig.projbuild | 37 +- .../a2dp_sink_int_codec_utils.c | 86 +++ .../a2dp_sink_int_codec_utils.h | 28 + .../audio_sink_service.h | 51 ++ .../audio_sink_service_dac.c | 222 ++++++ .../audio_sink_service_i2s.c | 229 ++++++ .../audio_sink_service_idle.c | 49 ++ .../a2dp_utils/include/a2dp_utils_tags.h | 13 + .../avrcp_abs_vol_utils/CMakeLists.txt | 4 + .../avrcp_abs_vol_service.c | 88 +++ .../avrcp_abs_vol_service.h | 48 ++ .../avrcp_abs_vol_utils/avrcp_abs_vol_utils.c | 103 +++ .../avrcp_abs_vol_utils/avrcp_abs_vol_utils.h | 20 + .../avrcp_common_utils/CMakeLists.txt | 3 + .../avrcp_common_utils/avrcp_common_utils.c | 228 ++++++ .../avrcp_common_utils/avrcp_common_utils.h | 82 ++ .../avrcp_metadata_utils/CMakeLists.txt | 4 + .../avrcp_metadata_service.c | 155 ++++ .../avrcp_metadata_service.h | 48 ++ .../avrcp_metadata_utils.c | 77 ++ .../avrcp_metadata_utils.h | 20 + .../avrcp_metadata_utils/idf_component.yml | 3 + .../avrcp_utils/include/avrcp_utils_tags.h | 15 + .../bredr_app_common_utils/CMakeLists.txt | 3 + .../bredr_app_common_utils/Kconfig.projbuild | 10 + .../bredr_app_common_utils.c | 185 +++++ .../bredr_app_common_utils.h | 37 + .../common/bt_app_core_utils/CMakeLists.txt | 2 + .../bt_app_core_utils/bt_app_core_utils.c | 138 ++++ .../bt_app_core_utils/bt_app_core_utils.h} | 37 +- 69 files changed, 3382 insertions(+), 1472 deletions(-) delete mode 100644 examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/CMakeLists.txt delete mode 100644 examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c delete mode 100644 examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.h delete mode 100644 examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c delete mode 100644 examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c rename examples/bluetooth/bluedroid/classic_bt/{a2dp_sink => a2dp_sink_stream}/CMakeLists.txt (93%) rename examples/bluetooth/bluedroid/classic_bt/{a2dp_sink => a2dp_sink_stream}/README.md (73%) create mode 100644 examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/Kconfig.projbuild create mode 100644 examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/idf_component.yml create mode 100644 examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/main.c rename examples/bluetooth/bluedroid/classic_bt/{a2dp_sink => a2dp_sink_stream}/sdkconfig.ci.ca_dis (75%) rename examples/bluetooth/bluedroid/classic_bt/{a2dp_sink => a2dp_sink_stream}/sdkconfig.ci.test (100%) rename examples/bluetooth/bluedroid/classic_bt/{a2dp_sink => a2dp_sink_stream}/sdkconfig.defaults (73%) rename examples/bluetooth/bluedroid/classic_bt/{a2dp_sink => a2dp_sink_stream}/tutorial/Example_A2DP_Sink.md (51%) create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/README.md create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/Kconfig.projbuild create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/idf_component.yml create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/main.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/sdkconfig.ci.test create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/sdkconfig.defaults create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/README.md create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/Kconfig.projbuild create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/idf_component.yml create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/main.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/pytest_classic_bt_metadata_test.py create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/sdkconfig.defaults create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/README.md create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils/a2dp_sink_common_utils.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils/a2dp_sink_common_utils.h create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils/a2dp_sink_ext_codec_utils.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils/a2dp_sink_ext_codec_utils.h create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/CMakeLists.txt rename examples/bluetooth/bluedroid/classic_bt/{a2dp_sink/main => common/a2dp_utils/a2dp_sink_int_codec_utils}/Kconfig.projbuild (54%) create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/a2dp_sink_int_codec_utils.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/a2dp_sink_int_codec_utils.h create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service.h create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_dac.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_i2s.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_idle.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/include/a2dp_utils_tags.h create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_service.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_service.h create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_utils.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_utils.h create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils/avrcp_common_utils.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils/avrcp_common_utils.h create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_service.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_service.h create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_utils.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_utils.h create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/idf_component.yml create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/include/avrcp_utils_tags.h create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/Kconfig.projbuild create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/bredr_app_common_utils.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/bredr_app_common_utils.h create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils/bt_app_core_utils.c rename examples/bluetooth/bluedroid/classic_bt/{a2dp_sink/main/bt_app_core.h => common/bt_app_core_utils/bt_app_core_utils.h} (64%) diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/CMakeLists.txt deleted file mode 100644 index e68a065139..0000000000 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register(SRCS "bt_app_av.c" - "bt_app_core.c" - "main.c" - PRIV_REQUIRES esp_driver_i2s bt nvs_flash esp_ringbuf esp_driver_dac - INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c deleted file mode 100644 index a6601f624c..0000000000 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c +++ /dev/null @@ -1,717 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -#include -#include -#include -#include -#include -#include "esp_log.h" - -#include "bt_app_core.h" -#include "bt_app_av.h" -#include "esp_bt_main.h" -#include "esp_bt_device.h" -#include "esp_gap_bt_api.h" -#include "esp_a2dp_api.h" -#include "esp_avrc_api.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC -#include "driver/dac_continuous.h" -#else -#include "driver/i2s_std.h" -#endif - -#include "sys/lock.h" - -/* AVRCP used transaction labels */ -#define APP_RC_CT_TL_GET_CAPS (0) -#define APP_RC_CT_TL_GET_META_DATA (1) -#define APP_RC_CT_TL_RN_TRACK_CHANGE (2) -#define APP_RC_CT_TL_RN_PLAYBACK_CHANGE (3) -#define APP_RC_CT_TL_RN_PLAY_POS_CHANGE (4) - -/* Application layer causes delay value */ -#define APP_DELAY_VALUE 50 // 5ms - -/******************************* - * STATIC FUNCTION DECLARATIONS - ******************************/ - -/* allocate new meta buffer */ -static void bt_app_alloc_meta_buffer(esp_avrc_ct_cb_param_t *param); -/* handler for new track is loaded */ -static void bt_av_new_track(void); -/* handler for track status change */ -static void bt_av_playback_changed(void); -/* handler for track playing position change */ -static void bt_av_play_pos_changed(void); -/* notification event handler */ -static void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *event_parameter); -/* installation for i2s */ -static void bt_i2s_driver_install(void); -/* uninstallation for i2s */ -static void bt_i2s_driver_uninstall(void); -/* set volume by remote controller */ -static void volume_set_by_controller(uint8_t volume); -/* set volume by local host */ -static void volume_set_by_local_host(uint8_t volume); -/* simulation volume change */ -static void volume_change_simulation(void *arg); -/* a2dp event handler */ -static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param); -/* avrc controller event handler */ -static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param); -/* avrc target event handler */ -static void bt_av_hdl_avrc_tg_evt(uint16_t event, void *p_param); - -/******************************* - * STATIC VARIABLE DEFINITIONS - ******************************/ - -static uint32_t s_pkt_cnt = 0; /* count for audio packet */ -static esp_a2d_audio_state_t s_audio_state = ESP_A2D_AUDIO_STATE_STOPPED; - /* audio stream datapath state */ -static const char *s_a2d_conn_state_str[] = {"Disconnected", "Connecting", "Connected", "Disconnecting"}; - /* connection state in string */ -static const char *s_a2d_audio_state_str[] = {"Suspended", "Started"}; - /* audio stream datapath state in string */ -static esp_avrc_rn_evt_cap_mask_t s_avrc_peer_rn_cap; - /* AVRC target notification capability bit mask */ -static _lock_t s_volume_lock; -static TaskHandle_t s_vcs_task_hdl = NULL; /* handle for volume change simulation task */ -static uint8_t s_volume = 0; /* local volume value */ -static bool s_volume_notify; /* notify volume change or not */ -#ifndef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC -i2s_chan_handle_t tx_chan = NULL; -#else -dac_continuous_handle_t tx_chan; -#endif - -#if CONFIG_EXAMPLE_AVRCP_CT_COVER_ART_ENABLE -static bool cover_art_connected = false; -static bool cover_art_getting = false; -static uint32_t cover_art_image_size = 0; -static uint8_t image_handle_old[7]; -#endif - -/******************************** - * STATIC FUNCTION DEFINITIONS - *******************************/ - -static void bt_app_alloc_meta_buffer(esp_avrc_ct_cb_param_t *param) -{ - esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(param); - uint8_t *attr_text = (uint8_t *) malloc (rc->meta_rsp.attr_length + 1); - - memcpy(attr_text, rc->meta_rsp.attr_text, rc->meta_rsp.attr_length); - attr_text[rc->meta_rsp.attr_length] = 0; - rc->meta_rsp.attr_text = attr_text; -} - -#if CONFIG_EXAMPLE_AVRCP_CT_COVER_ART_ENABLE -static bool image_handle_check(uint8_t *image_handle, int len) -{ - /* Image handle length must be 7 */ - if (len == 7 && memcmp(image_handle_old, image_handle, 7) != 0) { - memcpy(image_handle_old, image_handle, 7); - return true; - } - return false; -} -#endif - -static void bt_av_new_track(void) -{ - /* request metadata */ - uint8_t attr_mask = ESP_AVRC_MD_ATTR_TITLE | - ESP_AVRC_MD_ATTR_ARTIST | - ESP_AVRC_MD_ATTR_ALBUM | - ESP_AVRC_MD_ATTR_GENRE; -#if CONFIG_EXAMPLE_AVRCP_CT_COVER_ART_ENABLE - if (cover_art_connected) { - attr_mask |= ESP_AVRC_MD_ATTR_COVER_ART; - } -#endif - esp_avrc_ct_send_metadata_cmd(APP_RC_CT_TL_GET_META_DATA, attr_mask); - - /* register notification if peer support the event_id */ - if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, - ESP_AVRC_RN_TRACK_CHANGE)) { - esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_TRACK_CHANGE, - ESP_AVRC_RN_TRACK_CHANGE, 0); - } -} - -static void bt_av_playback_changed(void) -{ - /* register notification if peer support the event_id */ - if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, - ESP_AVRC_RN_PLAY_STATUS_CHANGE)) { - esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_PLAYBACK_CHANGE, - ESP_AVRC_RN_PLAY_STATUS_CHANGE, 0); - } -} - -static void bt_av_play_pos_changed(void) -{ - /* register notification if peer support the event_id */ - if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, - ESP_AVRC_RN_PLAY_POS_CHANGED)) { - esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_PLAY_POS_CHANGE, - ESP_AVRC_RN_PLAY_POS_CHANGED, 10); - } -} - -static void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *event_parameter) -{ - switch (event_id) { - /* when new track is loaded, this event comes */ - case ESP_AVRC_RN_TRACK_CHANGE: - bt_av_new_track(); - break; - /* when track status changed, this event comes */ - case ESP_AVRC_RN_PLAY_STATUS_CHANGE: - ESP_LOGI(BT_AV_TAG, "Playback status changed: 0x%x", event_parameter->playback); - bt_av_playback_changed(); - break; - /* when track playing position changed, this event comes */ - case ESP_AVRC_RN_PLAY_POS_CHANGED: - ESP_LOGI(BT_AV_TAG, "Play position changed: %"PRIu32"-ms", event_parameter->play_pos); - bt_av_play_pos_changed(); - break; - /* others */ - default: - ESP_LOGI(BT_AV_TAG, "unhandled event: %d", event_id); - break; - } -} - -void bt_i2s_driver_install(void) -{ -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - dac_continuous_config_t cont_cfg = { - .chan_mask = DAC_CHANNEL_MASK_ALL, - .desc_num = 8, - .buf_size = 2048, - .freq_hz = 44100, - .offset = 127, - .clk_src = DAC_DIGI_CLK_SRC_DEFAULT, // Using APLL as clock source to get a wider frequency range - .chan_mode = DAC_CHANNEL_MODE_ALTER, - }; - /* Allocate continuous channels */ - ESP_ERROR_CHECK(dac_continuous_new_channels(&cont_cfg, &tx_chan)); - /* Enable the continuous channels */ - ESP_ERROR_CHECK(dac_continuous_enable(tx_chan)); -#else - i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); - chan_cfg.auto_clear = true; - i2s_std_config_t std_cfg = { - .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(44100), - .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), - .gpio_cfg = { - .mclk = I2S_GPIO_UNUSED, - .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, - .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, - .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, - .din = I2S_GPIO_UNUSED, - .invert_flags = { - .mclk_inv = false, - .bclk_inv = false, - .ws_inv = false, - }, - }, - }; - /* enable I2S */ - ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_chan, NULL)); - ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &std_cfg)); - ESP_ERROR_CHECK(i2s_channel_enable(tx_chan)); -#endif -} - -void bt_i2s_driver_uninstall(void) -{ -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - ESP_ERROR_CHECK(dac_continuous_disable(tx_chan)); - ESP_ERROR_CHECK(dac_continuous_del_channels(tx_chan)); -#else - ESP_ERROR_CHECK(i2s_channel_disable(tx_chan)); - ESP_ERROR_CHECK(i2s_del_channel(tx_chan)); -#endif -} - -static void volume_set_by_controller(uint8_t volume) -{ - ESP_LOGI(BT_RC_TG_TAG, "Volume is set by remote controller to: %"PRIu32"%%", (uint32_t)volume * 100 / 0x7f); - /* set the volume in protection of lock */ - _lock_acquire(&s_volume_lock); - s_volume = volume; - _lock_release(&s_volume_lock); -} - -static void volume_set_by_local_host(uint8_t volume) -{ - ESP_LOGI(BT_RC_TG_TAG, "Volume is set locally to: %"PRIu32"%%", (uint32_t)volume * 100 / 0x7f); - /* set the volume in protection of lock */ - _lock_acquire(&s_volume_lock); - s_volume = volume; - _lock_release(&s_volume_lock); - - /* send notification response to remote AVRCP controller */ - if (s_volume_notify) { - esp_avrc_rn_param_t rn_param; - rn_param.volume = s_volume; - esp_avrc_tg_send_rn_rsp(ESP_AVRC_RN_VOLUME_CHANGE, ESP_AVRC_RN_RSP_CHANGED, &rn_param); - s_volume_notify = false; - } -} - -static void volume_change_simulation(void *arg) -{ - ESP_LOGI(BT_RC_TG_TAG, "start volume change simulation"); - - for (;;) { - /* volume up locally every 10 seconds */ - vTaskDelay(10000 / portTICK_PERIOD_MS); - uint8_t volume = (s_volume + 5) & 0x7f; - volume_set_by_local_host(volume); - } -} - -static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) -{ - ESP_LOGD(BT_AV_TAG, "%s event: %d", __func__, event); - - esp_a2d_cb_param_t *a2d = NULL; - - switch (event) { - /* when connection state changed, this event comes */ - case ESP_A2D_CONNECTION_STATE_EVT: { - a2d = (esp_a2d_cb_param_t *)(p_param); - uint8_t *bda = a2d->conn_stat.remote_bda; - ESP_LOGI(BT_AV_TAG, "A2DP connection state: %s, [%02x:%02x:%02x:%02x:%02x:%02x]", - s_a2d_conn_state_str[a2d->conn_stat.state], bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); - if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) { - esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); - bt_i2s_driver_uninstall(); - bt_i2s_task_shut_down(); - } else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTED){ - esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE); - bt_i2s_task_start_up(); - } else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTING) { - bt_i2s_driver_install(); - } - break; - } - /* when audio stream transmission state changed, this event comes */ - case ESP_A2D_AUDIO_STATE_EVT: { - a2d = (esp_a2d_cb_param_t *)(p_param); - ESP_LOGI(BT_AV_TAG, "A2DP audio state: %s", s_a2d_audio_state_str[a2d->audio_stat.state]); - s_audio_state = a2d->audio_stat.state; - if (ESP_A2D_AUDIO_STATE_STARTED == a2d->audio_stat.state) { - s_pkt_cnt = 0; - } - break; - } - /* when audio codec is configured, this event comes */ - case ESP_A2D_AUDIO_CFG_EVT: { - a2d = (esp_a2d_cb_param_t *)(p_param); - esp_a2d_mcc_t *p_mcc = &a2d->audio_cfg.mcc; - ESP_LOGI(BT_AV_TAG, "A2DP audio stream configuration, codec type: %d", p_mcc->type); - /* for now only SBC stream is supported */ - if (p_mcc->type == ESP_A2D_MCT_SBC) { - int sample_rate = 16000; - int ch_count = 2; - if (p_mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_32K) { - sample_rate = 32000; - } else if (p_mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_44K) { - sample_rate = 44100; - } else if (p_mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_48K) { - sample_rate = 48000; - } - - if (p_mcc->cie.sbc_info.ch_mode & ESP_A2D_SBC_CIE_CH_MODE_MONO) { - ch_count = 1; - } - #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - dac_continuous_disable(tx_chan); - dac_continuous_del_channels(tx_chan); - dac_continuous_config_t cont_cfg = { - .chan_mask = DAC_CHANNEL_MASK_ALL, - .desc_num = 8, - .buf_size = 2048, - .freq_hz = sample_rate, - .offset = 127, - .clk_src = DAC_DIGI_CLK_SRC_DEFAULT, // Using APLL as clock source to get a wider frequency range - .chan_mode = (ch_count == 1) ? DAC_CHANNEL_MODE_SIMUL : DAC_CHANNEL_MODE_ALTER, - }; - /* Allocate continuous channels */ - dac_continuous_new_channels(&cont_cfg, &tx_chan); - /* Enable the continuous channels */ - dac_continuous_enable(tx_chan); - #else - i2s_channel_disable(tx_chan); - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(sample_rate); - i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, ch_count); - i2s_channel_reconfig_std_clock(tx_chan, &clk_cfg); - i2s_channel_reconfig_std_slot(tx_chan, &slot_cfg); - i2s_channel_enable(tx_chan); - #endif - ESP_LOGI(BT_AV_TAG, "Configure audio player: 0x%x-0x%x-0x%x-0x%x-0x%x-%d-%d", - p_mcc->cie.sbc_info.samp_freq, - p_mcc->cie.sbc_info.ch_mode, - p_mcc->cie.sbc_info.block_len, - p_mcc->cie.sbc_info.num_subbands, - p_mcc->cie.sbc_info.alloc_mthd, - p_mcc->cie.sbc_info.min_bitpool, - p_mcc->cie.sbc_info.max_bitpool); - ESP_LOGI(BT_AV_TAG, "Audio player configured, sample rate: %d", sample_rate); - } - break; - } - /* when a2dp init or deinit completed, this event comes */ - case ESP_A2D_PROF_STATE_EVT: { - a2d = (esp_a2d_cb_param_t *)(p_param); - if (ESP_A2D_INIT_SUCCESS == a2d->a2d_prof_stat.init_state) { - ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Init Complete"); - } else { - ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Deinit Complete"); - } - break; - } - /* when using external codec, after sep registration done, this event comes */ - case ESP_A2D_SEP_REG_STATE_EVT: { - a2d = (esp_a2d_cb_param_t *)(p_param); - if (a2d->a2d_sep_reg_stat.reg_state == ESP_A2D_SEP_REG_SUCCESS) { - ESP_LOGI(BT_AV_TAG, "A2DP register SEP success, seid: %d", a2d->a2d_sep_reg_stat.seid); - } - else { - ESP_LOGI(BT_AV_TAG, "A2DP register SEP fail, seid: %d, state: %d", a2d->a2d_sep_reg_stat.seid, a2d->a2d_sep_reg_stat.reg_state); - } - break; - } - /* When protocol service capabilities configured, this event comes */ - case ESP_A2D_SNK_PSC_CFG_EVT: { - a2d = (esp_a2d_cb_param_t *)(p_param); - ESP_LOGI(BT_AV_TAG, "protocol service capabilities configured: 0x%x ", a2d->a2d_psc_cfg_stat.psc_mask); - if (a2d->a2d_psc_cfg_stat.psc_mask & ESP_A2D_PSC_DELAY_RPT) { - ESP_LOGI(BT_AV_TAG, "Peer device support delay reporting"); - } else { - ESP_LOGI(BT_AV_TAG, "Peer device unsupported delay reporting"); - } - break; - } - /* when set delay value completed, this event comes */ - case ESP_A2D_SNK_SET_DELAY_VALUE_EVT: { - a2d = (esp_a2d_cb_param_t *)(p_param); - if (ESP_A2D_SET_INVALID_PARAMS == a2d->a2d_set_delay_value_stat.set_state) { - ESP_LOGI(BT_AV_TAG, "Set delay report value: fail"); - } else { - ESP_LOGI(BT_AV_TAG, "Set delay report value: success, delay_value: %u * 1/10 ms", a2d->a2d_set_delay_value_stat.delay_value); - } - break; - } - /* when get delay value completed, this event comes */ - case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: { - a2d = (esp_a2d_cb_param_t *)(p_param); - ESP_LOGI(BT_AV_TAG, "Get delay report value: delay_value: %u * 1/10 ms", a2d->a2d_get_delay_value_stat.delay_value); - /* Default delay value plus delay caused by application layer */ - esp_a2d_sink_set_delay_value(a2d->a2d_get_delay_value_stat.delay_value + APP_DELAY_VALUE); - break; - } - /* others */ - default: - ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); - break; - } -} - -static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param) -{ - ESP_LOGD(BT_RC_CT_TAG, "%s event: %d", __func__, event); - - esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(p_param); - - switch (event) { - /* when connection state changed, this event comes */ - case ESP_AVRC_CT_CONNECTION_STATE_EVT: { - uint8_t *bda = rc->conn_stat.remote_bda; - ESP_LOGI(BT_RC_CT_TAG, "AVRC conn_state event: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", - rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); - - if (rc->conn_stat.connected) { - /* get remote supported event_ids of peer AVRCP Target */ - esp_avrc_ct_send_get_rn_capabilities_cmd(APP_RC_CT_TL_GET_CAPS); - } else { - /* clear peer notification capability record */ - s_avrc_peer_rn_cap.bits = 0; - } - break; - } - /* when passthrough response, this event comes */ - case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: { - ESP_LOGI(BT_RC_CT_TAG, "AVRC passthrough rsp: key_code 0x%x, key_state %d, rsp_code %d", rc->psth_rsp.key_code, - rc->psth_rsp.key_state, rc->psth_rsp.rsp_code); - break; - } - /* when metadata response, this event comes */ - case ESP_AVRC_CT_METADATA_RSP_EVT: { - ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text); -#if CONFIG_EXAMPLE_AVRCP_CT_COVER_ART_ENABLE - if(rc->meta_rsp.attr_id == 0x80 && cover_art_connected && cover_art_getting == false) { - /* check image handle is valid and different with last one, wo dont want to get an image repeatedly */ - if(image_handle_check(rc->meta_rsp.attr_text, rc->meta_rsp.attr_length)) { - esp_avrc_ct_cover_art_get_linked_thumbnail(rc->meta_rsp.attr_text); - cover_art_getting = true; - } - } -#endif - free(rc->meta_rsp.attr_text); - break; - } - /* when notified, this event comes */ - case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: { - ESP_LOGI(BT_RC_CT_TAG, "AVRC event notification: %d", rc->change_ntf.event_id); - bt_av_notify_evt_handler(rc->change_ntf.event_id, &rc->change_ntf.event_parameter); - break; - } - /* when feature of remote device indicated, this event comes */ - case ESP_AVRC_CT_REMOTE_FEATURES_EVT: { - ESP_LOGI(BT_RC_CT_TAG, "AVRC remote features %"PRIx32", TG features %x", rc->rmt_feats.feat_mask, rc->rmt_feats.tg_feat_flag); -#if CONFIG_EXAMPLE_AVRCP_CT_COVER_ART_ENABLE - if ((rc->rmt_feats.tg_feat_flag & ESP_AVRC_FEAT_FLAG_TG_COVER_ART) && !cover_art_connected) { - ESP_LOGW(BT_RC_CT_TAG, "Peer support Cover Art feature, start connection..."); - /* set mtu to zero to use a default value */ - esp_avrc_ct_cover_art_connect(0); - } -#endif - break; - } - /* when notification capability of peer device got, this event comes */ - case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: { - ESP_LOGI(BT_RC_CT_TAG, "remote rn_cap: count %d, bitmask 0x%x", rc->get_rn_caps_rsp.cap_count, - rc->get_rn_caps_rsp.evt_set.bits); - s_avrc_peer_rn_cap.bits = rc->get_rn_caps_rsp.evt_set.bits; - bt_av_new_track(); - bt_av_playback_changed(); - bt_av_play_pos_changed(); - break; - } - case ESP_AVRC_CT_COVER_ART_STATE_EVT: { -#if CONFIG_EXAMPLE_AVRCP_CT_COVER_ART_ENABLE - if (rc->cover_art_state.state == ESP_AVRC_COVER_ART_CONNECTED) { - cover_art_connected = true; - ESP_LOGW(BT_RC_CT_TAG, "Cover Art Client connected"); - } - else { - cover_art_connected = false; - ESP_LOGW(BT_RC_CT_TAG, "Cover Art Client disconnected, reason:%d", rc->cover_art_state.reason); - } -#endif - break; - } - case ESP_AVRC_CT_COVER_ART_DATA_EVT: { -#if CONFIG_EXAMPLE_AVRCP_CT_COVER_ART_ENABLE - /* when rc->cover_art_data.final is true, it means we have received the entire image or get operation failed */ - if (rc->cover_art_data.final) { - if(rc->cover_art_data.status == ESP_BT_STATUS_SUCCESS) { - ESP_LOGI(BT_RC_CT_TAG, "Cover Art Client final data event, image size: %lu bytes", cover_art_image_size); - } - else { - ESP_LOGE(BT_RC_CT_TAG, "Cover Art Client get operation failed"); - } - cover_art_image_size = 0; - /* set the getting state to false, we can get next image now */ - cover_art_getting = false; - } -#endif - break; - } - /* when avrcp controller init or deinit completed, this event comes */ - case ESP_AVRC_CT_PROF_STATE_EVT: { - if (ESP_AVRC_INIT_SUCCESS == rc->avrc_ct_init_stat.state) { - ESP_LOGI(BT_RC_CT_TAG, "AVRCP CT STATE: Init Complete"); - } else if (ESP_AVRC_DEINIT_SUCCESS == rc->avrc_ct_init_stat.state) { - ESP_LOGI(BT_RC_CT_TAG, "AVRCP CT STATE: Deinit Complete"); - } else { - ESP_LOGE(BT_RC_CT_TAG, "AVRCP CT STATE error: %d", rc->avrc_ct_init_stat.state); - } - break; - } - /* others */ - default: - ESP_LOGE(BT_RC_CT_TAG, "%s unhandled event: %d", __func__, event); - break; - } -} - -static void bt_av_hdl_avrc_tg_evt(uint16_t event, void *p_param) -{ - ESP_LOGD(BT_RC_TG_TAG, "%s event: %d", __func__, event); - - esp_avrc_tg_cb_param_t *rc = (esp_avrc_tg_cb_param_t *)(p_param); - - switch (event) { - /* when connection state changed, this event comes */ - case ESP_AVRC_TG_CONNECTION_STATE_EVT: { - uint8_t *bda = rc->conn_stat.remote_bda; - ESP_LOGI(BT_RC_TG_TAG, "AVRC conn_state evt: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", - rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); - if (rc->conn_stat.connected) { - /* create task to simulate volume change */ - xTaskCreate(volume_change_simulation, "vcsTask", 2048, NULL, 5, &s_vcs_task_hdl); - } else { - vTaskDelete(s_vcs_task_hdl); - ESP_LOGI(BT_RC_TG_TAG, "Stop volume change simulation"); - } - break; - } - /* when passthrough commanded, this event comes */ - case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT: { - ESP_LOGI(BT_RC_TG_TAG, "AVRC passthrough cmd: key_code 0x%x, key_state %d", rc->psth_cmd.key_code, rc->psth_cmd.key_state); - break; - } - /* when absolute volume command from remote device set, this event comes */ - case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: { - ESP_LOGI(BT_RC_TG_TAG, "AVRC set absolute volume: %d%%", (int)rc->set_abs_vol.volume * 100 / 0x7f); - volume_set_by_controller(rc->set_abs_vol.volume); - break; - } - /* when notification registered, this event comes */ - case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: { - ESP_LOGI(BT_RC_TG_TAG, "AVRC register event notification: %d, param: 0x%"PRIx32, rc->reg_ntf.event_id, rc->reg_ntf.event_parameter); - if (rc->reg_ntf.event_id == ESP_AVRC_RN_VOLUME_CHANGE) { - s_volume_notify = true; - esp_avrc_rn_param_t rn_param; - rn_param.volume = s_volume; - esp_avrc_tg_send_rn_rsp(ESP_AVRC_RN_VOLUME_CHANGE, ESP_AVRC_RN_RSP_INTERIM, &rn_param); - } - break; - } - /* when feature of remote device indicated, this event comes */ - case ESP_AVRC_TG_REMOTE_FEATURES_EVT: { - ESP_LOGI(BT_RC_TG_TAG, "AVRC remote features: %"PRIx32", CT features: %x", rc->rmt_feats.feat_mask, rc->rmt_feats.ct_feat_flag); - break; - } - /* when avrcp target init or deinit completed, this event comes */ - case ESP_AVRC_TG_PROF_STATE_EVT: { - if (ESP_AVRC_INIT_SUCCESS == rc->avrc_tg_init_stat.state) { - ESP_LOGI(BT_RC_CT_TAG, "AVRCP TG STATE: Init Complete"); - } else if (ESP_AVRC_DEINIT_SUCCESS == rc->avrc_tg_init_stat.state) { - ESP_LOGI(BT_RC_CT_TAG, "AVRCP TG STATE: Deinit Complete"); - } else { - ESP_LOGE(BT_RC_CT_TAG, "AVRCP TG STATE error: %d", rc->avrc_tg_init_stat.state); - } - break; - } - /* others */ - default: - ESP_LOGE(BT_RC_TG_TAG, "%s unhandled event: %d", __func__, event); - break; - } -} - -/******************************** - * EXTERNAL FUNCTION DEFINITIONS - *******************************/ - -void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) -{ - switch (event) { - case ESP_A2D_CONNECTION_STATE_EVT: - case ESP_A2D_AUDIO_STATE_EVT: - case ESP_A2D_AUDIO_CFG_EVT: - case ESP_A2D_PROF_STATE_EVT: - case ESP_A2D_SEP_REG_STATE_EVT: - case ESP_A2D_SNK_PSC_CFG_EVT: - case ESP_A2D_SNK_SET_DELAY_VALUE_EVT: - case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: { - bt_app_work_dispatch(bt_av_hdl_a2d_evt, event, param, sizeof(esp_a2d_cb_param_t), NULL); - break; - } - default: - ESP_LOGE(BT_AV_TAG, "Invalid A2DP event: %d", event); - break; - } -} - -#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE - -void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len) -{ - write_ringbuf(data, len); - - /* log the number every 100 packets */ - if (++s_pkt_cnt % 100 == 0) { - ESP_LOGI(BT_AV_TAG, "Audio packet count: %"PRIu32, s_pkt_cnt); - } -} - -#else - -void bt_app_a2d_audio_data_cb(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf) -{ - ESP_LOGI(BT_AV_TAG, "data_len: %d, number_frame: %d, ts: %lu", audio_buf->data_len, audio_buf->number_frame, audio_buf->timestamp); - - /* - * Normally, user should send the audio_buf to other task, decode and free audio buff, - * But the codec component is not merge into IDF now, so we just free audio data here - */ - esp_a2d_audio_buff_free(audio_buf); -} - -#endif - -void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param) -{ -#if CONFIG_EXAMPLE_AVRCP_CT_COVER_ART_ENABLE - /* we must handle ESP_AVRC_CT_COVER_ART_DATA_EVT in this callback, copy image data to other buff before return if need */ - if (event == ESP_AVRC_CT_COVER_ART_DATA_EVT && param->cover_art_data.status == ESP_BT_STATUS_SUCCESS) { - cover_art_image_size += param->cover_art_data.data_len; - /* copy image data to other place */ - /* memcpy(p_buf, param->cover_art_data.p_data, param->cover_art_data.data_len); */ - } -#endif - switch (event) { - case ESP_AVRC_CT_METADATA_RSP_EVT: - bt_app_alloc_meta_buffer(param); - /* fall through */ - case ESP_AVRC_CT_CONNECTION_STATE_EVT: - case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: - case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: - case ESP_AVRC_CT_REMOTE_FEATURES_EVT: - case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: - case ESP_AVRC_CT_COVER_ART_STATE_EVT: - case ESP_AVRC_CT_COVER_ART_DATA_EVT: - case ESP_AVRC_CT_PROF_STATE_EVT: { - bt_app_work_dispatch(bt_av_hdl_avrc_ct_evt, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL); - break; - } - default: - ESP_LOGE(BT_RC_CT_TAG, "Invalid AVRC event: %d", event); - break; - } -} - -void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param) -{ - switch (event) { - case ESP_AVRC_TG_CONNECTION_STATE_EVT: - case ESP_AVRC_TG_REMOTE_FEATURES_EVT: - case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT: - case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: - case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: - case ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT: - case ESP_AVRC_TG_PROF_STATE_EVT: - bt_app_work_dispatch(bt_av_hdl_avrc_tg_evt, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL); - break; - default: - ESP_LOGE(BT_RC_TG_TAG, "Invalid AVRC event: %d", event); - break; - } -} diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.h b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.h deleted file mode 100644 index 50a2116627..0000000000 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -#ifndef __BT_APP_AV_H__ -#define __BT_APP_AV_H__ - -#include -#include "esp_a2dp_api.h" -#include "esp_avrc_api.h" - -/* log tags */ -#define BT_AV_TAG "BT_AV" -#define BT_RC_TG_TAG "RC_TG" -#define BT_RC_CT_TAG "RC_CT" - -/** - * @brief callback function for A2DP sink - * - * @param [in] event event id - * @param [in] param callback parameter - */ -void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param); - -/** - * @brief callback function for A2DP sink audio data stream - * - * @param [out] data data stream writteen by application task - * @param [in] len length of data stream in byte - */ -void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len); - -/** - * @brief callback function for A2DP sink undecoded audio data - * - * @param [in] conn_hdl connection handle - * @param [in] audio_buf pointer to audio buff - */ -void bt_app_a2d_audio_data_cb(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf); - -/** - * @brief callback function for AVRCP controller - * - * @param [in] event event id - * @param [in] param callback parameter - */ -void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param); - -/** - * @brief callback function for AVRCP target - * - * @param [in] event event id - * @param [in] param callback parameter - */ -void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param); - -#endif /* __BT_APP_AV_H__*/ diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c deleted file mode 100644 index 29c915e893..0000000000 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -#include -#include -#include -#include "freertos/FreeRTOSConfig.h" -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" -#include "freertos/semphr.h" -#include "freertos/task.h" -#include "esp_log.h" -#include "bt_app_core.h" -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC -#include "driver/dac_continuous.h" -#else -#include "driver/i2s_std.h" -#endif -#include "freertos/ringbuf.h" - - -#define RINGBUF_HIGHEST_WATER_LEVEL (32 * 1024) -#define RINGBUF_PREFETCH_WATER_LEVEL (20 * 1024) - -enum { - RINGBUFFER_MODE_PROCESSING, /* ringbuffer is buffering incoming audio data, I2S is working */ - RINGBUFFER_MODE_PREFETCHING, /* ringbuffer is buffering incoming audio data, I2S is waiting */ - RINGBUFFER_MODE_DROPPING /* ringbuffer is not buffering (dropping) incoming audio data, I2S is working */ -}; - -/******************************* - * STATIC FUNCTION DECLARATIONS - ******************************/ - -/* handler for application task */ -static void bt_app_task_handler(void *arg); -/* handler for I2S task */ -static void bt_i2s_task_handler(void *arg); -/* message sender */ -static bool bt_app_send_msg(bt_app_msg_t *msg); -/* handle dispatched messages */ -static void bt_app_work_dispatched(bt_app_msg_t *msg); - -/******************************* - * STATIC VARIABLE DEFINITIONS - ******************************/ - -static QueueHandle_t s_bt_app_task_queue = NULL; /* handle of work queue */ -static TaskHandle_t s_bt_app_task_handle = NULL; /* handle of application task */ -static TaskHandle_t s_bt_i2s_task_handle = NULL; /* handle of I2S task */ -static RingbufHandle_t s_ringbuf_i2s = NULL; /* handle of ringbuffer for I2S */ -static SemaphoreHandle_t s_i2s_write_semaphore = NULL; -static uint16_t ringbuffer_mode = RINGBUFFER_MODE_PROCESSING; - -/********************************* - * EXTERNAL FUNCTION DECLARATIONS - ********************************/ -#ifndef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC -extern i2s_chan_handle_t tx_chan; -#else -extern dac_continuous_handle_t tx_chan; -#endif - -/******************************* - * STATIC FUNCTION DEFINITIONS - ******************************/ - -static bool bt_app_send_msg(bt_app_msg_t *msg) -{ - if (msg == NULL) { - return false; - } - - /* send the message to work queue */ - if (xQueueSend(s_bt_app_task_queue, msg, 10 / portTICK_PERIOD_MS) != pdTRUE) { - ESP_LOGE(BT_APP_CORE_TAG, "%s xQueue send failed", __func__); - return false; - } - return true; -} - -static void bt_app_work_dispatched(bt_app_msg_t *msg) -{ - if (msg->cb) { - msg->cb(msg->event, msg->param); - } -} - -static void bt_app_task_handler(void *arg) -{ - bt_app_msg_t msg; - - for (;;) { - /* receive message from work queue and handle it */ - if (pdTRUE == xQueueReceive(s_bt_app_task_queue, &msg, (TickType_t)portMAX_DELAY)) { - ESP_LOGD(BT_APP_CORE_TAG, "%s, signal: 0x%x, event: 0x%x", __func__, msg.sig, msg.event); - - switch (msg.sig) { - case BT_APP_SIG_WORK_DISPATCH: - bt_app_work_dispatched(&msg); - break; - default: - ESP_LOGW(BT_APP_CORE_TAG, "%s, unhandled signal: %d", __func__, msg.sig); - break; - } /* switch (msg.sig) */ - - if (msg.param) { - free(msg.param); - } - } - } -} - -static void bt_i2s_task_handler(void *arg) -{ - uint8_t *data = NULL; - size_t item_size = 0; - /** - * The total length of DMA buffer of I2S is: - * `dma_frame_num * dma_desc_num * i2s_channel_num * i2s_data_bit_width / 8`. - * Transmit `dma_frame_num * dma_desc_num` bytes to DMA is trade-off. - */ - const size_t item_size_upto = 240 * 6; - size_t bytes_written = 0; - - for (;;) { - if (pdTRUE == xSemaphoreTake(s_i2s_write_semaphore, portMAX_DELAY)) { - for (;;) { - item_size = 0; - /* receive data from ringbuffer and write it to I2S DMA transmit buffer */ - data = (uint8_t *)xRingbufferReceiveUpTo(s_ringbuf_i2s, &item_size, (TickType_t)pdMS_TO_TICKS(20), item_size_upto); - if (item_size == 0) { - ESP_LOGI(BT_APP_CORE_TAG, "ringbuffer underflowed! mode changed: RINGBUFFER_MODE_PREFETCHING"); - ringbuffer_mode = RINGBUFFER_MODE_PREFETCHING; - break; - } - - #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - dac_continuous_write(tx_chan, data, item_size, &bytes_written, -1); - #else - i2s_channel_write(tx_chan, data, item_size, &bytes_written, portMAX_DELAY); - #endif - vRingbufferReturnItem(s_ringbuf_i2s, (void *)data); - } - } - } -} - -/******************************** - * EXTERNAL FUNCTION DEFINITIONS - *******************************/ - -bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback) -{ - ESP_LOGD(BT_APP_CORE_TAG, "%s event: 0x%x, param len: %d", __func__, event, param_len); - - bt_app_msg_t msg; - memset(&msg, 0, sizeof(bt_app_msg_t)); - - msg.sig = BT_APP_SIG_WORK_DISPATCH; - msg.event = event; - msg.cb = p_cback; - - if (param_len == 0) { - return bt_app_send_msg(&msg); - } else if (p_params && param_len > 0) { - if ((msg.param = malloc(param_len)) != NULL) { - memcpy(msg.param, p_params, param_len); - /* check if caller has provided a copy callback to do the deep copy */ - if (p_copy_cback) { - p_copy_cback(msg.param, p_params, param_len); - } - return bt_app_send_msg(&msg); - } - } - - return false; -} - -void bt_app_task_start_up(void) -{ - s_bt_app_task_queue = xQueueCreate(10, sizeof(bt_app_msg_t)); - xTaskCreate(bt_app_task_handler, "BtAppTask", 3072, NULL, 10, &s_bt_app_task_handle); -} - -void bt_app_task_shut_down(void) -{ - if (s_bt_app_task_handle) { - vTaskDelete(s_bt_app_task_handle); - s_bt_app_task_handle = NULL; - } - if (s_bt_app_task_queue) { - vQueueDelete(s_bt_app_task_queue); - s_bt_app_task_queue = NULL; - } -} - -void bt_i2s_task_start_up(void) -{ - ESP_LOGI(BT_APP_CORE_TAG, "ringbuffer data empty! mode changed: RINGBUFFER_MODE_PREFETCHING"); - ringbuffer_mode = RINGBUFFER_MODE_PREFETCHING; - if ((s_i2s_write_semaphore = xSemaphoreCreateBinary()) == NULL) { - ESP_LOGE(BT_APP_CORE_TAG, "%s, Semaphore create failed", __func__); - return; - } - if ((s_ringbuf_i2s = xRingbufferCreate(RINGBUF_HIGHEST_WATER_LEVEL, RINGBUF_TYPE_BYTEBUF)) == NULL) { - ESP_LOGE(BT_APP_CORE_TAG, "%s, ringbuffer create failed", __func__); - return; - } - xTaskCreate(bt_i2s_task_handler, "BtI2STask", 2048, NULL, configMAX_PRIORITIES - 3, &s_bt_i2s_task_handle); -} - -void bt_i2s_task_shut_down(void) -{ - if (s_bt_i2s_task_handle) { - vTaskDelete(s_bt_i2s_task_handle); - s_bt_i2s_task_handle = NULL; - } - if (s_ringbuf_i2s) { - vRingbufferDelete(s_ringbuf_i2s); - s_ringbuf_i2s = NULL; - } - if (s_i2s_write_semaphore) { - vSemaphoreDelete(s_i2s_write_semaphore); - s_i2s_write_semaphore = NULL; - } -} - -size_t write_ringbuf(const uint8_t *data, size_t size) -{ - size_t item_size = 0; - BaseType_t done = pdFALSE; - - if (ringbuffer_mode == RINGBUFFER_MODE_DROPPING) { - ESP_LOGW(BT_APP_CORE_TAG, "ringbuffer is full, drop this packet!"); - vRingbufferGetInfo(s_ringbuf_i2s, NULL, NULL, NULL, NULL, &item_size); - if (item_size <= RINGBUF_PREFETCH_WATER_LEVEL) { - ESP_LOGI(BT_APP_CORE_TAG, "ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING"); - ringbuffer_mode = RINGBUFFER_MODE_PROCESSING; - } - return 0; - } - - done = xRingbufferSend(s_ringbuf_i2s, (void *)data, size, (TickType_t)0); - - if (!done) { - ESP_LOGW(BT_APP_CORE_TAG, "ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING"); - ringbuffer_mode = RINGBUFFER_MODE_DROPPING; - } - - if (ringbuffer_mode == RINGBUFFER_MODE_PREFETCHING) { - vRingbufferGetInfo(s_ringbuf_i2s, NULL, NULL, NULL, NULL, &item_size); - if (item_size >= RINGBUF_PREFETCH_WATER_LEVEL) { - ESP_LOGI(BT_APP_CORE_TAG, "ringbuffer data increased! mode changed: RINGBUFFER_MODE_PROCESSING"); - ringbuffer_mode = RINGBUFFER_MODE_PROCESSING; - if (pdFALSE == xSemaphoreGive(s_i2s_write_semaphore)) { - ESP_LOGE(BT_APP_CORE_TAG, "semphore give failed"); - } - } - } - - return done ? size : 0; -} diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c deleted file mode 100644 index 8393b3e40f..0000000000 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -#include -#include -#include -#include -#include -#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.h" -#include "bt_app_core.h" -#include "bt_app_av.h" -#include "esp_bt_main.h" -#include "esp_bt_device.h" -#include "esp_gap_bt_api.h" -#include "esp_a2dp_api.h" -#include "esp_avrc_api.h" - -/* device name */ -static const char local_device_name[] = CONFIG_EXAMPLE_LOCAL_DEVICE_NAME; - -/* event for stack up */ -enum { - BT_APP_EVT_STACK_UP = 0, -}; - -/******************************** - * STATIC FUNCTION DECLARATIONS - *******************************/ - -/* Device callback function */ -static void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param); -/* GAP callback function */ -static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param); -/* handler for bluetooth stack enabled events */ -static void bt_av_hdl_stack_evt(uint16_t event, void *p_param); - -/******************************* - * STATIC FUNCTION DEFINITIONS - ******************************/ -static char *bda2str(uint8_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 void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param) -{ - switch (event) { - case ESP_BT_DEV_NAME_RES_EVT: { - if (param->name_res.status == ESP_BT_STATUS_SUCCESS) { - ESP_LOGI(BT_AV_TAG, "Get local device name success: %s", param->name_res.name); - } else { - ESP_LOGE(BT_AV_TAG, "Get local device name failed, status: %d", param->name_res.status); - } - break; - } - default: { - ESP_LOGI(BT_AV_TAG, "event: %d", event); - break; - } - } -} - -static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) -{ - uint8_t *bda = NULL; - - switch (event) { - /* when authentication completed, this event comes */ - case ESP_BT_GAP_AUTH_CMPL_EVT: { - if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { - ESP_LOGI(BT_AV_TAG, "authentication success: %s", param->auth_cmpl.device_name); - ESP_LOG_BUFFER_HEX(BT_AV_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN); - } else { - ESP_LOGE(BT_AV_TAG, "authentication failed, status: %d", param->auth_cmpl.stat); - } - ESP_LOGI(BT_AV_TAG, "link key type of current link is: %d", param->auth_cmpl.lk_type); - break; - } - case ESP_BT_GAP_ENC_CHG_EVT: { - char *str_enc[3] = {"OFF", "E0", "AES"}; - bda = (uint8_t *)param->enc_chg.bda; - ESP_LOGI(BT_AV_TAG, "Encryption mode to [%02x:%02x:%02x:%02x:%02x:%02x] changed to %s", - bda[0], bda[1], bda[2], bda[3], bda[4], bda[5], str_enc[param->enc_chg.enc_mode]); - break; - } - -#if (CONFIG_EXAMPLE_A2DP_SINK_SSP_ENABLED == true) - /* when Security Simple Pairing user confirmation requested, this event comes */ - case ESP_BT_GAP_CFM_REQ_EVT: - ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %06"PRIu32, param->cfm_req.num_val); - esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true); - break; - /* when Security Simple Pairing passkey notified, this event comes */ - case ESP_BT_GAP_KEY_NOTIF_EVT: - ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey: %06"PRIu32, param->key_notif.passkey); - break; - /* when Security Simple Pairing passkey requested, this event comes */ - case ESP_BT_GAP_KEY_REQ_EVT: - ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!"); - break; -#endif - - /* when GAP mode changed, this event comes */ - case ESP_BT_GAP_MODE_CHG_EVT: - ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_MODE_CHG_EVT mode: %d, interval: %.2f ms", - param->mode_chg.mode, param->mode_chg.interval * 0.625); - break; - /* when ACL connection completed, this event comes */ - case ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT: - bda = (uint8_t *)param->acl_conn_cmpl_stat.bda; - ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT Connected to [%02x:%02x:%02x:%02x:%02x:%02x], status: 0x%x", - bda[0], bda[1], bda[2], bda[3], bda[4], bda[5], param->acl_conn_cmpl_stat.stat); - break; - /* when ACL disconnection completed, this event comes */ - case ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT: - bda = (uint8_t *)param->acl_disconn_cmpl_stat.bda; - ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_ACL_DISC_CMPL_STAT_EVT Disconnected from [%02x:%02x:%02x:%02x:%02x:%02x], reason: 0x%x", - bda[0], bda[1], bda[2], bda[3], bda[4], bda[5], param->acl_disconn_cmpl_stat.reason); - break; - /* others */ - default: { - ESP_LOGI(BT_AV_TAG, "event: %d", event); - break; - } - } -} - -static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) -{ - ESP_LOGD(BT_AV_TAG, "%s event: %d", __func__, event); - - switch (event) { - /* when do the stack up, this event comes */ - case BT_APP_EVT_STACK_UP: { - esp_bt_gap_set_device_name(local_device_name); - esp_bt_dev_register_callback(bt_app_dev_cb); - esp_bt_gap_register_callback(bt_app_gap_cb); - - esp_avrc_ct_register_callback(bt_app_rc_ct_cb); - assert(esp_avrc_ct_init() == ESP_OK); - esp_avrc_tg_register_callback(bt_app_rc_tg_cb); - assert(esp_avrc_tg_init() == ESP_OK); - - esp_avrc_rn_evt_cap_mask_t evt_set = {0}; - esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_SET, &evt_set, ESP_AVRC_RN_VOLUME_CHANGE); - assert(esp_avrc_tg_set_rn_evt_cap(&evt_set) == ESP_OK); - - esp_a2d_register_callback(&bt_app_a2d_cb); - assert(esp_a2d_sink_init() == ESP_OK); - -#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE - esp_a2d_sink_register_data_callback(bt_app_a2d_data_cb); -#else - esp_a2d_mcc_t mcc = {0}; - mcc.type = ESP_A2D_MCT_SBC; - mcc.cie.sbc_info.samp_freq = 0xf; - mcc.cie.sbc_info.ch_mode = 0xf; - mcc.cie.sbc_info.block_len = 0xf; - mcc.cie.sbc_info.num_subbands = 0x3; - mcc.cie.sbc_info.alloc_mthd = 0x3; - mcc.cie.sbc_info.max_bitpool = 250; - mcc.cie.sbc_info.min_bitpool = 2; - /* register stream end point, only support mSBC currently */ - esp_a2d_sink_register_stream_endpoint(0, &mcc); - esp_a2d_sink_register_audio_data_callback(bt_app_a2d_audio_data_cb); -#endif - /* Get the default value of the delay value */ - esp_a2d_sink_get_delay_value(); - /* Get local device name */ - esp_bt_gap_get_device_name(); - - /* set discoverable and connectable mode, wait to be connected */ - esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); - break; - } - /* others */ - default: - ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); - break; - } -} - -/******************************* - * MAIN ENTRY POINT - ******************************/ - -void app_main(void) -{ - char bda_str[18] = {0}; - /* initialize NVS — it is used to store PHY calibration data */ - esp_err_t err = nvs_flash_init(); - if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { - ESP_ERROR_CHECK(nvs_flash_erase()); - err = nvs_flash_init(); - } - ESP_ERROR_CHECK(err); - - /* - * This example only uses the functions of Classical Bluetooth. - * So release the controller memory for Bluetooth Low Energy. - */ - 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 ((err = esp_bt_controller_init(&bt_cfg)) != ESP_OK) { - ESP_LOGE(BT_AV_TAG, "%s initialize controller failed: %s", __func__, esp_err_to_name(err)); - return; - } - if ((err = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) { - ESP_LOGE(BT_AV_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(err)); - return; - } - - esp_bluedroid_config_t bluedroid_cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT(); -#if (CONFIG_EXAMPLE_A2DP_SINK_SSP_ENABLED == false) - bluedroid_cfg.ssp_en = false; -#endif - if ((err = esp_bluedroid_init_with_cfg(&bluedroid_cfg)) != ESP_OK) { - ESP_LOGE(BT_AV_TAG, "%s initialize bluedroid failed: %s", __func__, esp_err_to_name(err)); - return; - } - - if ((err = esp_bluedroid_enable()) != ESP_OK) { - ESP_LOGE(BT_AV_TAG, "%s enable bluedroid failed: %s", __func__, esp_err_to_name(err)); - return; - } - -#if (CONFIG_EXAMPLE_A2DP_SINK_SSP_ENABLED == true) - /* set default parameters for Secure Simple Pairing */ - esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE; - esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO; - esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t)); -#endif - - /* set default parameters for Legacy Pairing (use fixed pin code 1234) */ - esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED; - esp_bt_pin_code_t pin_code; - pin_code[0] = '1'; - pin_code[1] = '2'; - pin_code[2] = '3'; - pin_code[3] = '4'; - esp_bt_gap_set_pin(pin_type, 4, pin_code); - - ESP_LOGI(BT_AV_TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str))); - bt_app_task_start_up(); - /* bluetooth device name, connection mode and profile set up */ - bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL); -} diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/CMakeLists.txt similarity index 93% rename from examples/bluetooth/bluedroid/classic_bt/a2dp_sink/CMakeLists.txt rename to examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/CMakeLists.txt index 1d31e07835..4fd485ef82 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/CMakeLists.txt +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/CMakeLists.txt @@ -5,4 +5,4 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) # "Trim" the build. Include the minimal set of components, main, and anything it depends on. idf_build_set_property(MINIMAL_BUILD ON) -project(a2dp_sink) +project(a2dp_sink_stream) diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/README.md b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/README.md similarity index 73% rename from examples/bluetooth/bluedroid/classic_bt/a2dp_sink/README.md rename to examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/README.md index 072cacd12c..c21418d203 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/README.md +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/README.md @@ -1,16 +1,34 @@ | Supported Targets | ESP32 | | ----------------- | ----- | -A2DP-SINK EXAMPLE +A2DP-SINK-STREAM EXAMPLE ====================== Example of A2DP audio sink role This is the example of API implementing Advanced Audio Distribution Profile to receive an audio stream. -This example involves the use of Bluetooth legacy profile A2DP for audio stream reception, AVRCP for media information notifications, and I2S for audio stream output interface. +This example involves the use of Bluetooth legacy profile A2DP for audio stream reception and I2S for audio stream output interface. -Applications such as bluetooth speakers can take advantage of this example as a reference of basic functionalities. +## Required components + +- [bt_app_core_utils](../common/bt_app_core_utils) +- [bredr_app_common_utils](../common/bredr_app_common_utils) +- [a2dp_sink_common_utils](../common/a2dp_utils/a2dp_sink_common_utils) +- [a2dp_sink_int_codec_utils](../common/a2dp_utils/a2dp_sink_int_codec_utils) +- [a2dp_sink_ext_codec_utils](../common/a2dp_utils/a2dp_sink_ext_codec_utils) + +``` ++-------------------------+-------------------------+---------------------+ +|a2dp_sink_int_codec_utils|a2dp_sink_ext_codec_utils| | ++-------------------------+-------------------------+ | +| a2dp_sink_common_utils | bt_app_core_utils | ++---------------------------------------------------+ | +| bredr_app_common_utils | | ++---------------------------------------------------+---------------------+ +``` + +Detailed information can be viewed through the [../common/README.md](../common/README.md). ## How to use this example @@ -22,7 +40,7 @@ For the I2S codec, pick whatever chip or board works for you; this code was writ | ESP pin | I2S signal | | :-------- | :----------- | -| GPIO22 | LRCK | +| GPIO27 | LRCK | | GPIO25 | DATA | | GPIO26 | BCK | @@ -34,9 +52,7 @@ If the internal DAC is selected, analog audio will be available on GPIO25 and GP idf.py menuconfig ``` -* Choose external I2S codec or internal DAC for audio output, and configure the output PINs under A2DP Example Configuration - -* For AVRCP CT Cover Art feature, is enabled by default, we can disable it by unselecting menuconfig option `Component config --> Bluetooth --> Bluedroid Options --> Classic Bluetooth --> AVRCP Features --> AVRCP CT Cover Art`. This example will try to use AVRCP CT Cover Art feature, get cover art image and count the image size if peer device support, this can be disable in `A2DP Example Configuration --> Use AVRCP CT Cover Art Feature`. +* Choose external I2S codec or internal DAC for audio output, and configure the output PINs under A2DP Sink Internal Codec Example Configuration. ### Build and Flash @@ -68,13 +84,6 @@ I (126697) BT_AV: Audio packet count 300 I (128697) BT_AV: Audio packet count 400 ``` -The output when receiving a cover art image: - -``` -I (53349) RC_CT: AVRC metadata rsp: attribute id 0x80, 1000748 -I (53639) RC_CT: Cover Art Client final data event, image size: 14118 bytes -``` - Also, the sound will be heard if a loudspeaker is connected and possible external I2S codec is correctly configured. For ESP32 A2DP source example, the sound is noise as the audio source generates the samples with a random sequence. ## Troubleshooting diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/CMakeLists.txt new file mode 100644 index 0000000000..6b20ae1360 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/CMakeLists.txt @@ -0,0 +1,10 @@ +if(CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC) + set(EXTRA_COMPONENTS a2dp_sink_ext_codec_utils) +else() + set(EXTRA_COMPONENTS a2dp_sink_int_codec_utils) +endif() + +idf_component_register(SRCS "main.c" + PRIV_REQUIRES bt bt_app_core_utils bredr_app_common_utils a2dp_sink_common_utils + PRIV_REQUIRES ${EXTRA_COMPONENTS} + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/Kconfig.projbuild new file mode 100644 index 0000000000..605249c797 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/Kconfig.projbuild @@ -0,0 +1,15 @@ +menu "A2DP Example Configuration" + config EXAMPLE_LOCAL_DEVICE_NAME + string "Local Device Name" + default "ESP_SPEAKER" + help + Use this option to set local device name. + + config EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC + bool "Use External Codec Instead of Internal" + default n + select BT_A2DP_USE_EXTERNAL_CODEC + help + If enable, Bluedroid stack will not decode A2DP audio data, user need to decode it in application layer. + +endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/idf_component.yml b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/idf_component.yml new file mode 100644 index 0000000000..17c8a5daae --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/idf_component.yml @@ -0,0 +1,11 @@ +dependencies: + bt_app_core_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils + bredr_app_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils + a2dp_sink_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils + a2dp_sink_int_codec_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils + a2dp_sink_ext_codec_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/main.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/main.c new file mode 100644 index 0000000000..863c0127d1 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/main.c @@ -0,0 +1,177 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include + +#include "esp_log.h" +#include "esp_bt_device.h" +#include "esp_gap_bt_api.h" +#include "esp_a2dp_api.h" + +#include "bt_app_core_utils.h" +#include "bredr_app_common_utils.h" +#include "a2dp_sink_common_utils.h" +#include "a2dp_utils_tags.h" +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE +#include "a2dp_sink_int_codec_utils.h" +#else +#include "a2dp_sink_ext_codec_utils.h" +#endif + +/* device name */ +static const char local_device_name[] = CONFIG_EXAMPLE_LOCAL_DEVICE_NAME; + +/* event for stack up */ +enum { + BT_APP_EVT_STACK_UP = 0, +}; + +/******************************** + * STATIC FUNCTION DECLARATIONS + *******************************/ + +/* Device callback function */ +static void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param); + +/* GAP callback function */ +static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param); + +/* callback function for A2DP sink */ +static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param); + +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE +/* callback function for A2DP sink audio data stream */ +static void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len); +#else +/* callback function for A2DP sink undecoded audio data */ +static void bt_app_a2d_audio_data_cb(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf); +#endif + +/* handler for bluetooth stack enabled events */ +static void bt_av_hdl_stack_evt(uint16_t event, void *p_param); + +/******************************* + * STATIC FUNCTION DEFINITIONS + ******************************/ + +static void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param) +{ + bredr_app_dev_evt_def_hdl(event, param); +} + +static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) +{ + bredr_app_gap_evt_def_hdl(event, param); +} + +static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) +{ + switch (event) { + case ESP_A2D_PROF_STATE_EVT: + case ESP_A2D_SNK_PSC_CFG_EVT: + case ESP_A2D_SNK_SET_DELAY_VALUE_EVT: + case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: { + bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); + break; + } + case ESP_A2D_CONNECTION_STATE_EVT: + case ESP_A2D_AUDIO_STATE_EVT: + case ESP_A2D_AUDIO_CFG_EVT: + case ESP_A2D_SEP_REG_STATE_EVT: { +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE + bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); +#else + bt_app_work_dispatch(bt_a2d_evt_ext_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); +#endif + break; + } + default: + ESP_LOGE(BT_AV_TAG, "Invalid A2DP event: %d", event); + break; + } +} + +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE +static void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len) +{ + bt_a2d_data_hdl(data, len); +} +#else +static void bt_app_a2d_audio_data_cb(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf) +{ + bt_a2d_audio_data_hdl(conn_hdl, audio_buf); +} +#endif + +static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) +{ + ESP_LOGD(BT_AV_TAG, "%s event: %d", __func__, event); + + switch (event) { + /* when do the stack up, this event comes */ + case BT_APP_EVT_STACK_UP: { + esp_bt_gap_set_device_name(local_device_name); + esp_bt_dev_register_callback(bt_app_dev_cb); + esp_bt_gap_register_callback(bt_app_gap_cb); + + esp_a2d_register_callback(&bt_app_a2d_cb); + assert(esp_a2d_sink_init() == ESP_OK); + +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE + esp_a2d_sink_register_data_callback(bt_app_a2d_data_cb); +#else + esp_a2d_mcc_t mcc = {0}; + mcc.type = ESP_A2D_MCT_SBC; + mcc.cie.sbc_info.samp_freq = ESP_A2D_SBC_CIE_SF_16K | + ESP_A2D_SBC_CIE_SF_32K | + ESP_A2D_SBC_CIE_SF_44K | + ESP_A2D_SBC_CIE_SF_48K; + mcc.cie.sbc_info.ch_mode = ESP_A2D_SBC_CIE_CH_MODE_MONO | + ESP_A2D_SBC_CIE_CH_MODE_DUAL_CHANNEL | + ESP_A2D_SBC_CIE_CH_MODE_STEREO | + ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO; + mcc.cie.sbc_info.block_len = ESP_A2D_SBC_CIE_BLOCK_LEN_4 | + ESP_A2D_SBC_CIE_BLOCK_LEN_8 | + ESP_A2D_SBC_CIE_BLOCK_LEN_12 | + ESP_A2D_SBC_CIE_BLOCK_LEN_16; + mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8; + mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SRN | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS; + mcc.cie.sbc_info.max_bitpool = 250; + mcc.cie.sbc_info.min_bitpool = 2; + /* register stream end point, only support SBC currently */ + esp_a2d_sink_register_stream_endpoint(0, &mcc); + esp_a2d_sink_register_audio_data_callback(bt_app_a2d_audio_data_cb); +#endif + + /* Get the default value of the delay value */ + esp_a2d_sink_get_delay_value(); + /* Get local device name */ + esp_bt_gap_get_device_name(); + + /* set discoverable and connectable mode, wait to be connected */ + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + break; + } + /* others */ + default: + ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); + break; + } +} + +/******************************* + * MAIN ENTRY POINT + ******************************/ + +void app_main(void) +{ + ESP_ERROR_CHECK(bredr_app_common_init()); + + bt_app_task_start_up(); + /* bluetooth device name, connection mode and profile set up */ + bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL); +} diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.ci.ca_dis b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/sdkconfig.ci.ca_dis similarity index 75% rename from examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.ci.ca_dis rename to examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/sdkconfig.ci.ca_dis index 1c6372a1b3..9d5c2a060d 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.ci.ca_dis +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/sdkconfig.ci.ca_dis @@ -1,12 +1,9 @@ # Override some defaults so BT stack is enabled and # Classic BT is enabled and BT_DRAM_RELEASE is disabled CONFIG_BT_ENABLED=y -CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y -CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_BLUEDROID_ENABLED=y CONFIG_BT_CLASSIC_ENABLED=y CONFIG_BT_A2DP_ENABLE=y CONFIG_BT_AVRCP_CT_COVER_ART_ENABLED=n -CONFIG_EXAMPLE_AVRCP_CT_COVER_ART_ENABLE=n CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=n diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.ci.test b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/sdkconfig.ci.test similarity index 100% rename from examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.ci.test rename to examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/sdkconfig.ci.test diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/sdkconfig.defaults similarity index 73% rename from examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.defaults rename to examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/sdkconfig.defaults index 3d17667a4c..2b93a51a0e 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/sdkconfig.defaults @@ -1,11 +1,8 @@ # Override some defaults so BT stack is enabled and # Classic BT is enabled and BT_DRAM_RELEASE is disabled CONFIG_BT_ENABLED=y -CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y -CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_BLUEDROID_ENABLED=y CONFIG_BT_CLASSIC_ENABLED=y CONFIG_BT_A2DP_ENABLE=y -CONFIG_BT_AVRCP_CT_COVER_ART_ENABLED=y CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=n diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/tutorial/Example_A2DP_Sink.md similarity index 51% rename from examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md rename to examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/tutorial/Example_A2DP_Sink.md index 510077b9aa..72b06ad89e 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/tutorial/Example_A2DP_Sink.md @@ -4,36 +4,19 @@ In this tutorial, the A2DP sink example code is reviewed. The code implements an A2DP sink role, which receives audio stream from A2DP source devices. -## File Tree - -The file tree of this example is shown below. The [main](../main) folder contains the main files of this example including audio and video related files, program core files, main function file, etc. The [tutorial](../tutorial) folder contains this guidance document. - -```c -└── a2dp_sink -    ├── CMakeLists.txt -    ├── main -    │   ├── bt_app_av.c -    │   ├── bt_app_av.h -    │   ├── bt_app_core.c -    │   ├── bt_app_core.h -    │   ├── CMakeLists.txt -    │   ├── Kconfig.projbuild -    │   └── main.c -    ├── README.md -    ├── sdkconfig.defaults -    └── tutorial -    └── Example_A2DP_Sink.md - -2 directories, 11 files -``` - ## Main Entry Point -This example is located in the examples folder of the ESP-IDF under the [bluetooth/bluedroid/classic_bt/a2dp_sink](../). The entry point of this program is `app_main()` which contained in [main/main.c](../main/main.c). +This example is located in the examples folder of the ESP-IDF under the [bluetooth/bluedroid/classic_bt/a2dp_sink_stream](../). The entry point of this program is `app_main()` which contained in [main/main.c](../main/main.c). -### NVS Initialization +The main function first initializes through `bredr_app_common_init()`, and then calls `bt_app_task_start_up()` and `bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL)` to create and execute the task. -The main function starts by initializing the non-volatile storage library. This library allows to save key-value pairs in flash memory and is used by some components such as the Wi-Fi library to save the SSID and password: +### Classic Bluetooth Initialization + +Initialize the Classic Bluetooth by calling `bredr_app_common_init()`. + +#### NVS Initialization + +The `bredr_app_common_init()` starts by initializing the non-volatile storage library. This library allows to save key-value pairs in flash memory and is used by some components such as the Wi-Fi library to save the SSID and password: ```c /* initialize NVS — it is used to store PHY calibration */ @@ -45,9 +28,9 @@ if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(ret); ``` -### Bluetooth Controller and Stack Initialization +#### Bluetooth Controller and Stack Initialization -The main function also initializes the Bluetooth Controller with default settings. The Bluetooth Controller is invisible to the user applications and deals with the lower layers of the Bluetooth Stack. Next, the controller is enabled in Classic Bluetooth Mode. +The `bredr_app_common_init()` also initializes the Bluetooth Controller with default settings. The Bluetooth Controller is invisible to the user applications and deals with the lower layers of the Bluetooth Stack. Next, the controller is enabled in Classic Bluetooth Mode. ```c /* initialize Bluetooth Controller with default configuration */ @@ -86,58 +69,9 @@ The Classic Bluetooth uses an asynchronous programming paradigm. The entire Blue For example, after executing `esp_bt_gap_start_discovery()`, an event of `ESP_BT_GAP_DISC_STATE_CHANGED_EVT` occurs to inform that the discovery state has been changed. Application can do some processing at this time. -### I2S Installation +#### Paring Parameter Settings -The main function installs I2S to play the audio. A loudspeaker, additional ADC or hardware requirements and possibly an external I2S codec may be needed. - -```c - #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - /* I2S configuration parameters */ - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, - .sample_rate = 44100, - .bits_per_sample = 16, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, /* 2-channels */ - .communication_format = I2S_COMM_FORMAT_STAND_MSB, - .dma_buf_count = 6, - .dma_buf_len = 60, - .intr_alloc_flags = 0, /* default interrupt priority */ - .tx_desc_auto_clear = true /* auto clear tx descriptor on underflow */ - }; - - /* enable I2S */ - ESP_ERROR_CHECK(i2s_driver_install(0, &i2s_config, 0, NULL)); - ESP_ERROR_CHECK(i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN)); - ESP_ERROR_CHECK(i2s_set_pin(0, NULL)); - #else - i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); - chan_cfg.auto_clear = true; - i2s_std_config_t std_cfg = { - .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(44100), - .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), - .gpio_cfg = { - .mclk = I2S_GPIO_UNUSED, - .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, - .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, - .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, - .din = I2S_GPIO_UNUSED, - .invert_flags = { - .mclk_inv = false, - .bclk_inv = false, - .ws_inv = false, - }, - }, - }; - /* enable I2S */ - ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_chan, NULL)); - ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &std_cfg)); - ESP_ERROR_CHECK(i2s_channel_enable(tx_chan)); - #endif -``` - -### Paring Parameter Settings - -The main function continues to set up paring parameters including Secure Simple Pairing and Legacy Pairing. +The `bredr_app_common_init()` continues to set up paring parameters including Secure Simple Pairing and Legacy Pairing. ```c #if (CONFIG_EXAMPLE_A2DP_SINK_SSP_ENABLED == true) diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/CMakeLists.txt new file mode 100644 index 0000000000..a693a301aa --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/CMakeLists.txt @@ -0,0 +1,8 @@ +# 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) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(avrcp_absolute_volume) diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/README.md b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/README.md new file mode 100644 index 0000000000..c8080e5eff --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/README.md @@ -0,0 +1,70 @@ +| Supported Targets | ESP32 | +| ----------------- | ----- | + +AVRCP-ABSOLUTE-VOLUME EXAMPLE +====================== + +This is the example of API implementing Audio/Video Remote Control Profile to control absolute volume. + +## Required components + +- [bt_app_core_utils](../common/bt_app_core_utils) +- [bredr_app_common_utils](../common/bredr_app_common_utils) +- [a2dp_sink_common_utils](../common/a2dp_utils/a2dp_sink_common_utils) +- [a2dp_sink_int_codec_utils](../common/a2dp_utils/a2dp_sink_int_codec_utils) +- [a2dp_sink_ext_codec_utils](../common/a2dp_utils/a2dp_sink_ext_codec_utils) +- [avrcp_common_utils](../common/avrcp_utils/avrcp_common_utils) +- [avrcp_abs_vol_utils](../common/avrcp_utils/avrcp_abs_vol_utils) + +``` ++---------------------------------------------------+---------------------+ +| avrcp_abs_vol_utils | | ++---------------------------------------------------+ | +| avrcp_common_utils | | ++-------------------------+-------------------------+ | +|a2dp_sink_int_codec_utils|a2dp_sink_ext_codec_utils| bt_app_core_utils | ++-------------------------+-------------------------+ | +| a2dp_sink_common_utils | | ++---------------------------------------------------+ | +| bredr_app_common_utils | | ++---------------------------------------------------+---------------------+ +``` + +Detailed information can be viewed through the [../common/README.md](../common/README.md). + +## How to use this example + +### Configure the project + +``` +idf.py menuconfig +``` + +### 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 +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +## Example Output + +The output when the connection is established: + +``` +I (56320) RC_VC_SRV: Volume is set locally to: 3% +I (57160) RC_TG: AVRC register event notification: 13, param: 0x0 +I (66320) RC_VC_SRV: Volume is set locally to: 7% +I (67160) RC_TG: AVRC register event notification: 13, param: 0x0 +I (76320) RC_VC_SRV: Volume is set locally to: 11% +I (77160) RC_TG: AVRC register event notification: 13, param: 0x0 +I (86320) RC_VC_SRV: Volume is set locally to: 15% +I (87160) RC_TG: AVRC register event notification: 13, param: 0x0 +``` + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/CMakeLists.txt new file mode 100644 index 0000000000..d6ae771f4b --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/CMakeLists.txt @@ -0,0 +1,12 @@ +if(CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE) + if(CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC) + set(EXTRA_COMPONENTS a2dp_sink_ext_codec_utils) + else() + set(EXTRA_COMPONENTS a2dp_sink_int_codec_utils) + endif() +endif() + +idf_component_register(SRCS "main.c" + PRIV_REQUIRES bt bt_app_core_utils bredr_app_common_utils a2dp_sink_common_utils + PRIV_REQUIRES ${EXTRA_COMPONENTS} avrcp_common_utils avrcp_abs_vol_utils + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/Kconfig.projbuild new file mode 100644 index 0000000000..2a4dfc0176 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/Kconfig.projbuild @@ -0,0 +1,23 @@ +menu "AVRCP Example Configuration" + config EXAMPLE_LOCAL_DEVICE_NAME + string "Local Device Name" + default "ESP_SPEAKER" + help + Use this option to set local device name. + + config EXAMPLE_A2DP_SINK_STREAM_ENABLE + bool "Enable A2DP Sink Stream" + default y + help + This enables the A2DP sink stream. If disable this option, + audio data will not be transmitted + + config EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC + bool "Use External Codec Instead of Internal" + depends on EXAMPLE_A2DP_SINK_STREAM_ENABLE + default n + select BT_A2DP_USE_EXTERNAL_CODEC + help + If enable, Bluedroid stack will not decode A2DP audio data, user need to decode it in application layer. + +endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/idf_component.yml b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/idf_component.yml new file mode 100644 index 0000000000..5e5b34e4b4 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/idf_component.yml @@ -0,0 +1,15 @@ +dependencies: + bt_app_core_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils + bredr_app_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils + a2dp_sink_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils + a2dp_sink_int_codec_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils + a2dp_sink_ext_codec_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils + avrcp_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils + avrcp_abs_vol_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/main.c b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/main.c new file mode 100644 index 0000000000..47a494816c --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/main.c @@ -0,0 +1,251 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include + +#include "esp_log.h" +#include "esp_bt_device.h" +#include "esp_gap_bt_api.h" +#include "esp_a2dp_api.h" +#include "esp_avrc_api.h" + +#include "bt_app_core_utils.h" +#include "bredr_app_common_utils.h" +#include "a2dp_utils_tags.h" +#include "a2dp_sink_common_utils.h" +#include "avrcp_utils_tags.h" +#include "avrcp_common_utils.h" +#include "avrcp_abs_vol_utils.h" +#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE +#include "a2dp_sink_int_codec_utils.h" +#else +#include "a2dp_sink_ext_codec_utils.h" +#endif +#endif + +/* device name */ +static const char local_device_name[] = CONFIG_EXAMPLE_LOCAL_DEVICE_NAME; + +/* event for stack up */ +enum { + BT_APP_EVT_STACK_UP = 0, +}; + +/******************************** + * STATIC FUNCTION DECLARATIONS + *******************************/ + +/* Device callback function */ +static void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param); + +/* GAP callback function */ +static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param); + +/* callback function for A2DP sink */ +static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param); + +#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE +/* callback function for A2DP sink audio data stream */ +static void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len); +#else +/* callback function for A2DP sink undecoded audio data */ +static void bt_app_a2d_audio_data_cb(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf); +#endif +#endif + +/* callback function for AVRCP controller */ +static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param); + +/* callback function for AVRCP target */ +static void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param); + +/* handler for bluetooth stack enabled events */ +static void bt_av_hdl_stack_evt(uint16_t event, void *p_param); + +/******************************* + * STATIC FUNCTION DEFINITIONS + ******************************/ + +static void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param) +{ + bredr_app_dev_evt_def_hdl(event, param); +} + +static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) +{ + bredr_app_gap_evt_def_hdl(event, param); +} + +static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) +{ + switch (event) { + case ESP_A2D_PROF_STATE_EVT: + case ESP_A2D_SNK_PSC_CFG_EVT: + case ESP_A2D_SNK_SET_DELAY_VALUE_EVT: + case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: { + bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); + break; + } + case ESP_A2D_CONNECTION_STATE_EVT: + case ESP_A2D_AUDIO_STATE_EVT: + case ESP_A2D_AUDIO_CFG_EVT: + case ESP_A2D_SEP_REG_STATE_EVT: { +#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE + bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); +#else + bt_app_work_dispatch(bt_a2d_evt_ext_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); +#endif +#else + bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); +#endif + break; + } + default: + ESP_LOGE(BT_AV_TAG, "Invalid A2DP event: %d", event); + break; + } +} + +#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE +static void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len) +{ + bt_a2d_data_hdl(data, len); +} +#else +static void bt_app_a2d_audio_data_cb(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf) +{ + bt_a2d_audio_data_hdl(conn_hdl, audio_buf); +} +#endif +#endif + +static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param) +{ + switch (event) { + case ESP_AVRC_CT_METADATA_RSP_EVT: + case ESP_AVRC_CT_CONNECTION_STATE_EVT: + case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: + case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: + case ESP_AVRC_CT_REMOTE_FEATURES_EVT: + case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: + case ESP_AVRC_CT_COVER_ART_STATE_EVT: + case ESP_AVRC_CT_COVER_ART_DATA_EVT: + case ESP_AVRC_CT_PROF_STATE_EVT: { + bt_app_work_dispatch(bt_avrc_common_ct_evt_def_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL); + break; + } + default: + ESP_LOGE(BT_RC_CT_TAG, "Invalid AVRC event: %d", event); + break; + } +} + +static void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param) +{ + switch (event) { + case ESP_AVRC_TG_REMOTE_FEATURES_EVT: + case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT: + case ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT: + case ESP_AVRC_TG_PROF_STATE_EVT: { + bt_app_work_dispatch(bt_avrc_common_tg_evt_def_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL); + break; + } + case ESP_AVRC_TG_CONNECTION_STATE_EVT: + case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: + case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: { + bt_app_work_dispatch(bt_avrc_avc_tg_evt_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL); + break; + } + default: + ESP_LOGE(BT_RC_TG_TAG, "Invalid AVRC event: %d", event); + break; + } +} + +static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) +{ + ESP_LOGD(BT_AV_TAG, "%s event: %d", __func__, event); + + switch (event) { + /* when do the stack up, this event comes */ + case BT_APP_EVT_STACK_UP: { + esp_bt_gap_set_device_name(local_device_name); + esp_bt_dev_register_callback(bt_app_dev_cb); + esp_bt_gap_register_callback(bt_app_gap_cb); + + esp_avrc_ct_register_callback(bt_app_rc_ct_cb); + assert(esp_avrc_ct_init() == ESP_OK); + esp_avrc_tg_register_callback(bt_app_rc_tg_cb); + assert(esp_avrc_tg_init() == ESP_OK); + + esp_avrc_rn_evt_cap_mask_t evt_set = {0}; + esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_SET, &evt_set, ESP_AVRC_RN_VOLUME_CHANGE); + assert(esp_avrc_tg_set_rn_evt_cap(&evt_set) == ESP_OK); + + esp_a2d_register_callback(&bt_app_a2d_cb); + assert(esp_a2d_sink_init() == ESP_OK); + +#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE + esp_a2d_sink_register_data_callback(bt_app_a2d_data_cb); +#else + esp_a2d_mcc_t mcc = {0}; + mcc.type = ESP_A2D_MCT_SBC; + mcc.cie.sbc_info.samp_freq = ESP_A2D_SBC_CIE_SF_16K | + ESP_A2D_SBC_CIE_SF_32K | + ESP_A2D_SBC_CIE_SF_44K | + ESP_A2D_SBC_CIE_SF_48K; + mcc.cie.sbc_info.ch_mode = ESP_A2D_SBC_CIE_CH_MODE_MONO | + ESP_A2D_SBC_CIE_CH_MODE_DUAL_CHANNEL | + ESP_A2D_SBC_CIE_CH_MODE_STEREO | + ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO; + mcc.cie.sbc_info.block_len = ESP_A2D_SBC_CIE_BLOCK_LEN_4 | + ESP_A2D_SBC_CIE_BLOCK_LEN_8 | + ESP_A2D_SBC_CIE_BLOCK_LEN_12 | + ESP_A2D_SBC_CIE_BLOCK_LEN_16; + mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8; + mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SRN | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS; + mcc.cie.sbc_info.max_bitpool = 250; + mcc.cie.sbc_info.min_bitpool = 2; + /* register stream end point, only support SBC currently */ + esp_a2d_sink_register_stream_endpoint(0, &mcc); + esp_a2d_sink_register_audio_data_callback(bt_app_a2d_audio_data_cb); +#endif +#endif + + /* Get the default value of the delay value */ + esp_a2d_sink_get_delay_value(); + /* Get local device name */ + esp_bt_gap_get_device_name(); + + /* set discoverable and connectable mode, wait to be connected */ + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + break; + } + /* others */ + default: + ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); + break; + } +} + +/******************************* + * MAIN ENTRY POINT + ******************************/ + +void app_main(void) +{ + ESP_ERROR_CHECK(bredr_app_common_init()); + + bt_app_task_start_up(); + /* bluetooth device name, connection mode and profile set up */ + bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL); +} diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/sdkconfig.ci.test b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/sdkconfig.ci.test new file mode 100644 index 0000000000..79e4f555d6 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/sdkconfig.ci.test @@ -0,0 +1 @@ +CONFIG_EXAMPLE_LOCAL_DEVICE_NAME="${CI_PIPELINE_ID}_A2DP_SINK" diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/sdkconfig.defaults new file mode 100644 index 0000000000..2b93a51a0e --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/sdkconfig.defaults @@ -0,0 +1,8 @@ +# Override some defaults so BT stack is enabled and +# Classic BT is enabled and BT_DRAM_RELEASE is disabled +CONFIG_BT_ENABLED=y +CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y +CONFIG_BT_BLUEDROID_ENABLED=y +CONFIG_BT_CLASSIC_ENABLED=y +CONFIG_BT_A2DP_ENABLE=y +CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=n diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/CMakeLists.txt new file mode 100644 index 0000000000..4c2312939a --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/CMakeLists.txt @@ -0,0 +1,8 @@ +# 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) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(avrcp_ct_metadata) diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/README.md b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/README.md new file mode 100644 index 0000000000..5a02564951 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/README.md @@ -0,0 +1,67 @@ +| Supported Targets | ESP32 | +| ----------------- | ----- | + +AVRCP-CT-METADATA EXAMPLE +====================== + +This is the example of API implementing Audio/Video Remote Control Profile to get metadata. + +## Required components + +- [bt_app_core_utils](../common/bt_app_core_utils) +- [bredr_app_common_utils](../common/bredr_app_common_utils) +- [a2dp_sink_common_utils](../common/a2dp_utils/a2dp_sink_common_utils) +- [a2dp_sink_int_codec_utils](../common/a2dp_utils/a2dp_sink_int_codec_utils) +- [a2dp_sink_ext_codec_utils](../common/a2dp_utils/a2dp_sink_ext_codec_utils) +- [avrcp_common_utils](../common/avrcp_utils/avrcp_common_utils) +- [avrcp_metadata_utils](../common/avrcp_utils/avrcp_metadata_utils) + +``` ++---------------------------------------------------+---------------------+ +| avrcp_metadata_utils | | ++---------------------------------------------------+ | +| avrcp_common_utils | | ++-------------------------+-------------------------+ | +|a2dp_sink_int_codec_utils|a2dp_sink_ext_codec_utils| bt_app_core_utils | ++-------------------------+-------------------------+ | +| a2dp_sink_common_utils | | ++---------------------------------------------------+ | +| bredr_app_common_utils | | ++---------------------------------------------------+---------------------+ +``` + +Detailed information can be viewed through the [../common/README.md](../common/README.md). + +## How to use this example + +### Configure the project + +``` +idf.py menuconfig +``` + +### 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 +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +## Example Output + +The output when receiving metadata: + +``` +I (81700) RC_CT: AVRC event notification: 2 +I (81740) RC_CT: AVRC metadata rsp: attribute id 0x1, +I (81740) RC_CT: AVRC metadata rsp: attribute id 0x2, +I (81740) RC_CT: AVRC metadata rsp: attribute id 0x4, +I (81750) RC_CT: AVRC metadata rsp: attribute id 0x20, +``` + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/CMakeLists.txt new file mode 100644 index 0000000000..9807f92c7c --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/CMakeLists.txt @@ -0,0 +1,12 @@ +if(CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE) + if(CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC) + set(EXTRA_COMPONENTS a2dp_sink_ext_codec_utils) + else() + set(EXTRA_COMPONENTS a2dp_sink_int_codec_utils) + endif() +endif() + +idf_component_register(SRCS "main.c" + PRIV_REQUIRES bt bt_app_core_utils bredr_app_common_utils a2dp_sink_common_utils + PRIV_REQUIRES ${EXTRA_COMPONENTS} avrcp_common_utils avrcp_metadata_utils + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/Kconfig.projbuild new file mode 100644 index 0000000000..2a4dfc0176 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/Kconfig.projbuild @@ -0,0 +1,23 @@ +menu "AVRCP Example Configuration" + config EXAMPLE_LOCAL_DEVICE_NAME + string "Local Device Name" + default "ESP_SPEAKER" + help + Use this option to set local device name. + + config EXAMPLE_A2DP_SINK_STREAM_ENABLE + bool "Enable A2DP Sink Stream" + default y + help + This enables the A2DP sink stream. If disable this option, + audio data will not be transmitted + + config EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC + bool "Use External Codec Instead of Internal" + depends on EXAMPLE_A2DP_SINK_STREAM_ENABLE + default n + select BT_A2DP_USE_EXTERNAL_CODEC + help + If enable, Bluedroid stack will not decode A2DP audio data, user need to decode it in application layer. + +endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/idf_component.yml b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/idf_component.yml new file mode 100644 index 0000000000..bedf3538c1 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/idf_component.yml @@ -0,0 +1,15 @@ +dependencies: + bt_app_core_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils + bredr_app_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils + a2dp_sink_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils + a2dp_sink_int_codec_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils + a2dp_sink_ext_codec_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils + avrcp_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils + avrcp_metadata_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/main.c b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/main.c new file mode 100644 index 0000000000..3267570d8c --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/main.c @@ -0,0 +1,295 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include + +#include "esp_log.h" +#include "esp_bt_device.h" +#include "esp_gap_bt_api.h" +#include "esp_a2dp_api.h" +#include "esp_avrc_api.h" + +#include "bt_app_core_utils.h" +#include "bredr_app_common_utils.h" +#include "a2dp_utils_tags.h" +#include "a2dp_sink_common_utils.h" +#include "avrcp_utils_tags.h" +#include "avrcp_common_utils.h" +#include "avrcp_metadata_utils.h" +#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE +#include "a2dp_sink_int_codec_utils.h" +#else +#include "a2dp_sink_ext_codec_utils.h" +#endif +#endif + +/* device name */ +static const char local_device_name[] = CONFIG_EXAMPLE_LOCAL_DEVICE_NAME; + +/* event for stack up */ +enum { + BT_APP_EVT_STACK_UP = 0, +}; + +/******************************** + * STATIC FUNCTION DECLARATIONS + *******************************/ + +/* Device callback function */ +static void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param); + +/* GAP callback function */ +static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param); + +/* callback function for A2DP sink */ +static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param); + +#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE +/* callback function for A2DP sink audio data stream */ +static void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len); +#else +/* callback function for A2DP sink undecoded audio data */ +static void bt_app_a2d_audio_data_cb(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf); +#endif +#endif + +/* handler for AVRCP controller events */ +static void bt_app_avrc_ct_evt_hdl(uint16_t event, void *param); + +/* callback function for AVRCP controller */ +static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param); + +/* callback function for AVRCP target */ +static void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param); + +/* handler for bluetooth stack enabled events */ +static void bt_av_hdl_stack_evt(uint16_t event, void *p_param); + +/******************************* + * STATIC FUNCTION DEFINITIONS + ******************************/ + +static void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param) +{ + bredr_app_dev_evt_def_hdl(event, param); +} + +static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) +{ + bredr_app_gap_evt_def_hdl(event, param); +} + +static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) +{ + switch (event) { + case ESP_A2D_PROF_STATE_EVT: + case ESP_A2D_SNK_PSC_CFG_EVT: + case ESP_A2D_SNK_SET_DELAY_VALUE_EVT: + case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: { + bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); + break; + } + case ESP_A2D_CONNECTION_STATE_EVT: + case ESP_A2D_AUDIO_STATE_EVT: + case ESP_A2D_AUDIO_CFG_EVT: + case ESP_A2D_SEP_REG_STATE_EVT: { +#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE + bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); +#else + bt_app_work_dispatch(bt_a2d_evt_ext_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); +#endif +#else + bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); +#endif + break; + } + default: + ESP_LOGE(BT_AV_TAG, "Invalid A2DP event: %d", event); + break; + } +} + +#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE +static void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len) +{ + bt_a2d_data_hdl(data, len); +} +#else +static void bt_app_a2d_audio_data_cb(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf) +{ + bt_a2d_audio_data_hdl(conn_hdl, audio_buf); +} +#endif +#endif + +static void bt_app_avrc_ct_evt_hdl(uint16_t event, void *param) +{ + ESP_LOGD(BT_RC_CT_TAG, "%s event: %d", __func__, event); + + esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(param); + + switch (event) { + case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: + case ESP_AVRC_CT_REMOTE_FEATURES_EVT: + case ESP_AVRC_CT_PROF_STATE_EVT: { + bt_avrc_common_ct_evt_def_hdl(event, param); + break; + } + case ESP_AVRC_CT_CONNECTION_STATE_EVT: { + bt_avrc_md_ct_evt_hdl(event, param); + if (rc->conn_stat.connected) { + /* get remote supported event_ids of peer AVRCP Target */ + bt_avrc_common_ct_get_peer_rn_cap(); + } else { + /* clear peer notification capability record */ + bt_avrc_common_ct_set_peer_rn_cap(0); + } + break; + } + case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: { + bt_avrc_md_ct_evt_hdl(event, param); + bt_avrc_common_ct_notify_evt_handler(rc->change_ntf.event_id, &rc->change_ntf.event_parameter); + break; + } + case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: { + /* set peer notification capability record */ + bt_avrc_common_ct_set_peer_rn_cap(rc->get_rn_caps_rsp.evt_set.bits); + bt_avrc_common_ct_rn_track_changed(); + bt_avrc_common_ct_rn_play_status_changed(); + bt_avrc_common_ct_rn_play_pos_changed(); + + bt_avrc_md_ct_evt_hdl(event, param); + break; + } + case ESP_AVRC_CT_METADATA_RSP_EVT: { + bt_avrc_md_ct_evt_hdl(event, param); + break; + } + default: + ESP_LOGE(BT_RC_CT_TAG, "Invalid AVRC event: %d", event); + break; + } +} + +static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param) +{ + switch (event) { + case ESP_AVRC_CT_METADATA_RSP_EVT: { + bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), bt_avrc_common_copy_metadata); + break; + } + case ESP_AVRC_CT_CONNECTION_STATE_EVT: + case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: + case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: + case ESP_AVRC_CT_REMOTE_FEATURES_EVT: + case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: + case ESP_AVRC_CT_PROF_STATE_EVT: + bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL); + break; + default: + ESP_LOGE(BT_RC_CT_TAG, "Invalid AVRC event: %d", event); + break; + } +} + +static void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param) +{ + switch (event) { + case ESP_AVRC_TG_CONNECTION_STATE_EVT: + case ESP_AVRC_TG_REMOTE_FEATURES_EVT: + case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT: + case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: + case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: + case ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT: + case ESP_AVRC_TG_PROF_STATE_EVT: + bt_app_work_dispatch(bt_avrc_common_tg_evt_def_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL); + break; + default: + ESP_LOGE(BT_RC_TG_TAG, "Invalid AVRC event: %d", event); + break; + } +} + +static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) +{ + ESP_LOGD(BT_AV_TAG, "%s event: %d", __func__, event); + + switch (event) { + /* when do the stack up, this event comes */ + case BT_APP_EVT_STACK_UP: { + esp_bt_gap_set_device_name(local_device_name); + esp_bt_dev_register_callback(bt_app_dev_cb); + esp_bt_gap_register_callback(bt_app_gap_cb); + + esp_avrc_ct_register_callback(bt_app_rc_ct_cb); + assert(esp_avrc_ct_init() == ESP_OK); + esp_avrc_tg_register_callback(bt_app_rc_tg_cb); + assert(esp_avrc_tg_init() == ESP_OK); + + esp_a2d_register_callback(&bt_app_a2d_cb); + assert(esp_a2d_sink_init() == ESP_OK); + +#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE + esp_a2d_sink_register_data_callback(bt_app_a2d_data_cb); +#else + esp_a2d_mcc_t mcc = {0}; + mcc.type = ESP_A2D_MCT_SBC; + mcc.cie.sbc_info.samp_freq = ESP_A2D_SBC_CIE_SF_16K | + ESP_A2D_SBC_CIE_SF_32K | + ESP_A2D_SBC_CIE_SF_44K | + ESP_A2D_SBC_CIE_SF_48K; + mcc.cie.sbc_info.ch_mode = ESP_A2D_SBC_CIE_CH_MODE_MONO | + ESP_A2D_SBC_CIE_CH_MODE_DUAL_CHANNEL | + ESP_A2D_SBC_CIE_CH_MODE_STEREO | + ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO; + mcc.cie.sbc_info.block_len = ESP_A2D_SBC_CIE_BLOCK_LEN_4 | + ESP_A2D_SBC_CIE_BLOCK_LEN_8 | + ESP_A2D_SBC_CIE_BLOCK_LEN_12 | + ESP_A2D_SBC_CIE_BLOCK_LEN_16; + mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8; + mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SRN | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS; + mcc.cie.sbc_info.max_bitpool = 250; + mcc.cie.sbc_info.min_bitpool = 2; + /* register stream end point, only support SBC currently */ + esp_a2d_sink_register_stream_endpoint(0, &mcc); + esp_a2d_sink_register_audio_data_callback(bt_app_a2d_audio_data_cb); +#endif +#endif + + /* Get the default value of the delay value */ + esp_a2d_sink_get_delay_value(); + /* Get local device name */ + esp_bt_gap_get_device_name(); + + /* set discoverable and connectable mode, wait to be connected */ + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + break; + } + /* others */ + default: + ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); + break; + } +} + +/******************************* + * MAIN ENTRY POINT + ******************************/ + +void app_main(void) +{ + ESP_ERROR_CHECK(bredr_app_common_init()); + + bt_app_task_start_up(); + /* bluetooth device name, connection mode and profile set up */ + bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL); +} diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/pytest_classic_bt_metadata_test.py b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/pytest_classic_bt_metadata_test.py new file mode 100644 index 0000000000..1c01e7fff8 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/pytest_classic_bt_metadata_test.py @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 +import pytest +from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize + + +@pytest.mark.generic +@idf_parametrize('target', ['esp32'], indirect=['target']) +def test_bt_avrcp_metadata(dut: Dut) -> None: + dut.expect(r'AVRCP (CT|TG) STATE: Init Complete', timeout=30) + dut.expect(r'AVRCP (CT|TG) STATE: Init Complete', timeout=30) diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/sdkconfig.defaults new file mode 100644 index 0000000000..2b93a51a0e --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/sdkconfig.defaults @@ -0,0 +1,8 @@ +# Override some defaults so BT stack is enabled and +# Classic BT is enabled and BT_DRAM_RELEASE is disabled +CONFIG_BT_ENABLED=y +CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y +CONFIG_BT_BLUEDROID_ENABLED=y +CONFIG_BT_CLASSIC_ENABLED=y +CONFIG_BT_A2DP_ENABLE=y +CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=n diff --git a/examples/bluetooth/bluedroid/classic_bt/common/README.md b/examples/bluetooth/bluedroid/classic_bt/common/README.md new file mode 100644 index 0000000000..e830d23d75 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/README.md @@ -0,0 +1,44 @@ +COMMON CODE +====================== + +This folder provides the universal code for classic Bluetooth applications, and corresponding functions can be achieved by combining different parts. + +## File Tree + +The file tree of this folder is shown below. +- The [a2dp_utils](./a2dp_utils) folder contains the files of A2DP including `a2dp_sink_common_utils`, `a2dp_sink_ext_codec_utils` and `a2dp_sink_int_codec_utils` related files. The [a2dp_sink_common_utils](./a2dp_utils/a2dp_sink_common_utils) folder is about common handle function for A2DP sink event. The [a2dp_sink_ext_codec_utils](./a2dp_utils/a2dp_sink_ext_codec_utils) folder is about external codec of audio data. The [a2dp_sink_int_codec_utils](./a2dp_utils/a2dp_sink_int_codec_utils) folder is about internal codec of audio data. +- The [avrcp_utils](./avrcp_utils) folder contains the files of AVRCP including `avrcp_abs_vol_utils`, `avrcp_common_utils`, `avrcp_cover_art_utils` and `avrcp_metadata_utils` related files. The [avrcp_abs_vol_utils](./avrcp_utils/avrcp_abs_vol_utils) folder is about AVRCP absolute volume control event. The [avrcp_common_utils](./avrcp_utils/avrcp_common_utils) folder is about common handle function for AVRCP event. The [avrcp_cover_art_utils](./avrcp_utils/avrcp_cover_art_utils) folder is about AVRCP cover art event. The [avrcp_metadata_utils](./avrcp_utils/avrcp_metadata_utils) folder is about AVRCP metadata event. +- The [bredr_app_common_utils](./bredr_app_common_utils) folder contains the files of Classic Bluetooth common code including Classic Bluetooth common initialization and handle function about GAP and device. +- The [bt_app_core_utils](./bt_app_core_utils) folder contains the program core files. + +``` +└── common +    ├── a2dp_utils +    │   ├── a2dp_sink_common_utils +    │   ├── a2dp_sink_ext_codec_utils +    │   └── a2dp_sink_int_codec_utils +    ├── avrcp_utils +   │   ├── avrcp_abs_vol_utils +    │   ├── avrcp_common_utils +    │   ├── avrcp_cover_art_utils +    │   └── avrcp_metadata_utils +    ├── bredr_app_common_utils +    ├── bt_app_core_utils +    └── README.md +``` + +## How to use + +The functional framework diagram is shown below. The `bt_app_core_utils` is responsible for all event scheduling. Specific functions can be implemented by general code combined with unique code. For instance, the internal decoding audio output of A2DP sink can be achieved through components such as `bredr_app_common_utils`, `a2dp_sink_common_utils`, and `a2dp_sink_int_codec_utils`. On this basis, adding the code `avrcp_common_utils` and `avrcp_abs_vol_utils` can enable volume adjustment, or incorporating `avrcp_common_utils` and `avrcp_metadata_utils` can facilitate the transmission of metadata. + +``` ++---------------------------------------------------+---------------------+ +| AVRCP feature(avrcp_utils/unique code) | | ++-------------------------+-------------------------+ | +|a2dp_sink_int_codec_utils|a2dp_sink_ext_codec_utils| | ++-------------------------+-------------------------+ bt_app_core_utils | +| a2dp_sink_common_utils | | ++---------------------------------------------------+ | +| bredr_app_common_utils | | ++---------------------------------------------------+---------------------+ +``` diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils/CMakeLists.txt new file mode 100644 index 0000000000..f45a66c150 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "a2dp_sink_common_utils.c" + PRIV_REQUIRES bt + INCLUDE_DIRS "." "../include") diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils/a2dp_sink_common_utils.c b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils/a2dp_sink_common_utils.c new file mode 100644 index 0000000000..e5c886dd14 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils/a2dp_sink_common_utils.c @@ -0,0 +1,118 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include +#include + +#include "esp_log.h" +#include "esp_gap_bt_api.h" +#include "esp_a2dp_api.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "a2dp_sink_common_utils.h" +#include "a2dp_utils_tags.h" + +/* Application layer causes delay value */ +#define APP_DELAY_VALUE 50 // 5ms + +/******************************* + * STATIC VARIABLE DEFINITIONS + ******************************/ + +/* connection state in string */ +static const char *s_a2d_conn_state_str[] = {"Disconnected", "Connecting", "Connected", "Disconnecting"}; +/* audio stream datapath state in string */ +static const char *s_a2d_audio_state_str[] = {"Suspended", "Started"}; + +/******************************** + * EXTERNAL FUNCTION DEFINITIONS + *******************************/ + +void bt_a2d_evt_def_hdl(uint16_t event, void *param) +{ + ESP_LOGD(BT_AV_TAG, "%s event: %d", __func__, event); + + esp_a2d_cb_param_t *a2d = (esp_a2d_cb_param_t *)(param); + + switch (event) { + /* when connection state changed, this event comes */ + case ESP_A2D_CONNECTION_STATE_EVT: { + uint8_t *bda = a2d->conn_stat.remote_bda; + ESP_LOGI(BT_AV_TAG, "A2DP connection state: %s, [%02x:%02x:%02x:%02x:%02x:%02x]", + s_a2d_conn_state_str[a2d->conn_stat.state], bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); + if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) { + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + } else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTED) { + esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE); + } + break; + } + /* when audio stream transmission state changed, this event comes */ + case ESP_A2D_AUDIO_STATE_EVT: { + ESP_LOGI(BT_AV_TAG, "A2DP audio state: %s", s_a2d_audio_state_str[a2d->audio_stat.state]); + break; + } + /* when audio codec is configured, this event comes */ + case ESP_A2D_AUDIO_CFG_EVT: { + esp_a2d_mcc_t *p_mcc = &a2d->audio_cfg.mcc; + ESP_LOGI(BT_AV_TAG, "A2DP audio stream configuration, codec type: %d", p_mcc->type); + break; + } + /* when a2dp init or deinit completed, this event comes */ + case ESP_A2D_PROF_STATE_EVT: { + if (ESP_A2D_INIT_SUCCESS == a2d->a2d_prof_stat.init_state) { + ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Init Complete"); + } else { + ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Deinit Complete"); + } + break; + } + /* when using external codec, after sep registration done, this event comes */ + case ESP_A2D_SEP_REG_STATE_EVT: { + if (a2d->a2d_sep_reg_stat.reg_state == ESP_A2D_SEP_REG_SUCCESS) { + ESP_LOGI(BT_AV_TAG, "A2DP register SEP success, seid: %d", a2d->a2d_sep_reg_stat.seid); + } else { + ESP_LOGI(BT_AV_TAG, "A2DP register SEP fail, seid: %d, state: %d", a2d->a2d_sep_reg_stat.seid, a2d->a2d_sep_reg_stat.reg_state); + } + break; + } + /* When protocol service capabilities configured, this event comes */ + case ESP_A2D_SNK_PSC_CFG_EVT: { + ESP_LOGI(BT_AV_TAG, "protocol service capabilities configured: 0x%x ", a2d->a2d_psc_cfg_stat.psc_mask); + if (a2d->a2d_psc_cfg_stat.psc_mask & ESP_A2D_PSC_DELAY_RPT) { + ESP_LOGI(BT_AV_TAG, "Peer device support delay reporting"); + } else { + ESP_LOGI(BT_AV_TAG, "Peer device unsupported delay reporting"); + } + break; + } + /* when set delay value completed, this event comes */ + case ESP_A2D_SNK_SET_DELAY_VALUE_EVT: { + if (ESP_A2D_SET_INVALID_PARAMS == a2d->a2d_set_delay_value_stat.set_state) { + ESP_LOGI(BT_AV_TAG, "Set delay report value: fail"); + } else { + ESP_LOGI(BT_AV_TAG, "Set delay report value: success, delay_value: %u * 1/10 ms", a2d->a2d_set_delay_value_stat.delay_value); + } + break; + } + /* when get delay value completed, this event comes */ + case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: { + ESP_LOGI(BT_AV_TAG, "Get delay report value: delay_value: %u * 1/10 ms", a2d->a2d_get_delay_value_stat.delay_value); + /* Default delay value plus delay caused by application layer */ + esp_a2d_sink_set_delay_value(a2d->a2d_get_delay_value_stat.delay_value + APP_DELAY_VALUE); + break; + } + /* others */ + default: + ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); + break; + } +} diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils/a2dp_sink_common_utils.h b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils/a2dp_sink_common_utils.h new file mode 100644 index 0000000000..8a09368a94 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils/a2dp_sink_common_utils.h @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __A2DP_SINK_COMMON_UTILS_H__ +#define __A2DP_SINK_COMMON_UTILS_H__ + +#include + +/** + * @brief default handle function for A2DP sink event + * + * @param [in] event event id + * @param [in] param callback parameter + */ +void bt_a2d_evt_def_hdl(uint16_t event, void *param); + +#endif /* __A2DP_SINK_COMMON_UTILS_H__*/ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils/CMakeLists.txt new file mode 100644 index 0000000000..229a18af0e --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "a2dp_sink_ext_codec_utils.c" + PRIV_REQUIRES bt + INCLUDE_DIRS "." "../include") diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils/a2dp_sink_ext_codec_utils.c b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils/a2dp_sink_ext_codec_utils.c new file mode 100644 index 0000000000..e19ca2d95d --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils/a2dp_sink_ext_codec_utils.c @@ -0,0 +1,116 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include +#include + +#include "esp_log.h" +#include "esp_gap_bt_api.h" +#include "esp_a2dp_api.h" + +#include "a2dp_sink_ext_codec_utils.h" +#include "a2dp_utils_tags.h" + +/******************************* + * STATIC VARIABLE DEFINITIONS + ******************************/ + +/* count for audio packet */ +static uint32_t s_pkt_cnt = 0; +/* connection state in string */ +static const char *s_a2d_conn_state_str[] = {"Disconnected", "Connecting", "Connected", "Disconnecting"}; +/* audio stream datapath state in string */ +static const char *s_a2d_audio_state_str[] = {"Suspended", "Started"}; + +/******************************** + * EXTERNAL FUNCTION DEFINITIONS + *******************************/ + +void bt_a2d_evt_ext_codec_hdl(uint16_t event, void *param) +{ + ESP_LOGD(BT_AV_TAG, "%s event: %d", __func__, event); + + esp_a2d_cb_param_t *a2d = (esp_a2d_cb_param_t *)(param); + + switch (event) { + /* when connection state changed, this event comes */ + case ESP_A2D_CONNECTION_STATE_EVT: { + uint8_t *bda = a2d->conn_stat.remote_bda; + ESP_LOGI(BT_AV_TAG, "A2DP connection state: %s, [%02x:%02x:%02x:%02x:%02x:%02x]", + s_a2d_conn_state_str[a2d->conn_stat.state], bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); + if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) { + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + } else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTED) { + esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE); + } + break; + } + /* when audio stream transmission state changed, this event comes */ + case ESP_A2D_AUDIO_STATE_EVT: { + ESP_LOGI(BT_AV_TAG, "A2DP audio state: %s", s_a2d_audio_state_str[a2d->audio_stat.state]); + if (ESP_A2D_AUDIO_STATE_STARTED == a2d->audio_stat.state) { + s_pkt_cnt = 0; + } + break; + } + /* when audio codec is configured, this event comes */ + case ESP_A2D_AUDIO_CFG_EVT: { + esp_a2d_mcc_t *p_mcc = &a2d->audio_cfg.mcc; + ESP_LOGI(BT_AV_TAG, "A2DP audio stream configuration, codec type: %d", p_mcc->type); + /* for now only SBC stream is supported */ + if (p_mcc->type == ESP_A2D_MCT_SBC) { + int sample_rate = 16000; + if (p_mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_32K) { + sample_rate = 32000; + } else if (p_mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_44K) { + sample_rate = 44100; + } else if (p_mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_48K) { + sample_rate = 48000; + } + ESP_LOGI(BT_AV_TAG, "Configure audio player: 0x%x-0x%x-0x%x-0x%x-0x%x-%d-%d", + p_mcc->cie.sbc_info.samp_freq, + p_mcc->cie.sbc_info.ch_mode, + p_mcc->cie.sbc_info.block_len, + p_mcc->cie.sbc_info.num_subbands, + p_mcc->cie.sbc_info.alloc_mthd, + p_mcc->cie.sbc_info.min_bitpool, + p_mcc->cie.sbc_info.max_bitpool); + ESP_LOGI(BT_AV_TAG, "Audio player configured, sample rate: %d", sample_rate); + } + break; + } + /* when using external codec, after sep registration done, this event comes */ + case ESP_A2D_SEP_REG_STATE_EVT: { + if (a2d->a2d_sep_reg_stat.reg_state == ESP_A2D_SEP_REG_SUCCESS) { + ESP_LOGI(BT_AV_TAG, "A2DP register SEP success, seid: %d", a2d->a2d_sep_reg_stat.seid); + } else { + ESP_LOGI(BT_AV_TAG, "A2DP register SEP fail, seid: %d, state: %d", a2d->a2d_sep_reg_stat.seid, a2d->a2d_sep_reg_stat.reg_state); + } + break; + } + /* others */ + default: + ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); + break; + } +} + +void bt_a2d_audio_data_hdl(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf) +{ + /* log the number every 100 packets */ + if (++s_pkt_cnt % 100 == 0) { + ESP_LOGI(BT_AV_TAG, "Undecoded audio package count: %"PRIu32, s_pkt_cnt); + } + + /* + * Normally, user should send the audio_buf to other task, decode and free audio buff, + * But the codec component is not merge into IDF now, so we just free audio data here + */ + esp_a2d_audio_buff_free(audio_buf); +} diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils/a2dp_sink_ext_codec_utils.h b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils/a2dp_sink_ext_codec_utils.h new file mode 100644 index 0000000000..400b7ab376 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils/a2dp_sink_ext_codec_utils.h @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __A2DP_SINK_EXT_CODEC_UTILS_H__ +#define __A2DP_SINK_EXT_CODEC_UTILS_H__ + +#include +#include "esp_a2dp_api.h" + +/** + * @brief handle function for A2DP sink external codec + * + * @param [in] event event id + * @param [in] param callback parameter + */ +void bt_a2d_evt_ext_codec_hdl(uint16_t event, void *param); + +/** + * @brief handle function for A2DP sink undecoded audio data + * + * @param [in] conn_hdl connection handle + * @param [in] audio_buf pointer to audio buff + */ +void bt_a2d_audio_data_hdl(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf); + +#endif /* __A2DP_SINK_EXT_CODEC_UTILS_H__*/ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/CMakeLists.txt new file mode 100644 index 0000000000..4e39651fff --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/CMakeLists.txt @@ -0,0 +1,6 @@ +idf_component_register(SRCS "a2dp_sink_int_codec_utils.c" + "audio_sink_service_idle.c" + "audio_sink_service_i2s.c" + "audio_sink_service_dac.c" + PRIV_REQUIRES esp_driver_i2s bt esp_ringbuf esp_driver_dac + INCLUDE_DIRS "." "../include") diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/Kconfig.projbuild similarity index 54% rename from examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/Kconfig.projbuild rename to examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/Kconfig.projbuild index e627e8b5d1..cd16bd351a 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/Kconfig.projbuild +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/Kconfig.projbuild @@ -1,12 +1,4 @@ -menu "A2DP Example Configuration" - config EXAMPLE_A2DP_SINK_SSP_ENABLED - bool "Secure Simple Pairing" - depends on BT_CLASSIC_ENABLED - default y - help - This enables the Secure Simple Pairing. If disable this option, - Bluedroid will only support Legacy Pairing - +menu "A2DP Sink Internal Codec Example Configuration" choice EXAMPLE_A2DP_SINK_OUTPUT prompt "A2DP Sink Output" default EXAMPLE_A2DP_SINK_OUTPUT_EXTERNAL_I2S @@ -25,11 +17,16 @@ menu "A2DP Example Configuration" help Select this to use External I2S sink output + config EXAMPLE_A2DP_SINK_OUTPUT_IDLE + bool "Idle Output" + help + Select this to discard a2dp sink data + endchoice config EXAMPLE_I2S_LRCK_PIN int "I2S LRCK (WS) GPIO" - default 22 + default 27 depends on EXAMPLE_A2DP_SINK_OUTPUT_EXTERNAL_I2S help GPIO number to use for I2S LRCK(WS) Driver. @@ -48,24 +45,4 @@ menu "A2DP Example Configuration" help GPIO number to use for I2S Data Driver. - config EXAMPLE_LOCAL_DEVICE_NAME - string "Local Device Name" - default "ESP_SPEAKER" - help - Use this option to set local device name. - - config EXAMPLE_AVRCP_CT_COVER_ART_ENABLE - bool "Use AVRCP CT Cover Art Feature" - depends on BT_CLASSIC_ENABLED - default y - help - This enables the AVRCP Cover Art feature in example and try to get cover art image from peer device. - - config EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC - bool "Use External Codec Instead of Internal" - default n - select BT_A2DP_USE_EXTERNAL_CODEC - help - If enable, Bluedroid stack will not decode A2DP audio data, user need to decode it in application layer. - endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/a2dp_sink_int_codec_utils.c b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/a2dp_sink_int_codec_utils.c new file mode 100644 index 0000000000..105b0070ae --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/a2dp_sink_int_codec_utils.c @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include +#include + +#include "esp_log.h" +#include "esp_gap_bt_api.h" +#include "esp_a2dp_api.h" + +#include "audio_sink_service.h" +#include "a2dp_sink_int_codec_utils.h" +#include "a2dp_utils_tags.h" + +/******************************* + * STATIC VARIABLE DEFINITIONS + ******************************/ + +/* count for audio packet */ +static uint32_t s_pkt_cnt = 0; +/* connection state in string */ +static const char *s_a2d_conn_state_str[] = {"Disconnected", "Connecting", "Connected", "Disconnecting"}; +/* audio stream datapath state in string */ +static const char *s_a2d_audio_state_str[] = {"Suspended", "Started"}; + +/******************************** + * EXTERNAL FUNCTION DEFINITIONS + *******************************/ + +void bt_a2d_evt_int_codec_hdl(uint16_t event, void *param) +{ + esp_a2d_cb_param_t *a2d = (esp_a2d_cb_param_t *)(param); + + switch (event) { + /* when connection state changed, this event comes */ + case ESP_A2D_CONNECTION_STATE_EVT: { + uint8_t *bda = a2d->conn_stat.remote_bda; + ESP_LOGI(BT_AV_TAG, "A2DP connection state: %s, [%02x:%02x:%02x:%02x:%02x:%02x]", + s_a2d_conn_state_str[a2d->conn_stat.state], bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); + if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) { + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + audio_sink_srv_stop(); + audio_sink_srv_close(); + } else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTED) { + esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE); + audio_sink_srv_start(); + } else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTING) { + audio_sink_srv_open(); + } + break; + } + /* when audio stream transmission state changed, this event comes */ + case ESP_A2D_AUDIO_STATE_EVT: { + ESP_LOGI(BT_AV_TAG, "A2DP audio state: %s", s_a2d_audio_state_str[a2d->audio_stat.state]); + if (ESP_A2D_AUDIO_STATE_STARTED == a2d->audio_stat.state) { + s_pkt_cnt = 0; + } + break; + } + /* when audio codec is configured, this event comes */ + case ESP_A2D_AUDIO_CFG_EVT: { + audio_sink_srv_codec_info_update(&a2d->audio_cfg.mcc); + break; + } + /* others */ + default: + ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); + break; + } +} + +void bt_a2d_data_hdl(const uint8_t *data, uint32_t len) +{ + audio_sink_srv_data_output(data, len); + + /* log the number every 100 packets */ + if (++s_pkt_cnt % 100 == 0) { + ESP_LOGI(BT_AV_TAG, "Audio packet count: %"PRIu32, s_pkt_cnt); + } +} diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/a2dp_sink_int_codec_utils.h b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/a2dp_sink_int_codec_utils.h new file mode 100644 index 0000000000..7a3f44e28f --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/a2dp_sink_int_codec_utils.h @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __A2DP_SINK_INT_CODEC_UTILS_H__ +#define __A2DP_SINK_INT_CODEC_UTILS_H__ + +#include + +/** + * @brief handle function for A2DP sink internal codec + * + * @param [in] event event id + * @param [in] param callback parameter + */ +void bt_a2d_evt_int_codec_hdl(uint16_t event, void *param); + +/** + * @brief handle function for A2DP sink audio data stream + * + * @param [out] data data stream written by application task + * @param [in] len length of data stream in byte + */ +void bt_a2d_data_hdl(const uint8_t *data, uint32_t len); + +#endif /* __A2DP_SINK_INT_CODEC_UTILS_H__*/ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service.h b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service.h new file mode 100644 index 0000000000..6fbe7382e2 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service.h @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __AUDIO_SINK_SERVICE_H__ +#define __AUDIO_SINK_SERVICE_H__ + +#include +#include +#include "esp_a2dp_api.h" + +/** + * @brief open audio sink service + */ +void audio_sink_srv_open(void); + +/** + * @brief close audio sink service + */ +void audio_sink_srv_close(void); + +/** + * @brief start audio sink service + */ +void audio_sink_srv_start(void); + +/** + * @brief stop audio sink service + */ +void audio_sink_srv_stop(void); + +/** + * @brief update codec information + * + * @param [in] mcc codec information + */ +void audio_sink_srv_codec_info_update(esp_a2d_mcc_t *mcc); + +/** + * @brief write data to ringbuffer + * + * @param [in] data pointer to data stream + * @param [in] size data length in byte + * + * @return size if written ringbuffer successfully, 0 others + */ +size_t audio_sink_srv_data_output(const uint8_t *data, size_t size); + +#endif /* __AUDIO_SINK_SERVICE_H__ */ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_dac.c b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_dac.c new file mode 100644 index 0000000000..a87873fe98 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_dac.c @@ -0,0 +1,222 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include "esp_log.h" +#include "esp_a2dp_api.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/task.h" +#include "freertos/ringbuf.h" +#include "driver/dac_continuous.h" +#include "audio_sink_service.h" + +#if defined(CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC) + +/* log tag */ +#define AUDIO_SNK_SRV_DAC_TAG "SNK_SRV_DAC" + +#define RINGBUF_HIGHEST_WATER_LEVEL (32 * 1024) +#define RINGBUF_PREFETCH_WATER_LEVEL (20 * 1024) + +enum { + RINGBUFFER_MODE_PROCESSING, /* ringbuffer is buffering incoming audio data, I2S is working */ + RINGBUFFER_MODE_PREFETCHING, /* ringbuffer is buffering incoming audio data, I2S is waiting */ + RINGBUFFER_MODE_DROPPING /* ringbuffer is not buffering (dropping) incoming audio data, I2S is working */ +}; + +typedef struct { + dac_continuous_handle_t tx_chan; /* handle of dac continuous channel */ + TaskHandle_t write_task_handle; /* handle of writing task */ + RingbufHandle_t ringbuf; /* handle of ringbuffer */ + SemaphoreHandle_t write_semaphore; /* handle of write semaphore */ + uint16_t ringbuffer_mode; /* ringbuffer mode */ +} audio_sink_srv_dac_cb_t; + +/******************************* + * STATIC FUNCTION DECLARATIONS + ******************************/ + +/* task handler for writing data to dac */ +static void audio_sink_srv_dac_task_handler(void *arg); + +/******************************* + * STATIC VARIABLE DEFINITIONS + ******************************/ + +/* audio sink service for dac control block */ +static audio_sink_srv_dac_cb_t s_dac_cb; + +/******************************* + * STATIC FUNCTION DEFINITIONS + ******************************/ + +static void audio_sink_srv_dac_task_handler(void *arg) +{ + uint8_t *data = NULL; + size_t item_size = 0; + const size_t item_size_upto = 240 * 6; + size_t bytes_written = 0; + + for (;;) { + if (pdTRUE == xSemaphoreTake(s_dac_cb.write_semaphore, portMAX_DELAY)) { + for (;;) { + item_size = 0; + /* receive data from ringbuffer and write it to DAC DMA transmit buffer */ + data = (uint8_t *)xRingbufferReceiveUpTo(s_dac_cb.ringbuf, &item_size, (TickType_t)pdMS_TO_TICKS(20), item_size_upto); + if (item_size == 0) { + ESP_LOGI(AUDIO_SNK_SRV_DAC_TAG, "ringbuffer underflowed! mode changed: RINGBUFFER_MODE_PREFETCHING"); + s_dac_cb.ringbuffer_mode = RINGBUFFER_MODE_PREFETCHING; + break; + } + + dac_continuous_write(s_dac_cb.tx_chan, data, item_size, &bytes_written, -1); + vRingbufferReturnItem(s_dac_cb.ringbuf, (void *)data); + } + } + } +} + +/******************************* + * EXTERNAL FUNCTION DEFINITIONS + ******************************/ + +void audio_sink_srv_open(void) +{ + memset(&s_dac_cb, 0, sizeof(audio_sink_srv_dac_cb_t)); + dac_continuous_config_t cont_cfg = { + .chan_mask = DAC_CHANNEL_MASK_ALL, + .desc_num = 8, + .buf_size = 2048, + .freq_hz = 44100, + .offset = 127, + .clk_src = DAC_DIGI_CLK_SRC_DEFAULT, // Using APLL as clock source to get a wider frequency range + .chan_mode = DAC_CHANNEL_MODE_ALTER, + }; + /* Allocate continuous channels */ + ESP_ERROR_CHECK(dac_continuous_new_channels(&cont_cfg, &s_dac_cb.tx_chan)); +} + +void audio_sink_srv_close(void) +{ + ESP_ERROR_CHECK(dac_continuous_del_channels(s_dac_cb.tx_chan)); + if (s_dac_cb.write_task_handle) { + vTaskDelete(s_dac_cb.write_task_handle); + s_dac_cb.write_task_handle = NULL; + } + if (s_dac_cb.ringbuf) { + vRingbufferDelete(s_dac_cb.ringbuf); + s_dac_cb.ringbuf = NULL; + } + if (s_dac_cb.write_semaphore) { + vSemaphoreDelete(s_dac_cb.write_semaphore); + s_dac_cb.write_semaphore = NULL; + } + memset(&s_dac_cb, 0, sizeof(audio_sink_srv_dac_cb_t)); +} + +void audio_sink_srv_start(void) +{ + dac_continuous_enable(s_dac_cb.tx_chan); + ESP_LOGI(AUDIO_SNK_SRV_DAC_TAG, "ringbuffer data empty! mode changed: RINGBUFFER_MODE_PREFETCHING"); + s_dac_cb.ringbuffer_mode = RINGBUFFER_MODE_PREFETCHING; + if ((s_dac_cb.write_semaphore = xSemaphoreCreateBinary()) == NULL) { + ESP_LOGE(AUDIO_SNK_SRV_DAC_TAG, "%s, Semaphore create failed", __func__); + return; + } + if ((s_dac_cb.ringbuf = xRingbufferCreate(RINGBUF_HIGHEST_WATER_LEVEL, RINGBUF_TYPE_BYTEBUF)) == NULL) { + ESP_LOGE(AUDIO_SNK_SRV_DAC_TAG, "%s, ringbuffer create failed", __func__); + return; + } + xTaskCreate(audio_sink_srv_dac_task_handler, "BtDACTask", 4 * 1024, NULL, configMAX_PRIORITIES - 3, &s_dac_cb.write_task_handle); +} + +void audio_sink_srv_stop(void) +{ + ESP_ERROR_CHECK(dac_continuous_disable(s_dac_cb.tx_chan)); +} + +void audio_sink_srv_codec_info_update(esp_a2d_mcc_t *mcc) +{ + ESP_LOGI(AUDIO_SNK_SRV_DAC_TAG, "A2DP audio stream configuration, codec type: %d", mcc->type); + /* for now only SBC stream is supported */ + if (mcc->type == ESP_A2D_MCT_SBC) { + int sample_rate = 16000; + int ch_count = 2; + if (mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_32K) { + sample_rate = 32000; + } else if (mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_44K) { + sample_rate = 44100; + } else if (mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_48K) { + sample_rate = 48000; + } + + if (mcc->cie.sbc_info.ch_mode & ESP_A2D_SBC_CIE_CH_MODE_MONO) { + ch_count = 1; + } + dac_continuous_del_channels(s_dac_cb.tx_chan); + dac_continuous_config_t cont_cfg = { + .chan_mask = DAC_CHANNEL_MASK_ALL, + .desc_num = 8, + .buf_size = 2048, + .freq_hz = sample_rate, + .offset = 127, + .clk_src = DAC_DIGI_CLK_SRC_DEFAULT, // Using APLL as clock source to get a wider frequency range + .chan_mode = (ch_count == 1) ? DAC_CHANNEL_MODE_SIMUL : DAC_CHANNEL_MODE_ALTER, + }; + /* Allocate continuous channels */ + dac_continuous_new_channels(&cont_cfg, &s_dac_cb.tx_chan); + ESP_LOGI(AUDIO_SNK_SRV_DAC_TAG, "Configure audio player: 0x%x-0x%x-0x%x-0x%x-0x%x-%d-%d", + mcc->cie.sbc_info.samp_freq, + mcc->cie.sbc_info.ch_mode, + mcc->cie.sbc_info.block_len, + mcc->cie.sbc_info.num_subbands, + mcc->cie.sbc_info.alloc_mthd, + mcc->cie.sbc_info.min_bitpool, + mcc->cie.sbc_info.max_bitpool); + ESP_LOGI(AUDIO_SNK_SRV_DAC_TAG, "Audio player configured, sample rate: %d", sample_rate); + } +} + +size_t audio_sink_srv_data_output(const uint8_t *data, size_t size) +{ + size_t item_size = 0; + BaseType_t done = pdFALSE; + + if (s_dac_cb.ringbuffer_mode == RINGBUFFER_MODE_DROPPING) { + ESP_LOGW(AUDIO_SNK_SRV_DAC_TAG, "ringbuffer is full, drop this packet!"); + vRingbufferGetInfo(s_dac_cb.ringbuf, NULL, NULL, NULL, NULL, &item_size); + if (item_size <= RINGBUF_PREFETCH_WATER_LEVEL) { + ESP_LOGI(AUDIO_SNK_SRV_DAC_TAG, "ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING"); + s_dac_cb.ringbuffer_mode = RINGBUFFER_MODE_PROCESSING; + } + return 0; + } + + done = xRingbufferSend(s_dac_cb.ringbuf, (void *)data, size, (TickType_t)0); + + if (!done) { + ESP_LOGW(AUDIO_SNK_SRV_DAC_TAG, "ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING"); + s_dac_cb.ringbuffer_mode = RINGBUFFER_MODE_DROPPING; + } + + if (s_dac_cb.ringbuffer_mode == RINGBUFFER_MODE_PREFETCHING) { + vRingbufferGetInfo(s_dac_cb.ringbuf, NULL, NULL, NULL, NULL, &item_size); + if (item_size >= RINGBUF_PREFETCH_WATER_LEVEL) { + ESP_LOGI(AUDIO_SNK_SRV_DAC_TAG, "ringbuffer data increased! mode changed: RINGBUFFER_MODE_PROCESSING"); + s_dac_cb.ringbuffer_mode = RINGBUFFER_MODE_PROCESSING; + if (pdFALSE == xSemaphoreGive(s_dac_cb.write_semaphore)) { + ESP_LOGE(AUDIO_SNK_SRV_DAC_TAG, "semaphore give failed"); + } + } + } + + return done ? size : 0; +} + +#endif /* defined(CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC) */ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_i2s.c b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_i2s.c new file mode 100644 index 0000000000..bed32c1546 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_i2s.c @@ -0,0 +1,229 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include "esp_log.h" +#include "esp_a2dp_api.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/task.h" +#include "freertos/ringbuf.h" +#include "driver/i2s_std.h" +#include "audio_sink_service.h" + +#if defined(CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_EXTERNAL_I2S) + +/* log tag */ +#define AUDIO_SNK_SRV_I2S_TAG "SNK_SRV_I2S" + +#define RINGBUF_HIGHEST_WATER_LEVEL (32 * 1024) +#define RINGBUF_PREFETCH_WATER_LEVEL (20 * 1024) + +enum { + RINGBUFFER_MODE_PROCESSING, /* ringbuffer is buffering incoming audio data, I2S is working */ + RINGBUFFER_MODE_PREFETCHING, /* ringbuffer is buffering incoming audio data, I2S is waiting */ + RINGBUFFER_MODE_DROPPING /* ringbuffer is not buffering (dropping) incoming audio data, I2S is working */ +}; + +typedef struct { + i2s_chan_handle_t tx_chan; /* handle of i2s channel */ + TaskHandle_t write_task_handle; /* handle of writing task */ + RingbufHandle_t ringbuf; /* handle of ringbuffer */ + SemaphoreHandle_t write_semaphore;/* handle of write semaphore */ + uint16_t ringbuffer_mode; /* ringbuffer mode */ +} audio_sink_srv_i2s_cb_t; + +/******************************* + * STATIC FUNCTION DECLARATIONS + ******************************/ + +/* task handler for writing data to i2s */ +static void audio_sink_srv_i2s_task_handler(void *arg); + +/******************************* + * STATIC VARIABLE DEFINITIONS + ******************************/ + +/* audio sink service for i2s control block */ +static audio_sink_srv_i2s_cb_t s_i2s_cb; + +/******************************* + * STATIC FUNCTION DEFINITIONS + ******************************/ + +static void audio_sink_srv_i2s_task_handler(void *arg) +{ + uint8_t *data = NULL; + size_t item_size = 0; + /** + * The total length of DMA buffer of I2S is: + * `dma_frame_num * dma_desc_num * i2s_channel_num * i2s_data_bit_width / 8`. + * Transmit `dma_frame_num * dma_desc_num` bytes to DMA is trade-off. + */ + const size_t item_size_upto = 240 * 6; + size_t bytes_written = 0; + + for (;;) { + if (pdTRUE == xSemaphoreTake(s_i2s_cb.write_semaphore, portMAX_DELAY)) { + for (;;) { + item_size = 0; + /* receive data from ringbuffer and write it to I2S DMA transmit buffer */ + data = (uint8_t *)xRingbufferReceiveUpTo(s_i2s_cb.ringbuf, &item_size, (TickType_t)pdMS_TO_TICKS(20), item_size_upto); + if (item_size == 0) { + ESP_LOGI(AUDIO_SNK_SRV_I2S_TAG, "ringbuffer underflowed! mode changed: RINGBUFFER_MODE_PREFETCHING"); + s_i2s_cb.ringbuffer_mode = RINGBUFFER_MODE_PREFETCHING; + break; + } + + i2s_channel_write(s_i2s_cb.tx_chan, data, item_size, &bytes_written, portMAX_DELAY); + vRingbufferReturnItem(s_i2s_cb.ringbuf, (void *)data); + } + } + } +} + +/******************************* + * EXTERNAL FUNCTION DEFINITIONS + ******************************/ + +void audio_sink_srv_open(void) +{ + memset(&s_i2s_cb, 0, sizeof(audio_sink_srv_i2s_cb_t)); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + chan_cfg.auto_clear = true; + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(44100), + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, + .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, + .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, + .din = I2S_GPIO_UNUSED, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; + /* initialize I2S channel */ + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &s_i2s_cb.tx_chan, NULL)); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(s_i2s_cb.tx_chan, &std_cfg)); +} + +void audio_sink_srv_close(void) +{ + ESP_ERROR_CHECK(i2s_del_channel(s_i2s_cb.tx_chan)); + if (s_i2s_cb.write_task_handle) { + vTaskDelete(s_i2s_cb.write_task_handle); + s_i2s_cb.write_task_handle = NULL; + } + if (s_i2s_cb.ringbuf) { + vRingbufferDelete(s_i2s_cb.ringbuf); + s_i2s_cb.ringbuf = NULL; + } + if (s_i2s_cb.write_semaphore) { + vSemaphoreDelete(s_i2s_cb.write_semaphore); + s_i2s_cb.write_semaphore = NULL; + } + memset(&s_i2s_cb, 0, sizeof(audio_sink_srv_i2s_cb_t)); +} + +void audio_sink_srv_start(void) +{ + i2s_channel_enable(s_i2s_cb.tx_chan); + ESP_LOGI(AUDIO_SNK_SRV_I2S_TAG, "ringbuffer data empty! mode changed: RINGBUFFER_MODE_PREFETCHING"); + s_i2s_cb.ringbuffer_mode = RINGBUFFER_MODE_PREFETCHING; + if ((s_i2s_cb.write_semaphore = xSemaphoreCreateBinary()) == NULL) { + ESP_LOGE(AUDIO_SNK_SRV_I2S_TAG, "%s, Semaphore create failed", __func__); + return; + } + if ((s_i2s_cb.ringbuf = xRingbufferCreate(RINGBUF_HIGHEST_WATER_LEVEL, RINGBUF_TYPE_BYTEBUF)) == NULL) { + ESP_LOGE(AUDIO_SNK_SRV_I2S_TAG, "%s, ringbuffer create failed", __func__); + return; + } + xTaskCreate(audio_sink_srv_i2s_task_handler, "BtI2STask", 4 * 1024, NULL, configMAX_PRIORITIES - 3, &s_i2s_cb.write_task_handle); +} + +void audio_sink_srv_stop(void) +{ + ESP_ERROR_CHECK(i2s_channel_disable(s_i2s_cb.tx_chan)); +} + +void audio_sink_srv_codec_info_update(esp_a2d_mcc_t *mcc) +{ + ESP_LOGI(AUDIO_SNK_SRV_I2S_TAG, "A2DP audio stream configuration, codec type: %d", mcc->type); + /* for now only SBC stream is supported */ + if (mcc->type == ESP_A2D_MCT_SBC) { + int sample_rate = 16000; + int ch_count = 2; + if (mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_32K) { + sample_rate = 32000; + } else if (mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_44K) { + sample_rate = 44100; + } else if (mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_48K) { + sample_rate = 48000; + } + + if (mcc->cie.sbc_info.ch_mode & ESP_A2D_SBC_CIE_CH_MODE_MONO) { + ch_count = 1; + } + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(sample_rate); + i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, ch_count); + i2s_channel_reconfig_std_clock(s_i2s_cb.tx_chan, &clk_cfg); + i2s_channel_reconfig_std_slot(s_i2s_cb.tx_chan, &slot_cfg); + ESP_LOGI(AUDIO_SNK_SRV_I2S_TAG, "Configure audio player: 0x%x-0x%x-0x%x-0x%x-0x%x-%d-%d", + mcc->cie.sbc_info.samp_freq, + mcc->cie.sbc_info.ch_mode, + mcc->cie.sbc_info.block_len, + mcc->cie.sbc_info.num_subbands, + mcc->cie.sbc_info.alloc_mthd, + mcc->cie.sbc_info.min_bitpool, + mcc->cie.sbc_info.max_bitpool); + ESP_LOGI(AUDIO_SNK_SRV_I2S_TAG, "Audio player configured, sample rate: %d", sample_rate); + } +} + +size_t audio_sink_srv_data_output(const uint8_t *data, size_t size) +{ + size_t item_size = 0; + BaseType_t done = pdFALSE; + + if (s_i2s_cb.ringbuffer_mode == RINGBUFFER_MODE_DROPPING) { + ESP_LOGW(AUDIO_SNK_SRV_I2S_TAG, "ringbuffer is full, drop this packet!"); + vRingbufferGetInfo(s_i2s_cb.ringbuf, NULL, NULL, NULL, NULL, &item_size); + if (item_size <= RINGBUF_PREFETCH_WATER_LEVEL) { + ESP_LOGI(AUDIO_SNK_SRV_I2S_TAG, "ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING"); + s_i2s_cb.ringbuffer_mode = RINGBUFFER_MODE_PROCESSING; + } + return 0; + } + + done = xRingbufferSend(s_i2s_cb.ringbuf, (void *)data, size, (TickType_t)0); + + if (!done) { + ESP_LOGW(AUDIO_SNK_SRV_I2S_TAG, "ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING"); + s_i2s_cb.ringbuffer_mode = RINGBUFFER_MODE_DROPPING; + } + + if (s_i2s_cb.ringbuffer_mode == RINGBUFFER_MODE_PREFETCHING) { + vRingbufferGetInfo(s_i2s_cb.ringbuf, NULL, NULL, NULL, NULL, &item_size); + if (item_size >= RINGBUF_PREFETCH_WATER_LEVEL) { + ESP_LOGI(AUDIO_SNK_SRV_I2S_TAG, "ringbuffer data increased! mode changed: RINGBUFFER_MODE_PROCESSING"); + s_i2s_cb.ringbuffer_mode = RINGBUFFER_MODE_PROCESSING; + if (pdFALSE == xSemaphoreGive(s_i2s_cb.write_semaphore)) { + ESP_LOGE(AUDIO_SNK_SRV_I2S_TAG, "semaphore give failed"); + } + } + } + + return done ? size : 0; +} + +#endif /* defined(CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_EXTERNAL_I2S) */ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_idle.c b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_idle.c new file mode 100644 index 0000000000..85a1526c28 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_idle.c @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include "audio_sink_service.h" + +#if defined(CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_IDLE) + +/******************************* + * EXTERNAL FUNCTION DEFINITIONS + ******************************/ + +void audio_sink_srv_open(void) +{ + // do nothing +} + +void audio_sink_srv_close(void) +{ + // do nothing +} + +void audio_sink_srv_start(void) +{ + // do nothing +} + +void audio_sink_srv_stop(void) +{ + // do nothing +} + +void audio_sink_srv_codec_info_update(esp_a2d_mcc_t *mcc) +{ + // do nothing + (void)mcc; +} + +size_t audio_sink_srv_data_output(const uint8_t *data, size_t size) +{ + // do nothing + (void)data; + (void)size; + return 0; +} + +#endif /* defined(CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_IDLE) */ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/include/a2dp_utils_tags.h b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/include/a2dp_utils_tags.h new file mode 100644 index 0000000000..6ab3d8e6c4 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/include/a2dp_utils_tags.h @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __A2DP_UTILS_TAGS_H__ +#define __A2DP_UTILS_TAGS_H__ + +/* log tags */ +#define BT_AV_TAG "BT_AV" + +#endif /* __A2DP_UTILS_TAGS_H__ */ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/CMakeLists.txt new file mode 100644 index 0000000000..8c16db1f68 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "avrcp_abs_vol_utils.c" + "avrcp_abs_vol_service.c" + PRIV_REQUIRES bt + INCLUDE_DIRS "." "../include") diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_service.c b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_service.c new file mode 100644 index 0000000000..889b265111 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_service.c @@ -0,0 +1,88 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include "sys/lock.h" +#include "esp_log.h" +#include "esp_avrc_api.h" +#include "avrcp_abs_vol_service.h" + +/* tags */ +#define RC_VC_SRV_TAG "RC_VC_SRV" + +typedef struct { + _lock_t volume_lock; /* lock local volume value */ + uint8_t volume; /* local volume value */ + bool volume_notify; /* notify volume change or not */ +} avrc_abs_vol_srv_cb_t; + +/******************************* + * STATIC VARIABLE DEFINITIONS + ******************************/ + +/* AVRCP absolute volume service control block */ +static avrc_abs_vol_srv_cb_t s_avrc_abs_vol_srv_cb; + +/******************************** + * EXTERNAL FUNCTION DEFINITIONS + *******************************/ + +void avrc_abs_vol_srv_open(void) +{ + memset(&s_avrc_abs_vol_srv_cb, 0, sizeof(avrc_abs_vol_srv_cb_t)); +} + +void avrc_abs_vol_srv_close(void) +{ + memset(&s_avrc_abs_vol_srv_cb, 0, sizeof(avrc_abs_vol_srv_cb_t)); +} + +uint8_t avrc_abs_vol_srv_get_volume(void) +{ + return s_avrc_abs_vol_srv_cb.volume; +} + +void avrc_abs_vol_srv_set_volume(avrc_volume_set_t vol_set_t, uint8_t volume) +{ + switch (vol_set_t) { + case VOLUME_SET_BY_CONTROLLER: { + ESP_LOGI(RC_VC_SRV_TAG, "Volume is set by remote controller to: %"PRIu32"%%", (uint32_t)volume * 100 / 0x7f); + /* set the volume in protection of lock */ + _lock_acquire(&s_avrc_abs_vol_srv_cb.volume_lock); + s_avrc_abs_vol_srv_cb.volume = volume; + _lock_release(&s_avrc_abs_vol_srv_cb.volume_lock); + break; + } + case VOLUME_SET_BY_LOCAL_HOST: { + ESP_LOGI(RC_VC_SRV_TAG, "Volume is set locally to: %"PRIu32"%%", (uint32_t)volume * 100 / 0x7f); + /* set the volume in protection of lock */ + _lock_acquire(&s_avrc_abs_vol_srv_cb.volume_lock); + s_avrc_abs_vol_srv_cb.volume = volume; + _lock_release(&s_avrc_abs_vol_srv_cb.volume_lock); + + /* send notification response to remote AVRCP controller */ + if (s_avrc_abs_vol_srv_cb.volume_notify) { + esp_avrc_rn_param_t rn_param; + rn_param.volume = s_avrc_abs_vol_srv_cb.volume; + esp_avrc_tg_send_rn_rsp(ESP_AVRC_RN_VOLUME_CHANGE, ESP_AVRC_RN_RSP_CHANGED, &rn_param); + s_avrc_abs_vol_srv_cb.volume_notify = false; + } + break; + } + default: + ESP_LOGE(RC_VC_SRV_TAG, "Invalid volume setting type"); + break; + } +} + +void avrc_abs_vol_srv_rn_volume_change(void) +{ + s_avrc_abs_vol_srv_cb.volume_notify = true; + esp_avrc_rn_param_t rn_param; + rn_param.volume = s_avrc_abs_vol_srv_cb.volume; + esp_avrc_tg_send_rn_rsp(ESP_AVRC_RN_VOLUME_CHANGE, ESP_AVRC_RN_RSP_INTERIM, &rn_param); +} diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_service.h b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_service.h new file mode 100644 index 0000000000..d21c21ec58 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_service.h @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __AVRCP_ABS_VOL_SERVICE_H__ +#define __AVRCP_ABS_VOL_SERVICE_H__ + +#include +#include "esp_avrc_api.h" + +typedef enum { + VOLUME_SET_BY_CONTROLLER = 0, /*!< volume is set by controller */ + VOLUME_SET_BY_LOCAL_HOST, /*!< volume is set by local host */ +} avrc_volume_set_t; + +/** + * @brief open AVRCP absolute volume service + */ +void avrc_abs_vol_srv_open(void); + +/** + * @brief close AVRCP absolute volume service + */ +void avrc_abs_vol_srv_close(void); + +/** + * @brief get local volume value + * + * @return local volume value + */ +uint8_t avrc_abs_vol_srv_get_volume(void); + +/** + * @brief set volume value + * + * @param [in] vol_set_t volume setting type + * @param [in] volume volume value to be set + */ +void avrc_abs_vol_srv_set_volume(avrc_volume_set_t vol_set_t, uint8_t volume); + +/** + * @brief register notification of volume change + */ +void avrc_abs_vol_srv_rn_volume_change(void); + +#endif /* __AVRCP_ABS_VOL_SERVICE_H__ */ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_utils.c b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_utils.c new file mode 100644 index 0000000000..0a41ae063a --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_utils.c @@ -0,0 +1,103 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include +#include + +#include "sys/lock.h" + +#include "esp_log.h" +#include "esp_avrc_api.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "avrcp_abs_vol_utils.h" +#include "avrcp_utils_tags.h" +#include "avrcp_abs_vol_service.h" + +/******************************* + * STATIC FUNCTION DECLARATIONS + ******************************/ + +/* simulation volume change */ +static void volume_change_simulation(void *arg); + +/******************************* + * STATIC VARIABLE DEFINITIONS + ******************************/ + +static TaskHandle_t s_vcs_task_hdl = NULL; /* handle for volume change simulation task */ + +/******************************** + * STATIC FUNCTION DEFINITIONS + *******************************/ + +static void volume_change_simulation(void *arg) +{ + ESP_LOGI(BT_RC_TG_TAG, "start volume change simulation"); + + for (;;) { + /* volume up locally every 10 seconds */ + vTaskDelay(10000 / portTICK_PERIOD_MS); + uint8_t volume = (avrc_abs_vol_srv_get_volume() + 5) & 0x7f; + avrc_abs_vol_srv_set_volume(VOLUME_SET_BY_LOCAL_HOST, volume); + } +} + +/******************************** + * EXTERNAL FUNCTION DEFINITIONS + *******************************/ + +void bt_avrc_avc_tg_evt_hdl(uint16_t event, void *param) +{ + ESP_LOGD(BT_RC_TG_TAG, "%s event: %d", __func__, event); + + esp_avrc_tg_cb_param_t *rc = (esp_avrc_tg_cb_param_t *)(param); + + switch (event) { + /* when connection state changed, this event comes */ + case ESP_AVRC_TG_CONNECTION_STATE_EVT: { + uint8_t *bda = rc->conn_stat.remote_bda; + ESP_LOGI(BT_RC_TG_TAG, "AVRC conn_state evt: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", + rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); + if (rc->conn_stat.connected) { + /* create task to simulate volume change */ + avrc_abs_vol_srv_open(); + xTaskCreate(volume_change_simulation, "vcsTask", 4 * 1024, NULL, 5, &s_vcs_task_hdl); + } else { + avrc_abs_vol_srv_close(); + if (s_vcs_task_hdl) { + vTaskDelete(s_vcs_task_hdl); + s_vcs_task_hdl = NULL; + } + ESP_LOGI(BT_RC_TG_TAG, "Stop volume change simulation"); + } + break; + } + /* when absolute volume command from remote device set, this event comes */ + case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: { + ESP_LOGI(BT_RC_TG_TAG, "AVRC set absolute volume: %d%%", (int)rc->set_abs_vol.volume * 100 / 0x7f); + avrc_abs_vol_srv_set_volume(VOLUME_SET_BY_CONTROLLER, rc->set_abs_vol.volume); + break; + } + /* when notification registered, this event comes */ + case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: { + ESP_LOGI(BT_RC_TG_TAG, "AVRC register event notification: %d, param: 0x%"PRIx32, rc->reg_ntf.event_id, rc->reg_ntf.event_parameter); + if (rc->reg_ntf.event_id == ESP_AVRC_RN_VOLUME_CHANGE) { + avrc_abs_vol_srv_rn_volume_change(); + } + break; + } + /* others */ + default: + ESP_LOGE(BT_RC_TG_TAG, "%s unhandled event: %d", __func__, event); + break; + } +} diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_utils.h b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_utils.h new file mode 100644 index 0000000000..c10594049c --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils/avrcp_abs_vol_utils.h @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __AVRCP_ABS_VOL_UTILS_H__ +#define __AVRCP_ABS_VOL_UTILS_H__ + +#include + +/** + * @brief handle function for AVRCP target absolute volume control event + * + * @param [in] event event id + * @param [in] param callback parameter + */ +void bt_avrc_avc_tg_evt_hdl(uint16_t event, void *param); + +#endif /* __AVRCP_ABS_VOL_UTILS_H__ */ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils/CMakeLists.txt new file mode 100644 index 0000000000..6d95f6fac3 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "avrcp_common_utils.c" + PRIV_REQUIRES bt + INCLUDE_DIRS "." "../include") diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils/avrcp_common_utils.c b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils/avrcp_common_utils.c new file mode 100644 index 0000000000..6f3ae6801e --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils/avrcp_common_utils.c @@ -0,0 +1,228 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include +#include + +#include "esp_log.h" +#include "esp_bt_main.h" +#include "esp_avrc_api.h" + +#include "avrcp_common_utils.h" +#include "avrcp_utils_tags.h" + +typedef struct { + uint8_t tl; /* AVRCP transaction labels */ + esp_avrc_rn_evt_cap_mask_t peer_rn_cap; /* AVRCP target notification capability bit mask */ +} avrc_common_cb_t; + +/******************************* + * STATIC VARIABLE DEFINITIONS + ******************************/ + +static avrc_common_cb_t s_avrc_common_cb; + +/******************************** + * EXTERNAL FUNCTION DEFINITIONS + *******************************/ + +void bt_avrc_common_ct_evt_def_hdl(uint16_t event, void *param) +{ + ESP_LOGD(BT_RC_CT_TAG, "%s event: %d", __func__, event); + + esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(param); + + switch (event) { + /* when connection state changed, this event comes */ + case ESP_AVRC_CT_CONNECTION_STATE_EVT: { + uint8_t *bda = rc->conn_stat.remote_bda; + ESP_LOGI(BT_RC_CT_TAG, "AVRC conn_state event: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", + rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); + break; + } + /* when passthrough response, this event comes */ + case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: { + ESP_LOGI(BT_RC_CT_TAG, "AVRC passthrough rsp: key_code 0x%x, key_state %d, rsp_code %d", rc->psth_rsp.key_code, + rc->psth_rsp.key_state, rc->psth_rsp.rsp_code); + break; + } + /* when metadata response, this event comes */ + case ESP_AVRC_CT_METADATA_RSP_EVT: { + ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text); + break; + } + /* when notified, this event comes */ + case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: { + ESP_LOGI(BT_RC_CT_TAG, "AVRC event notification: %d", rc->change_ntf.event_id); + break; + } + /* when feature of remote device indicated, this event comes */ + case ESP_AVRC_CT_REMOTE_FEATURES_EVT: { + ESP_LOGI(BT_RC_CT_TAG, "AVRC remote features %"PRIx32", TG features %x", rc->rmt_feats.feat_mask, rc->rmt_feats.tg_feat_flag); + break; + } + /* when notification capability of peer device got, this event comes */ + case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: { + ESP_LOGI(BT_RC_CT_TAG, "remote rn_cap: count %d, bitmask 0x%x", rc->get_rn_caps_rsp.cap_count, + rc->get_rn_caps_rsp.evt_set.bits); + break; + } + /* when avrcp controller init or deinit completed, this event comes */ + case ESP_AVRC_CT_PROF_STATE_EVT: { + if (ESP_AVRC_INIT_SUCCESS == rc->avrc_ct_init_stat.state) { + ESP_LOGI(BT_RC_CT_TAG, "AVRCP CT STATE: Init Complete"); + } else if (ESP_AVRC_DEINIT_SUCCESS == rc->avrc_ct_init_stat.state) { + ESP_LOGI(BT_RC_CT_TAG, "AVRCP CT STATE: Deinit Complete"); + } else { + ESP_LOGE(BT_RC_CT_TAG, "AVRCP CT STATE error: %d", rc->avrc_ct_init_stat.state); + } + break; + } + /* others */ + default: + ESP_LOGE(BT_RC_CT_TAG, "%s unhandled event: %d", __func__, event); + break; + } +} + +void bt_avrc_common_tg_evt_def_hdl(uint16_t event, void *param) +{ + ESP_LOGD(BT_RC_TG_TAG, "%s event: %d", __func__, event); + + esp_avrc_tg_cb_param_t *rc = (esp_avrc_tg_cb_param_t *)(param); + + switch (event) { + /* when connection state changed, this event comes */ + case ESP_AVRC_TG_CONNECTION_STATE_EVT: { + uint8_t *bda = rc->conn_stat.remote_bda; + ESP_LOGI(BT_RC_TG_TAG, "AVRC conn_state evt: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", + rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); + break; + } + /* when passthrough commanded, this event comes */ + case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT: { + ESP_LOGI(BT_RC_TG_TAG, "AVRC passthrough cmd: key_code 0x%x, key_state %d", rc->psth_cmd.key_code, rc->psth_cmd.key_state); + break; + } + /* when absolute volume command from remote device set, this event comes */ + case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: { + ESP_LOGI(BT_RC_TG_TAG, "AVRC set absolute volume: %d%%", (int)rc->set_abs_vol.volume * 100 / 0x7f); + break; + } + /* when notification registered, this event comes */ + case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: { + ESP_LOGI(BT_RC_TG_TAG, "AVRC register event notification: %d, param: 0x%"PRIx32, rc->reg_ntf.event_id, rc->reg_ntf.event_parameter); + break; + } + /* when feature of remote device indicated, this event comes */ + case ESP_AVRC_TG_REMOTE_FEATURES_EVT: { + ESP_LOGI(BT_RC_TG_TAG, "AVRC remote features: %"PRIx32", CT features: %x", rc->rmt_feats.feat_mask, rc->rmt_feats.ct_feat_flag); + break; + } + /* when avrcp target init or deinit completed, this event comes */ + case ESP_AVRC_TG_PROF_STATE_EVT: { + if (ESP_AVRC_INIT_SUCCESS == rc->avrc_tg_init_stat.state) { + ESP_LOGI(BT_RC_TG_TAG, "AVRCP TG STATE: Init Complete"); + } else if (ESP_AVRC_DEINIT_SUCCESS == rc->avrc_tg_init_stat.state) { + ESP_LOGI(BT_RC_TG_TAG, "AVRCP TG STATE: Deinit Complete"); + } else { + ESP_LOGE(BT_RC_TG_TAG, "AVRCP TG STATE error: %d", rc->avrc_tg_init_stat.state); + } + break; + } + /* others */ + default: + ESP_LOGE(BT_RC_TG_TAG, "%s unhandled event: %d", __func__, event); + break; + } +} + +uint8_t bt_avrc_common_alloc_tl(void) +{ + if (s_avrc_common_cb.tl > ESP_AVRC_TRANS_LABEL_MAX) { + s_avrc_common_cb.tl = 0; + } + + return s_avrc_common_cb.tl++; +} + +void bt_avrc_common_copy_metadata(void *p_dest, void *p_src, int len) +{ + esp_avrc_ct_cb_param_t *p_dest_rc = (esp_avrc_ct_cb_param_t *)(p_dest); + esp_avrc_ct_cb_param_t *p_src_rc = (esp_avrc_ct_cb_param_t *)(p_src); + + p_dest_rc->meta_rsp.attr_id = p_src_rc->meta_rsp.attr_id; + p_dest_rc->meta_rsp.attr_length = p_src_rc->meta_rsp.attr_length; + + p_dest_rc->meta_rsp.attr_text = (uint8_t *) malloc(p_dest_rc->meta_rsp.attr_length + 1); + memcpy(p_dest_rc->meta_rsp.attr_text, p_src_rc->meta_rsp.attr_text, p_dest_rc->meta_rsp.attr_length); + p_dest_rc->meta_rsp.attr_text[p_dest_rc->meta_rsp.attr_length] = 0; +} + +void bt_avrc_common_ct_get_peer_rn_cap(void) +{ + esp_avrc_ct_send_get_rn_capabilities_cmd(bt_avrc_common_alloc_tl()); +} + +void bt_avrc_common_ct_set_peer_rn_cap(uint16_t peer_rn_cap_t) +{ + s_avrc_common_cb.peer_rn_cap.bits = peer_rn_cap_t; +} + +void bt_avrc_common_ct_rn_track_changed(void) +{ + /* register notification if peer support the event_id */ + if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_common_cb.peer_rn_cap, + ESP_AVRC_RN_TRACK_CHANGE)) { + esp_avrc_ct_send_register_notification_cmd(bt_avrc_common_alloc_tl(), ESP_AVRC_RN_TRACK_CHANGE, 0); + } +} + +void bt_avrc_common_ct_rn_play_status_changed(void) +{ + /* register notification if peer support the event_id */ + if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_common_cb.peer_rn_cap, + ESP_AVRC_RN_PLAY_STATUS_CHANGE)) { + esp_avrc_ct_send_register_notification_cmd(bt_avrc_common_alloc_tl(), ESP_AVRC_RN_PLAY_STATUS_CHANGE, 0); + } +} + +void bt_avrc_common_ct_rn_play_pos_changed(void) +{ + /* register notification if peer support the event_id */ + if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_common_cb.peer_rn_cap, + ESP_AVRC_RN_PLAY_POS_CHANGED)) { + esp_avrc_ct_send_register_notification_cmd(bt_avrc_common_alloc_tl(), ESP_AVRC_RN_PLAY_POS_CHANGED, 10); + } +} + +void bt_avrc_common_ct_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *event_parameter) +{ + switch (event_id) { + /* when new track is loaded, this event comes */ + case ESP_AVRC_RN_TRACK_CHANGE: + ESP_LOGI(BT_RC_CT_TAG, "New track loaded"); + bt_avrc_common_ct_rn_track_changed(); + break; + /* when track status changed, this event comes */ + case ESP_AVRC_RN_PLAY_STATUS_CHANGE: + ESP_LOGI(BT_RC_CT_TAG, "Playback status changed: 0x%x", event_parameter->playback); + bt_avrc_common_ct_rn_play_status_changed(); + break; + /* when track playing position changed, this event comes */ + case ESP_AVRC_RN_PLAY_POS_CHANGED: + ESP_LOGI(BT_RC_CT_TAG, "Play position changed: %"PRIu32"-ms", event_parameter->play_pos); + bt_avrc_common_ct_rn_play_pos_changed(); + break; + /* others */ + default: + ESP_LOGI(BT_RC_CT_TAG, "unhandled event: %d", event_id); + break; + } +} diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils/avrcp_common_utils.h b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils/avrcp_common_utils.h new file mode 100644 index 0000000000..e7d4c00fb8 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils/avrcp_common_utils.h @@ -0,0 +1,82 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __AVRCP_COMMON_UTILS_H__ +#define __AVRCP_COMMON_UTILS_H__ + +#include +#include "esp_avrc_api.h" + +/** + * @brief default handle function for AVRCP controller event + * + * @param [in] event event id + * @param [in] param callback parameter + */ +void bt_avrc_common_ct_evt_def_hdl(uint16_t event, void *param); + +/** + * @brief default handle function for AVRCP target event + * + * @param [in] event event id + * @param [in] param callback parameter + */ +void bt_avrc_common_tg_evt_def_hdl(uint16_t event, void *param); + +/** + * @brief AVRCP transaction labels allocation + * + * @param [out] tl transaction label + * + * @return transaction label + */ +uint8_t bt_avrc_common_alloc_tl(void); + +/** + * @brief AVRCP deep copy function + * + * @param [in] p_dest pointer to destination data + * @param [in] p_src pointer to source data + * @param [in] len data length in byte + */ +void bt_avrc_common_copy_metadata(void *p_dest, void *p_src, int len); + +/** + * @brief AVRCP controller get notification capabilities command + */ +void bt_avrc_common_ct_get_peer_rn_cap(void); + +/** + * @brief AVRCP controller set notification capabilities command + * + * @param [in] peer_rn_cap_t register notification capabilities of peer in bits + */ +void bt_avrc_common_ct_set_peer_rn_cap(uint16_t peer_rn_cap_t); + +/** + * @brief AVRCP controller track changed notification command + */ +void bt_avrc_common_ct_rn_track_changed(void); + +/** + * @brief AVRCP controller play status changed notification command + */ +void bt_avrc_common_ct_rn_play_status_changed(void); + +/** + * @brief AVRCP controller play position changed notification command + */ +void bt_avrc_common_ct_rn_play_pos_changed(void); + +/** + * @brief AVRCP controller notification event handler + * + * @param [in] event_id event id + * @param [in] event_parameter event parameter + */ +void bt_avrc_common_ct_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *event_parameter); + +#endif /* __AVRCP_COMMON_UTILS_H__ */ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/CMakeLists.txt new file mode 100644 index 0000000000..896be16c5a --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "avrcp_metadata_utils.c" + "avrcp_metadata_service.c" + PRIV_REQUIRES bt avrcp_common_utils + INCLUDE_DIRS "." "../include") diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_service.c b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_service.c new file mode 100644 index 0000000000..271311afb1 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_service.c @@ -0,0 +1,155 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include "esp_log.h" +#include "esp_avrc_api.h" +#include "avrcp_metadata_service.h" +#include "avrcp_common_utils.h" + +/* tags*/ +#define RC_MD_SRV_TAG "RC_MD_SRV" + +typedef struct { + /* AVRCP metadata response data from ESP_AVRC_CT_METADATA_RSP_EVT */ + avrc_metadata_srv_param_t attr_title; + avrc_metadata_srv_param_t attr_artist; + avrc_metadata_srv_param_t attr_album; + avrc_metadata_srv_param_t attr_genre; +} avrc_metadata_srv_cb_t; + +/******************************* + * STATIC VARIABLE DEFINITIONS + ******************************/ + +/* AVRCP metadata service control block */ +static avrc_metadata_srv_cb_t s_avrc_metadata_srv_cb; + +/******************************** + * STATIC FUNCTION DEFINITIONS + *******************************/ + +static void avrc_metadata_srv_copy_metadata(avrc_metadata_srv_param_t *p_dest, avrc_metadata_srv_param_t *p_src) +{ + p_dest->attr_id = p_src->attr_id; + p_dest->attr_length = p_src->attr_length; + + if (p_dest->attr_text) { + free(p_dest->attr_text); + p_dest->attr_text = NULL; + } + + p_dest->attr_text = (uint8_t *)malloc(p_dest->attr_length + 1); + if (p_dest->attr_text == NULL) { + ESP_LOGE(RC_MD_SRV_TAG, "Memory allocation failed."); + return; + } + + memcpy(p_dest->attr_text, p_src->attr_text, p_dest->attr_length); + p_dest->attr_text[p_dest->attr_length] = 0; +} + +/******************************** + * EXTERNAL FUNCTION DEFINITIONS + *******************************/ + +void avrc_metadata_srv_open(void) +{ + avrc_metadata_srv_md_free(ESP_AVRC_MD_ATTR_TITLE); + avrc_metadata_srv_md_free(ESP_AVRC_MD_ATTR_ARTIST); + avrc_metadata_srv_md_free(ESP_AVRC_MD_ATTR_ALBUM); + avrc_metadata_srv_md_free(ESP_AVRC_MD_ATTR_GENRE); + + memset(&s_avrc_metadata_srv_cb, 0, sizeof(avrc_metadata_srv_cb_t)); +} + +void avrc_metadata_srv_close(void) +{ + avrc_metadata_srv_md_free(ESP_AVRC_MD_ATTR_TITLE); + avrc_metadata_srv_md_free(ESP_AVRC_MD_ATTR_ARTIST); + avrc_metadata_srv_md_free(ESP_AVRC_MD_ATTR_ALBUM); + avrc_metadata_srv_md_free(ESP_AVRC_MD_ATTR_GENRE); + + memset(&s_avrc_metadata_srv_cb, 0, sizeof(avrc_metadata_srv_cb_t)); +} + +void avrc_metadata_srv_md_req(void) +{ + /* request metadata */ + uint8_t attr_mask = ESP_AVRC_MD_ATTR_TITLE | + ESP_AVRC_MD_ATTR_ARTIST | + ESP_AVRC_MD_ATTR_ALBUM | + ESP_AVRC_MD_ATTR_GENRE; + + /* send metadata request */ + esp_avrc_ct_send_metadata_cmd(bt_avrc_common_alloc_tl(), attr_mask); +} + +void avrc_metadata_srv_md_save(avrc_metadata_srv_param_t *param) +{ + avrc_metadata_srv_param_t *rc = param; + + switch (rc->attr_id) { + case ESP_AVRC_MD_ATTR_TITLE: { + avrc_metadata_srv_copy_metadata(&s_avrc_metadata_srv_cb.attr_title, rc); + break; + } + case ESP_AVRC_MD_ATTR_ARTIST: { + avrc_metadata_srv_copy_metadata(&s_avrc_metadata_srv_cb.attr_artist, rc); + break; + } + case ESP_AVRC_MD_ATTR_ALBUM: { + avrc_metadata_srv_copy_metadata(&s_avrc_metadata_srv_cb.attr_album, rc); + break; + } + case ESP_AVRC_MD_ATTR_GENRE: { + avrc_metadata_srv_copy_metadata(&s_avrc_metadata_srv_cb.attr_genre, rc); + break; + } + + default: + ESP_LOGW(RC_MD_SRV_TAG, "%s unhandled attr_id: %d", __func__, rc->attr_id); + break; + } +} + +void avrc_metadata_srv_md_free(uint8_t attr_id) +{ + switch (attr_id) { + case ESP_AVRC_MD_ATTR_TITLE: { + if (s_avrc_metadata_srv_cb.attr_title.attr_text) { + free(s_avrc_metadata_srv_cb.attr_title.attr_text); + s_avrc_metadata_srv_cb.attr_title.attr_text = NULL; + } + break; + } + case ESP_AVRC_MD_ATTR_ARTIST: { + if (s_avrc_metadata_srv_cb.attr_artist.attr_text) { + free(s_avrc_metadata_srv_cb.attr_artist.attr_text); + s_avrc_metadata_srv_cb.attr_artist.attr_text = NULL; + } + break; + } + case ESP_AVRC_MD_ATTR_ALBUM: { + if (s_avrc_metadata_srv_cb.attr_album.attr_text) { + free(s_avrc_metadata_srv_cb.attr_album.attr_text); + s_avrc_metadata_srv_cb.attr_album.attr_text = NULL; + } + break; + } + case ESP_AVRC_MD_ATTR_GENRE: { + if (s_avrc_metadata_srv_cb.attr_genre.attr_text) { + free(s_avrc_metadata_srv_cb.attr_genre.attr_text); + s_avrc_metadata_srv_cb.attr_genre.attr_text = NULL; + } + break; + } + + default: + ESP_LOGW(RC_MD_SRV_TAG, "%s unhandled attr_id: %d", __func__, attr_id); + break; + } +} diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_service.h b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_service.h new file mode 100644 index 0000000000..e90319bf31 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_service.h @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __AVRCP_METADATA_SERVICE_H__ +#define __AVRCP_METADATA_SERVICE_H__ + +#include +#include "esp_avrc_api.h" + +typedef struct { + uint8_t attr_id; /*!< id of metadata attribute */ + uint8_t *attr_text; /*!< attribute itself */ + int attr_length; /*!< attribute character length */ +} avrc_metadata_srv_param_t; + +/** + * @brief open AVRCP metadata service + */ +void avrc_metadata_srv_open(void); + +/** + * @brief close AVRCP metadata service + */ +void avrc_metadata_srv_close(void); + +/** + * @brief request AVRCP metadata + */ +void avrc_metadata_srv_md_req(void); + +/** + * @brief save AVRCP metadata response data from ESP_AVRC_CT_METADATA_RSP_EVT + * + * @param [in] param AVRCP metadata response data + */ +void avrc_metadata_srv_md_save(avrc_metadata_srv_param_t *param); + +/** + * @brief free AVRCP metadata response data from ESP_AVRC_CT_METADATA_RSP_EVT + * + * @param [in] attr_id attribute id + */ +void avrc_metadata_srv_md_free(uint8_t attr_id); + +#endif /* __AVRCP_METADATA_SERVICE_H__ */ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_utils.c b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_utils.c new file mode 100644 index 0000000000..5516db7d4e --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_utils.c @@ -0,0 +1,77 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include +#include + +#include "esp_log.h" +#include "esp_bt_main.h" +#include "esp_avrc_api.h" + +#include "avrcp_metadata_utils.h" +#include "avrcp_utils_tags.h" +#include "avrcp_metadata_service.h" + +/******************************** + * EXTERNAL FUNCTION DEFINITIONS + *******************************/ + +void bt_avrc_md_ct_evt_hdl(uint16_t event, void *param) +{ + ESP_LOGD(BT_RC_CT_TAG, "%s event: %d", __func__, event); + + esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(param); + + switch (event) { + /* when connection state changed, this event comes */ + case ESP_AVRC_CT_CONNECTION_STATE_EVT: { + uint8_t *bda = rc->conn_stat.remote_bda; + ESP_LOGI(BT_RC_CT_TAG, "AVRC conn_state event: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", + rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); + + if (rc->conn_stat.connected) { + /* get remote supported event_ids of peer AVRCP Target */ + avrc_metadata_srv_open(); + } else { + /* clear peer notification capability record */ + avrc_metadata_srv_close(); + } + break; + } + /* when metadata response, this event comes */ + case ESP_AVRC_CT_METADATA_RSP_EVT: { + ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text); + /* save metadata to avrcp metadata service and then if there is a need to handle metadata, + functions can be added in the avrcp metadata service for processing */ + avrc_metadata_srv_md_save((avrc_metadata_srv_param_t *)rc); + break; + } + /* when notified, this event comes */ + case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: { + ESP_LOGI(BT_RC_CT_TAG, "AVRC event notification: %d", rc->change_ntf.event_id); + if (rc->change_ntf.event_id == ESP_AVRC_RN_TRACK_CHANGE) { + /* request metadata */ + avrc_metadata_srv_md_req(); + } + break; + } + /* when notification capability of peer device got, this event comes */ + case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: { + ESP_LOGI(BT_RC_CT_TAG, "remote rn_cap: count %d, bitmask 0x%x", rc->get_rn_caps_rsp.cap_count, + rc->get_rn_caps_rsp.evt_set.bits); + /* request metadata */ + avrc_metadata_srv_md_req(); + break; + } + /* others */ + default: + ESP_LOGE(BT_RC_CT_TAG, "%s unhandled event: %d", __func__, event); + break; + } +} diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_utils.h b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_utils.h new file mode 100644 index 0000000000..0d979b8b18 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/avrcp_metadata_utils.h @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __AVRCP_METADATA_UTILS_H__ +#define __AVRCP_METADATA_UTILS_H__ + +#include + +/** + * @brief handle function for AVRCP controller metadata event + * + * @param [in] event event id + * @param [in] param callback parameter + */ +void bt_avrc_md_ct_evt_hdl(uint16_t event, void *param); + +#endif /* __AVRCP_METADATA_UTILS_H__*/ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/idf_component.yml b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/idf_component.yml new file mode 100644 index 0000000000..421ea1aa86 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils/idf_component.yml @@ -0,0 +1,3 @@ +dependencies: + avrcp_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/include/avrcp_utils_tags.h b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/include/avrcp_utils_tags.h new file mode 100644 index 0000000000..a722fbb8b1 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/include/avrcp_utils_tags.h @@ -0,0 +1,15 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __AVRCP_UTILS_TAGS_H__ +#define __AVRCP_UTILS_TAGS_H__ + +/* log tags */ +#define BT_RC_TAG "RC" +#define BT_RC_TG_TAG "RC_TG" +#define BT_RC_CT_TAG "RC_CT" + +#endif /* __AVRCP_UTILS_TAGS_H__ */ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/CMakeLists.txt new file mode 100644 index 0000000000..3dd3d34ef1 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "bredr_app_common_utils.c" + PRIV_REQUIRES bt nvs_flash + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/Kconfig.projbuild new file mode 100644 index 0000000000..7f1d22b398 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/Kconfig.projbuild @@ -0,0 +1,10 @@ +menu "BR/EDR App Common Example Configuration" + config EXAMPLE_SSP_ENABLED + bool "Secure Simple Pairing" + depends on BT_CLASSIC_ENABLED + default y + help + This enables the Secure Simple Pairing. If disable this option, + Bluedroid will only support Legacy Pairing + +endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/bredr_app_common_utils.c b/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/bredr_app_common_utils.c new file mode 100644 index 0000000000..05d0cd7715 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/bredr_app_common_utils.c @@ -0,0 +1,185 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include +#include +#include "nvs.h" +#include "nvs_flash.h" + +#include "esp_system.h" +#include "esp_log.h" +#include "esp_bt.h" +#include "esp_bt_main.h" +#include "esp_bt_device.h" +#include "esp_gap_bt_api.h" + +#include "bredr_app_common_utils.h" + +#define BREDR_APP_TAG "BREDR_APP" + +/******************************* + * STATIC FUNCTION DEFINITIONS + ******************************/ + +static char *bda2str(uint8_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; +} + +void bredr_app_dev_evt_def_hdl(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param) +{ + switch (event) { + case ESP_BT_DEV_NAME_RES_EVT: { + if (param->name_res.status == ESP_BT_STATUS_SUCCESS) { + ESP_LOGI(BREDR_APP_TAG, "Get local device name success: %s", param->name_res.name); + } else { + ESP_LOGE(BREDR_APP_TAG, "Get local device name failed, status: %d", param->name_res.status); + } + break; + } + default: { + ESP_LOGI(BREDR_APP_TAG, "event: %d", event); + break; + } + } +} + +void bredr_app_gap_evt_def_hdl(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) +{ + uint8_t *bda = NULL; + + switch (event) { + /* when authentication completed, this event comes */ + case ESP_BT_GAP_AUTH_CMPL_EVT: { + if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { + ESP_LOGI(BREDR_APP_TAG, "authentication success: %s", param->auth_cmpl.device_name); + ESP_LOG_BUFFER_HEX(BREDR_APP_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN); + } else { + ESP_LOGE(BREDR_APP_TAG, "authentication failed, status: %d", param->auth_cmpl.stat); + } + ESP_LOGI(BREDR_APP_TAG, "link key type of current link is: %d", param->auth_cmpl.lk_type); + break; + } + case ESP_BT_GAP_ENC_CHG_EVT: { + char *str_enc[3] = {"OFF", "E0", "AES"}; + bda = (uint8_t *)param->enc_chg.bda; + ESP_LOGI(BREDR_APP_TAG, "Encryption mode to [%02x:%02x:%02x:%02x:%02x:%02x] changed to %s", + bda[0], bda[1], bda[2], bda[3], bda[4], bda[5], str_enc[param->enc_chg.enc_mode]); + break; + } + +#if (CONFIG_EXAMPLE_SSP_ENABLED == true) + /* when Security Simple Pairing user confirmation requested, this event comes */ + case ESP_BT_GAP_CFM_REQ_EVT: + ESP_LOGI(BREDR_APP_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %06"PRIu32, param->cfm_req.num_val); + esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true); + break; + /* when Security Simple Pairing passkey notified, this event comes */ + case ESP_BT_GAP_KEY_NOTIF_EVT: + ESP_LOGI(BREDR_APP_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey: %06"PRIu32, param->key_notif.passkey); + break; + /* when Security Simple Pairing passkey requested, this event comes */ + case ESP_BT_GAP_KEY_REQ_EVT: + ESP_LOGI(BREDR_APP_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!"); + break; +#endif + + /* when GAP mode changed, this event comes */ + case ESP_BT_GAP_MODE_CHG_EVT: + ESP_LOGI(BREDR_APP_TAG, "ESP_BT_GAP_MODE_CHG_EVT mode: %d, interval: %.2f ms", + param->mode_chg.mode, param->mode_chg.interval * 0.625); + break; + /* when ACL connection completed, this event comes */ + case ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT: + bda = (uint8_t *)param->acl_conn_cmpl_stat.bda; + ESP_LOGI(BREDR_APP_TAG, "ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT Connected to [%02x:%02x:%02x:%02x:%02x:%02x], status: 0x%x", + bda[0], bda[1], bda[2], bda[3], bda[4], bda[5], param->acl_conn_cmpl_stat.stat); + break; + /* when ACL disconnection completed, this event comes */ + case ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT: + bda = (uint8_t *)param->acl_disconn_cmpl_stat.bda; + ESP_LOGI(BREDR_APP_TAG, "ESP_BT_GAP_ACL_DISC_CMPL_STAT_EVT Disconnected from [%02x:%02x:%02x:%02x:%02x:%02x], reason: 0x%x", + bda[0], bda[1], bda[2], bda[3], bda[4], bda[5], param->acl_disconn_cmpl_stat.reason); + break; + /* others */ + default: { + ESP_LOGI(BREDR_APP_TAG, "event: %d", event); + break; + } + } +} + +esp_err_t bredr_app_common_init(void) +{ + char bda_str[18] = {0}; + /* initialize NVS — it is used to store PHY calibration data */ + esp_err_t err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + ESP_ERROR_CHECK(err); + + /* + * This example only uses the functions of Classic Bluetooth. + * So release the controller memory for Bluetooth Low Energy. + */ + 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 ((err = esp_bt_controller_init(&bt_cfg)) != ESP_OK) { + ESP_LOGE(BREDR_APP_TAG, "%s initialize controller failed: %s", __func__, esp_err_to_name(err)); + return err; + } + if ((err = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) { + ESP_LOGE(BREDR_APP_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(err)); + return err; + } + + esp_bluedroid_config_t bluedroid_cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT(); +#if (CONFIG_EXAMPLE_SSP_ENABLED == false) + bluedroid_cfg.ssp_en = false; +#endif + if ((err = esp_bluedroid_init_with_cfg(&bluedroid_cfg)) != ESP_OK) { + ESP_LOGE(BREDR_APP_TAG, "%s initialize bluedroid failed: %s", __func__, esp_err_to_name(err)); + return err; + } + + if ((err = esp_bluedroid_enable()) != ESP_OK) { + ESP_LOGE(BREDR_APP_TAG, "%s enable bluedroid failed: %s", __func__, esp_err_to_name(err)); + return err; + } + +#if (CONFIG_EXAMPLE_SSP_ENABLED == true) + /* set default parameters for Secure Simple Pairing */ + esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE; + esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO; + esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t)); +#endif + + /* set default parameters for Legacy Pairing (use fixed pin code 1234) */ + esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED; + esp_bt_pin_code_t pin_code; + pin_code[0] = '1'; + pin_code[1] = '2'; + pin_code[2] = '3'; + pin_code[3] = '4'; + esp_bt_gap_set_pin(pin_type, 4, pin_code); + + ESP_LOGI(BREDR_APP_TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str))); + + return ESP_OK; +} diff --git a/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/bredr_app_common_utils.h b/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/bredr_app_common_utils.h new file mode 100644 index 0000000000..590144b095 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils/bredr_app_common_utils.h @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __BREDR_APP_COMMON_UTILS_H__ +#define __BREDR_APP_COMMON_UTILS_H__ + +#include +#include "esp_bt_device.h" +#include "esp_gap_bt_api.h" + +/** + * @brief Device event default handle function + * + * @param [in] event event id + * @param [in] param handler parameter + */ +void bredr_app_dev_evt_def_hdl(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param); + +/** + * @brief GAP event default handle function + * + * @param [in] event event id + * @param [in] param handler parameter + */ +void bredr_app_gap_evt_def_hdl(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param); + +/** + * @brief Classic BT common initialization + * + * @return ESP_OK on successful init + */ +esp_err_t bredr_app_common_init(void); + +#endif /* __BREDR_APP_COMMON_UTILS_H__*/ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils/CMakeLists.txt new file mode 100644 index 0000000000..2f000acd2b --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "bt_app_core_utils.c" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils/bt_app_core_utils.c b/examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils/bt_app_core_utils.c new file mode 100644 index 0000000000..514ce77f80 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils/bt_app_core_utils.c @@ -0,0 +1,138 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include + +#include "esp_log.h" + +#include "freertos/FreeRTOSConfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/task.h" + +#include "bt_app_core_utils.h" + +/* log tag */ +#define BT_APP_CORE_TAG "BT_APP_CORE" + +/******************************* + * STATIC FUNCTION DECLARATIONS + ******************************/ + +/* handler for application task */ +static void bt_app_task_handler(void *arg); +/* message sender */ +static bool bt_app_send_msg(bt_app_msg_t *msg); +/* handle dispatched messages */ +static void bt_app_work_dispatched(bt_app_msg_t *msg); + +/******************************* + * STATIC VARIABLE DEFINITIONS + ******************************/ + +static QueueHandle_t s_bt_app_task_queue = NULL; /* handle of work queue */ +static TaskHandle_t s_bt_app_task_handle = NULL; /* handle of application task */ + +/******************************* + * STATIC FUNCTION DEFINITIONS + ******************************/ + +static bool bt_app_send_msg(bt_app_msg_t *msg) +{ + if (msg == NULL) { + return false; + } + + /* send the message to work queue */ + if (xQueueSend(s_bt_app_task_queue, msg, 10 / portTICK_PERIOD_MS) != pdTRUE) { + ESP_LOGE(BT_APP_CORE_TAG, "%s xQueue send failed", __func__); + return false; + } + return true; +} + +static void bt_app_work_dispatched(bt_app_msg_t *msg) +{ + if (msg->cb) { + msg->cb(msg->event, msg->param); + } +} + +static void bt_app_task_handler(void *arg) +{ + bt_app_msg_t msg; + + for (;;) { + /* receive message from work queue and handle it */ + if (pdTRUE == xQueueReceive(s_bt_app_task_queue, &msg, (TickType_t)portMAX_DELAY)) { + ESP_LOGD(BT_APP_CORE_TAG, "%s, signal: 0x%x, event: 0x%x", __func__, msg.sig, msg.event); + + switch (msg.sig) { + case BT_APP_SIG_WORK_DISPATCH: + bt_app_work_dispatched(&msg); + break; + default: + ESP_LOGW(BT_APP_CORE_TAG, "%s, unhandled signal: %d", __func__, msg.sig); + break; + } /* switch (msg.sig) */ + + if (msg.param) { + free(msg.param); + } + } + } +} + +/******************************** + * EXTERNAL FUNCTION DEFINITIONS + *******************************/ + +bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback) +{ + ESP_LOGD(BT_APP_CORE_TAG, "%s event: 0x%x, param len: %d", __func__, event, param_len); + + bt_app_msg_t msg; + memset(&msg, 0, sizeof(bt_app_msg_t)); + + msg.sig = BT_APP_SIG_WORK_DISPATCH; + msg.event = event; + msg.cb = p_cback; + + if (param_len == 0) { + return bt_app_send_msg(&msg); + } else if (p_params && param_len > 0) { + if ((msg.param = malloc(param_len)) != NULL) { + memcpy(msg.param, p_params, param_len); + /* check if caller has provided a copy callback to do the deep copy */ + if (p_copy_cback) { + p_copy_cback(msg.param, p_params, param_len); + } + return bt_app_send_msg(&msg); + } + } + + return false; +} + +void bt_app_task_start_up(void) +{ + s_bt_app_task_queue = xQueueCreate(10, sizeof(bt_app_msg_t)); + xTaskCreate(bt_app_task_handler, "BtAppTask", 3072, NULL, 10, &s_bt_app_task_handle); +} + +void bt_app_task_shut_down(void) +{ + if (s_bt_app_task_handle) { + vTaskDelete(s_bt_app_task_handle); + s_bt_app_task_handle = NULL; + } + if (s_bt_app_task_queue) { + vQueueDelete(s_bt_app_task_queue); + s_bt_app_task_queue = NULL; + } +} diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.h b/examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils/bt_app_core_utils.h similarity index 64% rename from examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.h rename to examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils/bt_app_core_utils.h index 055f7609f1..9161f08155 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.h +++ b/examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils/bt_app_core_utils.h @@ -1,19 +1,16 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ -#ifndef __BT_APP_CORE_H__ -#define __BT_APP_CORE_H__ +#ifndef __BT_APP_CORE_UTILS_H__ +#define __BT_APP_CORE_UTILS_H__ #include #include #include -/* log tag */ -#define BT_APP_CORE_TAG "BT_APP_CORE" - /* signal for `bt_app_work_dispatch` */ #define BT_APP_SIG_WORK_DISPATCH (0x01) @@ -23,7 +20,7 @@ * @param [in] event event id * @param [in] param handler parameter */ -typedef void (* bt_app_cb_t) (uint16_t event, void *param); +typedef void (* bt_app_cb_t)(uint16_t event, void *param); /* message to be sent */ typedef struct { @@ -40,14 +37,14 @@ typedef struct { * @param [in] p_src pointer to source data * @param [in] len data length in byte */ -typedef void (* bt_app_copy_cb_t) (void *p_dest, void *p_src, int len); +typedef void (* bt_app_copy_cb_t)(void *p_dest, void *p_src, int len); /** * @brief work dispatcher for the application task * * @param [in] p_cback callback function * @param [in] event event id - * @param [in] p_params callback paramters + * @param [in] p_params callback parameters * @param [in] param_len parameter length in byte * @param [in] p_copy_cback parameter deep-copy function * @@ -65,24 +62,4 @@ void bt_app_task_start_up(void); */ void bt_app_task_shut_down(void); -/** - * @brief start up the is task - */ -void bt_i2s_task_start_up(void); - -/** - * @brief shut down the I2S task - */ -void bt_i2s_task_shut_down(void); - -/** - * @brief write data to ringbuffer - * - * @param [in] data pointer to data stream - * @param [in] size data length in byte - * - * @return size if writteen ringbuffer successfully, 0 others - */ -size_t write_ringbuf(const uint8_t *data, size_t size); - -#endif /* __BT_APP_CORE_H__ */ +#endif /* __BT_APP_CORE_UTILS_H__ */ From 2136c80f1f530fffa3f9426e6e3f497998b022db Mon Sep 17 00:00:00 2001 From: yangfeng Date: Mon, 27 Oct 2025 20:46:31 +0800 Subject: [PATCH 024/226] refactor: Refactor the example of the coexistence of A2DP sink and GATT service --- .../coex/a2dp_gatts_coex/main/CMakeLists.txt | 14 +- .../a2dp_gatts_coex/main/Kconfig.projbuild | 51 -- .../coex/a2dp_gatts_coex/main/bt_app_av.c | 545 ++---------------- .../coex/a2dp_gatts_coex/main/bt_app_av.h | 7 +- .../coex/a2dp_gatts_coex/main/bt_app_core.c | 266 --------- .../coex/a2dp_gatts_coex/main/bt_app_core.h | 88 --- .../a2dp_gatts_coex/main/idf_component.yml | 15 + .../coex/a2dp_gatts_coex/main/main.c | 215 +++---- .../coex/a2dp_gatts_coex/sdkconfig.defaults | 2 - 9 files changed, 176 insertions(+), 1027 deletions(-) delete mode 100644 examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/Kconfig.projbuild delete mode 100644 examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c delete mode 100644 examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.h create mode 100644 examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/idf_component.yml diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/CMakeLists.txt b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/CMakeLists.txt index e68a065139..da473926c8 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/CMakeLists.txt +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/CMakeLists.txt @@ -1,5 +1,15 @@ +set(MY_COMPONENT_REQUIRES + bt_app_core_utils + bredr_app_common_utils + a2dp_sink_common_utils + a2dp_sink_int_codec_utils + avrcp_common_utils + avrcp_metadata_utils + avrcp_abs_vol_utils +) + idf_component_register(SRCS "bt_app_av.c" - "bt_app_core.c" "main.c" - PRIV_REQUIRES esp_driver_i2s bt nvs_flash esp_ringbuf esp_driver_dac + PRIV_REQUIRES bt nvs_flash + PRIV_REQUIRES ${MY_COMPONENT_REQUIRES} INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/Kconfig.projbuild deleted file mode 100644 index ce29dd6c03..0000000000 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/Kconfig.projbuild +++ /dev/null @@ -1,51 +0,0 @@ -menu "A2DP Example Configuration" - config EXAMPLE_A2DP_SINK_SSP_ENABLED - bool "Secure Simple Pairing" - depends on BT_CLASSIC_ENABLED - default y - help - This enables the Secure Simple Pairing. If disable this option, - Bluedroid will only support Legacy Pairing - - choice EXAMPLE_A2DP_SINK_OUTPUT - prompt "A2DP Sink Output" - default EXAMPLE_A2DP_SINK_OUTPUT_EXTERNAL_I2S - help - Select to use Internal DAC or external I2S driver - - config EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - bool "Internal DAC" - help - Select this to use Internal DAC sink output, - note that DAC_DMA_AUTO_16BIT_ALIGN should be turned off - because the audio data are already 16-bit width - - config EXAMPLE_A2DP_SINK_OUTPUT_EXTERNAL_I2S - bool "External I2S Codec" - help - Select this to use External I2S sink output - - endchoice - - config EXAMPLE_I2S_LRCK_PIN - int "I2S LRCK (WS) GPIO" - default 22 - depends on EXAMPLE_A2DP_SINK_OUTPUT_EXTERNAL_I2S - help - GPIO number to use for I2S LRCK(WS) Driver. - - config EXAMPLE_I2S_BCK_PIN - int "I2S BCK GPIO" - default 26 - depends on EXAMPLE_A2DP_SINK_OUTPUT_EXTERNAL_I2S - help - GPIO number to use for I2S BCK Driver. - - config EXAMPLE_I2S_DATA_PIN - int "I2S DATA GPIO" - default 25 - depends on EXAMPLE_A2DP_SINK_OUTPUT_EXTERNAL_I2S - help - GPIO number to use for I2S Data Driver. - -endmenu diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c index b0b166209f..7bed853682 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -9,506 +9,75 @@ #include #include #include -#include "esp_log.h" -#include "bt_app_core.h" -#include "bt_app_av.h" -#include "esp_bt_main.h" +#include "esp_log.h" #include "esp_bt_device.h" #include "esp_gap_bt_api.h" -#include "esp_a2dp_api.h" #include "esp_avrc_api.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC -#include "driver/dac_continuous.h" -#else -#include "driver/i2s_std.h" -#endif -#include "sys/lock.h" - -/* AVRCP used transaction labels */ -#define APP_RC_CT_TL_GET_CAPS (0) -#define APP_RC_CT_TL_GET_META_DATA (1) -#define APP_RC_CT_TL_RN_TRACK_CHANGE (2) -#define APP_RC_CT_TL_RN_PLAYBACK_CHANGE (3) -#define APP_RC_CT_TL_RN_PLAY_POS_CHANGE (4) - -/* Application layer causes delay value */ -#define APP_DELAY_VALUE 50 // 5ms - -/******************************* - * STATIC FUNCTION DECLARATIONS - ******************************/ - -/* allocate new meta buffer */ -static void bt_app_alloc_meta_buffer(esp_avrc_ct_cb_param_t *param); -/* handler for new track is loaded */ -static void bt_av_new_track(void); -/* handler for track status change */ -static void bt_av_playback_changed(void); -/* handler for track playing position change */ -static void bt_av_play_pos_changed(void); -/* notification event handler */ -static void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *event_parameter); -/* installation for i2s */ -static void bt_i2s_driver_install(void); -/* uninstallation for i2s */ -static void bt_i2s_driver_uninstall(void); -/* set volume by remote controller */ -static void volume_set_by_controller(uint8_t volume); -/* set volume by local host */ -static void volume_set_by_local_host(uint8_t volume); -/* simulation volume change */ -static void volume_change_simulation(void *arg); -/* a2dp event handler */ -static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param); -/* avrc controller event handler */ -static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param); -/* avrc target event handler */ -static void bt_av_hdl_avrc_tg_evt(uint16_t event, void *p_param); - -/******************************* - * STATIC VARIABLE DEFINITIONS - ******************************/ - -static uint32_t s_pkt_cnt = 0; /* count for audio packet */ -static esp_a2d_audio_state_t s_audio_state = ESP_A2D_AUDIO_STATE_STOPPED; - /* audio stream datapath state */ -static const char *s_a2d_conn_state_str[] = {"Disconnected", "Connecting", "Connected", "Disconnecting"}; - /* connection state in string */ -static const char *s_a2d_audio_state_str[] = {"Suspended", "Started"}; - /* audio stream datapath state in string */ -static esp_avrc_rn_evt_cap_mask_t s_avrc_peer_rn_cap; - /* AVRC target notification capability bit mask */ -static _lock_t s_volume_lock; -static TaskHandle_t s_vcs_task_hdl = NULL; /* handle for volume change simulation task */ -static uint8_t s_volume = 0; /* local volume value */ -static bool s_volume_notify; /* notify volume change or not */ -#ifndef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC -i2s_chan_handle_t tx_chan = NULL; -#else -dac_continuous_handle_t tx_chan; -#endif +#include "bt_app_core_utils.h" +#include "avrcp_utils_tags.h" +#include "avrcp_common_utils.h" +#include "avrcp_metadata_utils.h" +#include "avrcp_abs_vol_utils.h" +#include "a2dp_utils_tags.h" +#include "a2dp_sink_common_utils.h" +#include "a2dp_sink_int_codec_utils.h" +#include "bt_app_av.h" /******************************** * STATIC FUNCTION DEFINITIONS *******************************/ -static void bt_app_alloc_meta_buffer(esp_avrc_ct_cb_param_t *param) -{ - esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(param); - uint8_t *attr_text = (uint8_t *) malloc (rc->meta_rsp.attr_length + 1); - - memcpy(attr_text, rc->meta_rsp.attr_text, rc->meta_rsp.attr_length); - attr_text[rc->meta_rsp.attr_length] = 0; - rc->meta_rsp.attr_text = attr_text; -} - -static void bt_av_new_track(void) -{ - /* request metadata */ - uint8_t attr_mask = ESP_AVRC_MD_ATTR_TITLE | - ESP_AVRC_MD_ATTR_ARTIST | - ESP_AVRC_MD_ATTR_ALBUM | - ESP_AVRC_MD_ATTR_GENRE; - esp_avrc_ct_send_metadata_cmd(APP_RC_CT_TL_GET_META_DATA, attr_mask); - - /* register notification if peer support the event_id */ - if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, - ESP_AVRC_RN_TRACK_CHANGE)) { - esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_TRACK_CHANGE, - ESP_AVRC_RN_TRACK_CHANGE, 0); - } -} - -static void bt_av_playback_changed(void) -{ - /* register notification if peer support the event_id */ - if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, - ESP_AVRC_RN_PLAY_STATUS_CHANGE)) { - esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_PLAYBACK_CHANGE, - ESP_AVRC_RN_PLAY_STATUS_CHANGE, 0); - } -} - -static void bt_av_play_pos_changed(void) -{ - /* register notification if peer support the event_id */ - if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, - ESP_AVRC_RN_PLAY_POS_CHANGED)) { - esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_PLAY_POS_CHANGE, - ESP_AVRC_RN_PLAY_POS_CHANGED, 10); - } -} - -static void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *event_parameter) -{ - switch (event_id) { - /* when new track is loaded, this event comes */ - case ESP_AVRC_RN_TRACK_CHANGE: - bt_av_new_track(); - break; - /* when track status changed, this event comes */ - case ESP_AVRC_RN_PLAY_STATUS_CHANGE: - ESP_LOGI(BT_AV_TAG, "Playback status changed: 0x%x", event_parameter->playback); - bt_av_playback_changed(); - break; - /* when track playing position changed, this event comes */ - case ESP_AVRC_RN_PLAY_POS_CHANGED: - ESP_LOGI(BT_AV_TAG, "Play position changed: %"PRIu32"-ms", event_parameter->play_pos); - bt_av_play_pos_changed(); - break; - /* others */ - default: - ESP_LOGI(BT_AV_TAG, "unhandled event: %d", event_id); - break; - } -} - -void bt_i2s_driver_install(void) -{ -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - dac_continuous_config_t cont_cfg = { - .chan_mask = DAC_CHANNEL_MASK_ALL, - .desc_num = 8, - .buf_size = 2048, - .freq_hz = 44100, - .offset = 127, - .clk_src = DAC_DIGI_CLK_SRC_DEFAULT, // Using APLL as clock source to get a wider frequency range - .chan_mode = DAC_CHANNEL_MODE_ALTER, - }; - /* Allocate continuous channels */ - ESP_ERROR_CHECK(dac_continuous_new_channels(&cont_cfg, &tx_chan)); - /* Enable the continuous channels */ - ESP_ERROR_CHECK(dac_continuous_enable(tx_chan)); -#else - i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); - chan_cfg.auto_clear = true; - i2s_std_config_t std_cfg = { - .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(44100), - .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), - .gpio_cfg = { - .mclk = I2S_GPIO_UNUSED, - .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, - .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, - .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, - .din = I2S_GPIO_UNUSED, - .invert_flags = { - .mclk_inv = false, - .bclk_inv = false, - .ws_inv = false, - }, - }, - }; - /* enable I2S */ - ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_chan, NULL)); - ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &std_cfg)); - ESP_ERROR_CHECK(i2s_channel_enable(tx_chan)); -#endif -} - -void bt_i2s_driver_uninstall(void) -{ -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - ESP_ERROR_CHECK(dac_continuous_disable(tx_chan)); - ESP_ERROR_CHECK(dac_continuous_del_channels(tx_chan)); -#else - ESP_ERROR_CHECK(i2s_channel_disable(tx_chan)); - ESP_ERROR_CHECK(i2s_del_channel(tx_chan)); -#endif -} - -static void volume_set_by_controller(uint8_t volume) -{ - ESP_LOGI(BT_RC_TG_TAG, "Volume is set by remote controller to: %"PRIu32"%%", (uint32_t)volume * 100 / 0x7f); - /* set the volume in protection of lock */ - _lock_acquire(&s_volume_lock); - s_volume = volume; - _lock_release(&s_volume_lock); -} - -static void volume_set_by_local_host(uint8_t volume) -{ - ESP_LOGI(BT_RC_TG_TAG, "Volume is set locally to: %"PRIu32"%%", (uint32_t)volume * 100 / 0x7f); - /* set the volume in protection of lock */ - _lock_acquire(&s_volume_lock); - s_volume = volume; - _lock_release(&s_volume_lock); - - /* send notification response to remote AVRCP controller */ - if (s_volume_notify) { - esp_avrc_rn_param_t rn_param; - rn_param.volume = s_volume; - esp_avrc_tg_send_rn_rsp(ESP_AVRC_RN_VOLUME_CHANGE, ESP_AVRC_RN_RSP_CHANGED, &rn_param); - s_volume_notify = false; - } -} - -static void volume_change_simulation(void *arg) -{ - ESP_LOGI(BT_RC_TG_TAG, "start volume change simulation"); - - for (;;) { - /* volume up locally every 10 seconds */ - vTaskDelay(10000 / portTICK_PERIOD_MS); - uint8_t volume = (s_volume + 5) & 0x7f; - volume_set_by_local_host(volume); - } -} - -static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) -{ - ESP_LOGD(BT_AV_TAG, "%s event: %d", __func__, event); - - esp_a2d_cb_param_t *a2d = NULL; - - switch (event) { - /* when connection state changed, this event comes */ - case ESP_A2D_CONNECTION_STATE_EVT: { - a2d = (esp_a2d_cb_param_t *)(p_param); - uint8_t *bda = a2d->conn_stat.remote_bda; - ESP_LOGI(BT_AV_TAG, "A2DP connection state: %s, [%02x:%02x:%02x:%02x:%02x:%02x]", - s_a2d_conn_state_str[a2d->conn_stat.state], bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); - if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) { - esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); - bt_i2s_driver_uninstall(); - bt_i2s_task_shut_down(); - } else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTED){ - esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE); - bt_i2s_task_start_up(); - } else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTING) { - bt_i2s_driver_install(); - } - break; - } - /* when audio stream transmission state changed, this event comes */ - case ESP_A2D_AUDIO_STATE_EVT: { - a2d = (esp_a2d_cb_param_t *)(p_param); - ESP_LOGI(BT_AV_TAG, "A2DP audio state: %s", s_a2d_audio_state_str[a2d->audio_stat.state]); - s_audio_state = a2d->audio_stat.state; - if (ESP_A2D_AUDIO_STATE_STARTED == a2d->audio_stat.state) { - s_pkt_cnt = 0; - } - break; - } - /* when audio codec is configured, this event comes */ - case ESP_A2D_AUDIO_CFG_EVT: { - a2d = (esp_a2d_cb_param_t *)(p_param); - esp_a2d_mcc_t *p_mcc = &a2d->audio_cfg.mcc; - ESP_LOGI(BT_AV_TAG, "A2DP audio stream configuration, codec type: %d", p_mcc->type); - /* for now only SBC stream is supported */ - if (p_mcc->type == ESP_A2D_MCT_SBC) { - int sample_rate = 16000; - int ch_count = 2; - if (p_mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_32K) { - sample_rate = 32000; - } else if (p_mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_44K) { - sample_rate = 44100; - } else if (p_mcc->cie.sbc_info.samp_freq & ESP_A2D_SBC_CIE_SF_48K) { - sample_rate = 48000; - } - - if (p_mcc->cie.sbc_info.ch_mode & ESP_A2D_SBC_CIE_CH_MODE_MONO) { - ch_count = 1; - } - #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - dac_continuous_disable(tx_chan); - dac_continuous_del_channels(tx_chan); - dac_continuous_config_t cont_cfg = { - .chan_mask = DAC_CHANNEL_MASK_ALL, - .desc_num = 8, - .buf_size = 2048, - .freq_hz = sample_rate, - .offset = 127, - .clk_src = DAC_DIGI_CLK_SRC_DEFAULT, // Using APLL as clock source to get a wider frequency range - .chan_mode = (ch_count == 1) ? DAC_CHANNEL_MODE_SIMUL : DAC_CHANNEL_MODE_ALTER, - }; - /* Allocate continuous channels */ - dac_continuous_new_channels(&cont_cfg, &tx_chan); - /* Enable the continuous channels */ - dac_continuous_enable(tx_chan); - #else - i2s_channel_disable(tx_chan); - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(sample_rate); - i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, ch_count); - i2s_channel_reconfig_std_clock(tx_chan, &clk_cfg); - i2s_channel_reconfig_std_slot(tx_chan, &slot_cfg); - i2s_channel_enable(tx_chan); - #endif - ESP_LOGI(BT_AV_TAG, "Configure audio player: 0x%x-0x%x-0x%x-0x%x-0x%x-%d-%d", - p_mcc->cie.sbc_info.samp_freq, - p_mcc->cie.sbc_info.ch_mode, - p_mcc->cie.sbc_info.block_len, - p_mcc->cie.sbc_info.num_subbands, - p_mcc->cie.sbc_info.alloc_mthd, - p_mcc->cie.sbc_info.min_bitpool, - p_mcc->cie.sbc_info.max_bitpool); - ESP_LOGI(BT_AV_TAG, "Audio player configured, sample rate: %d", sample_rate); - } - break; - } - /* when a2dp init or deinit completed, this event comes */ - case ESP_A2D_PROF_STATE_EVT: { - a2d = (esp_a2d_cb_param_t *)(p_param); - if (ESP_A2D_INIT_SUCCESS == a2d->a2d_prof_stat.init_state) { - ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Init Complete"); - } else { - ESP_LOGI(BT_AV_TAG, "A2DP PROF STATE: Deinit Complete"); - } - break; - } - /* When protocol service capabilities configured, this event comes */ - case ESP_A2D_SNK_PSC_CFG_EVT: { - a2d = (esp_a2d_cb_param_t *)(p_param); - ESP_LOGI(BT_AV_TAG, "protocol service capabilities configured: 0x%x ", a2d->a2d_psc_cfg_stat.psc_mask); - if (a2d->a2d_psc_cfg_stat.psc_mask & ESP_A2D_PSC_DELAY_RPT) { - ESP_LOGI(BT_AV_TAG, "Peer device support delay reporting"); - } else { - ESP_LOGI(BT_AV_TAG, "Peer device unsupported delay reporting"); - } - break; - } - /* when set delay value completed, this event comes */ - case ESP_A2D_SNK_SET_DELAY_VALUE_EVT: { - a2d = (esp_a2d_cb_param_t *)(p_param); - if (ESP_A2D_SET_INVALID_PARAMS == a2d->a2d_set_delay_value_stat.set_state) { - ESP_LOGI(BT_AV_TAG, "Set delay report value: fail"); - } else { - ESP_LOGI(BT_AV_TAG, "Set delay report value: success, delay_value: %u * 1/10 ms", a2d->a2d_set_delay_value_stat.delay_value); - } - break; - } - /* when get delay value completed, this event comes */ - case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: { - a2d = (esp_a2d_cb_param_t *)(p_param); - ESP_LOGI(BT_AV_TAG, "Get delay report value: delay_value: %u * 1/10 ms", a2d->a2d_get_delay_value_stat.delay_value); - /* Default delay value plus delay caused by application layer */ - esp_a2d_sink_set_delay_value(a2d->a2d_get_delay_value_stat.delay_value + APP_DELAY_VALUE); - break; - } - /* others */ - default: - ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); - break; - } -} - -static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param) +/* handler for AVRCP controller events */ +static void bt_app_avrc_ct_evt_hdl(uint16_t event, void *param) { ESP_LOGD(BT_RC_CT_TAG, "%s event: %d", __func__, event); - esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(p_param); + esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(param); switch (event) { - /* when connection state changed, this event comes */ + case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: + case ESP_AVRC_CT_REMOTE_FEATURES_EVT: + case ESP_AVRC_CT_PROF_STATE_EVT: { + bt_avrc_common_ct_evt_def_hdl(event, param); + break; + } case ESP_AVRC_CT_CONNECTION_STATE_EVT: { - uint8_t *bda = rc->conn_stat.remote_bda; - ESP_LOGI(BT_RC_CT_TAG, "AVRC conn_state event: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", - rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); - + bt_avrc_md_ct_evt_hdl(event, param); if (rc->conn_stat.connected) { /* get remote supported event_ids of peer AVRCP Target */ - esp_avrc_ct_send_get_rn_capabilities_cmd(APP_RC_CT_TL_GET_CAPS); + bt_avrc_common_ct_get_peer_rn_cap(); } else { /* clear peer notification capability record */ - s_avrc_peer_rn_cap.bits = 0; + bt_avrc_common_ct_set_peer_rn_cap(0); } break; } - /* when passthrough responded, this event comes */ - case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: { - ESP_LOGI(BT_RC_CT_TAG, "AVRC passthrough rsp: key_code 0x%x, key_state %d, rsp_code %d", rc->psth_rsp.key_code, - rc->psth_rsp.key_state, rc->psth_rsp.rsp_code); - break; - } - /* when metadata responded, this event comes */ - case ESP_AVRC_CT_METADATA_RSP_EVT: { - ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text); - free(rc->meta_rsp.attr_text); - break; - } - /* when notified, this event comes */ case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: { - ESP_LOGI(BT_RC_CT_TAG, "AVRC event notification: %d", rc->change_ntf.event_id); - bt_av_notify_evt_handler(rc->change_ntf.event_id, &rc->change_ntf.event_parameter); + bt_avrc_md_ct_evt_hdl(event, param); + bt_avrc_common_ct_notify_evt_handler(rc->change_ntf.event_id, &rc->change_ntf.event_parameter); break; } - /* when feature of remote device indicated, this event comes */ - case ESP_AVRC_CT_REMOTE_FEATURES_EVT: { - ESP_LOGI(BT_RC_CT_TAG, "AVRC remote features %"PRIx32", TG features %x", rc->rmt_feats.feat_mask, rc->rmt_feats.tg_feat_flag); - break; - } - /* when notification capability of peer device got, this event comes */ case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: { - ESP_LOGI(BT_RC_CT_TAG, "remote rn_cap: count %d, bitmask 0x%x", rc->get_rn_caps_rsp.cap_count, - rc->get_rn_caps_rsp.evt_set.bits); - s_avrc_peer_rn_cap.bits = rc->get_rn_caps_rsp.evt_set.bits; - bt_av_new_track(); - bt_av_playback_changed(); - bt_av_play_pos_changed(); + /* set peer notification capability record */ + bt_avrc_common_ct_set_peer_rn_cap(rc->get_rn_caps_rsp.evt_set.bits); + bt_avrc_common_ct_rn_track_changed(); + bt_avrc_common_ct_rn_play_status_changed(); + bt_avrc_common_ct_rn_play_pos_changed(); + + bt_avrc_md_ct_evt_hdl(event, param); + break; + } + case ESP_AVRC_CT_METADATA_RSP_EVT: { + bt_avrc_md_ct_evt_hdl(event, param); break; } - /* others */ default: - ESP_LOGE(BT_RC_CT_TAG, "%s unhandled event: %d", __func__, event); - break; - } -} - -static void bt_av_hdl_avrc_tg_evt(uint16_t event, void *p_param) -{ - ESP_LOGD(BT_RC_TG_TAG, "%s event: %d", __func__, event); - - esp_avrc_tg_cb_param_t *rc = (esp_avrc_tg_cb_param_t *)(p_param); - - switch (event) { - /* when connection state changed, this event comes */ - case ESP_AVRC_TG_CONNECTION_STATE_EVT: { - uint8_t *bda = rc->conn_stat.remote_bda; - ESP_LOGI(BT_RC_TG_TAG, "AVRC conn_state evt: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", - rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); - if (rc->conn_stat.connected) { - /* create task to simulate volume change */ - xTaskCreate(volume_change_simulation, "vcsTask", 2048, NULL, 5, &s_vcs_task_hdl); - } else { - vTaskDelete(s_vcs_task_hdl); - ESP_LOGI(BT_RC_TG_TAG, "Stop volume change simulation"); - } - break; - } - /* when passthrough commanded, this event comes */ - case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT: { - ESP_LOGI(BT_RC_TG_TAG, "AVRC passthrough cmd: key_code 0x%x, key_state %d", rc->psth_cmd.key_code, rc->psth_cmd.key_state); - break; - } - /* when absolute volume command from remote device set, this event comes */ - case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: { - ESP_LOGI(BT_RC_TG_TAG, "AVRC set absolute volume: %d%%", (int)rc->set_abs_vol.volume * 100 / 0x7f); - volume_set_by_controller(rc->set_abs_vol.volume); - break; - } - /* when notification registered, this event comes */ - case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: { - ESP_LOGI(BT_RC_TG_TAG, "AVRC register event notification: %d, param: 0x%"PRIx32, rc->reg_ntf.event_id, rc->reg_ntf.event_parameter); - if (rc->reg_ntf.event_id == ESP_AVRC_RN_VOLUME_CHANGE) { - s_volume_notify = true; - esp_avrc_rn_param_t rn_param; - rn_param.volume = s_volume; - esp_avrc_tg_send_rn_rsp(ESP_AVRC_RN_VOLUME_CHANGE, ESP_AVRC_RN_RSP_INTERIM, &rn_param); - } - break; - } - /* when feature of remote device indicated, this event comes */ - case ESP_AVRC_TG_REMOTE_FEATURES_EVT: { - ESP_LOGI(BT_RC_TG_TAG, "AVRC remote features: %"PRIx32", CT features: %x", rc->rmt_feats.feat_mask, rc->rmt_feats.ct_feat_flag); - break; - } - /* others */ - default: - ESP_LOGE(BT_RC_TG_TAG, "%s unhandled event: %d", __func__, event); + ESP_LOGE(BT_RC_CT_TAG, "Invalid AVRC event: %d", event); break; } } @@ -522,12 +91,15 @@ void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) switch (event) { case ESP_A2D_CONNECTION_STATE_EVT: case ESP_A2D_AUDIO_STATE_EVT: - case ESP_A2D_AUDIO_CFG_EVT: + case ESP_A2D_AUDIO_CFG_EVT: { + bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); + break; + } case ESP_A2D_PROF_STATE_EVT: case ESP_A2D_SNK_PSC_CFG_EVT: case ESP_A2D_SNK_SET_DELAY_VALUE_EVT: case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: { - bt_app_work_dispatch(bt_av_hdl_a2d_evt, event, param, sizeof(esp_a2d_cb_param_t), NULL); + bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); break; } default: @@ -538,28 +110,24 @@ void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len) { - write_ringbuf(data, len); - - /* log the number every 100 packets */ - if (++s_pkt_cnt % 100 == 0) { - ESP_LOGI(BT_AV_TAG, "Audio packet count: %"PRIu32, s_pkt_cnt); - } + bt_a2d_data_hdl(data, len); } void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param) { switch (event) { - case ESP_AVRC_CT_METADATA_RSP_EVT: - bt_app_alloc_meta_buffer(param); - /* fall through */ + case ESP_AVRC_CT_METADATA_RSP_EVT: { + bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), bt_avrc_common_copy_metadata); + break; + } case ESP_AVRC_CT_CONNECTION_STATE_EVT: case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: case ESP_AVRC_CT_REMOTE_FEATURES_EVT: - case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: { - bt_app_work_dispatch(bt_av_hdl_avrc_ct_evt, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL); + case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: + case ESP_AVRC_CT_PROF_STATE_EVT: + bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL); break; - } default: ESP_LOGE(BT_RC_CT_TAG, "Invalid AVRC event: %d", event); break; @@ -569,14 +137,19 @@ void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param) { switch (event) { - case ESP_AVRC_TG_CONNECTION_STATE_EVT: case ESP_AVRC_TG_REMOTE_FEATURES_EVT: case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT: - case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: - case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: case ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT: - bt_app_work_dispatch(bt_av_hdl_avrc_tg_evt, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL); + case ESP_AVRC_TG_PROF_STATE_EVT: { + bt_app_work_dispatch(bt_avrc_common_tg_evt_def_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL); break; + } + case ESP_AVRC_TG_CONNECTION_STATE_EVT: + case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: + case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: { + bt_app_work_dispatch(bt_avrc_avc_tg_evt_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL); + break; + } default: ESP_LOGE(BT_RC_TG_TAG, "Invalid AVRC event: %d", event); break; diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.h b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.h index d0e6e6c789..3750ba67c3 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.h +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -11,11 +11,6 @@ #include "esp_a2dp_api.h" #include "esp_avrc_api.h" -/* log tags */ -#define BT_AV_TAG "BT_AV" -#define BT_RC_TG_TAG "RC_TG" -#define BT_RC_CT_TAG "RC_CT" - /** * @brief callback function for A2DP sink * diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c deleted file mode 100644 index 29c915e893..0000000000 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -#include -#include -#include -#include "freertos/FreeRTOSConfig.h" -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" -#include "freertos/semphr.h" -#include "freertos/task.h" -#include "esp_log.h" -#include "bt_app_core.h" -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC -#include "driver/dac_continuous.h" -#else -#include "driver/i2s_std.h" -#endif -#include "freertos/ringbuf.h" - - -#define RINGBUF_HIGHEST_WATER_LEVEL (32 * 1024) -#define RINGBUF_PREFETCH_WATER_LEVEL (20 * 1024) - -enum { - RINGBUFFER_MODE_PROCESSING, /* ringbuffer is buffering incoming audio data, I2S is working */ - RINGBUFFER_MODE_PREFETCHING, /* ringbuffer is buffering incoming audio data, I2S is waiting */ - RINGBUFFER_MODE_DROPPING /* ringbuffer is not buffering (dropping) incoming audio data, I2S is working */ -}; - -/******************************* - * STATIC FUNCTION DECLARATIONS - ******************************/ - -/* handler for application task */ -static void bt_app_task_handler(void *arg); -/* handler for I2S task */ -static void bt_i2s_task_handler(void *arg); -/* message sender */ -static bool bt_app_send_msg(bt_app_msg_t *msg); -/* handle dispatched messages */ -static void bt_app_work_dispatched(bt_app_msg_t *msg); - -/******************************* - * STATIC VARIABLE DEFINITIONS - ******************************/ - -static QueueHandle_t s_bt_app_task_queue = NULL; /* handle of work queue */ -static TaskHandle_t s_bt_app_task_handle = NULL; /* handle of application task */ -static TaskHandle_t s_bt_i2s_task_handle = NULL; /* handle of I2S task */ -static RingbufHandle_t s_ringbuf_i2s = NULL; /* handle of ringbuffer for I2S */ -static SemaphoreHandle_t s_i2s_write_semaphore = NULL; -static uint16_t ringbuffer_mode = RINGBUFFER_MODE_PROCESSING; - -/********************************* - * EXTERNAL FUNCTION DECLARATIONS - ********************************/ -#ifndef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC -extern i2s_chan_handle_t tx_chan; -#else -extern dac_continuous_handle_t tx_chan; -#endif - -/******************************* - * STATIC FUNCTION DEFINITIONS - ******************************/ - -static bool bt_app_send_msg(bt_app_msg_t *msg) -{ - if (msg == NULL) { - return false; - } - - /* send the message to work queue */ - if (xQueueSend(s_bt_app_task_queue, msg, 10 / portTICK_PERIOD_MS) != pdTRUE) { - ESP_LOGE(BT_APP_CORE_TAG, "%s xQueue send failed", __func__); - return false; - } - return true; -} - -static void bt_app_work_dispatched(bt_app_msg_t *msg) -{ - if (msg->cb) { - msg->cb(msg->event, msg->param); - } -} - -static void bt_app_task_handler(void *arg) -{ - bt_app_msg_t msg; - - for (;;) { - /* receive message from work queue and handle it */ - if (pdTRUE == xQueueReceive(s_bt_app_task_queue, &msg, (TickType_t)portMAX_DELAY)) { - ESP_LOGD(BT_APP_CORE_TAG, "%s, signal: 0x%x, event: 0x%x", __func__, msg.sig, msg.event); - - switch (msg.sig) { - case BT_APP_SIG_WORK_DISPATCH: - bt_app_work_dispatched(&msg); - break; - default: - ESP_LOGW(BT_APP_CORE_TAG, "%s, unhandled signal: %d", __func__, msg.sig); - break; - } /* switch (msg.sig) */ - - if (msg.param) { - free(msg.param); - } - } - } -} - -static void bt_i2s_task_handler(void *arg) -{ - uint8_t *data = NULL; - size_t item_size = 0; - /** - * The total length of DMA buffer of I2S is: - * `dma_frame_num * dma_desc_num * i2s_channel_num * i2s_data_bit_width / 8`. - * Transmit `dma_frame_num * dma_desc_num` bytes to DMA is trade-off. - */ - const size_t item_size_upto = 240 * 6; - size_t bytes_written = 0; - - for (;;) { - if (pdTRUE == xSemaphoreTake(s_i2s_write_semaphore, portMAX_DELAY)) { - for (;;) { - item_size = 0; - /* receive data from ringbuffer and write it to I2S DMA transmit buffer */ - data = (uint8_t *)xRingbufferReceiveUpTo(s_ringbuf_i2s, &item_size, (TickType_t)pdMS_TO_TICKS(20), item_size_upto); - if (item_size == 0) { - ESP_LOGI(BT_APP_CORE_TAG, "ringbuffer underflowed! mode changed: RINGBUFFER_MODE_PREFETCHING"); - ringbuffer_mode = RINGBUFFER_MODE_PREFETCHING; - break; - } - - #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - dac_continuous_write(tx_chan, data, item_size, &bytes_written, -1); - #else - i2s_channel_write(tx_chan, data, item_size, &bytes_written, portMAX_DELAY); - #endif - vRingbufferReturnItem(s_ringbuf_i2s, (void *)data); - } - } - } -} - -/******************************** - * EXTERNAL FUNCTION DEFINITIONS - *******************************/ - -bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback) -{ - ESP_LOGD(BT_APP_CORE_TAG, "%s event: 0x%x, param len: %d", __func__, event, param_len); - - bt_app_msg_t msg; - memset(&msg, 0, sizeof(bt_app_msg_t)); - - msg.sig = BT_APP_SIG_WORK_DISPATCH; - msg.event = event; - msg.cb = p_cback; - - if (param_len == 0) { - return bt_app_send_msg(&msg); - } else if (p_params && param_len > 0) { - if ((msg.param = malloc(param_len)) != NULL) { - memcpy(msg.param, p_params, param_len); - /* check if caller has provided a copy callback to do the deep copy */ - if (p_copy_cback) { - p_copy_cback(msg.param, p_params, param_len); - } - return bt_app_send_msg(&msg); - } - } - - return false; -} - -void bt_app_task_start_up(void) -{ - s_bt_app_task_queue = xQueueCreate(10, sizeof(bt_app_msg_t)); - xTaskCreate(bt_app_task_handler, "BtAppTask", 3072, NULL, 10, &s_bt_app_task_handle); -} - -void bt_app_task_shut_down(void) -{ - if (s_bt_app_task_handle) { - vTaskDelete(s_bt_app_task_handle); - s_bt_app_task_handle = NULL; - } - if (s_bt_app_task_queue) { - vQueueDelete(s_bt_app_task_queue); - s_bt_app_task_queue = NULL; - } -} - -void bt_i2s_task_start_up(void) -{ - ESP_LOGI(BT_APP_CORE_TAG, "ringbuffer data empty! mode changed: RINGBUFFER_MODE_PREFETCHING"); - ringbuffer_mode = RINGBUFFER_MODE_PREFETCHING; - if ((s_i2s_write_semaphore = xSemaphoreCreateBinary()) == NULL) { - ESP_LOGE(BT_APP_CORE_TAG, "%s, Semaphore create failed", __func__); - return; - } - if ((s_ringbuf_i2s = xRingbufferCreate(RINGBUF_HIGHEST_WATER_LEVEL, RINGBUF_TYPE_BYTEBUF)) == NULL) { - ESP_LOGE(BT_APP_CORE_TAG, "%s, ringbuffer create failed", __func__); - return; - } - xTaskCreate(bt_i2s_task_handler, "BtI2STask", 2048, NULL, configMAX_PRIORITIES - 3, &s_bt_i2s_task_handle); -} - -void bt_i2s_task_shut_down(void) -{ - if (s_bt_i2s_task_handle) { - vTaskDelete(s_bt_i2s_task_handle); - s_bt_i2s_task_handle = NULL; - } - if (s_ringbuf_i2s) { - vRingbufferDelete(s_ringbuf_i2s); - s_ringbuf_i2s = NULL; - } - if (s_i2s_write_semaphore) { - vSemaphoreDelete(s_i2s_write_semaphore); - s_i2s_write_semaphore = NULL; - } -} - -size_t write_ringbuf(const uint8_t *data, size_t size) -{ - size_t item_size = 0; - BaseType_t done = pdFALSE; - - if (ringbuffer_mode == RINGBUFFER_MODE_DROPPING) { - ESP_LOGW(BT_APP_CORE_TAG, "ringbuffer is full, drop this packet!"); - vRingbufferGetInfo(s_ringbuf_i2s, NULL, NULL, NULL, NULL, &item_size); - if (item_size <= RINGBUF_PREFETCH_WATER_LEVEL) { - ESP_LOGI(BT_APP_CORE_TAG, "ringbuffer data decreased! mode changed: RINGBUFFER_MODE_PROCESSING"); - ringbuffer_mode = RINGBUFFER_MODE_PROCESSING; - } - return 0; - } - - done = xRingbufferSend(s_ringbuf_i2s, (void *)data, size, (TickType_t)0); - - if (!done) { - ESP_LOGW(BT_APP_CORE_TAG, "ringbuffer overflowed, ready to decrease data! mode changed: RINGBUFFER_MODE_DROPPING"); - ringbuffer_mode = RINGBUFFER_MODE_DROPPING; - } - - if (ringbuffer_mode == RINGBUFFER_MODE_PREFETCHING) { - vRingbufferGetInfo(s_ringbuf_i2s, NULL, NULL, NULL, NULL, &item_size); - if (item_size >= RINGBUF_PREFETCH_WATER_LEVEL) { - ESP_LOGI(BT_APP_CORE_TAG, "ringbuffer data increased! mode changed: RINGBUFFER_MODE_PROCESSING"); - ringbuffer_mode = RINGBUFFER_MODE_PROCESSING; - if (pdFALSE == xSemaphoreGive(s_i2s_write_semaphore)) { - ESP_LOGE(BT_APP_CORE_TAG, "semphore give failed"); - } - } - } - - return done ? size : 0; -} diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.h b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.h deleted file mode 100644 index 055f7609f1..0000000000 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -#ifndef __BT_APP_CORE_H__ -#define __BT_APP_CORE_H__ - -#include -#include -#include - -/* log tag */ -#define BT_APP_CORE_TAG "BT_APP_CORE" - -/* signal for `bt_app_work_dispatch` */ -#define BT_APP_SIG_WORK_DISPATCH (0x01) - -/** - * @brief handler for the dispatched work - * - * @param [in] event event id - * @param [in] param handler parameter - */ -typedef void (* bt_app_cb_t) (uint16_t event, void *param); - -/* message to be sent */ -typedef struct { - uint16_t sig; /*!< signal to bt_app_task */ - uint16_t event; /*!< message event id */ - bt_app_cb_t cb; /*!< context switch callback */ - void *param; /*!< parameter area needs to be last */ -} bt_app_msg_t; - -/** - * @brief parameter deep-copy function to be customized - * - * @param [out] p_dest pointer to destination data - * @param [in] p_src pointer to source data - * @param [in] len data length in byte - */ -typedef void (* bt_app_copy_cb_t) (void *p_dest, void *p_src, int len); - -/** - * @brief work dispatcher for the application task - * - * @param [in] p_cback callback function - * @param [in] event event id - * @param [in] p_params callback paramters - * @param [in] param_len parameter length in byte - * @param [in] p_copy_cback parameter deep-copy function - * - * @return true if work dispatch successfully, false otherwise - */ -bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback); - -/** - * @brief start up the application task - */ -void bt_app_task_start_up(void); - -/** - * @brief shut down the application task - */ -void bt_app_task_shut_down(void); - -/** - * @brief start up the is task - */ -void bt_i2s_task_start_up(void); - -/** - * @brief shut down the I2S task - */ -void bt_i2s_task_shut_down(void); - -/** - * @brief write data to ringbuffer - * - * @param [in] data pointer to data stream - * @param [in] size data length in byte - * - * @return size if writteen ringbuffer successfully, 0 others - */ -size_t write_ringbuf(const uint8_t *data, size_t size); - -#endif /* __BT_APP_CORE_H__ */ diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/idf_component.yml b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/idf_component.yml new file mode 100644 index 0000000000..d43bddf6d1 --- /dev/null +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/idf_component.yml @@ -0,0 +1,15 @@ +dependencies: + bt_app_core_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils + bredr_app_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils + a2dp_sink_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils + a2dp_sink_int_codec_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils + avrcp_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils + avrcp_metadata_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils + avrcp_abs_vol_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_abs_vol_utils diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c index 12e8bdd8b1..348f429af8 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c @@ -21,27 +21,30 @@ #include #include #include -#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.h" -#include "bt_app_core.h" -#include "bt_app_av.h" #include "esp_bt_main.h" #include "esp_bt_device.h" #include "esp_gap_bt_api.h" #include "esp_a2dp_api.h" #include "esp_avrc_api.h" - #include "esp_gap_ble_api.h" #include "esp_gatts_api.h" #include "esp_bt_defs.h" #include "esp_gatt_common_api.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "bt_app_core_utils.h" +#include "bredr_app_common_utils.h" +#include "a2dp_sink_int_codec_utils.h" +#include "bt_app_av.h" + /* log tag */ #define BT_BLE_COEX_TAG "BT_BLE_COEX" /* device name */ @@ -138,8 +141,8 @@ static void ble_init_adv_data(const char *name) size_t len = strlen(name); // ADV data max is 31 bytes; overhead is 5 bytes (Flags: 3, Name header: 2) - #define ADV_DATA_MAX_LEN 31 - #define ADV_DATA_OVERHEAD 5 +#define ADV_DATA_MAX_LEN 31 +#define ADV_DATA_OVERHEAD 5 if (len > (ADV_DATA_MAX_LEN - ADV_DATA_OVERHEAD)) { ESP_LOGW(BT_BLE_COEX_TAG, "ADV name too long (%d), truncating to %d", (int)len, ADV_DATA_MAX_LEN - ADV_DATA_OVERHEAD); @@ -160,11 +163,11 @@ static void ble_init_adv_data(const char *name) //The length of adv data must be less than 31 bytes esp_err_t raw_adv_ret = esp_ble_gap_config_adv_data_raw(raw_adv_data, adv_data_len); - if (raw_adv_ret){ + if (raw_adv_ret) { ESP_LOGE(BT_BLE_COEX_TAG, "config raw adv data failed, error code = 0x%x ", raw_adv_ret); } esp_err_t raw_scan_ret = esp_ble_gap_config_scan_rsp_data_raw(raw_adv_data, adv_data_len); - if (raw_scan_ret){ + if (raw_scan_ret) { ESP_LOGE(BT_BLE_COEX_TAG, "config raw scan rsp data failed, error code = 0x%x", raw_scan_ret); } } @@ -182,33 +185,33 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param //advertising start complete event to indicate advertising start successfully or failed if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { ESP_LOGE(BT_BLE_COEX_TAG, "Advertising start failed"); - }else { + } else { ESP_LOGI(BT_BLE_COEX_TAG, "Start adv successfully"); } break; case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) { ESP_LOGE(BT_BLE_COEX_TAG, "Advertising stop failed"); - } - else { + } else { ESP_LOGI(BT_BLE_COEX_TAG, "Stop adv successfully"); } break; case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: - ESP_LOGI(BT_BLE_COEX_TAG, "update connection params status = %d, conn_int = %d, latency = %d, timeout = %d", - param->update_conn_params.status, - param->update_conn_params.conn_int, - param->update_conn_params.latency, - param->update_conn_params.timeout); + ESP_LOGI(BT_BLE_COEX_TAG, "update connection params status = %d, conn_int = %d, latency = %d, timeout = %d", + param->update_conn_params.status, + param->update_conn_params.conn_int, + param->update_conn_params.latency, + param->update_conn_params.timeout); break; default: break; } } -void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param){ +void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param) +{ esp_gatt_status_t status = ESP_GATT_OK; - if (param->write.need_rsp){ + if (param->write.need_rsp) { if (param->write.is_prep) { if (param->write.offset > PREPARE_BUF_MAX_SIZE) { status = ESP_GATT_INVALID_OFFSET; @@ -217,7 +220,7 @@ void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare } if (status == ESP_GATT_OK && prepare_write_env->prepare_buf == NULL) { - prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE*sizeof(uint8_t)); + prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE * sizeof(uint8_t)); prepare_write_env->prepare_len = 0; if (prepare_write_env->prepare_buf == NULL) { ESP_LOGE(BT_BLE_COEX_TAG, "Gatt_server prep no mem"); @@ -233,7 +236,7 @@ void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare gatt_rsp->attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE; memcpy(gatt_rsp->attr_value.value, param->write.value, param->write.len); esp_err_t response_err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, gatt_rsp); - if (response_err != ESP_OK){ + if (response_err != ESP_OK) { ESP_LOGE(BT_BLE_COEX_TAG, "Send response error\n"); } free(gatt_rsp); @@ -241,7 +244,7 @@ void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare ESP_LOGE(BT_BLE_COEX_TAG, "%s, malloc failed", __func__); status = ESP_GATT_NO_RESOURCES; } - if (status != ESP_GATT_OK){ + if (status != ESP_GATT_OK) { return; } memcpy(prepare_write_env->prepare_buf + param->write.offset, @@ -249,17 +252,18 @@ void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare param->write.len); prepare_write_env->prepare_len += param->write.len; - }else{ + } else { esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, NULL); } } } -void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param){ - if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC){ +void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param) +{ + if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) { ESP_LOG_BUFFER_HEX(BT_BLE_COEX_TAG, prepare_write_env->prepare_buf, prepare_write_env->prepare_len); - }else{ - ESP_LOGI(BT_BLE_COEX_TAG,"ESP_GATT_PREP_WRITE_CANCEL"); + } else { + ESP_LOGI(BT_BLE_COEX_TAG, "ESP_GATT_PREP_WRITE_CANCEL"); } if (prepare_write_env->prepare_buf) { free(prepare_write_env->prepare_buf); @@ -268,7 +272,8 @@ void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble prepare_write_env->prepare_len = 0; } -static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { +static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) +{ switch (event) { case ESP_GATTS_REG_EVT: ESP_LOGI(BT_BLE_COEX_TAG, "REGISTER_APP_EVT, status %d, app_id %d", param->reg.status, param->reg.app_id); @@ -297,39 +302,36 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i } case ESP_GATTS_WRITE_EVT: { ESP_LOGI(BT_BLE_COEX_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %"PRIu32", handle %d", param->write.conn_id, param->write.trans_id, param->write.handle); - if (!param->write.is_prep){ + if (!param->write.is_prep) { ESP_LOGI(BT_BLE_COEX_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len); ESP_LOG_BUFFER_HEX(BT_BLE_COEX_TAG, param->write.value, param->write.len); - if (gl_profile_tab[PROFILE_A_APP_ID].descr_handle == param->write.handle && param->write.len == 2){ - uint16_t descr_value = param->write.value[1]<<8 | param->write.value[0]; - if (descr_value == 0x0001){ - if (a_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY){ + if (gl_profile_tab[PROFILE_A_APP_ID].descr_handle == param->write.handle && param->write.len == 2) { + uint16_t descr_value = param->write.value[1] << 8 | param->write.value[0]; + if (descr_value == 0x0001) { + if (a_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY) { ESP_LOGI(BT_BLE_COEX_TAG, "notify enable"); uint8_t notify_data[15]; - for (int i = 0; i < sizeof(notify_data); ++i) - { - notify_data[i] = i%0xff; + for (int i = 0; i < sizeof(notify_data); ++i) { + notify_data[i] = i % 0xff; } //the size of notify_data[] need less than MTU size esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle, - sizeof(notify_data), notify_data, false); + sizeof(notify_data), notify_data, false); } - }else if (descr_value == 0x0002){ - if (a_property & ESP_GATT_CHAR_PROP_BIT_INDICATE){ + } else if (descr_value == 0x0002) { + if (a_property & ESP_GATT_CHAR_PROP_BIT_INDICATE) { ESP_LOGI(BT_BLE_COEX_TAG, "indicate enable"); uint8_t indicate_data[15]; - for (int i = 0; i < sizeof(indicate_data); ++i) - { - indicate_data[i] = i%0xff; + for (int i = 0; i < sizeof(indicate_data); ++i) { + indicate_data[i] = i % 0xff; } //the size of indicate_data[] need less than MTU size esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle, - sizeof(indicate_data), indicate_data, true); + sizeof(indicate_data), indicate_data, true); } - } - else if (descr_value == 0x0000){ + } else if (descr_value == 0x0000) { ESP_LOGI(BT_BLE_COEX_TAG, "notify/indicate disable "); - }else{ + } else { ESP_LOGE(BT_BLE_COEX_TAG, "unknown descr value"); ESP_LOG_BUFFER_HEX(BT_BLE_COEX_TAG, param->write.value, param->write.len); } @@ -340,7 +342,7 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i break; } case ESP_GATTS_EXEC_WRITE_EVT: - ESP_LOGI(BT_BLE_COEX_TAG,"ESP_GATTS_EXEC_WRITE_EVT"); + ESP_LOGI(BT_BLE_COEX_TAG, "ESP_GATTS_EXEC_WRITE_EVT"); esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); example_exec_write_event_env(&a_prepare_write_env, param); break; @@ -361,21 +363,21 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, a_property, &gatts_initial_char_val, NULL); - if (add_char_ret){ - ESP_LOGE(BT_BLE_COEX_TAG, "add char failed, error code = 0x%x",add_char_ret); + if (add_char_ret) { + ESP_LOGE(BT_BLE_COEX_TAG, "add char failed, error code = 0x%x", add_char_ret); } break; case ESP_GATTS_ADD_INCL_SRVC_EVT: break; case ESP_GATTS_ADD_CHAR_EVT: { ESP_LOGI(BT_BLE_COEX_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d", - param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); + param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle; gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; esp_err_t add_descr_ret = esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL); - if (add_descr_ret){ + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL); + if (add_descr_ret) { ESP_LOGE(BT_BLE_COEX_TAG, "add char descr failed, error code = 0x%x", add_descr_ret); } break; @@ -404,7 +406,7 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i break; case ESP_GATTS_CONF_EVT: ESP_LOGI(BT_BLE_COEX_TAG, "ESP_GATTS_CONF_EVT, status %d", param->conf.status); - if (param->conf.status != ESP_GATT_OK){ + if (param->conf.status != ESP_GATT_OK) { ESP_LOG_BUFFER_HEX(BT_BLE_COEX_TAG, param->conf.value, param->conf.len); } break; @@ -418,7 +420,8 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i } } -static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { +static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) +{ switch (event) { case ESP_GATTS_REG_EVT: ESP_LOGI(BT_BLE_COEX_TAG, "REGISTER_APP_EVT, status %d, app_id %d", param->reg.status, param->reg.app_id); @@ -445,39 +448,36 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i } case ESP_GATTS_WRITE_EVT: { ESP_LOGI(BT_BLE_COEX_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %"PRIu32", handle %d", param->write.conn_id, param->write.trans_id, param->write.handle); - if (!param->write.is_prep){ + if (!param->write.is_prep) { ESP_LOGI(BT_BLE_COEX_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len); ESP_LOG_BUFFER_HEX(BT_BLE_COEX_TAG, param->write.value, param->write.len); - if (gl_profile_tab[PROFILE_B_APP_ID].descr_handle == param->write.handle && param->write.len == 2){ - uint16_t descr_value= param->write.value[1]<<8 | param->write.value[0]; - if (descr_value == 0x0001){ - if (b_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY){ + if (gl_profile_tab[PROFILE_B_APP_ID].descr_handle == param->write.handle && param->write.len == 2) { + uint16_t descr_value = param->write.value[1] << 8 | param->write.value[0]; + if (descr_value == 0x0001) { + if (b_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY) { ESP_LOGI(BT_BLE_COEX_TAG, "notify enable"); uint8_t notify_data[15]; - for (int i = 0; i < sizeof(notify_data); ++i) - { - notify_data[i] = i%0xff; + for (int i = 0; i < sizeof(notify_data); ++i) { + notify_data[i] = i % 0xff; } //the size of notify_data[] need less than MTU size esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_B_APP_ID].char_handle, - sizeof(notify_data), notify_data, false); + sizeof(notify_data), notify_data, false); } - }else if (descr_value == 0x0002){ - if (b_property & ESP_GATT_CHAR_PROP_BIT_INDICATE){ + } else if (descr_value == 0x0002) { + if (b_property & ESP_GATT_CHAR_PROP_BIT_INDICATE) { ESP_LOGI(BT_BLE_COEX_TAG, "indicate enable"); uint8_t indicate_data[15]; - for (int i = 0; i < sizeof(indicate_data); ++i) - { - indicate_data[i] = i%0xff; + for (int i = 0; i < sizeof(indicate_data); ++i) { + indicate_data[i] = i % 0xff; } //the size of indicate_data[] need less than MTU size esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_B_APP_ID].char_handle, - sizeof(indicate_data), indicate_data, true); + sizeof(indicate_data), indicate_data, true); } - } - else if (descr_value == 0x0000){ + } else if (descr_value == 0x0000) { ESP_LOGI(BT_BLE_COEX_TAG, "notify/indicate disable "); - }else{ + } else { ESP_LOGE(BT_BLE_COEX_TAG, "unknown value"); } @@ -487,7 +487,7 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i break; } case ESP_GATTS_EXEC_WRITE_EVT: - ESP_LOGI(BT_BLE_COEX_TAG,"ESP_GATTS_EXEC_WRITE_EVT"); + ESP_LOGI(BT_BLE_COEX_TAG, "ESP_GATTS_EXEC_WRITE_EVT"); esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); example_exec_write_event_env(&b_prepare_write_env, param); break; @@ -504,12 +504,12 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i esp_ble_gatts_start_service(gl_profile_tab[PROFILE_B_APP_ID].service_handle); b_property = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY; - esp_err_t add_char_ret =esp_ble_gatts_add_char( gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].char_uuid, + esp_err_t add_char_ret = esp_ble_gatts_add_char(gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].char_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, b_property, NULL, NULL); - if (add_char_ret){ - ESP_LOGE(BT_BLE_COEX_TAG, "add char failed, error code = 0x%x",add_char_ret); + if (add_char_ret) { + ESP_LOGE(BT_BLE_COEX_TAG, "add char failed, error code = 0x%x", add_char_ret); } break; case ESP_GATTS_ADD_INCL_SRVC_EVT: @@ -547,10 +547,10 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i break; case ESP_GATTS_CONF_EVT: ESP_LOGI(BT_BLE_COEX_TAG, "ESP_GATTS_CONF_EVT status %d", param->conf.status); - if (param->conf.status != ESP_GATT_OK){ + if (param->conf.status != ESP_GATT_OK) { ESP_LOG_BUFFER_HEX(BT_BLE_COEX_TAG, param->conf.value, param->conf.len); } - break; + break; case ESP_GATTS_DISCONNECT_EVT: case ESP_GATTS_OPEN_EVT: case ESP_GATTS_CANCEL_OPEN_EVT: @@ -570,8 +570,8 @@ static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_ gl_profile_tab[param->reg.app_id].gatts_if = gatts_if; } else { ESP_LOGI(BT_BLE_COEX_TAG, "Reg app failed, app_id %04x, status %d", - param->reg.app_id, - param->reg.status); + param->reg.app_id, + param->reg.status); return; } } @@ -594,27 +594,27 @@ static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_ static void ble_gatts_init(void) { esp_err_t ret = esp_ble_gatts_register_callback(gatts_event_handler); - if (ret){ + if (ret) { ESP_LOGE(BT_BLE_COEX_TAG, "gatts register error, error code = 0x%x", ret); return; } ret = esp_ble_gap_register_callback(gap_event_handler); - if (ret){ + if (ret) { ESP_LOGE(BT_BLE_COEX_TAG, "gap register error, error code = 0x%x", ret); return; } ret = esp_ble_gatts_app_register(PROFILE_A_APP_ID); - if (ret){ + if (ret) { ESP_LOGE(BT_BLE_COEX_TAG, "gatts app register error, error code = 0x%x", ret); return; } ret = esp_ble_gatts_app_register(PROFILE_B_APP_ID); - if (ret){ + if (ret) { ESP_LOGE(BT_BLE_COEX_TAG, "gatts app register error, error code = 0x%x", ret); return; } esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(500); - if (local_mtu_ret){ + if (local_mtu_ret) { ESP_LOGE(BT_BLE_COEX_TAG, "set local MTU failed, error code = 0x%x", local_mtu_ret); } } @@ -634,44 +634,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param); static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) { - switch (event) { - /* when authentication completed, this event comes */ - case ESP_BT_GAP_AUTH_CMPL_EVT: { - if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { - ESP_LOGI(BT_BLE_COEX_TAG, "authentication success: %s", param->auth_cmpl.device_name); - ESP_LOG_BUFFER_HEX(BT_BLE_COEX_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN); - } else { - ESP_LOGE(BT_BLE_COEX_TAG, "authentication failed, status: %d", param->auth_cmpl.stat); - } - break; - } - -#if (CONFIG_EXAMPLE_A2DP_SINK_SSP_ENABLED == true) - /* when Security Simple Pairing user confirmation requested, this event comes */ - case ESP_BT_GAP_CFM_REQ_EVT: - ESP_LOGI(BT_BLE_COEX_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %06"PRIu32, param->cfm_req.num_val); - esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true); - break; - /* when Security Simple Pairing passkey notified, this event comes */ - case ESP_BT_GAP_KEY_NOTIF_EVT: - ESP_LOGI(BT_BLE_COEX_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey: %06"PRIu32, param->key_notif.passkey); - break; - /* when Security Simple Pairing passkey requested, this event comes */ - case ESP_BT_GAP_KEY_REQ_EVT: - ESP_LOGI(BT_BLE_COEX_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!"); - break; -#endif - - /* when GAP mode changed, this event comes */ - case ESP_BT_GAP_MODE_CHG_EVT: - ESP_LOGI(BT_BLE_COEX_TAG, "ESP_BT_GAP_MODE_CHG_EVT mode: %d", param->mode_chg.mode); - break; - /* others */ - default: { - ESP_LOGI(BT_BLE_COEX_TAG, "event: %d", event); - break; - } - } + bredr_app_gap_evt_def_hdl(event, param); } static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) @@ -738,7 +701,7 @@ void app_main(void) } esp_bluedroid_config_t bluedroid_cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT(); -#if (CONFIG_EXAMPLE_A2DP_SINK_SSP_ENABLED == false) +#if (CONFIG_EXAMPLE_SSP_ENABLED == false) bluedroid_cfg.ssp_en = false; #endif if ((err = esp_bluedroid_init_with_cfg(&bluedroid_cfg)) != ESP_OK) { @@ -751,7 +714,7 @@ void app_main(void) return; } -#if (CONFIG_EXAMPLE_A2DP_SINK_SSP_ENABLED == true) +#if (CONFIG_EXAMPLE_SSP_ENABLED == true) /* set default parameters for Secure Simple Pairing */ esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE; esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO; diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults index a20f726e12..9800abe7ad 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults @@ -1,8 +1,6 @@ # Override some defaults so BT stack is enabled and # Classic BT is enabled and BT_DRAM_RELEASE is disabled CONFIG_BT_ENABLED=y -CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n -CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n CONFIG_BTDM_CTRL_MODE_BTDM=y CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y CONFIG_BTDM_CTRL_PINNED_TO_CORE_1=n From 70866321053f2df850c2daed37de99f0770439fb Mon Sep 17 00:00:00 2001 From: yangfeng Date: Fri, 5 Dec 2025 16:48:51 +0800 Subject: [PATCH 025/226] refactor(examples/classic_bt): Add common code for AVRCP cover art example --- .../avrcp_cover_art_utils/CMakeLists.txt | 4 + .../avrcp_cover_art_utils/Kconfig.projbuild | 8 + .../avrcp_cover_art_service.c | 347 ++++++++++++++++++ .../avrcp_cover_art_service.h | 66 ++++ .../avrcp_cover_art_utils.c | 91 +++++ .../avrcp_cover_art_utils.h | 20 + .../avrcp_cover_art_utils/idf_component.yml | 5 + 7 files changed, 541 insertions(+) create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/Kconfig.projbuild create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_service.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_service.h create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_utils.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_utils.h create mode 100644 examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/idf_component.yml diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/CMakeLists.txt new file mode 100644 index 0000000000..bcd7cd6879 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "avrcp_cover_art_utils.c" + "avrcp_cover_art_service.c" + PRIV_REQUIRES bt esp_lcd avrcp_common_utils + INCLUDE_DIRS "." "../include") diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/Kconfig.projbuild new file mode 100644 index 0000000000..78035b2618 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/Kconfig.projbuild @@ -0,0 +1,8 @@ +menu "AVRCP Cover Art Example Configuration" + config EXAMPLE_LCD_FLUSH_PARALLEL_LINES + int "LCD flush parallel lines" + default 16 + help + To speed up transfers, every SPI transfer sends a bunch of lines. + +endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_service.c b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_service.c new file mode 100644 index 0000000000..bd837329f6 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_service.c @@ -0,0 +1,347 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include "driver/spi_master.h" +#include "driver/gpio.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_lcd_panel_io.h" +#include "esp_lcd_panel_vendor.h" +#include "esp_lcd_panel_ops.h" +#include "jpeg_decoder.h" +#include "avrcp_common_utils.h" +#include "avrcp_cover_art_service.h" + +/* tags*/ +#define RC_CA_SRV_TAG "RC_CA_SRV" + +//Define the height and width of the jpeg file. Make sure this matches the actual jpeg +//dimensions. +#define IMAGE_W 200 +#define IMAGE_H 200 + +// Using SPI2 in the example, as it also supports octal modes on some targets +#define LCD_HOST SPI2_HOST +// To speed up transfers, every SPI transfer sends a bunch of lines. This define specifies how many. +// More means more memory use, but less overhead for setting up / finishing transfers. Make sure 240 +// is dividable by this. +#define PARALLEL_LINES CONFIG_EXAMPLE_LCD_FLUSH_PARALLEL_LINES + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// Please update the following configuration according to your LCD spec ////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define EXAMPLE_LCD_PIXEL_CLOCK_HZ (20 * 1000 * 1000) +#define EXAMPLE_LCD_BK_LIGHT_ON_LEVEL 0 +#define EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL !EXAMPLE_LCD_BK_LIGHT_ON_LEVEL +#define EXAMPLE_PIN_NUM_DATA0 23 /*!< for 1-line SPI, this also referred as MOSI */ +#define EXAMPLE_PIN_NUM_PCLK 19 +#define EXAMPLE_PIN_NUM_CS 22 +#define EXAMPLE_PIN_NUM_DC 21 +#define EXAMPLE_PIN_NUM_RST 18 +#define EXAMPLE_PIN_NUM_BK_LIGHT 5 + +// The pixel number in horizontal and vertical +#define EXAMPLE_LCD_H_RES 200 +#define EXAMPLE_LCD_V_RES 200 +// Bit number used to represent command and parameter +#define EXAMPLE_LCD_CMD_BITS 8 +#define EXAMPLE_LCD_PARAM_BITS 8 + +/** + * @brief AVRCP cover art service control block structure + */ +typedef struct { + bool connected; /* Connection status flag */ + bool getting; /* Flag indicating if image is being retrieved */ + /* Related to the image */ + uint8_t image_hdl_old[7]; /* Previous image handle, used to detect image changes */ + uint32_t image_size; /* Size of the image data in bytes */ + uint8_t *image_data; /* Pointer to the image data buffer */ + bool image_final; /* Indicate whether the image reception has been completed */ + uint16_t *pixels; /* Pointer to decoded pixel data */ + esp_lcd_panel_io_handle_t io_handle; /* LCD panel IO handle */ + esp_lcd_panel_handle_t panel_handle; /* LCD panel handle */ +} avrc_cover_art_srv_cb_t; + +/******************************* + * STATIC FUNCTION DECLARATIONS + ******************************/ + +/* image handle check */ +static bool avrc_cover_art_srv_image_handle_check(uint8_t *image_handle, int len); +/* free image data */ +static void avrc_cover_art_srv_free_image_data(void); +/* initialize display (currently supports LCD only) */ +static void avrc_cover_art_srv_init_display(void); +/* deinitialize display (currently supports LCD only) */ +static void avrc_cover_art_srv_deinit_display(void); +/* free pixels */ +static void avrc_cover_art_srv_free_pixels(void); +/* decode image */ +static esp_err_t avrc_cover_art_srv_decode_image(void); +/* display image */ +static void avrc_cover_art_srv_display_image(void); + +/******************************* + * STATIC VARIABLE DEFINITIONS + ******************************/ + +/* avrcp cover art service control block */ +static avrc_cover_art_srv_cb_t s_avrc_cover_art_srv_cb; + +/******************************** + * STATIC FUNCTION DEFINITIONS + *******************************/ + +static bool avrc_cover_art_srv_image_handle_check(uint8_t *image_handle, int len) +{ + /* Image handle length must be 7 */ + if (len == 7 && memcmp(s_avrc_cover_art_srv_cb.image_hdl_old, image_handle, 7) != 0) { + memcpy(s_avrc_cover_art_srv_cb.image_hdl_old, image_handle, 7); + return true; + } + return false; +} + +static void avrc_cover_art_srv_free_image_data(void) +{ + if (s_avrc_cover_art_srv_cb.image_data) { + free(s_avrc_cover_art_srv_cb.image_data); + s_avrc_cover_art_srv_cb.image_data = NULL; + } + s_avrc_cover_art_srv_cb.image_size = 0; +} + +static void avrc_cover_art_srv_init_display(void) +{ + gpio_config_t bk_gpio_config = { + .mode = GPIO_MODE_OUTPUT, + .pin_bit_mask = 1ULL << EXAMPLE_PIN_NUM_BK_LIGHT + }; + /* Initialize the GPIO of backlight */ + ESP_ERROR_CHECK(gpio_config(&bk_gpio_config)); + + spi_bus_config_t buscfg = { + .sclk_io_num = EXAMPLE_PIN_NUM_PCLK, + .mosi_io_num = EXAMPLE_PIN_NUM_DATA0, + .miso_io_num = -1, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = PARALLEL_LINES * EXAMPLE_LCD_H_RES * 2 + 8 + }; + /* Initialize the SPI bus */ + ESP_ERROR_CHECK(spi_bus_initialize(LCD_HOST, &buscfg, SPI_DMA_CH_AUTO)); + + esp_lcd_panel_io_spi_config_t io_config = { + .dc_gpio_num = EXAMPLE_PIN_NUM_DC, + .cs_gpio_num = EXAMPLE_PIN_NUM_CS, + .pclk_hz = EXAMPLE_LCD_PIXEL_CLOCK_HZ, + .lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS, + .lcd_param_bits = EXAMPLE_LCD_PARAM_BITS, + .spi_mode = 0, + .trans_queue_depth = 10, + }; + /* Attach the LCD to the SPI bus */ + ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_HOST, &io_config, &s_avrc_cover_art_srv_cb.io_handle)); + + esp_lcd_panel_dev_config_t panel_config = { + .reset_gpio_num = EXAMPLE_PIN_NUM_RST, + .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, + .bits_per_pixel = 16, + }; + /* Initialize the LCD configuration */ + ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(s_avrc_cover_art_srv_cb.io_handle, &panel_config, &s_avrc_cover_art_srv_cb.panel_handle)); + + /* Turn off backlight to avoid unpredictable display on the LCD screen while initializing + * the LCD panel driver. (Different LCD screens may need different levels) */ + ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_PIN_NUM_BK_LIGHT, EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL)); + + /* Reset the display */ + ESP_ERROR_CHECK(esp_lcd_panel_reset(s_avrc_cover_art_srv_cb.panel_handle)); + + /* Initialize LCD panel */ + ESP_ERROR_CHECK(esp_lcd_panel_init(s_avrc_cover_art_srv_cb.panel_handle)); + + /* Turn on the screen */ + ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(s_avrc_cover_art_srv_cb.panel_handle, true)); + ESP_ERROR_CHECK(esp_lcd_panel_invert_color(s_avrc_cover_art_srv_cb.panel_handle, true)); + + /* Swap x and y axis (Different LCD screens may need different options) */ + ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(s_avrc_cover_art_srv_cb.panel_handle, true)); + + /* Turn on backlight (Different LCD screens may need different levels) */ + ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_PIN_NUM_BK_LIGHT, EXAMPLE_LCD_BK_LIGHT_ON_LEVEL)); +} + +static void avrc_cover_art_srv_deinit_display(void) +{ + /* Turn off backlight first */ + ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_PIN_NUM_BK_LIGHT, EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL)); + + /* Turn off the display */ + if (s_avrc_cover_art_srv_cb.panel_handle) { + ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(s_avrc_cover_art_srv_cb.panel_handle, false)); + /* Delete the LCD panel */ + ESP_ERROR_CHECK(esp_lcd_panel_del(s_avrc_cover_art_srv_cb.panel_handle)); + s_avrc_cover_art_srv_cb.panel_handle = NULL; + } + + /* Delete the LCD panel IO */ + if (s_avrc_cover_art_srv_cb.io_handle) { + ESP_ERROR_CHECK(esp_lcd_panel_io_del(s_avrc_cover_art_srv_cb.io_handle)); + s_avrc_cover_art_srv_cb.io_handle = NULL; + } + + /* Free the SPI bus */ + ESP_ERROR_CHECK(spi_bus_free(LCD_HOST)); + + /* Reset backlight GPIO */ + ESP_ERROR_CHECK(gpio_reset_pin(EXAMPLE_PIN_NUM_BK_LIGHT)); +} + +static void avrc_cover_art_srv_free_pixels(void) +{ + if (s_avrc_cover_art_srv_cb.pixels) { + free(s_avrc_cover_art_srv_cb.pixels); + s_avrc_cover_art_srv_cb.pixels = NULL; + } +} + +static esp_err_t avrc_cover_art_srv_decode_image(void) +{ + esp_err_t ret = ESP_OK; + + avrc_cover_art_srv_free_pixels(); + + /* Allocate pixel memory. Each line is an array of IMAGE_W 16-bit pixels; the `s_avrc_cover_art_srv_cb.pixels` array itself contains pointers to these lines. */ + s_avrc_cover_art_srv_cb.pixels = calloc(IMAGE_H * IMAGE_W, sizeof(uint16_t)); + + ESP_GOTO_ON_FALSE(s_avrc_cover_art_srv_cb.pixels, ESP_ERR_NO_MEM, err, RC_CA_SRV_TAG, "Error allocating memory for lines"); + + /* JPEG decode config */ + esp_jpeg_image_cfg_t jpeg_cfg = { + .indata = (uint8_t *)s_avrc_cover_art_srv_cb.image_data, + .indata_size = s_avrc_cover_art_srv_cb.image_size, + .outbuf = (uint8_t*)(s_avrc_cover_art_srv_cb.pixels), + .outbuf_size = IMAGE_W * IMAGE_H * sizeof(uint16_t), + .out_format = JPEG_IMAGE_FORMAT_RGB565, + .out_scale = JPEG_IMAGE_SCALE_0, + .flags = { + .swap_color_bytes = 1, + } + }; + + /* JPEG decode */ + esp_jpeg_image_output_t outimg; + ret = esp_jpeg_decode(&jpeg_cfg, &outimg); + + ESP_LOGI(RC_CA_SRV_TAG, "JPEG image decoded! Size of the decoded image is: %dpx x %dpx.", outimg.width, outimg.height); + + return ret; +err: + /* Something went wrong! Exit cleanly, de-allocating everything we allocated. */ + avrc_cover_art_srv_free_pixels(); + return ret; +} + +static void avrc_cover_art_srv_display_image(void) +{ + if (s_avrc_cover_art_srv_cb.panel_handle && s_avrc_cover_art_srv_cb.pixels) { + esp_lcd_panel_draw_bitmap(s_avrc_cover_art_srv_cb.panel_handle, 0, 0, EXAMPLE_LCD_H_RES, EXAMPLE_LCD_V_RES, s_avrc_cover_art_srv_cb.pixels); + } +} + +/******************************** + * EXTERNAL FUNCTION DEFINITIONS + *******************************/ + +void avrc_cover_art_srv_open(void) +{ + memset(&s_avrc_cover_art_srv_cb, 0, sizeof(avrc_cover_art_srv_cb_t)); + /* initialize the display */ + avrc_cover_art_srv_init_display(); +} + +void avrc_cover_art_srv_close(void) +{ + /* deinitialize the display */ + avrc_cover_art_srv_deinit_display(); + + avrc_cover_art_srv_free_image_data(); + avrc_cover_art_srv_free_pixels(); + + memset(&s_avrc_cover_art_srv_cb, 0, sizeof(avrc_cover_art_srv_cb_t)); +} + +void avrc_cover_art_srv_connect(uint16_t mtu) +{ + if (!s_avrc_cover_art_srv_cb.connected) { + ESP_LOGW(RC_CA_SRV_TAG, "Start cover art connection..."); + /* start the cover art connection */ + esp_avrc_ct_cover_art_connect(mtu); + } +} + +void avrc_cover_art_srv_set_image_final(bool final) +{ + s_avrc_cover_art_srv_cb.image_final = final; + if (s_avrc_cover_art_srv_cb.image_final) { + ESP_LOGI(RC_CA_SRV_TAG, "Cover Art Client final data event, image size: %lu bytes", s_avrc_cover_art_srv_cb.image_size); + + /* decode and display the image */ + avrc_cover_art_srv_decode_image(); + /* display the image */ + avrc_cover_art_srv_display_image(); + /* set the getting state to false, we can get next image now */ + s_avrc_cover_art_srv_cb.getting = false; + } +} + +void avrc_cover_art_srv_set_connected(bool connected) +{ + s_avrc_cover_art_srv_cb.connected = connected; +} + +void avrc_cover_art_srv_ca_req(void) +{ + /* request cover art */ + if (s_avrc_cover_art_srv_cb.connected) { + uint8_t attr_mask = ESP_AVRC_MD_ATTR_COVER_ART; + + esp_avrc_ct_send_metadata_cmd(bt_avrc_common_alloc_tl(), attr_mask); + } +} + +void avrc_cover_art_srv_save_image_data(uint8_t *p_data, uint16_t data_len) +{ + s_avrc_cover_art_srv_cb.image_size += data_len; + + uint8_t *p_buf = (uint8_t *)realloc(s_avrc_cover_art_srv_cb.image_data, s_avrc_cover_art_srv_cb.image_size * sizeof(uint8_t)); + if (!p_buf) { + ESP_LOGE(RC_CA_SRV_TAG, "%s: The memory allocation of Cover art image data failed", __func__); + avrc_cover_art_srv_free_image_data(); + return; + } + s_avrc_cover_art_srv_cb.image_data = p_buf; + memcpy(s_avrc_cover_art_srv_cb.image_data + s_avrc_cover_art_srv_cb.image_size - data_len, p_data, data_len); +} + +void avrc_cover_art_srv_ct_metadata_update(uint8_t *image_handle, int len) +{ + if (s_avrc_cover_art_srv_cb.connected && !s_avrc_cover_art_srv_cb.getting) { + /* check image handle is valid and different with last one, we don't want to get an image repeatedly */ + if (avrc_cover_art_srv_image_handle_check(image_handle, len)) { + /* free the previous image data */ + avrc_cover_art_srv_free_image_data(); + /* get the linked thumbnail */ + esp_avrc_ct_cover_art_get_linked_thumbnail(image_handle); + s_avrc_cover_art_srv_cb.getting = true; + } + } +} diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_service.h b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_service.h new file mode 100644 index 0000000000..f92ca796ce --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_service.h @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __AVRCP_COVER_ART_SERVICE_H__ +#define __AVRCP_COVER_ART_SERVICE_H__ + +#include +#include "esp_avrc_api.h" +#include "esp_err.h" + +/** + * @brief open AVRCP cover art service + */ +void avrc_cover_art_srv_open(void); + +/** + * @brief close AVRCP cover art service + */ +void avrc_cover_art_srv_close(void); + +/** + * @brief start the cover art connection + * + * @param [in] mtu: maximum transmission unit + */ +void avrc_cover_art_srv_connect(uint16_t mtu); + +/** + * @brief set AVRCP cover art image final, and then if image final is true, display the image + * + * @param [in] final: true if image reception has been completed, false otherwise + */ +void avrc_cover_art_srv_set_image_final(bool final); + +/** + * @brief set AVRCP cover art connected + * + * @param [in] connected: true if connected, false otherwise + */ +void avrc_cover_art_srv_set_connected(bool connected); + +/** + * @brief request AVRCP cover art + */ +void avrc_cover_art_srv_ca_req(void); + +/** + * @brief save cover art data + * + * @param [in] p_data: pointer to the cover art data + * @param [in] data_len: length of the cover art data + */ +void avrc_cover_art_srv_save_image_data(uint8_t *p_data, uint16_t data_len); + +/** + * @brief handle the cover art update when metadata response + * + * @param [in] image_handle: pointer to the image handle + * @param [in] len: length of the image handle + */ +void avrc_cover_art_srv_ct_metadata_update(uint8_t *image_handle, int len); + +#endif /* __AVRCP_COVER_ART_SERVICE_H__ */ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_utils.c b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_utils.c new file mode 100644 index 0000000000..1d9eeefaf8 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_utils.c @@ -0,0 +1,91 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include +#include +#include "esp_log.h" +#include "esp_avrc_api.h" +#include "avrcp_utils_tags.h" +#include "avrcp_cover_art_service.h" + +void bt_avrc_ca_ct_evt_hdl(uint16_t event, void *param) +{ + ESP_LOGD(BT_RC_CT_TAG, "%s event: %d", __func__, event); + + esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(param); + + switch (event) { + /* when connection state changed, this event comes */ + case ESP_AVRC_CT_CONNECTION_STATE_EVT: { + if (rc->conn_stat.connected) { + /* open the cover art service */ + avrc_cover_art_srv_open(); + } else { + /* close the cover art service */ + avrc_cover_art_srv_close(); + } + break; + } + /* when metadata response, this event comes */ + case ESP_AVRC_CT_METADATA_RSP_EVT: { + ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text); + if (rc->meta_rsp.attr_id == ESP_AVRC_MD_ATTR_COVER_ART) { + avrc_cover_art_srv_ct_metadata_update(rc->meta_rsp.attr_text, rc->meta_rsp.attr_length); + } + break; + } + /* when notified, this event comes */ + case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: { + if (rc->change_ntf.event_id == ESP_AVRC_RN_TRACK_CHANGE) { + /* request the cover art */ + avrc_cover_art_srv_ca_req(); + } + break; + } + /* when feature of remote device indicated, this event comes */ + case ESP_AVRC_CT_REMOTE_FEATURES_EVT: { + ESP_LOGI(BT_RC_CT_TAG, "AVRC remote features %"PRIx32", TG features %x", rc->rmt_feats.feat_mask, rc->rmt_feats.tg_feat_flag); + if ((rc->rmt_feats.tg_feat_flag & ESP_AVRC_FEAT_FLAG_TG_COVER_ART)) { + ESP_LOGW(BT_RC_CT_TAG, "Peer support Cover Art feature"); + /* start the cover art connection */ + avrc_cover_art_srv_connect(ESP_AVRC_CA_MTU_MAX); + } + break; + } + /* when notification capability of peer device got, this event comes */ + case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: { + /* request the cover art */ + avrc_cover_art_srv_ca_req(); + break; + } + /* when the state of cover art changes, this event comes */ + case ESP_AVRC_CT_COVER_ART_STATE_EVT: { + if (rc->cover_art_state.state == ESP_AVRC_COVER_ART_CONNECTED) { + avrc_cover_art_srv_set_connected(true); + ESP_LOGW(BT_RC_CT_TAG, "Cover Art Client connected"); + /* request the cover art */ + avrc_cover_art_srv_ca_req(); + } else { + avrc_cover_art_srv_set_connected(false); + ESP_LOGW(BT_RC_CT_TAG, "Cover Art Client disconnected, reason:%d", rc->cover_art_state.reason); + } + break; + } + /* when obtaining the cover art image data, this event comes */ + case ESP_AVRC_CT_COVER_ART_DATA_EVT: { + /* when rc->cover_art_data.final is true, it means we have received the entire image */ + avrc_cover_art_srv_set_image_final(rc->cover_art_data.final); + break; + } + /* others */ + default: + ESP_LOGE(BT_RC_CT_TAG, "%s unhandled event: %d", __func__, event); + break; + } +} diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_utils.h b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_utils.h new file mode 100644 index 0000000000..88e9bcd747 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_utils.h @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __AVRCP_COVER_ART_UTILS_H__ +#define __AVRCP_COVER_ART_UTILS_H__ + +#include + +/** + * @brief handle function for AVRCP controller cover art event + * + * @param [in] event event id + * @param [in] param callback parameter + */ +void bt_avrc_ca_ct_evt_hdl(uint16_t event, void *param); + +#endif /* __AVRCP_COVER_ART_UTILS_H__*/ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/idf_component.yml b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/idf_component.yml new file mode 100644 index 0000000000..d5b8ca349a --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils/idf_component.yml @@ -0,0 +1,5 @@ +dependencies: + idf: ">=4.4" + esp_jpeg: ">=1.0.2" + avrcp_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils From 809327f5fdbe06807e29f8e28dce0d8102add4b0 Mon Sep 17 00:00:00 2001 From: yangfeng Date: Fri, 29 Aug 2025 16:00:22 +0800 Subject: [PATCH 026/226] refactor(examples/classic_bt): Add AVRCP cover art example with LCD display --- .../avrcp_ct_cover_art/CMakeLists.txt | 8 + .../classic_bt/avrcp_ct_cover_art/README.md | 121 ++++++++++ .../avrcp_ct_cover_art/main/CMakeLists.txt | 13 ++ .../avrcp_ct_cover_art/main/Kconfig.projbuild | 23 ++ .../avrcp_ct_cover_art/main/bt_app_av.c | 206 ++++++++++++++++++ .../avrcp_ct_cover_art/main/bt_app_av.h | 54 +++++ .../avrcp_ct_cover_art/main/idf_component.yml | 17 ++ .../classic_bt/avrcp_ct_cover_art/main/main.c | 133 +++++++++++ .../pytest_classic_bt_cover_art_test.py | 12 + .../avrcp_ct_cover_art/sdkconfig.defaults | 11 + 10 files changed, 598 insertions(+) create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/README.md create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/Kconfig.projbuild create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/bt_app_av.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/bt_app_av.h create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/idf_component.yml create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/main.c create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/pytest_classic_bt_cover_art_test.py create mode 100644 examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/sdkconfig.defaults diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/CMakeLists.txt new file mode 100644 index 0000000000..d09bd51b21 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/CMakeLists.txt @@ -0,0 +1,8 @@ +# 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) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(avrcp_ct_cover_art) diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/README.md b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/README.md new file mode 100644 index 0000000000..509db09502 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/README.md @@ -0,0 +1,121 @@ +| Supported Targets | ESP32 | +| ----------------- | ----- | + +AVRCP-CT-COVER-ART EXAMPLE +====================== + +This is an example demonstrating the API for implementing Audio/Video Remote Control Profile to get and display cover art image. + +## Required components + +- [bt_app_core_utils](../common/bt_app_core_utils) +- [bredr_app_common_utils](../common/bredr_app_common_utils) +- [a2dp_sink_common_utils](../common/a2dp_utils/a2dp_sink_common_utils) +- [a2dp_sink_int_codec_utils](../common/a2dp_utils/a2dp_sink_int_codec_utils) +- [a2dp_sink_ext_codec_utils](../common/a2dp_utils/a2dp_sink_ext_codec_utils) +- [avrcp_common_utils](../common/avrcp_utils/avrcp_common_utils) +- [avrcp_metadata_utils](../common/avrcp_utils/avrcp_metadata_utils) +- [avrcp_cover_art_utils](../common/avrcp_utils/avrcp_cover_art_utils) + +``` ++---------------------------------------------------+---------------------+ +| avrcp_cover_art_utils | | ++---------------------------------------------------+ | +| avrcp_metadata_utils | | ++---------------------------------------------------+ | +| avrcp_common_utils | | ++-------------------------+-------------------------+ bt_app_core_utils | +|a2dp_sink_int_codec_utils|a2dp_sink_ext_codec_utils| | ++-------------------------+-------------------------+ | +| a2dp_sink_common_utils | | ++---------------------------------------------------+ | +| bredr_app_common_utils | | ++---------------------------------------------------+---------------------+ +``` + +Detailed information can be viewed through the [../common/README.md](../common/README.md). + +## How to use this example + +### Hardware Required + +* An ESP32 development board +* A SPI-interfaced LCD +* A USB cable for power supply and programming + +### Hardware Connection + +The connection between ESP32 Board and the LCD is as follows: + +``` + ESP32 Board LCD Screen + +---------+ +---------------------------------+ + | | | | + | 3V3 +--------------+ VCC +----------------------+ | + | | | | | | + | GND +--------------+ GND | | | + | | | | | | + | DATA0 +--------------+ MOSI | | | + | | | | | | + | PCLK +--------------+ SCK | | | + | | | | | | + | CS +--------------+ CS | | | + | | | | | | + | D/C +--------------+ D/C | | | + | | | | | | + | RST +--------------+ RST | | | + | | | | | | + |BK_LIGHT +--------------+ BCKL +----------------------+ | + | | | | + +---------+ +---------------------------------+ +``` + +The GPIO number used by this example can be changed in [avrcp_cover_art_service.c](../common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_service.c), where: + +| GPIO number | LCD pin | +| ------------------------ | ------- | +| EXAMPLE_PIN_NUM_PCLK | SCK | +| EXAMPLE_PIN_NUM_CS | CS | +| EXAMPLE_PIN_NUM_DC | DC | +| EXAMPLE_PIN_NUM_RST | RST | +| EXAMPLE_PIN_NUM_DATA0 | MOSI | +| EXAMPLE_PIN_NUM_BK_LIGHT | BCKL | + +Note that the level used to turn on the LCD backlight may vary: some LCD modules need a low level to turn it on, while others require a high level. You can change the backlight level macro `EXAMPLE_LCD_BK_LIGHT_ON_LEVEL` in [avrcp_cover_art_service.c](../common/avrcp_utils/avrcp_cover_art_utils/avrcp_cover_art_service.c). + +### Configure the project + +``` +idf.py menuconfig +``` + +* The AVRCP CT Cover Art feature is enabled by default. We can disable it by unselecting the menuconfig option `Component config --> Bluetooth --> Bluedroid Options --> Classic Bluetooth --> AVRCP Features --> AVRCP CT Cover Art`. This example will try to use the AVRCP CT Cover Art feature to get the cover art image, count the image size, and display it if the peer device supports it. +* **Memory Configuration**: To ensure that the A2DP sink stream and the display of AVRCP cover art on the LCD can run simultaneously, the following configurations are required and have been set in `sdkconfig.defaults`: + * `CONFIG_SPIRAM=y`: Enables external SPI RAM (PSRAM) support. This provides additional memory space needed for buffering audio data during A2DP streaming while simultaneously handling cover art image decoding and display operations. Without this, the application may run out of internal RAM when processing both audio streams and image data. + * `CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y`: Selects the single large app partition table scheme, which allocates more space for the application binary. This is necessary because the example application includes multiple Bluetooth profiles (A2DP, AVRCP), image decoding libraries, and LCD display drivers, requiring a larger application partition than the default partition table provides. + +### 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 +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +## Example Output + +The output when receiving a cover art image: + +``` +I (31579) RC_CT: AVRC metadata rsp: attribute id 0x80, 1000526 +I (32039) RC_CA_SRV: Cover Art Client final data event, image size: 12315 bytes +I (32119) RC_CA_SRV: JPEG image decoded! Size of the decoded image is: 200px x 200px. +``` + +And then, the LCD screen will display the cover art image. + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/CMakeLists.txt b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/CMakeLists.txt new file mode 100644 index 0000000000..6cb6aebf26 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/CMakeLists.txt @@ -0,0 +1,13 @@ +if(CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE) + if(CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC) + set(EXTRA_COMPONENTS a2dp_sink_ext_codec_utils) + else() + set(EXTRA_COMPONENTS a2dp_sink_int_codec_utils) + endif() +endif() + +idf_component_register(SRCS "bt_app_av.c" + "main.c" + PRIV_REQUIRES bt bt_app_core_utils bredr_app_common_utils a2dp_sink_common_utils + PRIV_REQUIRES ${EXTRA_COMPONENTS} avrcp_common_utils avrcp_metadata_utils avrcp_cover_art_utils + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/Kconfig.projbuild new file mode 100644 index 0000000000..2a4dfc0176 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/Kconfig.projbuild @@ -0,0 +1,23 @@ +menu "AVRCP Example Configuration" + config EXAMPLE_LOCAL_DEVICE_NAME + string "Local Device Name" + default "ESP_SPEAKER" + help + Use this option to set local device name. + + config EXAMPLE_A2DP_SINK_STREAM_ENABLE + bool "Enable A2DP Sink Stream" + default y + help + This enables the A2DP sink stream. If disable this option, + audio data will not be transmitted + + config EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC + bool "Use External Codec Instead of Internal" + depends on EXAMPLE_A2DP_SINK_STREAM_ENABLE + default n + select BT_A2DP_USE_EXTERNAL_CODEC + help + If enable, Bluedroid stack will not decode A2DP audio data, user need to decode it in application layer. + +endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/bt_app_av.c b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/bt_app_av.c new file mode 100644 index 0000000000..6683dc9306 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/bt_app_av.c @@ -0,0 +1,206 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include +#include + +#include "esp_log.h" +#include "esp_bt_device.h" +#include "esp_gap_bt_api.h" +#include "esp_avrc_api.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "bt_app_core_utils.h" +#include "bt_app_av.h" +#include "avrcp_utils_tags.h" +#include "avrcp_common_utils.h" +#include "avrcp_metadata_service.h" +#include "avrcp_metadata_utils.h" +#include "a2dp_utils_tags.h" +#include "a2dp_sink_common_utils.h" +#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE +#include "a2dp_sink_int_codec_utils.h" +#else +#include "a2dp_sink_ext_codec_utils.h" +#endif +#endif +#include "avrcp_cover_art_service.h" +#include "avrcp_cover_art_utils.h" + +/******************************** + * STATIC FUNCTION DEFINITIONS + *******************************/ + +static void bt_app_avrc_ct_evt_hdl(uint16_t event, void *param) +{ + ESP_LOGD(BT_RC_CT_TAG, "%s event: %d", __func__, event); + + esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)(param); + + switch (event) { + case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: + case ESP_AVRC_CT_PROF_STATE_EVT: { + bt_avrc_common_ct_evt_def_hdl(event, param); + break; + } + case ESP_AVRC_CT_CONNECTION_STATE_EVT: { + bt_avrc_md_ct_evt_hdl(event, param); + bt_avrc_ca_ct_evt_hdl(event, param); + if (rc->conn_stat.connected) { + /* get remote supported event_ids of peer AVRCP Target */ + bt_avrc_common_ct_get_peer_rn_cap(); + } else { + /* clear peer notification capability record */ + bt_avrc_common_ct_set_peer_rn_cap(0); + } + break; + } + case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: { + bt_avrc_md_ct_evt_hdl(event, param); + bt_avrc_ca_ct_evt_hdl(event, param); + bt_avrc_common_ct_notify_evt_handler(rc->change_ntf.event_id, &rc->change_ntf.event_parameter); + break; + } + case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: { + /* set peer notification capability record */ + bt_avrc_common_ct_set_peer_rn_cap(rc->get_rn_caps_rsp.evt_set.bits); + bt_avrc_common_ct_rn_track_changed(); + bt_avrc_common_ct_rn_play_status_changed(); + bt_avrc_common_ct_rn_play_pos_changed(); + + bt_avrc_md_ct_evt_hdl(event, param); + bt_avrc_ca_ct_evt_hdl(event, param); + break; + } + case ESP_AVRC_CT_METADATA_RSP_EVT: { + if (rc->meta_rsp.attr_id == ESP_AVRC_MD_ATTR_COVER_ART) { + bt_avrc_ca_ct_evt_hdl(event, param); + } else { + bt_avrc_md_ct_evt_hdl(event, param); + } + break; + } + case ESP_AVRC_CT_REMOTE_FEATURES_EVT: { + bt_avrc_ca_ct_evt_hdl(event, param); + break; + } + case ESP_AVRC_CT_COVER_ART_STATE_EVT: + case ESP_AVRC_CT_COVER_ART_DATA_EVT: { + bt_avrc_ca_ct_evt_hdl(event, param); + break; + } + default: + ESP_LOGE(BT_RC_CT_TAG, "Invalid AVRC event: %d", event); + break; + } +} + +/******************************** + * EXTERNAL FUNCTION DEFINITIONS + *******************************/ + +void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) +{ + switch (event) { + case ESP_A2D_PROF_STATE_EVT: + case ESP_A2D_SNK_PSC_CFG_EVT: + case ESP_A2D_SNK_SET_DELAY_VALUE_EVT: + case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: { + bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); + break; + } + case ESP_A2D_CONNECTION_STATE_EVT: + case ESP_A2D_AUDIO_STATE_EVT: + case ESP_A2D_AUDIO_CFG_EVT: + case ESP_A2D_SEP_REG_STATE_EVT: { +#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE + bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); +#else + bt_app_work_dispatch(bt_a2d_evt_ext_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); +#endif +#else + bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL); +#endif + break; + } + default: + ESP_LOGE(BT_AV_TAG, "Invalid A2DP event: %d", event); + break; + } +} + +#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE +void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len) +{ + bt_a2d_data_hdl(data, len); +} +#else +void bt_app_a2d_audio_data_cb(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf) +{ + bt_a2d_audio_data_hdl(conn_hdl, audio_buf); +} +#endif +#endif + +void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param) +{ + switch (event) { + case ESP_AVRC_CT_METADATA_RSP_EVT: { + bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), bt_avrc_common_copy_metadata); + break; + } + case ESP_AVRC_CT_COVER_ART_DATA_EVT: { + /* we must handle ESP_AVRC_CT_COVER_ART_DATA_EVT in avrcp controller callback, */ + /* copy image data to other buff before return if need */ + if (param->cover_art_data.status == ESP_BT_STATUS_SUCCESS) { + avrc_cover_art_srv_save_image_data(param->cover_art_data.p_data, param->cover_art_data.data_len); + } else { + ESP_LOGE(BT_RC_CT_TAG, "Cover Art Client get operation failed"); + break; + } + bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL); + break; + } + case ESP_AVRC_CT_CONNECTION_STATE_EVT: + case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: + case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: + case ESP_AVRC_CT_REMOTE_FEATURES_EVT: + case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: + case ESP_AVRC_CT_COVER_ART_STATE_EVT: + case ESP_AVRC_CT_PROF_STATE_EVT: + bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL); + break; + default: + ESP_LOGE(BT_RC_CT_TAG, "Invalid AVRC event: %d", event); + break; + } +} + +void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param) +{ + switch (event) { + case ESP_AVRC_TG_CONNECTION_STATE_EVT: + case ESP_AVRC_TG_REMOTE_FEATURES_EVT: + case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT: + case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: + case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: + case ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT: + case ESP_AVRC_TG_PROF_STATE_EVT: + bt_app_work_dispatch(bt_avrc_common_tg_evt_def_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL); + break; + default: + ESP_LOGE(BT_RC_TG_TAG, "Invalid AVRC event: %d", event); + break; + } +} diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/bt_app_av.h b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/bt_app_av.h new file mode 100644 index 0000000000..5669ad6fca --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/bt_app_av.h @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __BT_APP_AV_H__ +#define __BT_APP_AV_H__ + +#include +#include "esp_a2dp_api.h" +#include "esp_avrc_api.h" + +/** + * @brief callback function for A2DP sink + * + * @param [in] event event id + * @param [in] param callback parameter + */ +void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param); + +/** + * @brief callback function for A2DP sink audio data stream + * + * @param [out] data data stream writteen by application task + * @param [in] len length of data stream in byte + */ +void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len); + +/** + * @brief callback function for A2DP sink undecoded audio data + * + * @param [in] conn_hdl connection handle + * @param [in] audio_buf pointer to audio buff + */ +void bt_app_a2d_audio_data_cb(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_buff_t *audio_buf); + +/** + * @brief callback function for AVRCP controller + * + * @param [in] event event id + * @param [in] param callback parameter + */ +void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param); + +/** + * @brief callback function for AVRCP target + * + * @param [in] event event id + * @param [in] param callback parameter + */ +void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param); + +#endif /* __BT_APP_AV_H__*/ diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/idf_component.yml b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/idf_component.yml new file mode 100644 index 0000000000..39b2c44fae --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/idf_component.yml @@ -0,0 +1,17 @@ +dependencies: + bt_app_core_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/bt_app_core_utils + bredr_app_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/bredr_app_common_utils + a2dp_sink_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_common_utils + a2dp_sink_int_codec_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils + a2dp_sink_ext_codec_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_ext_codec_utils + avrcp_common_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_common_utils + avrcp_metadata_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_metadata_utils + avrcp_cover_art_utils: + path: ${IDF_PATH}/examples/bluetooth/bluedroid/classic_bt/common/avrcp_utils/avrcp_cover_art_utils diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/main.c b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/main.c new file mode 100644 index 0000000000..f2d6d91108 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/main.c @@ -0,0 +1,133 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include + +#include "esp_log.h" +#include "esp_bt_device.h" +#include "esp_gap_bt_api.h" +#include "esp_a2dp_api.h" +#include "esp_avrc_api.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "bt_app_av.h" +#include "bt_app_core_utils.h" +#include "bredr_app_common_utils.h" +#include "a2dp_utils_tags.h" + +/* device name */ +static const char local_device_name[] = CONFIG_EXAMPLE_LOCAL_DEVICE_NAME; + +/* event for stack up */ +enum { + BT_APP_EVT_STACK_UP = 0, +}; + +/******************************** + * STATIC FUNCTION DECLARATIONS + *******************************/ + +/* Device callback function */ +static void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param); + +/* GAP callback function */ +static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param); + +/* handler for bluetooth stack enabled events */ +static void bt_av_hdl_stack_evt(uint16_t event, void *p_param); + +/******************************* + * STATIC FUNCTION DEFINITIONS + ******************************/ + +static void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param) +{ + bredr_app_dev_evt_def_hdl(event, param); +} + +static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) +{ + bredr_app_gap_evt_def_hdl(event, param); +} + +static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) +{ + ESP_LOGD(BT_AV_TAG, "%s event: %d", __func__, event); + + switch (event) { + /* when do the stack up, this event comes */ + case BT_APP_EVT_STACK_UP: { + esp_bt_gap_set_device_name(local_device_name); + esp_bt_dev_register_callback(bt_app_dev_cb); + esp_bt_gap_register_callback(bt_app_gap_cb); + + esp_avrc_ct_register_callback(bt_app_rc_ct_cb); + assert(esp_avrc_ct_init() == ESP_OK); + esp_avrc_tg_register_callback(bt_app_rc_tg_cb); + assert(esp_avrc_tg_init() == ESP_OK); + + esp_a2d_register_callback(&bt_app_a2d_cb); + assert(esp_a2d_sink_init() == ESP_OK); + +#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE +#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE + esp_a2d_sink_register_data_callback(bt_app_a2d_data_cb); +#else + esp_a2d_mcc_t mcc = {0}; + mcc.type = ESP_A2D_MCT_SBC; + mcc.cie.sbc_info.samp_freq = ESP_A2D_SBC_CIE_SF_16K | + ESP_A2D_SBC_CIE_SF_32K | + ESP_A2D_SBC_CIE_SF_44K | + ESP_A2D_SBC_CIE_SF_48K; + mcc.cie.sbc_info.ch_mode = ESP_A2D_SBC_CIE_CH_MODE_MONO | + ESP_A2D_SBC_CIE_CH_MODE_DUAL_CHANNEL | + ESP_A2D_SBC_CIE_CH_MODE_STEREO | + ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO; + mcc.cie.sbc_info.block_len = ESP_A2D_SBC_CIE_BLOCK_LEN_4 | + ESP_A2D_SBC_CIE_BLOCK_LEN_8 | + ESP_A2D_SBC_CIE_BLOCK_LEN_12 | + ESP_A2D_SBC_CIE_BLOCK_LEN_16; + mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8; + mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SRN | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS; + mcc.cie.sbc_info.max_bitpool = 250; + mcc.cie.sbc_info.min_bitpool = 2; + /* register stream end point, only support SBC currently */ + esp_a2d_sink_register_stream_endpoint(0, &mcc); + esp_a2d_sink_register_audio_data_callback(bt_app_a2d_audio_data_cb); +#endif +#endif + + /* Get the default value of the delay value */ + esp_a2d_sink_get_delay_value(); + /* Get local device name */ + esp_bt_gap_get_device_name(); + + /* set discoverable and connectable mode, wait to be connected */ + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + break; + } + /* others */ + default: + ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event); + break; + } +} + +/******************************* + * MAIN ENTRY POINT + ******************************/ + +void app_main(void) +{ + ESP_ERROR_CHECK(bredr_app_common_init()); + + bt_app_task_start_up(); + /* bluetooth device name, connection mode and profile set up */ + bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL); +} diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/pytest_classic_bt_cover_art_test.py b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/pytest_classic_bt_cover_art_test.py new file mode 100644 index 0000000000..8e141cafac --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/pytest_classic_bt_cover_art_test.py @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 +import pytest +from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize + + +@pytest.mark.generic +@idf_parametrize('target', ['esp32'], indirect=['target']) +def test_bt_avrcp_cover_art(dut: Dut) -> None: + dut.expect(r'AVRCP (CT|TG) STATE: Init Complete', timeout=30) + dut.expect(r'AVRCP (CT|TG) STATE: Init Complete', timeout=30) diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/sdkconfig.defaults new file mode 100644 index 0000000000..cde91dde57 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/sdkconfig.defaults @@ -0,0 +1,11 @@ +# Override some defaults so BT stack is enabled and +# Classic BT is enabled and BT_DRAM_RELEASE is disabled +CONFIG_BT_ENABLED=y +CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y +CONFIG_BT_BLUEDROID_ENABLED=y +CONFIG_BT_CLASSIC_ENABLED=y +CONFIG_BT_A2DP_ENABLE=y +CONFIG_BT_AVRCP_CT_COVER_ART_ENABLED=y +CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=n +CONFIG_SPIRAM=y +CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y From 167f52d1ad6228e52240d7b1ecafb187ebbb1f99 Mon Sep 17 00:00:00 2001 From: yangfeng Date: Sat, 11 Oct 2025 11:11:49 +0800 Subject: [PATCH 027/226] docs: Add explanations for the A2DP sink stream and AVRCP examples - Modify the path of A2DP sink example --- docs/en/api-reference/bluetooth/esp_a2dp.rst | 2 +- docs/en/api-reference/bluetooth/esp_avrc.rst | 9 +++++++++ .../bluetooth/bluedroid/classic_bt/a2dp_source/README.md | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/en/api-reference/bluetooth/esp_a2dp.rst b/docs/en/api-reference/bluetooth/esp_a2dp.rst index efed7e5e58..c3ecdc2c31 100644 --- a/docs/en/api-reference/bluetooth/esp_a2dp.rst +++ b/docs/en/api-reference/bluetooth/esp_a2dp.rst @@ -4,7 +4,7 @@ Bluetooth® A2DP API Application Examples -------------------- -- :example:`bluetooth/bluedroid/classic_bt/a2dp_sink` demonstrates how to implement an audio sink device using the Advanced Audio Distribution Profile (A2DP) to receive audio streams. This example also shows how to use AVRCP for media information notifications and I2S for audio stream output. +- :example:`bluetooth/bluedroid/classic_bt/a2dp_sink_stream` demonstrates how to implement an audio sink device using the Advanced Audio Distribution Profile (A2DP) to receive audio streams. This example also shows how to use I2S for audio stream output. - :example:`bluetooth/bluedroid/classic_bt/a2dp_source` demonstrates how to use A2DP APIs to transmit audio streams. diff --git a/docs/en/api-reference/bluetooth/esp_avrc.rst b/docs/en/api-reference/bluetooth/esp_avrc.rst index 10ad910382..9a4af36091 100644 --- a/docs/en/api-reference/bluetooth/esp_avrc.rst +++ b/docs/en/api-reference/bluetooth/esp_avrc.rst @@ -6,6 +6,15 @@ Overview Bluetooth AVRCP reference APIs. +Application Examples +-------------------- + +- :example:`bluetooth/bluedroid/classic_bt/avrcp_absolute_volume` demonstrates how to implement Audio/Video Remote Control Profile to control absolute volume. + +- :example:`bluetooth/bluedroid/classic_bt/avrcp_ct_metadata` demonstrates how to implement Audio/Video Remote Control Profile to get metadata. + +- :example:`bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art` demonstrates how to implement Audio/Video Remote Control Profile to get and display cover art image. + API Reference ------------- diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/README.md b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/README.md index ed7db5d1bc..5d095f6c88 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/README.md +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/README.md @@ -12,7 +12,7 @@ This is the example of using Advanced Audio Distribution Profile (A2DP) APIs to ### Hardware Required -This example is able to run on any commonly available ESP32 development board, and is supposed to connect to [A2DP sink example](../a2dp_sink) in ESP-IDF. +This example is able to run on any commonly available ESP32 development board, and is supposed to connect to [A2DP sink example](../a2dp_sink_stream) in ESP-IDF. ### Configure the project From 59cd911a83897796599c5a5e09b67a5ee36906b5 Mon Sep 17 00:00:00 2001 From: yangfeng Date: Mon, 1 Sep 2025 19:49:51 +0800 Subject: [PATCH 028/226] refactor(examples/classic_bt): Add example tests for A2DP and AVRCP examples --- examples/bluetooth/.build-test-rules.yml | 3 + .../classic_bt/pytest_classic_bt_test.py | 87 ++++++++++++------- 2 files changed, 60 insertions(+), 30 deletions(-) diff --git a/examples/bluetooth/.build-test-rules.yml b/examples/bluetooth/.build-test-rules.yml index 69caebef10..d0e2fdb7fe 100644 --- a/examples/bluetooth/.build-test-rules.yml +++ b/examples/bluetooth/.build-test-rules.yml @@ -63,6 +63,7 @@ examples/bluetooth/bluedroid/classic_bt: disable: - if: SOC_BT_CLASSIC_SUPPORTED != 1 depends_components+: + - esp_lcd - esp_console - esp_driver_gpio - esp_driver_i2s @@ -73,6 +74,8 @@ examples/bluetooth/bluedroid/classic_bt: - components/driver/dac/**/* - examples/bluetooth/bluedroid/esp_hid_host/**/* - examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py + - examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/pytest_classic_bt_cover_art_test.py + - examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/pytest_classic_bt_metadata_test.py - examples/bluetooth/bluedroid/classic_bt/bt_discovery/pytest_classic_bt_discovery_test.py examples/bluetooth/bluedroid/coex/a2dp_gatts_coex: diff --git a/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py b/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py index 3190035c38..acd55d9f75 100644 --- a/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py +++ b/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py @@ -72,34 +72,7 @@ def test_bt_spp_vfs(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: acceptor.expect_exact('ESP_SPP_SRV_OPEN_EVT status:0', timeout=30) -# Case 3: A2DP -@pytest.mark.two_duts -@pytest.mark.parametrize( - 'count, app_path, target, config', - [ - ( - 2, - f'{os.path.join(os.path.dirname(__file__), "a2dp_sink")}|' - f'{os.path.join(os.path.dirname(__file__), "a2dp_source")}', - 'esp32|esp32', - 'test', - ), - ], - indirect=True, -) -def test_bt_a2dp(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: - sink_dut = dut[0] - source_dut = dut[1] - source_dut_mac = source_dut.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') - sink_dut.expect_exact('A2DP PROF STATE: Init Complete', timeout=30) - source_dut.expect_exact('a2dp connecting to peer', timeout=30) - source_dut.expect_exact('a2dp connected', timeout=30) - source_dut.expect_exact('a2dp media start successfully', timeout=30) - sink_dut.expect_exact(f'A2DP connection state: Connected, [{source_dut_mac}]', timeout=30) - sink_dut.expect_exact('start volume change simulation', timeout=30) - - -# Case 4: HFP +# Case 3: HFP @pytest.mark.two_duts @pytest.mark.parametrize( 'count, app_path, target, config', @@ -124,7 +97,7 @@ def test_bt_hfp(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: hfp_ag.expect_exact('connection state SLC_CONNECTED', timeout=30) -# # Case 5: HID +# # Case 4: HID @pytest.mark.two_duts @pytest.mark.parametrize( 'count, app_path, target, config', @@ -153,7 +126,7 @@ def test_bt_hid(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: hid_host.expect_exact(f'ESP_HIDH_DEMO: {hid_device_mac} OPEN', timeout=30) -# Case 6: L2CAP +# Case 5: L2CAP @pytest.mark.two_duts @pytest.mark.parametrize( 'count, app_path, target, config', @@ -182,3 +155,57 @@ def test_bt_l2cap(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: client.expect_exact('ESP_SDP_SEARCH_COMP_EVT: status:0', timeout=30) client.expect_exact('ESP_BT_L2CAP_OPEN_EVT: status:0', timeout=30) server.expect_exact('ESP_BT_L2CAP_OPEN_EVT: status:0', timeout=30) + + +# case 6: A2DP Stream +@pytest.mark.two_duts +@pytest.mark.parametrize( + 'count, app_path, target, config', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "a2dp_sink_stream")}|' + f'{os.path.join(os.path.dirname(__file__), "a2dp_source")}', + 'esp32|esp32', + 'test', + ), + ], + indirect=True, +) +def test_bt_a2dp_stream(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: + sink_dut = dut[0] + source_dut = dut[1] + source_dut_mac = source_dut.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') + sink_dut.expect_exact('A2DP PROF STATE: Init Complete', timeout=30) + source_dut.expect_exact('a2dp connecting to peer', timeout=30) + source_dut.expect_exact('a2dp connected', timeout=30) + source_dut.expect_exact('a2dp media start successfully', timeout=30) + sink_dut.expect_exact(f'A2DP connection state: Connected, [{source_dut_mac}]', timeout=30) + + +# case 7: AVRCP absolute volume +@pytest.mark.two_duts +@pytest.mark.parametrize( + 'count, app_path, target, config', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "avrcp_absolute_volume")}|' + f'{os.path.join(os.path.dirname(__file__), "a2dp_source")}', + 'esp32|esp32', + 'test', + ), + ], + indirect=True, +) +def test_bt_avrcp_absolute_volume(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: + sink_dut = dut[0] + source_dut = dut[1] + source_dut_mac = source_dut.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') + sink_dut.expect_exact('AVRCP CT STATE: Init Complete', timeout=30) + sink_dut.expect_exact('AVRCP TG STATE: Init Complete', timeout=30) + source_dut.expect_exact('a2dp connecting to peer', timeout=30) + source_dut.expect_exact('a2dp connected', timeout=30) + sink_dut.expect_exact(f'AVRC conn_state event: state 1, [{source_dut_mac}]', timeout=30) + sink_dut.expect_exact(f'AVRC conn_state evt: state 1, [{source_dut_mac}]', timeout=30) + sink_dut.expect_exact('start volume change simulation', timeout=30) From a2ca229d2a0cf3f3aad5771e61c05ebf14c40825 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 20 Nov 2025 10:47:42 +0800 Subject: [PATCH 029/226] change(esp_hw_support): add kconfig option to put rtc clock module into iram --- components/esp_hw_support/Kconfig | 6 ++++++ components/esp_hw_support/linker.lf | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index d10007399d..241415ecc0 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -219,6 +219,12 @@ menu "Hardware Settings" menu "RTC Clock Config" orsource "./port/$IDF_TARGET/Kconfig.rtc" + + config RTC_CLK_FUNC_IN_IRAM + bool "Place RTC clock module functions into IRAM" + default y + help + Place RTC clock module (all rtc clock functions and const data) into IRAM. endmenu menu "Peripheral Control" diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index 48fb35f098..f19df19e5d 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -14,9 +14,10 @@ entries: esp_memory_utils (noflash) clk_utils (noflash) if PM_SLP_IRAM_OPT = y: - rtc_clk (noflash) rtc_time (noflash_text) esp_clk_tree: esp_clk_tree_enable_src (noflash) + if RTC_CLK_FUNC_IN_IRAM = y: + rtc_clk (noflash) if IDF_TARGET_ESP32 = y: rtc_clk:rtc_clk_cpu_freq_to_pll_mhz (noflash) rtc_clk:rtc_clk_cpu_freq_to_xtal (noflash) From 2efc896aec79661bd5419fa9967d5cd5ad8dac1d Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 20 Nov 2025 10:51:34 +0800 Subject: [PATCH 030/226] change(esp_hw_support): add kconfig option to put rtc time module into iram --- components/esp_hw_support/Kconfig | 6 ++++++ components/esp_hw_support/linker.lf | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index 241415ecc0..a2d5fcc245 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -225,6 +225,12 @@ menu "Hardware Settings" default y help Place RTC clock module (all rtc clock functions and const data) into IRAM. + + config RTC_TIME_FUNC_IN_IRAM + bool "Place RTC time module functions into IRAM" + default y + help + Place RTC time module (all rtc clock functions) into IRAM. endmenu menu "Peripheral Control" diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index f19df19e5d..676f475450 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -14,13 +14,14 @@ entries: esp_memory_utils (noflash) clk_utils (noflash) if PM_SLP_IRAM_OPT = y: - rtc_time (noflash_text) esp_clk_tree: esp_clk_tree_enable_src (noflash) if RTC_CLK_FUNC_IN_IRAM = y: rtc_clk (noflash) if IDF_TARGET_ESP32 = y: rtc_clk:rtc_clk_cpu_freq_to_pll_mhz (noflash) rtc_clk:rtc_clk_cpu_freq_to_xtal (noflash) + if RTC_TIME_FUNC_IN_IRAM = y: + rtc_time (noflash_text) if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED = y: rtc_init:rtc_vddsdio_get_config (noflash) rtc_init:rtc_vddsdio_set_config (noflash) From 72895e7b718b100b87141b5d5bb5c921ae98cfba Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 20 Nov 2025 11:00:42 +0800 Subject: [PATCH 031/226] change(esp_hw_support): modify the default value of the kconfig option for place peripheral control module into iram to y --- components/esp_hw_support/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index a2d5fcc245..24c349b768 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -236,7 +236,7 @@ menu "Hardware Settings" menu "Peripheral Control" config ESP_PERIPH_CTRL_FUNC_IN_IRAM bool "Place peripheral control functions into IRAM" - default n + default y help Place peripheral control functions (e.g. periph_module_reset) into IRAM, so that these functions can be IRAM-safe and able to be called in the other IRAM interrupt context. From 613f0051f263684627ccd952974317a9ca170bea Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 20 Nov 2025 11:08:37 +0800 Subject: [PATCH 032/226] change(esp_pm): add dependencies on the rtc clock and rtc_time modules for power managment module --- components/esp_pm/Kconfig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/esp_pm/Kconfig b/components/esp_pm/Kconfig index ca843fff48..6986cccff5 100644 --- a/components/esp_pm/Kconfig +++ b/components/esp_pm/Kconfig @@ -1,12 +1,14 @@ menu "Power Management" config PM_SLEEP_FUNC_IN_IRAM - bool "Place Power Management module functions in IRAM" if IDF_TARGET_ESP32C2 - default y + bool "Place Power Management module functions in IRAM" + default n select PM_SLP_IRAM_OPT if SOC_LIGHT_SLEEP_SUPPORTED select PM_RTOS_IDLE_OPT if FREERTOS_USE_TICKLESS_IDLE select ESP_PERIPH_CTRL_FUNC_IN_IRAM select ESP_REGI2C_CTRL_FUNC_IN_IRAM + select RTC_CLK_FUNC_IN_IRAM + select RTC_TIME_FUNC_IN_IRAM config PM_ENABLE From d80819f6d713f0511fb32efe0a4c57a36c148c16 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 20 Nov 2025 11:23:14 +0800 Subject: [PATCH 033/226] change(esp_pm): add an option associated with flash auto suspend and make it dependent on the hardware support modules --- components/esp_hw_support/Kconfig | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index 24c349b768..efaf9a418a 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -1,5 +1,14 @@ menu "Hardware Settings" + config ESP_HW_SUPPORT_FUNC_IN_IRAM + bool + default n if SPI_FLASH_AUTO_SUSPEND + default y + select ESP_PERIPH_CTRL_FUNC_IN_IRAM + select ESP_REGI2C_CTRL_FUNC_IN_IRAM + select RTC_CLK_FUNC_IN_IRAM + select RTC_TIME_FUNC_IN_IRAM + menu "Chip revision" # Insert chip-specific HW config orsource "./port/$IDF_TARGET/Kconfig.hw_support" From 9ed3a7a49abacb5d58593c2241d152fcab8c715b Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 20 Nov 2025 11:59:28 +0800 Subject: [PATCH 034/226] change(tools): disable place rtc clock and rtc time modules into iram for flash auto suspend test --- .../configs/sdkconfig.flash_auto_suspend_iram_reduction | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/test_apps/configs/sdkconfig.flash_auto_suspend_iram_reduction b/tools/test_apps/configs/sdkconfig.flash_auto_suspend_iram_reduction index 0e1236fa14..09019098d4 100644 --- a/tools/test_apps/configs/sdkconfig.flash_auto_suspend_iram_reduction +++ b/tools/test_apps/configs/sdkconfig.flash_auto_suspend_iram_reduction @@ -72,6 +72,8 @@ CONFIG_ESP_REGI2C_CTRL_FUNC_IN_IRAM=n # System common CONFIG_ESP_PERIPH_CTRL_FUNC_IN_IRAM=n +CONFIG_RTC_CLK_FUNC_IN_IRAM=n +CONFIG_RTC_TIME_FUNC_IN_IRAM=n # Phy related options CONFIG_ESP_PHY_IRAM_OPT=n From c2de93eca926dd75a91e9f19e31dedeaf8d7e475 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Fri, 21 Nov 2025 15:31:25 +0800 Subject: [PATCH 035/226] change(example): sleep iram optimization support for esp_timer demo --- examples/system/esp_timer/main/esp_timer_example_main.c | 1 - examples/system/esp_timer/sdkconfig.defaults | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/system/esp_timer/main/esp_timer_example_main.c b/examples/system/esp_timer/main/esp_timer_example_main.c index 54183cb8a3..30da583018 100644 --- a/examples/system/esp_timer/main/esp_timer_example_main.c +++ b/examples/system/esp_timer/main/esp_timer_example_main.c @@ -71,7 +71,6 @@ void app_main(void) int64_t t2 = esp_timer_get_time(); ESP_LOGI(TAG, "Woke up from light sleep, time since boot: %lld us", t2); - // TODO: PM-232 assert(((t2 - t1 - 500000) < 1000) && ((t2 - t1 - 500000) > -2000)); #endif diff --git a/examples/system/esp_timer/sdkconfig.defaults b/examples/system/esp_timer/sdkconfig.defaults index c4a1e55cf8..3c7b19a00f 100644 --- a/examples/system/esp_timer/sdkconfig.defaults +++ b/examples/system/esp_timer/sdkconfig.defaults @@ -4,3 +4,6 @@ CONFIG_ESP_TIMER_PROFILING=y # NEWLIB_NANO_FORMAT is enabled by default on ESP32-C2 # This example needs 64-bit integer formatting, this is why this option is disabled CONFIG_NEWLIB_NANO_FORMAT=n + +# Put sleep related source code in IRAM +CONFIG_PM_SLP_IRAM_OPT=y From ea6b0ff2da51198dea50a6dfd3bbdfea7095901a Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Mon, 24 Nov 2025 17:49:32 +0800 Subject: [PATCH 036/226] fix(esp_hw_support): fix the esp32h2 sleep TG0 watchdog reset issue caused by power down the top domain --- components/esp_hw_support/sleep_modes.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index b7f54b6e1e..f7c21485ab 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -948,6 +948,9 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint #if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD esp_sleep_mmu_retention(false); #endif +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA + sleep_retention_do_system_retention(false); +#endif #if CONFIG_IDF_TARGET_ESP32P4 && (CONFIG_ESP_REV_MIN_FULL == 300) sleep_flash_p4_rev3_workaround(); sleep_retention_do_extra_retention(false); @@ -1176,11 +1179,6 @@ static esp_err_t SLEEP_FN_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t cl cache_ll_invalidate_all(CACHE_LL_LEVEL_ALL, CACHE_TYPE_ALL, CACHE_LL_ID_ALL); #endif s_config.ccount_ticks_record = esp_cpu_get_cycle_count(); -#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA - if (sleep_flags & PMU_SLEEP_PD_TOP) { - sleep_retention_do_system_retention(false); - } -#endif } misc_modules_wake_prepare(sleep_flags); } From bb5e96f5968c0beff415b238dfbce9fc497d4429 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Tue, 25 Nov 2025 12:13:16 +0800 Subject: [PATCH 037/226] fix(esp_hw_support): fix cpu lockup reset issue caused by i-cache illegal access during esp_restart --- components/esp_hw_support/linker.lf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index 676f475450..c5c80bdff1 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -13,8 +13,7 @@ entries: cpu: esp_cpu_compare_and_set (noflash) esp_memory_utils (noflash) clk_utils (noflash) - if PM_SLP_IRAM_OPT = y: - esp_clk_tree: esp_clk_tree_enable_src (noflash) + esp_clk_tree: esp_clk_tree_enable_src (noflash) if RTC_CLK_FUNC_IN_IRAM = y: rtc_clk (noflash) if IDF_TARGET_ESP32 = y: From 12d208bc1543df25417b75d28b0372f14758f7e4 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Tue, 25 Nov 2025 20:44:49 +0800 Subject: [PATCH 038/226] fix(esp_hw_support): fix esp32p4 HP_SYS_HP_WDT_RESET issue caused by cache invalid all --- components/esp_hw_support/sleep_modes.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index f7c21485ab..78c1162354 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -1163,13 +1163,10 @@ static esp_err_t SLEEP_FN_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t cl if (!deep_sleep) { if (result == ESP_OK) { -#if !CONFIG_PM_SLP_IRAM_OPT && !CONFIG_IDF_TARGET_ESP32 +#if !CONFIG_PM_SLP_IRAM_OPT && !(CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32P4) #if CONFIG_SPIRAM -# if CONFIG_IDF_TARGET_ESP32P4 - cache_ll_writeback_all(CACHE_LL_LEVEL_ALL, CACHE_TYPE_DATA, CACHE_LL_ID_ALL); -# else + // TODO: PM-651 Cache_WriteBack_All(); -# endif #endif /* When the IRAM optimization for the sleep flow is disabled, all * cache contents are forcibly invalidated before exiting the sleep From bbba2471eaf177c20a0fae7718a9d0d7e939e00b Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 27 Nov 2025 17:52:28 +0800 Subject: [PATCH 039/226] change(esp_hw_support): update some sleep parameters when sleep iram optimization is disabled --- components/esp_hw_support/sleep_modes.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 78c1162354..f71edb65b5 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -164,6 +164,10 @@ #elif CONFIG_IDF_TARGET_ESP32S3 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (382) #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (133) +# if !CONFIG_PM_SLP_IRAM_OPT + #undef DEFAULT_SLEEP_OUT_OVERHEAD_US + #define DEFAULT_SLEEP_OUT_OVERHEAD_US (8628) +# endif #elif CONFIG_IDF_TARGET_ESP32C3 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (105) #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (37) @@ -1163,6 +1167,7 @@ static esp_err_t SLEEP_FN_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t cl if (!deep_sleep) { if (result == ESP_OK) { + s_config.ccount_ticks_record = esp_cpu_get_cycle_count(); #if !CONFIG_PM_SLP_IRAM_OPT && !(CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32P4) #if CONFIG_SPIRAM // TODO: PM-651 @@ -1175,7 +1180,6 @@ static esp_err_t SLEEP_FN_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t cl * dynamically calculate the sleep adjustment time. */ cache_ll_invalidate_all(CACHE_LL_LEVEL_ALL, CACHE_TYPE_ALL, CACHE_LL_ID_ALL); #endif - s_config.ccount_ticks_record = esp_cpu_get_cycle_count(); } misc_modules_wake_prepare(sleep_flags); } From 52bc4e27fd0b8b3d5a25f9c6a538da2792a092b2 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Wed, 31 Dec 2025 15:17:10 +0800 Subject: [PATCH 040/226] change(example): change for pre-commit check pass of some Kconfig options are deprecated --- examples/system/esp_timer/sdkconfig.defaults | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/system/esp_timer/sdkconfig.defaults b/examples/system/esp_timer/sdkconfig.defaults index 3c7b19a00f..dfd208c65a 100644 --- a/examples/system/esp_timer/sdkconfig.defaults +++ b/examples/system/esp_timer/sdkconfig.defaults @@ -3,7 +3,7 @@ CONFIG_ESP_TIMER_PROFILING=y # NEWLIB_NANO_FORMAT is enabled by default on ESP32-C2 # This example needs 64-bit integer formatting, this is why this option is disabled -CONFIG_NEWLIB_NANO_FORMAT=n +CONFIG_LIBC_NEWLIB_NANO_FORMAT=n # Put sleep related source code in IRAM CONFIG_PM_SLP_IRAM_OPT=y From 1f95182e555bc7a00b40f8a56229cf33141f0c66 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Wed, 5 Nov 2025 20:53:49 +0800 Subject: [PATCH 041/226] fix(ld): fix cannot move location counter backwards (from 3fc88000 to 3fc87a00) --- components/esp_system/ld/esp32s3/sections.ld.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/esp_system/ld/esp32s3/sections.ld.in b/components/esp_system/ld/esp32s3/sections.ld.in index c6649ba3a6..f293976428 100644 --- a/components/esp_system/ld/esp32s3/sections.ld.in +++ b/components/esp_system/ld/esp32s3/sections.ld.in @@ -205,7 +205,8 @@ SECTIONS */ .dram0.dummy (NOLOAD): { - . = ORIGIN(dram0_0_seg) + MAX(_iram_end - _diram_i_start, 0); + /* MAX() uses unsigned long arithmetic. Add offset to prevent underflow when _iram_end < _diram_i_start */ + . = ORIGIN(dram0_0_seg) + MAX(_iram_end - _diram_i_start + (_diram_i_start - ORIGIN(iram0_0_seg)), (_diram_i_start - ORIGIN(iram0_0_seg))) - (_diram_i_start - ORIGIN(iram0_0_seg)); } > dram0_0_seg .dram0.data : From c05fc9c5e8f996a23c0aa85cd448c8157b7bb212 Mon Sep 17 00:00:00 2001 From: Xu Si Yu Date: Thu, 25 Dec 2025 16:54:25 +0800 Subject: [PATCH 042/226] fix(openthread): remove the default netif configuration from the ot_br example --- examples/openthread/ot_br/main/esp_ot_br.c | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/openthread/ot_br/main/esp_ot_br.c b/examples/openthread/ot_br/main/esp_ot_br.c index 7cfcca642b..5f8c4b44bd 100644 --- a/examples/openthread/ot_br/main/esp_ot_br.c +++ b/examples/openthread/ot_br/main/esp_ot_br.c @@ -113,7 +113,6 @@ void app_main(void) }; ESP_ERROR_CHECK(esp_openthread_start(&config)); - esp_netif_set_default_netif(esp_openthread_get_netif()); #if CONFIG_OPENTHREAD_CLI_ESP_EXTENSION esp_cli_custom_command_init(); #endif From ba74b304ab8bc9acb45eaa85612fcd4147a96d45 Mon Sep 17 00:00:00 2001 From: Sumeet Singh Date: Wed, 24 Dec 2025 14:14:24 +0530 Subject: [PATCH 043/226] feat(nimble): Support for getting the local IRK and Identity Address (v5.5) --- components/bt/host/nimble/nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index e2f8239def..112925dfe7 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit e2f8239def9fc39b03dd5c719f6c794b1d675c23 +Subproject commit 112925dfe7712ecfe9ccfe37510c7fdcb1fd962a From a01961b74e18ff76acd7dc6fd7c69da21d343853 Mon Sep 17 00:00:00 2001 From: armando Date: Tue, 9 Dec 2025 16:14:54 +0800 Subject: [PATCH 044/226] ci(isp): reenable tests --- .../esp_driver_isp/test_apps/isp/pytest_isp.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/components/esp_driver_isp/test_apps/isp/pytest_isp.py b/components/esp_driver_isp/test_apps/isp/pytest_isp.py index 92c6291f7c..501c1fb873 100644 --- a/components/esp_driver_isp/test_apps/isp/pytest_isp.py +++ b/components/esp_driver_isp/test_apps/isp/pytest_isp.py @@ -1,7 +1,13 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 -from pytest_embedded_idf import IdfDut +import pytest +from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize +from pytest_embedded_idf.utils import soc_filtered_targets -def test_isp(dut: IdfDut) -> None: +@pytest.mark.camera +@pytest.mark.ov5647 +@idf_parametrize('target', soc_filtered_targets('SOC_ISP_SUPPORTED == 1'), indirect=['target']) +def test_isp(dut: Dut) -> None: dut.run_all_single_board_cases() From 4f660e5ee1a0f2bbc40bf8d5ed680a989f33a2cb Mon Sep 17 00:00:00 2001 From: armando Date: Thu, 11 Dec 2025 10:24:31 +0800 Subject: [PATCH 045/226] feat(isp): allow ccm to bypass shadow register --- .../esp_driver_isp/include/driver/isp_ccm.h | 3 +++ components/esp_driver_isp/src/isp_ccm.c | 2 +- .../test_apps/isp/main/test_isp_driver.c | 9 ++++++-- components/hal/esp32p4/include/hal/isp_ll.h | 22 ++++++++++++------- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/components/esp_driver_isp/include/driver/isp_ccm.h b/components/esp_driver_isp/include/driver/isp_ccm.h index 1560782894..f779ff3cb7 100644 --- a/components/esp_driver_isp/include/driver/isp_ccm.h +++ b/components/esp_driver_isp/include/driver/isp_ccm.h @@ -26,6 +26,9 @@ typedef struct { * When saturation is true, and final value will be limited to 4.0, and won't rise error * When saturation is false, `esp_isp_ccm_configure` will rise ESP_ERR_INVALID_ARG error */ + struct { + uint32_t update_once_configured : 1; ///< If set, apply configuration to hardware immediately; otherwise defer to frame boundary + } flags; ///< Driver behaviour flags } esp_isp_ccm_config_t; /** diff --git a/components/esp_driver_isp/src/isp_ccm.c b/components/esp_driver_isp/src/isp_ccm.c index 4168a1ad52..cb688dc7f3 100644 --- a/components/esp_driver_isp/src/isp_ccm.c +++ b/components/esp_driver_isp/src/isp_ccm.c @@ -26,7 +26,7 @@ esp_err_t esp_isp_ccm_configure(isp_proc_handle_t proc, const esp_isp_ccm_config portENTER_CRITICAL(&proc->spinlock); isp_ll_ccm_set_clk_ctrl_mode(proc->hal.hw, ISP_LL_PIPELINE_CLK_CTRL_AUTO); ret = isp_hal_ccm_set_matrix(&proc->hal, ccm_cfg->saturation, ccm_cfg->matrix); - valid = isp_ll_shadow_update_ccm(proc->hal.hw); + valid = isp_ll_shadow_update_ccm(proc->hal.hw, ccm_cfg->flags.update_once_configured); portEXIT_CRITICAL(&proc->spinlock); ESP_RETURN_ON_FALSE(ret, ESP_ERR_INVALID_ARG, TAG, "invalid argument: ccm matrix contain NaN or out of range"); ESP_RETURN_ON_FALSE(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update ccm shadow register"); diff --git a/components/esp_driver_isp/test_apps/isp/main/test_isp_driver.c b/components/esp_driver_isp/test_apps/isp/main/test_isp_driver.c index d14f6033a2..e73b45fb4e 100644 --- a/components/esp_driver_isp/test_apps/isp/main/test_isp_driver.c +++ b/components/esp_driver_isp/test_apps/isp/main/test_isp_driver.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -210,15 +210,20 @@ TEST_CASE("ISP CCM basic function", "[isp]") esp_isp_ccm_config_t ccm_cfg = { .matrix = { - {5.0, 0.0, 0.0}, + {16.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0} }, .saturation = false, + .flags = { + .update_once_configured = true, + }, }; // Out of range case TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_isp_ccm_configure(isp_proc, &ccm_cfg)); + // saturation case + ccm_cfg.matrix[0][0] = 5.0; ccm_cfg.saturation = true; TEST_ESP_OK(esp_isp_ccm_configure(isp_proc, &ccm_cfg)); TEST_ESP_OK(esp_isp_ccm_enable(isp_proc)); diff --git a/components/hal/esp32p4/include/hal/isp_ll.h b/components/hal/esp32p4/include/hal/isp_ll.h index d5abfc435d..4a1715d335 100644 --- a/components/hal/esp32p4/include/hal/isp_ll.h +++ b/components/hal/esp32p4/include/hal/isp_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -1965,21 +1965,27 @@ static inline bool isp_ll_shadow_update_wbg(isp_dev_t *hw) /** * @brief Update CCM shadow register * - * @param[in] hw Hardware instance address + * @param[in] hw Hardware instance address + * @param[in] force_update Force update * @return * - True if update is successful, False otherwise */ -static inline bool isp_ll_shadow_update_ccm(isp_dev_t *hw) +static inline bool isp_ll_shadow_update_ccm(isp_dev_t *hw, bool force_update) { //only valid when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC HAL_ASSERT(hw->shadow_reg_ctrl.shadow_update_sel == ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC); - if (hw->shadow_reg_ctrl.ccm_update == 1) { - return false; - } + if (force_update) { + //don't care shadow register + hw->shadow_reg_ctrl.ccm_update = 1; + } else { + if (hw->shadow_reg_ctrl.ccm_update == 1) { + return false; + } - //self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC - hw->shadow_reg_ctrl.ccm_update = 1; + //self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC + hw->shadow_reg_ctrl.ccm_update = 1; + } return true; } From 874f7c4f34bc54f73160641e46d7c5f41458cf1c Mon Sep 17 00:00:00 2001 From: armando Date: Fri, 12 Dec 2025 10:04:29 +0800 Subject: [PATCH 046/226] fix(isp): fix isp rev012 build --- components/esp_adc/test_apps/adc/pytest_adc.py | 1 + .../esp_driver_isp/test_apps/isp/pytest_isp.py | 15 +++++++++++++++ .../test_apps/isp/sdkconfig.ci.esp32p4_eco4 | 2 ++ components/hal/esp32p4/include/hal/isp_ll.h | 2 +- 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 components/esp_driver_isp/test_apps/isp/sdkconfig.ci.esp32p4_eco4 diff --git a/components/esp_adc/test_apps/adc/pytest_adc.py b/components/esp_adc/test_apps/adc/pytest_adc.py index 3cc1661ac2..b914333b98 100644 --- a/components/esp_adc/test_apps/adc/pytest_adc.py +++ b/components/esp_adc/test_apps/adc/pytest_adc.py @@ -32,6 +32,7 @@ def test_adc_esp32c2_xtal_26mhz(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120, reset=True) +# TODO: IDF-15005 # P4 REV2 adc @pytest.mark.adc @pytest.mark.esp32p4_eco4 diff --git a/components/esp_driver_isp/test_apps/isp/pytest_isp.py b/components/esp_driver_isp/test_apps/isp/pytest_isp.py index 501c1fb873..c92c3db11e 100644 --- a/components/esp_driver_isp/test_apps/isp/pytest_isp.py +++ b/components/esp_driver_isp/test_apps/isp/pytest_isp.py @@ -11,3 +11,18 @@ from pytest_embedded_idf.utils import soc_filtered_targets @idf_parametrize('target', soc_filtered_targets('SOC_ISP_SUPPORTED == 1'), indirect=['target']) def test_isp(dut: Dut) -> None: dut.run_all_single_board_cases() + + +# TODO: IDF-15006 +# @pytest.mark.generic +# @pytest.mark.esp32p4_eco4 +# @pytest.mark.parametrize( +# 'config', +# [ +# ('esp32p4_eco4'), +# ], +# indirect=True, +# ) +# @idf_parametrize('target', ['esp32p4'], indirect=['target']) +# def test_isp_esp32p4_rev2(dut: Dut) -> None: +# dut.run_all_single_board_cases() diff --git a/components/esp_driver_isp/test_apps/isp/sdkconfig.ci.esp32p4_eco4 b/components/esp_driver_isp/test_apps/isp/sdkconfig.ci.esp32p4_eco4 new file mode 100644 index 0000000000..2c6c907fab --- /dev/null +++ b/components/esp_driver_isp/test_apps/isp/sdkconfig.ci.esp32p4_eco4 @@ -0,0 +1,2 @@ +CONFIG_IDF_TARGET="esp32p4" +CONFIG_ESP32P4_SELECTS_REV_LESS_V3=y diff --git a/components/hal/esp32p4/include/hal/isp_ll.h b/components/hal/esp32p4/include/hal/isp_ll.h index 4a1715d335..21d5e93d72 100644 --- a/components/hal/esp32p4/include/hal/isp_ll.h +++ b/components/hal/esp32p4/include/hal/isp_ll.h @@ -2064,7 +2064,7 @@ static inline bool isp_ll_shadow_update_wbg(isp_dev_t *hw) return true; } -static inline bool isp_ll_shadow_update_ccm(isp_dev_t *hw) +static inline bool isp_ll_shadow_update_ccm(isp_dev_t *hw, bool force_update) { //for compatibility return true; From 502a10b5dcd2e9e3d7f661aac54191ad769ffd8a Mon Sep 17 00:00:00 2001 From: armando Date: Mon, 15 Dec 2025 11:54:38 +0800 Subject: [PATCH 047/226] ci: enable isp default tests --- components/esp_driver_isp/test_apps/isp/pytest_isp.py | 7 +++++++ .../esp_driver_isp/test_apps/isp/sdkconfig.ci.default | 1 + 2 files changed, 8 insertions(+) create mode 100644 components/esp_driver_isp/test_apps/isp/sdkconfig.ci.default diff --git a/components/esp_driver_isp/test_apps/isp/pytest_isp.py b/components/esp_driver_isp/test_apps/isp/pytest_isp.py index c92c3db11e..44884efbeb 100644 --- a/components/esp_driver_isp/test_apps/isp/pytest_isp.py +++ b/components/esp_driver_isp/test_apps/isp/pytest_isp.py @@ -8,6 +8,13 @@ from pytest_embedded_idf.utils import soc_filtered_targets @pytest.mark.camera @pytest.mark.ov5647 +@pytest.mark.parametrize( + 'config', + [ + ('default'), + ], + indirect=True, +) @idf_parametrize('target', soc_filtered_targets('SOC_ISP_SUPPORTED == 1'), indirect=['target']) def test_isp(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_isp/test_apps/isp/sdkconfig.ci.default b/components/esp_driver_isp/test_apps/isp/sdkconfig.ci.default new file mode 100644 index 0000000000..7c05891852 --- /dev/null +++ b/components/esp_driver_isp/test_apps/isp/sdkconfig.ci.default @@ -0,0 +1 @@ +# For pytest to run default tests From 9b0f6330e8775414892a9c9d49d18ae5fad098bb Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Thu, 13 Nov 2025 19:40:44 +0800 Subject: [PATCH 048/226] fix(bt): Update esp32 libbtdm_app.a (15a18b1a) - fix(ble): fixed BLE enable scan timeout - fix(ble): fixed crash in "btdm_controller_task" --- components/bt/controller/lib_esp32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32 b/components/bt/controller/lib_esp32 index a184fa951e..06dc466733 160000 --- a/components/bt/controller/lib_esp32 +++ b/components/bt/controller/lib_esp32 @@ -1 +1 @@ -Subproject commit a184fa951eb366c3d99a968a4171feb33b99fb82 +Subproject commit 06dc466733e3e8738c6c638615e6f04e52ca1aa7 From b97da17cebefdc8bf1780026313f005901f5e958 Mon Sep 17 00:00:00 2001 From: liqigan Date: Fri, 28 Nov 2025 10:28:57 +0800 Subject: [PATCH 049/226] fix(bt/controller): Fixed hci connection request event filter bug --- components/bt/controller/lib_esp32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32 b/components/bt/controller/lib_esp32 index 06dc466733..05e9c75b89 160000 --- a/components/bt/controller/lib_esp32 +++ b/components/bt/controller/lib_esp32 @@ -1 +1 @@ -Subproject commit 06dc466733e3e8738c6c638615e6f04e52ca1aa7 +Subproject commit 05e9c75b8977a3767c5cf5afedcd4c7f8c0f5f62 From 801c1cab778ae1ab48dc993999e1d4a4778a10fb Mon Sep 17 00:00:00 2001 From: zhangyanjiao Date: Sun, 4 Jan 2026 14:17:17 +0800 Subject: [PATCH 050/226] fix(wifi/espnow): fixed the espnow set peer rate memory leak --- components/esp_wifi/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 01d52d9e69..f2221f65aa 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 01d52d9e69032c486015dc28b08c3bf6aaf348a9 +Subproject commit f2221f65aa9bcb3d5ff54c68a7823c5f0d2b01aa From a7597ac11e19c28f13e995464d5ff90305463e3d Mon Sep 17 00:00:00 2001 From: Zhao Wei Liang Date: Fri, 5 Dec 2025 09:51:40 +0800 Subject: [PATCH 051/226] fix(ble): fixed the assert issue when using tinycrypt on ESP32-C2 (cherry picked from commit ac5d14d9544a596fc600993e4e0783d3987b64d7) Co-authored-by: zhaoweiliang --- components/bt/controller/esp32c2/bt.c | 34 ++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/components/bt/controller/esp32c2/bt.c b/components/bt/controller/esp32c2/bt.c index c9b227a5f7..104503d8e2 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -232,6 +232,10 @@ static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE static bool esp_bt_check_wakeup_by_bt(void); #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) +#include "tinycrypt/ecc.h" +static int ecc_rand_func(uint8_t *dst, unsigned int len); +#endif // (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) /* Local variable definition *************************************************************************** */ @@ -1024,6 +1028,9 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) ESP_LOGW(NIMBLE_PORT_LOG_TAG, "hci transport init failed %d", ret); goto free_controller; } +#if (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) + uECC_set_rng(ecc_rand_func); +#endif // (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) return ESP_OK; free_controller: hci_transport_deinit(); @@ -1457,6 +1464,27 @@ static mbedtls_ecp_keypair keypair; #if CONFIG_BT_LE_SM_SC #include "tinycrypt/cmac_mode.h" #include "tinycrypt/ecc_dh.h" + + +/* Used by uECC to get random data */ +static int ecc_rand_func(uint8_t *dst, unsigned int len) +{ + int offset_cnt = 0; + uint8_t *u8ptr = dst; + uint64_t random_64 = 0; + + while(len > 0) { + random64 = (uint64_t)esp_random(); + random64 = (random64 << 32)| (uint64_t)esp_random();; + offset_cnt = len < sizeof(uint64_t) ? len : sizeof(uint64_t); + memcpy(u8ptr, &random64, offset_cnt); + len -= offset_cnt; + u8ptr += offset_cnt; + } + + return 1; +} + #endif // CONFIG_BT_LE_SM_SC #endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS @@ -1548,11 +1576,11 @@ exit: } #else - if (uECC_valid_public_key(pk, &curve_secp256r1) < 0) { + if (uECC_valid_public_key(pk, uECC_secp256r1()) < 0) { return BLE_SM_KEY_ERR; } - rc = uECC_shared_secret(pk, priv, dh, &curve_secp256r1); + rc = uECC_shared_secret(pk, priv, dh, uECC_secp256r1()); if (rc == TC_CRYPTO_FAIL) { return BLE_SM_KEY_ERR; } @@ -1628,7 +1656,7 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) return BLE_SM_KEY_ERR; } #else - if (uECC_make_key(pk, priv, &curve_secp256r1) != TC_CRYPTO_SUCCESS) { + if (uECC_make_key(pk, priv, uECC_secp256r1()) != TC_CRYPTO_SUCCESS) { return BLE_SM_KEY_ERR; } #endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS From c42a382a705d227608985c3453c1f94ed5ea127d Mon Sep 17 00:00:00 2001 From: zhaoweiliang Date: Tue, 2 Dec 2025 19:09:08 +0800 Subject: [PATCH 052/226] change(ble): [AUTO_MR] Update lib_esp32h2 to faf10639 --- components/bt/controller/lib_esp32h2/esp32h2-bt-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib index a568fa5a03..33a575696b 160000 --- a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib +++ b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib @@ -1 +1 @@ -Subproject commit a568fa5a03545dd133a301ccdbae99afa3692923 +Subproject commit 33a575696b811a255dfb68bbea1370ea5e95265f From 4eb392586fae6732eb1460bbf926b2628edae62c Mon Sep 17 00:00:00 2001 From: zhaoweiliang Date: Tue, 2 Dec 2025 19:09:08 +0800 Subject: [PATCH 053/226] change(ble): [AUTO_MR] Update lib_esp32c5 to faf10639 --- components/bt/controller/lib_esp32c5/esp32c5-bt-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32c5/esp32c5-bt-lib b/components/bt/controller/lib_esp32c5/esp32c5-bt-lib index a5feba34e1..cc21d43f5c 160000 --- a/components/bt/controller/lib_esp32c5/esp32c5-bt-lib +++ b/components/bt/controller/lib_esp32c5/esp32c5-bt-lib @@ -1 +1 @@ -Subproject commit a5feba34e144c82374fb9818108d6efc5216dc1f +Subproject commit cc21d43f5c3c3203125a13329391ba3b3c5ab518 From fb5882d86c54b12508e0d5c6602061fca5700a90 Mon Sep 17 00:00:00 2001 From: zhaoweiliang Date: Tue, 2 Dec 2025 19:09:08 +0800 Subject: [PATCH 054/226] change(ble): [AUTO_MR] Update lib_esp32c6 to faf10639 --- components/bt/controller/lib_esp32c6/esp32c6-bt-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib index cf7c287226..237c0ce2eb 160000 --- a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib +++ b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib @@ -1 +1 @@ -Subproject commit cf7c287226c2c8575dc1cb9896d54a14a18d1dd4 +Subproject commit 237c0ce2eb75becf4890d96897105174659e07b5 From eefc31f4ae45fa0942f43cc43683d7954ee3b803 Mon Sep 17 00:00:00 2001 From: zhaoweiliang Date: Fri, 28 Nov 2025 20:31:30 +0800 Subject: [PATCH 055/226] feat(ble): add CONFIG_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN config on ESP32-H2 --- components/bt/controller/esp32h2/Kconfig.in | 8 ++++ components/bt/controller/esp32h2/bt.c | 39 +++++++++++++++++-- components/bt/controller/esp32h2/esp_bt_cfg.h | 7 ++++ .../bt/include/esp32h2/include/esp_bt.h | 4 +- 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/components/bt/controller/esp32h2/Kconfig.in b/components/bt/controller/esp32h2/Kconfig.in index c3d7df55e0..47820f717c 100644 --- a/components/bt/controller/esp32h2/Kconfig.in +++ b/components/bt/controller/esp32h2/Kconfig.in @@ -989,3 +989,11 @@ config BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN When this option is enabled, the Controller continues receiving PDUs In the next connection event instead of entering latency After a data packet is received. + +config BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN + bool "Enables the automatic initiation of a data length update(Experimental)." + default n + help + When this option is enabled, the Controller automatically initiates a data length update + Using the appropriate data length parameters + When a PHY update or a connection interval update occurs. diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index 6ea4185a27..c51cd40c95 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -187,6 +187,7 @@ extern int r_ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_c extern char *ble_controller_get_compile_version(void); extern int esp_ble_register_bb_funcs(void); extern void esp_ble_unregister_bb_funcs(void); +extern bool esp_ble_controller_lib_check(void); extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_end; extern uint32_t _bt_controller_bss_start; @@ -226,6 +227,10 @@ static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE static bool esp_bt_check_wakeup_by_bt(void); #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) +#include "tinycrypt/ecc.h" +static int ecc_rand_func(uint8_t *dst, unsigned int len); +#endif // (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) /* Local variable definition *************************************************************************** */ @@ -1009,6 +1014,7 @@ static void ble_rtc_clk_init(esp_bt_controller_config_t *cfg) esp_bt_rtc_slow_clk_select(s_bt_lpclk_src); } + esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) { uint8_t mac[6]; @@ -1144,6 +1150,13 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) goto free_controller; } + if (!esp_ble_controller_lib_check()) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Controller lib version mismatch!"); + } + +#if (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) + uECC_set_rng(ecc_rand_func); +#endif // (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) return ESP_OK; free_controller: hci_transport_deinit(); @@ -1614,6 +1627,25 @@ static mbedtls_ecp_keypair keypair; #if CONFIG_BT_LE_SM_SC #include "tinycrypt/cmac_mode.h" #include "tinycrypt/ecc_dh.h" + +/* Used by uECC to get random data */ +static int ecc_rand_func(uint8_t *dst, unsigned int len) +{ + int offset_cnt = 0; + uint8_t *u8ptr = dst; + uint64_t random_64 = 0; + + while(len > 0) { + random64 = (uint64_t)esp_random(); + random64 = (random64 << 32)| (uint64_t)esp_random();; + offset_cnt = len < sizeof(uint64_t) ? len : sizeof(uint64_t); + memcpy(u8ptr, &random64, offset_cnt); + len -= offset_cnt; + u8ptr += offset_cnt; + } + + return 1; +} #endif // CONFIG_BT_LE_SM_SC #endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS @@ -1705,11 +1737,11 @@ exit: } #else - if (uECC_valid_public_key(pk, &curve_secp256r1) < 0) { + if (uECC_valid_public_key(pk, uECC_secp256r1()) < 0) { return BLE_SM_KEY_ERR; } - rc = uECC_shared_secret(pk, priv, dh, &curve_secp256r1); + rc = uECC_shared_secret(pk, priv, dh, uECC_secp256r1()); if (rc == TC_CRYPTO_FAIL) { return BLE_SM_KEY_ERR; } @@ -1785,7 +1817,7 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) return BLE_SM_KEY_ERR; } #else - if (uECC_make_key(pk, priv, &curve_secp256r1) != TC_CRYPTO_SUCCESS) { + if (uECC_make_key(pk, priv, uECC_secp256r1()) != TC_CRYPTO_SUCCESS) { return BLE_SM_KEY_ERR; } #endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS @@ -1801,6 +1833,7 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) #endif // CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) + #if CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED #include "esp_gdbstub.h" #endif // CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED diff --git a/components/bt/controller/esp32h2/esp_bt_cfg.h b/components/bt/controller/esp32h2/esp_bt_cfg.h index 4dbe2f2fe8..20f2ec7edb 100644 --- a/components/bt/controller/esp32h2/esp_bt_cfg.h +++ b/components/bt/controller/esp32h2/esp_bt_cfg.h @@ -215,6 +215,13 @@ extern "C" { #define DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN (0) #endif + +#if defined(CONFIG_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN) +#define DEFAULT_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN (CONFIG_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN) +#else +#define DEFAULT_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN (0) +#endif + #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART #else diff --git a/components/bt/include/esp32h2/include/esp_bt.h b/components/bt/include/esp32h2/include/esp_bt.h index a171b52a6b..f3d06ac7c5 100644 --- a/components/bt/include/esp32h2/include/esp_bt.h +++ b/components/bt/include/esp32h2/include/esp_bt.h @@ -161,7 +161,7 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type */ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle); -#define CONFIG_VERSION 0x20251104 +#define CONFIG_VERSION 0x20251125 #define CONFIG_MAGIC 0x5A5AA5A5 /** @@ -238,6 +238,7 @@ typedef struct { uint8_t conn_rsv_cnt; /*!< BLE conn state machine reserve count number */ uint8_t priority_level_cfg; /*!< The option for priority level configuration */ uint8_t slv_fst_rx_lat_en; /*!< The option for enabling slave fast PDU reception during latency. */ + uint8_t dl_itvl_phy_sync_en; /*!< The option for automatically initiate the data length update when phy update or connect interval update. */ uint32_t config_magic; /*!< Configuration magic value */ } esp_bt_controller_config_t; @@ -302,6 +303,7 @@ typedef struct { .conn_rsv_cnt = BLE_LL_CONN_SM_RESERVE_CNT_N, \ .priority_level_cfg = BT_LL_CTRL_PRIO_LVL_CFG, \ .slv_fst_rx_lat_en = DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN, \ + .dl_itvl_phy_sync_en = DEFAULT_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN, \ .config_magic = CONFIG_MAGIC, \ } From 0b89e031d8c734423741b7f4699ddaac10cec564 Mon Sep 17 00:00:00 2001 From: zhaoweiliang Date: Tue, 2 Dec 2025 20:07:34 +0800 Subject: [PATCH 056/226] feat(ble): add CONFIG_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN config on ESP32-C6 --- components/bt/controller/esp32c6/Kconfig.in | 8 ++++ components/bt/controller/esp32c6/bt.c | 44 ++++++++++++++++--- components/bt/controller/esp32c6/esp_bt_cfg.h | 8 +++- .../bt/include/esp32c6/include/esp_bt.h | 7 ++- 4 files changed, 57 insertions(+), 10 deletions(-) diff --git a/components/bt/controller/esp32c6/Kconfig.in b/components/bt/controller/esp32c6/Kconfig.in index bffab12e66..58fc31715d 100644 --- a/components/bt/controller/esp32c6/Kconfig.in +++ b/components/bt/controller/esp32c6/Kconfig.in @@ -985,3 +985,11 @@ config BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN When this option is enabled, the Controller continues receiving PDUs In the next connection event instead of entering latency After a data packet is received. + +config BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN + bool "Enables the automatic initiation of a data length update(Experimental)." + default n + help + When this option is enabled, the Controller automatically initiates a data length update + Using the appropriate data length parameters + When a PHY update or a connection interval update occurs. diff --git a/components/bt/controller/esp32c6/bt.c b/components/bt/controller/esp32c6/bt.c index a442f8d85c..de8d8f51fc 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -34,8 +34,8 @@ #include "os/endian.h" #include "esp_bt.h" -#include "esp_intr_alloc.h" #include "ble_priv.h" +#include "esp_intr_alloc.h" #include "esp_sleep.h" #include "esp_pm.h" #ifdef CONFIG_ESP_PHY_ENABLED @@ -133,7 +133,6 @@ typedef union { }; uint32_t val; } bt_wakeup_params_t; - /* External functions or variables ************************************************************************ */ @@ -192,6 +191,7 @@ extern int r_ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_c extern char *ble_controller_get_compile_version(void); extern int esp_ble_register_bb_funcs(void); extern void esp_ble_unregister_bb_funcs(void); +extern bool esp_ble_controller_lib_check(void); extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_end; extern uint32_t _bt_controller_bss_start; @@ -233,6 +233,11 @@ static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE static bool esp_bt_check_wakeup_by_bt(void); #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE + +#if (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) +#include "tinycrypt/ecc.h" +static int ecc_rand_func(uint8_t *dst, unsigned int len); +#endif // (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) /* Local variable definition *************************************************************************** */ @@ -1055,6 +1060,7 @@ static void ble_rtc_clk_init(esp_bt_controller_config_t *cfg) esp_bt_rtc_slow_clk_select(s_bt_lpclk_src); } + esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) { uint8_t mac[6]; @@ -1191,6 +1197,13 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) goto free_controller; } + if (!esp_ble_controller_lib_check()) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Controller lib version mismatch!"); + } + +#if (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) + uECC_set_rng(ecc_rand_func); +#endif // (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) return ESP_OK; free_controller: hci_transport_deinit(); @@ -1443,7 +1456,6 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) return ret; } - esp_bt_controller_status_t esp_bt_controller_get_status(void) { return ble_controller_status; @@ -1664,6 +1676,25 @@ static mbedtls_ecp_keypair keypair; #if CONFIG_BT_LE_SM_SC #include "tinycrypt/cmac_mode.h" #include "tinycrypt/ecc_dh.h" + +/* Used by uECC to get random data */ +static int ecc_rand_func(uint8_t *dst, unsigned int len) +{ + int offset_cnt = 0; + uint8_t *u8ptr = dst; + uint64_t random_64 = 0; + + while(len > 0) { + random64 = (uint64_t)esp_random(); + random64 = (random64 << 32)| (uint64_t)esp_random();; + offset_cnt = len < sizeof(uint64_t) ? len : sizeof(uint64_t); + memcpy(u8ptr, &random64, offset_cnt); + len -= offset_cnt; + u8ptr += offset_cnt; + } + + return 1; +} #endif // CONFIG_BT_LE_SM_SC #endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS @@ -1755,11 +1786,11 @@ exit: } #else - if (uECC_valid_public_key(pk, &curve_secp256r1) < 0) { + if (uECC_valid_public_key(pk, uECC_secp256r1()) < 0) { return BLE_SM_KEY_ERR; } - rc = uECC_shared_secret(pk, priv, dh, &curve_secp256r1); + rc = uECC_shared_secret(pk, priv, dh, uECC_secp256r1()); if (rc == TC_CRYPTO_FAIL) { return BLE_SM_KEY_ERR; } @@ -1835,7 +1866,7 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) return BLE_SM_KEY_ERR; } #else - if (uECC_make_key(pk, priv, &curve_secp256r1) != TC_CRYPTO_SUCCESS) { + if (uECC_make_key(pk, priv, uECC_secp256r1()) != TC_CRYPTO_SUCCESS) { return BLE_SM_KEY_ERR; } #endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS @@ -1851,7 +1882,6 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) #endif // CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) - #if CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED #include "esp_gdbstub.h" #endif // CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED diff --git a/components/bt/controller/esp32c6/esp_bt_cfg.h b/components/bt/controller/esp32c6/esp_bt_cfg.h index 71f7f9d194..e5d378ad9b 100644 --- a/components/bt/controller/esp32c6/esp_bt_cfg.h +++ b/components/bt/controller/esp32c6/esp_bt_cfg.h @@ -218,6 +218,13 @@ extern "C" { #define DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN (0) #endif + +#if defined(CONFIG_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN) +#define DEFAULT_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN (CONFIG_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN) +#else +#define DEFAULT_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN (0) +#endif + #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART #else @@ -307,7 +314,6 @@ extern "C" { #define RUN_QA_TEST (0) #define NIMBLE_DISABLE_SCAN_BACKOFF (0) #define BT_LL_CTRL_PRIO_LVL_CFG ((CONFIG_BT_LE_DFT_SYNC_SCHED_PRIO_LEVEL << 4) | (CONFIG_BT_LE_DFT_PERIODIC_ADV_SCHED_PRIO_LEVEL << 2) | CONFIG_BT_LE_DFT_ADV_SCHED_PRIO_LEVEL) - #ifdef __cplusplus } #endif diff --git a/components/bt/include/esp32c6/include/esp_bt.h b/components/bt/include/esp32c6/include/esp_bt.h index 3ccdeb7cb7..5771335a99 100644 --- a/components/bt/include/esp32c6/include/esp_bt.h +++ b/components/bt/include/esp32c6/include/esp_bt.h @@ -156,7 +156,7 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type */ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle); -#define CONFIG_VERSION 0x20251104 +#define CONFIG_VERSION 0x20251125 #define CONFIG_MAGIC 0x5A5AA5A5 /** @@ -236,6 +236,7 @@ typedef struct { uint8_t conn_rsv_cnt; /*!< BLE conn state machine reserve count number */ uint8_t priority_level_cfg; /*!< The option for priority level configuration */ uint8_t slv_fst_rx_lat_en; /*!< The option for enabling slave fast PDU reception during latency. */ + uint8_t dl_itvl_phy_sync_en; /*!< The option for automatically initiate the data length update when phy update or connect interval update. */ uint32_t config_magic; /*!< Magic number for configuration validation */ } esp_bt_controller_config_t; @@ -301,7 +302,8 @@ typedef struct { .adv_rsv_cnt = BLE_LL_ADV_SM_RESERVE_CNT_N, \ .conn_rsv_cnt = BLE_LL_CONN_SM_RESERVE_CNT_N, \ .priority_level_cfg = BT_LL_CTRL_PRIO_LVL_CFG, \ - .slv_fst_rx_lat_en = DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN, \ + .slv_fst_rx_lat_en = DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN, \ + .dl_itvl_phy_sync_en = DEFAULT_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN, \ .config_magic = CONFIG_MAGIC, \ } #elif CONFIG_IDF_TARGET_ESP32C61 @@ -365,6 +367,7 @@ typedef struct { .conn_rsv_cnt = BLE_LL_CONN_SM_RESERVE_CNT_N, \ .priority_level_cfg = BT_LL_CTRL_PRIO_LVL_CFG, \ .slv_fst_rx_lat_en = DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN, \ + .dl_itvl_phy_sync_en = DEFAULT_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN, \ .config_magic = CONFIG_MAGIC, \ } #endif From 80b7c2b0f15b2210f255219cf3d1db1c062bd9d8 Mon Sep 17 00:00:00 2001 From: zhaoweiliang Date: Tue, 2 Dec 2025 20:11:57 +0800 Subject: [PATCH 057/226] feat(ble): add CONFIG_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN config on ESP32-C5 --- components/bt/controller/esp32c5/Kconfig.in | 8 ++++ components/bt/controller/esp32c5/bt.c | 38 +++++++++++++++++-- components/bt/controller/esp32c5/esp_bt_cfg.h | 7 ++++ components/bt/controller/esp32h2/bt.c | 1 - .../bt/include/esp32c5/include/esp_bt.h | 4 +- 5 files changed, 53 insertions(+), 5 deletions(-) diff --git a/components/bt/controller/esp32c5/Kconfig.in b/components/bt/controller/esp32c5/Kconfig.in index cfcef62e17..dbd2a8e212 100644 --- a/components/bt/controller/esp32c5/Kconfig.in +++ b/components/bt/controller/esp32c5/Kconfig.in @@ -951,3 +951,11 @@ config BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN When this option is enabled, the Controller continues receiving PDUs In the next connection event instead of entering latency After a data packet is received. + +config BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN + bool "Enables the automatic initiation of a data length update(Experimental)." + default n + help + When this option is enabled, the Controller automatically initiates a data length update + Using the appropriate data length parameters + When a PHY update or a connection interval update occurs. diff --git a/components/bt/controller/esp32c5/bt.c b/components/bt/controller/esp32c5/bt.c index 7453a6917f..6354eb9928 100644 --- a/components/bt/controller/esp32c5/bt.c +++ b/components/bt/controller/esp32c5/bt.c @@ -180,6 +180,7 @@ extern int r_ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_c extern char *ble_controller_get_compile_version(void); extern int esp_ble_register_bb_funcs(void); extern void esp_ble_unregister_bb_funcs(void); +extern bool esp_ble_controller_lib_check(void); extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_end; extern uint32_t _bt_controller_bss_start; @@ -218,6 +219,10 @@ static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE static bool esp_bt_check_wakeup_by_bt(void); #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) +#include "tinycrypt/ecc.h" +static int ecc_rand_func(uint8_t *dst, unsigned int len); +#endif // (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) /* Local variable definition *************************************************************************** */ @@ -1121,6 +1126,13 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) goto free_controller; } + if (!esp_ble_controller_lib_check()) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Controller lib version mismatch!"); + } + +#if (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) + uECC_set_rng(ecc_rand_func); +#endif // (CONFIG_BT_CONTROLLER_ONLY) && (CONFIG_BT_LE_SM_SC) && (!CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS) return ESP_OK; free_controller: hci_transport_deinit(); @@ -1594,6 +1606,26 @@ static mbedtls_ecp_keypair keypair; #if CONFIG_BT_LE_SM_SC #include "tinycrypt/cmac_mode.h" #include "tinycrypt/ecc_dh.h" + +/* Used by uECC to get random data */ +static int ecc_rand_func(uint8_t *dst, unsigned int len) +{ + int offset_cnt = 0; + uint8_t *u8ptr = dst; + uint64_t random_64 = 0; + + while(len > 0) { + random64 = (uint64_t)esp_random(); + random64 = (random64 << 32)| (uint64_t)esp_random();; + offset_cnt = len < sizeof(uint64_t) ? len : sizeof(uint64_t); + memcpy(u8ptr, &random64, offset_cnt); + len -= offset_cnt; + u8ptr += offset_cnt; + } + + return 1; +} + #endif // CONFIG_BT_LE_SM_SC #endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS @@ -1685,11 +1717,11 @@ exit: } #else - if (uECC_valid_public_key(pk, &curve_secp256r1) < 0) { + if (uECC_valid_public_key(pk, uECC_secp256r1()) < 0) { return BLE_SM_KEY_ERR; } - rc = uECC_shared_secret(pk, priv, dh, &curve_secp256r1); + rc = uECC_shared_secret(pk, priv, dh, uECC_secp256r1()); if (rc == TC_CRYPTO_FAIL) { return BLE_SM_KEY_ERR; } @@ -1765,7 +1797,7 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) return BLE_SM_KEY_ERR; } #else - if (uECC_make_key(pk, priv, &curve_secp256r1) != TC_CRYPTO_SUCCESS) { + if (uECC_make_key(pk, priv, uECC_secp256r1()) != TC_CRYPTO_SUCCESS) { return BLE_SM_KEY_ERR; } #endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS diff --git a/components/bt/controller/esp32c5/esp_bt_cfg.h b/components/bt/controller/esp32c5/esp_bt_cfg.h index 4dbe2f2fe8..20f2ec7edb 100644 --- a/components/bt/controller/esp32c5/esp_bt_cfg.h +++ b/components/bt/controller/esp32c5/esp_bt_cfg.h @@ -215,6 +215,13 @@ extern "C" { #define DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN (0) #endif + +#if defined(CONFIG_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN) +#define DEFAULT_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN (CONFIG_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN) +#else +#define DEFAULT_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN (0) +#endif + #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART #else diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index c51cd40c95..ffa419c6e0 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -1014,7 +1014,6 @@ static void ble_rtc_clk_init(esp_bt_controller_config_t *cfg) esp_bt_rtc_slow_clk_select(s_bt_lpclk_src); } - esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) { uint8_t mac[6]; diff --git a/components/bt/include/esp32c5/include/esp_bt.h b/components/bt/include/esp32c5/include/esp_bt.h index b44c861e72..478c4df11a 100644 --- a/components/bt/include/esp32c5/include/esp_bt.h +++ b/components/bt/include/esp32c5/include/esp_bt.h @@ -159,7 +159,7 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type */ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle); -#define CONFIG_VERSION 0x20251104 +#define CONFIG_VERSION 0x20251125 #define CONFIG_MAGIC 0x5A5AA5A5 /** @@ -236,6 +236,7 @@ typedef struct { uint8_t conn_rsv_cnt; /*!< BLE conn state machine reserve count number */ uint8_t priority_level_cfg; /*!< The option for priority level configuration */ uint8_t slv_fst_rx_lat_en; /*!< The option for enabling slave fast PDU reception during latency. */ + uint8_t dl_itvl_phy_sync_en; /*!< The option for automatically initiate the data length update when phy update or connect interval update. */ uint32_t config_magic; /*!< Magic number for configuration validation */ } esp_bt_controller_config_t; @@ -299,6 +300,7 @@ typedef struct { .conn_rsv_cnt = BLE_LL_CONN_SM_RESERVE_CNT_N, \ .priority_level_cfg = BT_LL_CTRL_PRIO_LVL_CFG, \ .slv_fst_rx_lat_en = DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN, \ + .dl_itvl_phy_sync_en = DEFAULT_BT_LE_CTRL_DL_ITVL_PHY_SYNC_EN, \ .config_magic = CONFIG_MAGIC, \ } From 3d45deb23a5758c0c310fbedd09953d5faab7593 Mon Sep 17 00:00:00 2001 From: zhaoweiliang Date: Wed, 31 Dec 2025 11:45:14 +0800 Subject: [PATCH 058/226] change(ble): [AUTO_MR] Update lib_esp32h2 to 2406161c --- components/bt/controller/lib_esp32h2/esp32h2-bt-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib index 33a575696b..bfbcfa6ee4 160000 --- a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib +++ b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib @@ -1 +1 @@ -Subproject commit 33a575696b811a255dfb68bbea1370ea5e95265f +Subproject commit bfbcfa6ee46f4e2e323d9ddf6069984d6f836aa4 From 9a7d360faaa0adbbc76479664eaf4cfa3b72eeea Mon Sep 17 00:00:00 2001 From: zhaoweiliang Date: Wed, 31 Dec 2025 11:45:14 +0800 Subject: [PATCH 059/226] change(ble): [AUTO_MR] Update lib_esp32c5 to 2406161c --- components/bt/controller/lib_esp32c5/esp32c5-bt-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32c5/esp32c5-bt-lib b/components/bt/controller/lib_esp32c5/esp32c5-bt-lib index cc21d43f5c..955958046d 160000 --- a/components/bt/controller/lib_esp32c5/esp32c5-bt-lib +++ b/components/bt/controller/lib_esp32c5/esp32c5-bt-lib @@ -1 +1 @@ -Subproject commit cc21d43f5c3c3203125a13329391ba3b3c5ab518 +Subproject commit 955958046d6306726cf10ff420805e33c429e0e8 From e047f40baa224cbf66c9130c0eb58c337523c357 Mon Sep 17 00:00:00 2001 From: zhaoweiliang Date: Wed, 31 Dec 2025 11:45:14 +0800 Subject: [PATCH 060/226] change(ble): [AUTO_MR] Update lib_esp32c6 to 2406161c --- components/bt/controller/lib_esp32c6/esp32c6-bt-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib index 237c0ce2eb..8175cc3655 160000 --- a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib +++ b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib @@ -1 +1 @@ -Subproject commit 237c0ce2eb75becf4890d96897105174659e07b5 +Subproject commit 8175cc3655be5a08d85dd38149d3dd79d7c1fe49 From 86613d225f0964204d8b5799d3042d1b4f417c70 Mon Sep 17 00:00:00 2001 From: zhaoweiliang Date: Wed, 31 Dec 2025 12:04:37 +0800 Subject: [PATCH 061/226] fix(ble): fixed build error on ESP32-C6 --- components/bt/controller/esp32c2/bt.c | 4 +++- components/bt/controller/esp32c6/bt.c | 4 +++- components/bt/controller/esp32h2/bt.c | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/components/bt/controller/esp32c2/bt.c b/components/bt/controller/esp32c2/bt.c index 104503d8e2..41149cd8e5 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -1466,12 +1466,13 @@ static mbedtls_ecp_keypair keypair; #include "tinycrypt/ecc_dh.h" +#if CONFIG_BT_CONTROLLER_ONLY /* Used by uECC to get random data */ static int ecc_rand_func(uint8_t *dst, unsigned int len) { int offset_cnt = 0; uint8_t *u8ptr = dst; - uint64_t random_64 = 0; + uint64_t random64 = 0; while(len > 0) { random64 = (uint64_t)esp_random(); @@ -1485,6 +1486,7 @@ static int ecc_rand_func(uint8_t *dst, unsigned int len) return 1; } +#endif // CONFIG_BT_CONTROLLER_ONLY #endif // CONFIG_BT_LE_SM_SC #endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS diff --git a/components/bt/controller/esp32c6/bt.c b/components/bt/controller/esp32c6/bt.c index de8d8f51fc..018f06ff6f 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -1677,12 +1677,13 @@ static mbedtls_ecp_keypair keypair; #include "tinycrypt/cmac_mode.h" #include "tinycrypt/ecc_dh.h" +#if CONFIG_BT_CONTROLLER_ONLY /* Used by uECC to get random data */ static int ecc_rand_func(uint8_t *dst, unsigned int len) { int offset_cnt = 0; uint8_t *u8ptr = dst; - uint64_t random_64 = 0; + uint64_t random64 = 0; while(len > 0) { random64 = (uint64_t)esp_random(); @@ -1695,6 +1696,7 @@ static int ecc_rand_func(uint8_t *dst, unsigned int len) return 1; } +#endif // CONFIG_BT_CONTROLLER_ONLY #endif // CONFIG_BT_LE_SM_SC #endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index ffa419c6e0..9fb20c0f57 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -1627,12 +1627,13 @@ static mbedtls_ecp_keypair keypair; #include "tinycrypt/cmac_mode.h" #include "tinycrypt/ecc_dh.h" +#if CONFIG_BT_CONTROLLER_ONLY /* Used by uECC to get random data */ static int ecc_rand_func(uint8_t *dst, unsigned int len) { int offset_cnt = 0; uint8_t *u8ptr = dst; - uint64_t random_64 = 0; + uint64_t random64 = 0; while(len > 0) { random64 = (uint64_t)esp_random(); @@ -1645,6 +1646,7 @@ static int ecc_rand_func(uint8_t *dst, unsigned int len) return 1; } +#endif // CONFIG_BT_CONTROLLER_ONLY #endif // CONFIG_BT_LE_SM_SC #endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS From 823ebb1ce35b86ffe2da8af720c65ecc0ab650ed Mon Sep 17 00:00:00 2001 From: zhaoweiliang Date: Wed, 31 Dec 2025 12:06:41 +0800 Subject: [PATCH 062/226] fix(ble): fixed build error on ESP32-C5 --- components/bt/controller/esp32c5/bt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/bt/controller/esp32c5/bt.c b/components/bt/controller/esp32c5/bt.c index 6354eb9928..2b1945ccd9 100644 --- a/components/bt/controller/esp32c5/bt.c +++ b/components/bt/controller/esp32c5/bt.c @@ -1606,13 +1606,13 @@ static mbedtls_ecp_keypair keypair; #if CONFIG_BT_LE_SM_SC #include "tinycrypt/cmac_mode.h" #include "tinycrypt/ecc_dh.h" - +#if CONFIG_BT_CONTROLLER_ONLY /* Used by uECC to get random data */ static int ecc_rand_func(uint8_t *dst, unsigned int len) { int offset_cnt = 0; uint8_t *u8ptr = dst; - uint64_t random_64 = 0; + uint64_t random64 = 0; while(len > 0) { random64 = (uint64_t)esp_random(); @@ -1625,7 +1625,7 @@ static int ecc_rand_func(uint8_t *dst, unsigned int len) return 1; } - +#endif // CONFIG_BT_CONTROLLER_ONLY #endif // CONFIG_BT_LE_SM_SC #endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS From f0ea86592c3e284cb8aa6437a1402a815feab6f1 Mon Sep 17 00:00:00 2001 From: Chen Chen Date: Mon, 8 Dec 2025 15:32:09 +0800 Subject: [PATCH 063/226] fix(isp): Added subwindow configuration for AWB --- .../esp_driver_isp/include/driver/isp_awb.h | 8 +++- components/esp_driver_isp/src/isp_awb.c | 47 ++++++++++++++++++- components/hal/esp32p4/include/hal/isp_ll.h | 22 +++++++++ components/hal/include/hal/isp_hal.h | 13 ++++- components/hal/isp_hal.c | 20 +++++++- 5 files changed, 106 insertions(+), 4 deletions(-) diff --git a/components/esp_driver_isp/include/driver/isp_awb.h b/components/esp_driver_isp/include/driver/isp_awb.h index 4cd508cd10..070c3390e5 100644 --- a/components/esp_driver_isp/include/driver/isp_awb.h +++ b/components/esp_driver_isp/include/driver/isp_awb.h @@ -27,12 +27,18 @@ typedef struct { * If your camera doesn't support the manual gain or don't want to change the camera configuration, * then you can choose to sample after CCM, and set the calculated gain to the CCM */ - isp_window_t window; /*!< Statistic window of AWB. + isp_window_t window; /*!< Statistic main window of AWB. * Suggest to set it at the middle of the image and a little smaller than the whole image. * It will be more reliable because the edges of image are easily to be overexposure, * the overexposure pixels are almost at maximum luminance, * which are not good references to calculate the gain for white balance. */ + isp_window_t subwindow; /*!< Statistic subwindow of AWB. + * Need to be set no greater than the main window. + * It will be evenly divided into a grid of ISP_AWB_WINDOW_X_NUM * ISP_AWB_WINDOW_Y_NUM blocks. + * The blocks share the same restrictions in R/G, B/G and luminance range as the main window. + * The statistics result of each block will be returned in the `isp_awb_stat_result_t::subwin_result` field. + */ struct { isp_u32_range_t luminance; /*!< Luminance range of the white patch. Range [0, 255 * 3] * Not suggest to set the max value to 255 * 3, diff --git a/components/esp_driver_isp/src/isp_awb.c b/components/esp_driver_isp/src/isp_awb.c index 28ab0393bb..d596d3ee19 100644 --- a/components/esp_driver_isp/src/isp_awb.c +++ b/components/esp_driver_isp/src/isp_awb.c @@ -14,6 +14,7 @@ #include "esp_heap_caps.h" #include "driver/isp_awb.h" #include "esp_private/isp_private.h" +#include "hal/efuse_hal.h" typedef struct isp_awb_controller_t { _Atomic isp_fsm_t fsm; @@ -71,14 +72,58 @@ static esp_err_t s_esp_isp_awb_config_hardware(isp_proc_handle_t isp_proc, const { isp_ll_awb_set_sample_point(isp_proc->hal.hw, awb_cfg->sample_point); ESP_RETURN_ON_FALSE(isp_hal_awb_set_window_range(&isp_proc->hal, &awb_cfg->window), - ESP_ERR_INVALID_ARG, TAG, "invalid window"); + ESP_ERR_INVALID_ARG, TAG, "invalid window range"); + + // Subwindow feature is only supported on REV >= 3.0 + if (efuse_hal_chip_revision() < 300) { + bool subwindow_is_zero = awb_cfg->subwindow.top_left.x == 0 && + awb_cfg->subwindow.top_left.y == 0 && + awb_cfg->subwindow.btm_right.x == 0 && + awb_cfg->subwindow.btm_right.y == 0; + if (!subwindow_is_zero) { + ESP_LOGW(TAG, "Subwindow feature is not supported on REV < 3.0, subwindow will not be configured"); + } + } + + isp_window_t subwindow = awb_cfg->subwindow; + ESP_RETURN_ON_FALSE( + (subwindow.top_left.x >= awb_cfg->window.top_left.x) && + (subwindow.top_left.y >= awb_cfg->window.top_left.y) && + (subwindow.btm_right.x <= awb_cfg->window.btm_right.x) && + (subwindow.btm_right.y <= awb_cfg->window.btm_right.y), + ESP_ERR_INVALID_ARG, TAG, "subwindow exceeds window range" + ); + + if ((subwindow.btm_right.x - subwindow.top_left.x + 1) / ISP_AWB_WINDOW_X_NUM < 4 || + (subwindow.btm_right.y - subwindow.top_left.y + 1) / ISP_AWB_WINDOW_Y_NUM < 4) { + ESP_LOGE(TAG, "subwindow block size is too small: width and height must be at least 4 (got %"PRIu32" x %"PRIu32")", + (subwindow.btm_right.x - subwindow.top_left.x + 1) / ISP_AWB_WINDOW_X_NUM, + (subwindow.btm_right.y - subwindow.top_left.y + 1) / ISP_AWB_WINDOW_Y_NUM); + return ESP_ERR_INVALID_ARG; + } + + int size_x = subwindow.btm_right.x - subwindow.top_left.x + 1; + int size_y = subwindow.btm_right.y - subwindow.top_left.y + 1; + if ((size_x % ISP_AWB_WINDOW_X_NUM != 0) || (size_y % ISP_AWB_WINDOW_Y_NUM != 0)) { + ESP_LOGW(TAG, "subwindow size (%d x %d) is not divisible by AWB subwindow blocks grid (%d x %d). \ + Resolution will be floored to the nearest divisible value.", + size_x, size_y, ISP_AWB_WINDOW_X_NUM, ISP_AWB_WINDOW_Y_NUM); + // floor to the nearest divisible value + subwindow.btm_right.x -= size_x % ISP_AWB_WINDOW_X_NUM; + subwindow.btm_right.y -= size_y % ISP_AWB_WINDOW_Y_NUM; + } + ESP_RETURN_ON_FALSE(isp_hal_awb_set_subwindow_range(&isp_proc->hal, &subwindow), + ESP_ERR_INVALID_ARG, TAG, "invalid subwindow range"); + isp_u32_range_t lum_range = awb_cfg->white_patch.luminance; ESP_RETURN_ON_FALSE(isp_hal_awb_set_luminance_range(&isp_proc->hal, lum_range.min, lum_range.max), ESP_ERR_INVALID_ARG, TAG, "invalid luminance range"); + isp_float_range_t rg_range = awb_cfg->white_patch.red_green_ratio; ESP_RETURN_ON_FALSE(rg_range.min < rg_range.max && rg_range.min >= 0 && isp_hal_awb_set_rg_ratio_range(&isp_proc->hal, rg_range.min, rg_range.max), ESP_ERR_INVALID_ARG, TAG, "invalid range of Red Green ratio"); + isp_float_range_t bg_range = awb_cfg->white_patch.blue_green_ratio; ESP_RETURN_ON_FALSE(bg_range.min < bg_range.max && bg_range.min >= 0 && isp_hal_awb_set_bg_ratio_range(&isp_proc->hal, bg_range.min, bg_range.max), diff --git a/components/hal/esp32p4/include/hal/isp_ll.h b/components/hal/esp32p4/include/hal/isp_ll.h index d5abfc435d..6e94d189ff 100644 --- a/components/hal/esp32p4/include/hal/isp_ll.h +++ b/components/hal/esp32p4/include/hal/isp_ll.h @@ -1723,6 +1723,23 @@ static inline uint32_t isp_ll_awb_get_accumulated_b_value(isp_dev_t *hw) } #if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 +/** + * @brief Set AWB subwindow range + * + * @param[in] hw Hardware instance address + * @param[in] top_left_x Top left pixel x axis value + * @param[in] top_left_y Top left pixel y axis value + * @param[in] sub_window_xsize Subwindow x size (minimum 4) + * @param[in] sub_window_ysize Subwindow y size (minimum 4) + */ +static inline void isp_ll_awb_set_subwindow_range(isp_dev_t *hw, uint32_t top_left_x, uint32_t top_left_y, uint32_t sub_window_xsize, uint32_t sub_window_ysize) +{ + hw->awb_bx.awb_x_start = top_left_x; + hw->awb_bx.awb_x_bsize = sub_window_xsize; + hw->awb_by.awb_y_start = top_left_y; + hw->awb_by.awb_y_bsize = sub_window_ysize; +} + /** * @brief Enable AWB white balance gain * @@ -1758,6 +1775,11 @@ static inline void isp_ll_awb_set_wb_gain(isp_dev_t *hw, isp_wbg_gain_t gain) hw->wbg_coef_b.wbg_b = gain.gain_b; } #else +static inline void isp_ll_awb_set_subwindow_range(isp_dev_t *hw, uint32_t top_left_x, uint32_t top_left_y, uint32_t sub_window_xsize, uint32_t sub_window_ysize) +{ + // for compatibility +} + static inline void isp_ll_awb_enable_wb_gain(isp_dev_t *hw, bool enable) { //for compatibility diff --git a/components/hal/include/hal/isp_hal.h b/components/hal/include/hal/isp_hal.h index a8eb6b502d..952c43445c 100644 --- a/components/hal/include/hal/isp_hal.h +++ b/components/hal/include/hal/isp_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -132,6 +132,17 @@ void isp_hal_ae_window_config(isp_hal_context_t *hal, const isp_window_t *window */ bool isp_hal_awb_set_window_range(isp_hal_context_t *hal, const isp_window_t *win); +/** + * @brief Set the subwindow range of the AWB + * + * @param[in] hal Context of the HAL layer + * @param[in] win Pointer to the subwindow of the AWB + * @return + * - true Set success + * - false Invalid arg + */ +bool isp_hal_awb_set_subwindow_range(isp_hal_context_t *hal, const isp_window_t *win); + /** * @brief Set the luminance range of the white patch * diff --git a/components/hal/isp_hal.c b/components/hal/isp_hal.c index 6dc1cad264..592f83b3ff 100644 --- a/components/hal/isp_hal.c +++ b/components/hal/isp_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -66,6 +66,24 @@ bool isp_hal_awb_set_window_range(isp_hal_context_t *hal, const isp_window_t *wi return true; } +bool isp_hal_awb_set_subwindow_range(isp_hal_context_t *hal, const isp_window_t *win) +{ + if (win->top_left.x > win->btm_right.x || + win->top_left.y > win->btm_right.y || + win->btm_right.x > ISP_LL_AWB_WINDOW_MAX_RANGE || + win->btm_right.y > ISP_LL_AWB_WINDOW_MAX_RANGE) { + return false; + } + isp_ll_awb_set_subwindow_range( + hal->hw, + win->top_left.x, + win->top_left.y, + (win->btm_right.x - win->top_left.x) / SOC_ISP_AWB_WINDOW_X_NUMS, + (win->btm_right.y - win->top_left.y) / SOC_ISP_AWB_WINDOW_Y_NUMS + ); + return true; +} + bool isp_hal_awb_set_luminance_range(isp_hal_context_t *hal, uint32_t lum_min, uint32_t lum_max) { if (lum_min > lum_max || lum_max > ISP_LL_AWB_LUM_MAX_RANGE) { From 1de00c8ac9398963a8f1a4ad5129c32fe0336187 Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Mon, 27 Oct 2025 17:31:40 +0800 Subject: [PATCH 064/226] fix(ble/bluedroid): Fixed GATT response timeout setting --- components/bt/host/bluedroid/stack/gatt/gatt_utils.c | 7 +------ .../bt/host/bluedroid/stack/gatt/include/gatt_int.h | 9 ++++++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c index 5565169a78..5f4afcfd95 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c @@ -1296,14 +1296,9 @@ BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid_rec, UINT16 uuid_size, UINT8 * void gatt_start_rsp_timer(UINT16 clcb_idx) { tGATT_CLCB *p_clcb = gatt_clcb_find_by_idx(clcb_idx); - UINT32 timeout = GATT_WAIT_FOR_RSP_TOUT; p_clcb->rsp_timer_ent.param = (TIMER_PARAM_TYPE)p_clcb; - if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && - p_clcb->op_subtype == GATT_DISC_SRVC_ALL) { - timeout = GATT_WAIT_FOR_DISC_RSP_TOUT; - } btu_start_timer (&p_clcb->rsp_timer_ent, BTU_TTYPE_ATT_WAIT_FOR_RSP, - timeout); + GATT_WAIT_FOR_RSP_TOUT); } /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h index 778e7d92bf..8701c746d1 100644 --- a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -76,9 +76,12 @@ typedef UINT8 tGATT_SEC_ACTION; #define GATT_HDR_SIZE 3 /* 1B opcode + 2B handle */ -/* wait for ATT cmd response timeout value */ -#define GATT_WAIT_FOR_RSP_TOUT 30 -#define GATT_WAIT_FOR_DISC_RSP_TOUT 15 +/** + * Wait for ATT cmd response timeout value (40 seconds). + * The max connection supervision timeout is 32 seconds, + * And The ATT cmd may not be sent out by controller immediately. + */ +#define GATT_WAIT_FOR_RSP_TOUT 40 #define GATT_REQ_RETRY_LIMIT 2 #define GATT_WAIT_FOR_IND_ACK_TOUT 5 From 027290be826bf3d0f7761ebba01cc22f7800c4c8 Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Thu, 4 Sep 2025 17:24:58 +0800 Subject: [PATCH 065/226] feat(ble/bluedroid): Add more debug log for bluedroid --- components/bt/common/include/bt_common.h | 10 ++++ components/bt/common/include/bt_user_config.h | 18 +++++++ components/bt/common/osi/allocator.c | 8 ++- components/bt/common/osi/thread.c | 50 +++++++++++++++++ components/bt/host/bluedroid/Kconfig.in | 41 +++++++++++--- .../host/bluedroid/bta/gatt/bta_gattc_act.c | 6 +++ .../bt/host/bluedroid/bta/gatt/bta_gattc_co.c | 4 +- .../host/bluedroid/bta/gatt/bta_gattc_utils.c | 5 +- .../bluedroid/bta/include/bta/bta_gatt_api.h | 2 + .../common/include/common/bt_trace.h | 8 +++ components/bt/host/bluedroid/hci/hci_layer.c | 28 ++++++++++ .../bt/host/bluedroid/hci/packet_fragmenter.c | 3 +- .../bt/host/bluedroid/stack/btm/btm_acl.c | 2 +- .../bt/host/bluedroid/stack/btm/btm_ble.c | 32 +++++------ .../host/bluedroid/stack/btm/btm_ble_bgconn.c | 1 + .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 1 + .../bt/host/bluedroid/stack/btm/btm_dev.c | 10 ++-- .../host/bluedroid/stack/gatt/att_protocol.c | 4 +- .../bt/host/bluedroid/stack/gatt/gatt_main.c | 3 +- .../bt/host/bluedroid/stack/gatt/gatt_sr.c | 4 +- .../bt/host/bluedroid/stack/gatt/gatt_utils.c | 5 +- .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 6 +++ .../bt/host/bluedroid/stack/l2cap/l2c_api.c | 2 + .../bt/host/bluedroid/stack/l2cap/l2c_ble.c | 32 +++++------ .../bt/host/bluedroid/stack/l2cap/l2c_utils.c | 3 ++ .../bt/host/bluedroid/stack/smp/smp_act.c | 54 +++++++++---------- .../bt/host/bluedroid/stack/smp/smp_api.c | 4 +- .../bt/host/bluedroid/stack/smp/smp_keys.c | 12 +++-- .../bt/host/bluedroid/stack/smp/smp_utils.c | 3 +- 29 files changed, 264 insertions(+), 97 deletions(-) diff --git a/components/bt/common/include/bt_common.h b/components/bt/common/include/bt_common.h index f687e3afe7..098082f647 100644 --- a/components/bt/common/include/bt_common.h +++ b/components/bt/common/include/bt_common.h @@ -61,6 +61,16 @@ #define HEAP_MEMORY_DEBUG FALSE #endif +#if UC_BT_BLUEDROID_THREAD_DEBUG +#define OSI_THREAD_DEBUG TRUE +#else +#define OSI_THREAD_DEBUG FALSE +#endif + +#define OSI_THREAD_BLOCK_TIME UC_BT_BLUEDROID_THREAD_BLOCK_TIME + +#define OSI_THREAD_BLOCK_MSG UC_BT_BLUEDROID_THREAD_BLOCK_MSG + #ifndef BT_BLE_DYNAMIC_ENV_MEMORY #define BT_BLE_DYNAMIC_ENV_MEMORY FALSE #endif diff --git a/components/bt/common/include/bt_user_config.h b/components/bt/common/include/bt_user_config.h index 5632b5fe22..2d695fa1c3 100644 --- a/components/bt/common/include/bt_user_config.h +++ b/components/bt/common/include/bt_user_config.h @@ -107,6 +107,24 @@ #define UC_BT_BLUEDROID_MEM_DEBUG FALSE #endif +#ifdef CONFIG_BT_BLUEDROID_THREAD_DEBUG +#define UC_BT_BLUEDROID_THREAD_DEBUG TRUE +#else +#define UC_BT_BLUEDROID_THREAD_DEBUG FALSE +#endif + +#ifdef CONFIG_BT_BLUEDROID_THREAD_BLOCK_TIME +#define UC_BT_BLUEDROID_THREAD_BLOCK_TIME CONFIG_BT_BLUEDROID_THREAD_BLOCK_TIME +#else +#define UC_BT_BLUEDROID_THREAD_BLOCK_TIME 1000 +#endif + +#ifdef CONFIG_BT_BLUEDROID_THREAD_BLOCK_MSG +#define UC_BT_BLUEDROID_THREAD_BLOCK_MSG CONFIG_BT_BLUEDROID_THREAD_BLOCK_MSG +#else +#define UC_BT_BLUEDROID_THREAD_BLOCK_MSG 50 +#endif + #ifdef CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST #define UC_HEAP_ALLOCATION_FROM_SPIRAM_FIRST CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST #else diff --git a/components/bt/common/osi/allocator.c b/components/bt/common/osi/allocator.c index 0293daa8c4..91ec942eb5 100644 --- a/components/bt/common/osi/allocator.c +++ b/components/bt/common/osi/allocator.c @@ -216,7 +216,9 @@ void *osi_malloc_func(size_t size) void *p = osi_malloc_base(size); if (size != 0 && p == NULL) { - OSI_TRACE_ERROR("malloc failed (caller=%p size=%u)\n", __builtin_return_address(0), size); + OSI_TRACE_ERROR("malloc failed (caller=%p size=%u)", __builtin_return_address(0), size); + OSI_TRACE_ERROR("heap info: free=%d, largest_block=%d", + heap_caps_get_free_size(MALLOC_CAP_DEFAULT), heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT)); #if HEAP_ALLOCATION_FAILS_ABORT assert(0); #endif @@ -230,7 +232,9 @@ void *osi_calloc_func(size_t size) void *p = osi_calloc_base(size); if (size != 0 && p == NULL) { - OSI_TRACE_ERROR("calloc failed (caller=%p size=%u)\n", __builtin_return_address(0), size); + OSI_TRACE_ERROR("calloc failed (caller=%p size=%u)", __builtin_return_address(0), size); + OSI_TRACE_ERROR("heap info: free=%d, largest_block=%d", + heap_caps_get_free_size(MALLOC_CAP_DEFAULT), heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT)); #if HEAP_ALLOCATION_FAILS_ABORT assert(0); #endif diff --git a/components/bt/common/osi/thread.c b/components/bt/common/osi/thread.c index 91bc7906ce..95475670be 100644 --- a/components/bt/common/osi/thread.c +++ b/components/bt/common/osi/thread.c @@ -61,6 +61,10 @@ struct osi_event { static const size_t DEFAULT_WORK_QUEUE_CAPACITY = 100; +#if OSI_THREAD_DEBUG +static void osi_thread_run_item(osi_thread_t *thread, int wq_idx, struct work_item *item); +#endif + static struct work_queue *osi_work_queue_create(size_t capacity) { if (capacity == 0) { @@ -162,7 +166,11 @@ static void osi_thread_run(void *arg) struct work_item item; while (!thread->stop && idx < thread->work_queue_num) { if (osi_thead_work_queue_get(thread->work_queues[idx], &item) == true) { + #if OSI_THREAD_DEBUG + osi_thread_run_item(thread, idx, &item); + #else item.func(item.context); + #endif idx = 0; continue; } else { @@ -451,3 +459,45 @@ bool osi_thread_post_event(struct osi_event *event, uint32_t timeout) return ret; } + +#if OSI_THREAD_DEBUG +static void osi_thread_run_item(osi_thread_t *thread, int wq_idx, struct work_item *item) +{ + uint32_t pre_time; + uint32_t pre_msg_cnt; + uint32_t cur_time; + uint32_t cur_msg_cnt; + + pre_time = esp_log_timestamp(); + pre_msg_cnt = uxQueueMessagesWaiting(thread->work_queues[wq_idx]->queue); + item->func(item->context); + cur_time = esp_log_timestamp(); + cur_msg_cnt = uxQueueMessagesWaiting(thread->work_queues[wq_idx]->queue); + if ((cur_time - pre_time) >= OSI_THREAD_BLOCK_TIME || + (cur_msg_cnt > pre_msg_cnt && (cur_msg_cnt - pre_msg_cnt) >= OSI_THREAD_BLOCK_MSG)) { + OSI_TRACE_ERROR("%s was blocked while running item: %p exec_time=[%u %u] msg_inc=[%u %u]", + pcTaskGetName(thread->thread_handle), item->func, cur_time, pre_time, cur_msg_cnt, pre_msg_cnt); + assert(0); + } +} + +void osi_thread_workqueue_dump(osi_thread_t *thread) +{ + int idx = 0; + struct work_item item; + + vTaskSuspendAll(); + + while (idx < thread->work_queue_num) { + if (osi_thead_work_queue_get(thread->work_queues[idx], &item) == true) { + esp_rom_printf("[%u] %p %p\n", idx, item.func, item.context); + idx = 0; + continue; + } else { + idx++; + } + } + + xTaskResumeAll(); +} +#endif // OSI_THREAD_DEBUG diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 929e539919..2bd78f05f1 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -33,13 +33,6 @@ config BT_BTU_TASK_STACK_SIZE help This select btu task stack size -config BT_BLUEDROID_MEM_DEBUG - bool "Bluedroid memory debug" - depends on BT_BLUEDROID_ENABLED - default n - help - Bluedroid memory debug - config BT_BLUEDROID_ESP_COEX_VSC bool "Enable Espressif Vendor-specific HCI commands for coexist status configuration" depends on BT_BLUEDROID_ENABLED @@ -481,6 +474,40 @@ config BT_BLE_RPA_SUPPORTED For other BLE chips, devices support network privacy mode and device privacy mode, users can switch the two modes according to their own needs. So this option is enabled by default. +menu "Bluedroid debug option" + config BT_BLUEDROID_MEM_DEBUG + bool "Bluedroid memory debug" + depends on BT_BLUEDROID_ENABLED + default n + help + Bluedroid memory debug + + config BT_BLUEDROID_THREAD_DEBUG + bool "Bluedroid thread debug" + depends on BT_BLUEDROID_ENABLED + default n + help + Enable Bluedroid thread debug mode. + Used to debug whether the thread is blocked and + dump information about the thread’s related work queue. + + config BT_BLUEDROID_THREAD_BLOCK_TIME + int "OSI thread block time (in ms)" + depends on BT_BLUEDROID_THREAD_DEBUG + default 1000 + help + Indicates how long it takes for the thread to execute an item + before it is considered blocked. + + config BT_BLUEDROID_THREAD_BLOCK_MSG + int "OSI thread block message count" + depends on BT_BLUEDROID_THREAD_DEBUG + default 50 + help + Indicates how many messages are added to the queue + while the threadis executing an item before it is considered blocked. +endmenu #BT debug option + config BT_STACK_NO_LOG bool "Disable BT debug logs (minimize bin size)" depends on BT_BLUEDROID_ENABLED diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c index bbbc1ba09f..07ebff2877 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c @@ -736,6 +736,7 @@ void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) #if (GATTC_CACHE_NVS == TRUE) p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD; if (bta_gattc_cache_load(p_clcb)) { + APPL_TRACE_DEBUG("%s found gattc cache", __func__); p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE; bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK); //register service change @@ -743,6 +744,7 @@ void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) } else #endif { /* cache is building */ + APPL_TRACE_DEBUG("%s cache not found, start discovery %u", __func__, bta_gattc_cb.auto_disc); if (bta_gattc_cb.auto_disc) { p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC; /* cache load failure, start discovery */ @@ -1856,6 +1858,8 @@ void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg) UINT8 i; UNUSED(p_cb); + APPL_TRACE_DEBUG("%s", __func__); + if (p_srvc_cb != NULL) { /* try to find a CLCB */ if (p_srvc_cb->connected && p_srvc_cb->num_clcb != 0) { @@ -1974,6 +1978,8 @@ void bta_gattc_process_api_cache_clean(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_m tBTA_GATTC_SERV *p_srvc_cb = bta_gattc_find_srvr_cache(p_msg->api_clean.remote_bda); UNUSED(p_cb); + APPL_TRACE_DEBUG("%s", __func__); + if (p_srvc_cb != NULL && p_srvc_cb->p_srvc_cache != NULL) { //mark it and delete the cache */ list_free(p_srvc_cb->p_srvc_cache); diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_co.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_co.c index 8ec3a55dff..d6ca7bca47 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_co.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_co.c @@ -444,6 +444,8 @@ void bta_gattc_co_cache_addr_init(void) void bta_gattc_co_cache_addr_deinit(void) { + APPL_TRACE_DEBUG("%s is_open=%d", __func__, cache_env->is_open); + if(!cache_env->is_open) { return; } @@ -553,7 +555,7 @@ void bta_gattc_co_cache_addr_save(BD_ADDR bd_addr, hash_key_t hash_key) memcpy(cache_env->cache_addr[new_index].addr, bd_addr, sizeof(BD_ADDR)); memcpy(cache_env->cache_addr[new_index].hash_key, hash_key, sizeof(hash_key_t)); cache_env->num_addr++; - APPL_TRACE_DEBUG("%s(), num = %d", __func__, cache_env->num_addr); + APPL_TRACE_DEBUG("%s bd_addr="MACSTR" num=%d", __func__, MAC2STR(bd_addr), cache_env->num_addr); } nvs_handle_t *fp = &cache_env->addr_fp; diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c index 18632d2dfa..4b2d019252 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c @@ -327,6 +327,8 @@ void bta_gattc_clcb_dealloc_by_conn_id(UINT16 conn_id) { tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); + APPL_TRACE_DEBUG("%s conn_id=%u p_clcb=%p", __func__, conn_id, p_clcb); + if (p_clcb) { tBTA_GATTC_RCB *p_clreg = p_clcb->p_rcb; bta_gattc_clcb_dealloc(p_clcb); @@ -523,8 +525,7 @@ BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) cmd_data->api_write.p_value = (UINT8 *)(cmd_data + 1); memcpy(cmd_data->api_write.p_value, p_data->api_write.p_value, len); } else { - APPL_TRACE_ERROR("%s(), line = %d, alloc fail, size %d, no memory. free=%d, largest_block=%d", __func__, __LINE__, - sizeof(tBTA_GATTC_DATA) + len, heap_caps_get_free_size(MALLOC_CAP_DEFAULT), heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT)); + APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memory.", __func__, __LINE__); return FALSE; } } else { diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h index 7819b8a718..7c2a4c154c 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h @@ -39,9 +39,11 @@ #endif +#if (APPL_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_DEBUG) #ifndef BTA_GATT_DEBUG #define BTA_GATT_DEBUG FALSE #endif +#endif typedef enum { BTGATT_DB_PRIMARY_SERVICE, diff --git a/components/bt/host/bluedroid/common/include/common/bt_trace.h b/components/bt/host/bluedroid/common/include/common/bt_trace.h index bd3b1ed8fc..85ddbe58d4 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_trace.h +++ b/components/bt/host/bluedroid/common/include/common/bt_trace.h @@ -57,6 +57,14 @@ static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t l #define BTTRC_DUMP_BUFFER(_prefix, _data, _len) #endif +#ifndef MAC2STR +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" +#endif + +/* Support up to 64 bytes of buffer */ +const char *bt_hex2str(const void *buf, size_t len); + //static const char BTE_LOGMSG_MODULE[] = "bte_logmsg_module"; /* BTrgs);E tracing IDs for debug purposes */ diff --git a/components/bt/host/bluedroid/hci/hci_layer.c b/components/bt/host/bluedroid/hci/hci_layer.c index f87b7f7c8f..c6a6efa4ee 100644 --- a/components/bt/host/bluedroid/hci/hci_layer.c +++ b/components/bt/host/bluedroid/hci/hci_layer.c @@ -51,6 +51,10 @@ #define HCI_DOWNSTREAM_DATA_QUEUE_IDX (0) +#ifndef MIN +#define MIN(a,b) (((a)<(b))?(a):(b)) +#endif + typedef struct { bool timer_is_set; osi_alarm_t *command_response_timer; @@ -711,3 +715,27 @@ const char *hci_status_code_to_string(uint8_t status) } } #endif + +const char *bt_hex2str(const void *buf, size_t len) +{ + static const char hex[] = "0123456789abcdef"; + static char str[129]; + const uint8_t *b = buf; + size_t i; + + len = MIN(len, (sizeof(str) - 1) / 2); + + for (i = 0; i < len; i++) { + str[i * 2] = hex[b[i] >> 4]; + str[i * 2 + 1] = hex[b[i] & 0xf]; + } + + str[i * 2] = '\0'; + + return str; +} + +int get_hci_work_queue_size(int wq_idx) +{ + return osi_thread_queue_wait_size(hci_host_thread, wq_idx); +} diff --git a/components/bt/host/bluedroid/hci/packet_fragmenter.c b/components/bt/host/bluedroid/hci/packet_fragmenter.c index f0ee531433..ccc220fbf1 100644 --- a/components/bt/host/bluedroid/hci/packet_fragmenter.c +++ b/components/bt/host/bluedroid/hci/packet_fragmenter.c @@ -180,8 +180,7 @@ static void reassemble_and_dispatch(BT_HDR *packet) partial_packet = (BT_HDR *)osi_calloc(full_length + sizeof(BT_HDR)); if (partial_packet == NULL) { - HCI_TRACE_WARNING("%s full_length %d no memory, free=%d, largest_block=%d", __func__, full_length, - heap_caps_get_free_size(MALLOC_CAP_DEFAULT), heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT)); + HCI_TRACE_WARNING("%s full_length %d no memory.", __func__, full_length); assert(0); } diff --git a/components/bt/host/bluedroid/stack/btm/btm_acl.c b/components/bt/host/bluedroid/stack/btm/btm_acl.c index 6350f4ba26..fc4b44a277 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_acl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_acl.c @@ -786,7 +786,7 @@ void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable) tBTM_SEC_DEV_REC *p_dev_rec; tBTM_BL_ROLE_CHG_DATA evt; - BTM_TRACE_DEBUG ("btm_acl_encrypt_change handle=%d status=%d encr_enabl=%d\n", + BTM_TRACE_DEBUG ("btm_acl_encrypt_change handle=%d status=%d encr_enable=%d\n", handle, status, encr_enable); p = btm_handle_to_acl(handle); if (p == NULL) { diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble.c b/components/bt/host/bluedroid/stack/btm/btm_ble.c index d65e632931..a99614e93c 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble.c @@ -77,18 +77,16 @@ BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE d tBTM_SEC_DEV_REC *p_dev_rec; tBTM_INQ_INFO *p_info = NULL; - BTM_TRACE_DEBUG ("BTM_SecAddBleDevice dev_type=0x%x", dev_type); + BTM_TRACE_DEBUG ("%s dev_type=0x%x bd_addr="MACSTR"", __func__, dev_type, MAC2STR(bd_addr)); p_dev_rec = btm_find_dev (bd_addr); if (!p_dev_rec) { - BTM_TRACE_DEBUG("Add a new device"); - /* There is no device record, allocate one. * If we can not find an empty spot for this one, let it fail. */ if (list_length(btm_cb.p_sec_dev_rec_list) < BTM_SEC_MAX_DEVICE_RECORDS) { - p_dev_rec = (tBTM_SEC_DEV_REC *)osi_malloc(sizeof(tBTM_SEC_DEV_REC)); - if(p_dev_rec) { - list_append(btm_cb.p_sec_dev_rec_list, p_dev_rec); + p_dev_rec = (tBTM_SEC_DEV_REC *)osi_malloc(sizeof(tBTM_SEC_DEV_REC)); + if (p_dev_rec) { + list_append(btm_cb.p_sec_dev_rec_list, p_dev_rec); BTM_TRACE_DEBUG ("allocate a new dev rec idx=0x%x\n", list_length(btm_cb.p_sec_dev_rec_list)); /* Mark this record as in use and initialize */ @@ -158,22 +156,20 @@ BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE d BOOLEAN BTM_SecAddBleKey (BD_ADDR bd_addr, tBTM_LE_KEY_VALUE *p_le_key, tBTM_LE_KEY_TYPE key_type) { tBTM_SEC_DEV_REC *p_dev_rec; - BTM_TRACE_DEBUG ("BTM_SecAddBleKey"); p_dev_rec = btm_find_dev (bd_addr); + if (!p_dev_rec || !p_le_key || (key_type != BTM_LE_KEY_PENC && key_type != BTM_LE_KEY_PID && key_type != BTM_LE_KEY_PCSRK && key_type != BTM_LE_KEY_LENC && key_type != BTM_LE_KEY_LCSRK && key_type != BTM_LE_KEY_LID)) { - BTM_TRACE_WARNING ("BTM_SecAddBleKey() Wrong Type, or No Device record \ - for bdaddr: %08x%04x, Type: %d", - (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3], - (bd_addr[4] << 8) + bd_addr[5], key_type); + BTM_TRACE_WARNING ("BTM_SecAddBleKey() Wrong Type, or No Device record \ + for bdaddr: "MACSTR", key_type: %02x", + MAC2STR(bd_addr), key_type); return (FALSE); } - BTM_TRACE_DEBUG ("BTM_SecAddLeKey() BDA: %08x%04x, Type: 0x%02x", - (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3], - (bd_addr[4] << 8) + bd_addr[5], key_type); + BTM_TRACE_DEBUG ("BTM_SecAddLeKey() BDA: "MACSTR", key_type: 0x%02x", + MAC2STR(bd_addr), key_type); btm_sec_save_le_key (bd_addr, key_type, p_le_key, FALSE); @@ -1759,15 +1755,14 @@ void btm_ble_ltk_request_reply(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk) tBTM_CB *p_cb = &btm_cb; if (p_rec == NULL) { - BTM_TRACE_ERROR("btm_ble_ltk_request_reply received for unknown device"); + BTM_TRACE_ERROR("%s received for unknown device "MACSTR"", __func__, MAC2STR(bda)); return; } - BTM_TRACE_DEBUG ("btm_ble_ltk_request_reply"); + BTM_TRACE_DEBUG ("%s key_type=%x key_size=%d", __func__, p_rec->ble.key_type, p_rec->ble.keys.key_size); p_cb->enc_handle = p_rec->ble_hci_handle; p_cb->key_size = p_rec->ble.keys.key_size; - BTM_TRACE_DEBUG("key size = %d", p_rec->ble.keys.key_size); if (use_stk) { btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, stk); } else { /* calculate LTK using peer device */ @@ -2047,7 +2042,8 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced) STREAM_TO_UINT8 (role, p); STREAM_TO_UINT8 (bda_type, p); STREAM_TO_BDADDR (bda, p); - BTM_TRACE_DEBUG("status = %d, handle = %d, role = %d, bda_type = %d",status,handle,role,bda_type); + BTM_TRACE_DEBUG("status=%d handle=%d role=%d bda_type=%d bda="MACSTR"", + status, handle, role, bda_type, MAC2STR(bda)); if (status == 0) { if (enhanced) { STREAM_TO_BDADDR (local_rpa, p); diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c index 1eb67844f1..b418bd70f7 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c @@ -821,6 +821,7 @@ tBTM_BLE_CONN_ST btm_ble_get_conn_st(void) *******************************************************************************/ void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st) { + BTM_TRACE_DEBUG("%s old=%u new=%u", __func__, btm_cb.ble_ctr_cb.conn_state, new_st); btm_cb.ble_ctr_cb.conn_state = new_st; if (new_st == BLE_BG_CONN || new_st == BLE_DIR_CONN) { diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index e43185e72d..61580de047 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -2136,6 +2136,7 @@ void BTM_Recovery_Pre_State(void) { #if ((BLE_42_ADV_EN == TRUE) || (BLE_42_SCAN_EN == TRUE)) tBTM_BLE_INQ_CB *ble_inq_cb = &btm_cb.ble_ctr_cb.inq_var; + BTM_TRACE_DEBUG("%s state=0x%x", __func__, ble_inq_cb->state); #endif // #if ((BLE_42_ADV_EN == TRUE) || (BLE_42_SCAN_EN == TRUE)) #if (BLE_42_ADV_EN == TRUE) if (ble_inq_cb->state & BTM_BLE_ADVERTISING) { diff --git a/components/bt/host/bluedroid/stack/btm/btm_dev.c b/components/bt/host/bluedroid/stack/btm/btm_dev.c index 1784d4a353..cc5ad3358b 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_dev.c +++ b/components/bt/host/bluedroid/stack/btm/btm_dev.c @@ -73,9 +73,11 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, /* There is no device record, allocate one. * If we can not find an empty spot for this one, let it fail. */ if (list_length(btm_cb.p_sec_dev_rec_list) < BTM_SEC_MAX_DEVICE_RECORDS) { - p_dev_rec = (tBTM_SEC_DEV_REC *)osi_malloc(sizeof(tBTM_SEC_DEV_REC)); - if(p_dev_rec) { - list_append(btm_cb.p_sec_dev_rec_list, p_dev_rec); + p_dev_rec = (tBTM_SEC_DEV_REC *)osi_malloc(sizeof(tBTM_SEC_DEV_REC)); + if(p_dev_rec) { + BTM_TRACE_DEBUG("%s alloc a new dev rec %p bd_addr="MACSTR"", + __func__, p_dev_rec, MAC2STR(bd_addr)); + list_append(btm_cb.p_sec_dev_rec_list, p_dev_rec); /* Mark this record as in use and initialize */ memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC)); p_dev_rec->sec_flags = BTM_SEC_IN_USE; @@ -360,6 +362,8 @@ tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr) if (list_length(btm_cb.p_sec_dev_rec_list) < BTM_SEC_MAX_DEVICE_RECORDS){ p_dev_new_rec = (tBTM_SEC_DEV_REC *)osi_malloc(sizeof(tBTM_SEC_DEV_REC)); if (p_dev_new_rec) { + BTM_TRACE_DEBUG("%s alloc a new dev rec %p bd_addr="MACSTR"", + __func__, p_dev_new_rec, MAC2STR(bd_addr)); new_entry_found = TRUE; malloc_new_entry = TRUE; } else { diff --git a/components/bt/host/bluedroid/stack/gatt/att_protocol.c b/components/bt/host/bluedroid/stack/gatt/att_protocol.c index ea7776e4c7..c16967c6ef 100644 --- a/components/bt/host/bluedroid/stack/gatt/att_protocol.c +++ b/components/bt/host/bluedroid/stack/gatt/att_protocol.c @@ -495,7 +495,7 @@ BT_HDR *attp_build_sr_msg(tGATT_TCB *p_tcb, UINT8 op_code, tGATT_SR_MSG *p_msg) ** Description This function sends the server response or indication message ** to client. ** -** Parameter p_tcb: pointer to the connection control block. +** Parameter p_tcb: pointer to the connection control block. ** p_msg: pointer to message parameters structure. ** ** Returns GATT_SUCCESS if successfully sent; otherwise error code. @@ -661,7 +661,7 @@ tGATT_STATUS attp_send_cl_msg (tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code, if (p_cmd != NULL) { status = attp_cl_send_cmd(p_tcb, clcb_idx, op_code, p_cmd); } - + GATT_TRACE_DEBUG("%s opcode=%x status=%x", __func__, op_code, status); } else { GATT_TRACE_ERROR("Peer device not connected"); } diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_main.c b/components/bt/host/bluedroid/stack/gatt/gatt_main.c index 4eaae0d302..f92a2c392b 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_main.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_main.c @@ -997,6 +997,7 @@ void gatt_data_process (tGATT_TCB *p_tcb, BT_HDR *p_buf) pseudo_op_code = op_code & (~GATT_WRITE_CMD_MASK); if (pseudo_op_code < GATT_OP_CODE_MAX) { + GATT_TRACE_DEBUG("%s opcode=%x msg_len=%u", __func__, op_code, msg_len); if (op_code == GATT_SIGN_CMD_WRITE) { #if (SMP_INCLUDED == TRUE) gatt_verify_signature(p_tcb, p_buf); @@ -1222,7 +1223,6 @@ tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB *p_tcb) { tGATT_CH_STATE ch_state = GATT_CH_CLOSE; if (p_tcb) { - GATT_TRACE_DEBUG ("gatt_get_ch_state: ch_state=%d", p_tcb->ch_state); ch_state = p_tcb->ch_state; } return ch_state; @@ -1235,6 +1235,7 @@ uint16_t gatt_get_local_mtu(void) void gatt_set_local_mtu(uint16_t mtu) { + GATT_TRACE_DEBUG("%s mtu=%u", __func__, mtu); gatt_default.local_mtu = mtu; } diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c index 5947239cf1..585a4c921a 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c @@ -405,7 +405,7 @@ tGATT_STATUS gatt_sr_process_app_rsp (tGATT_TCB *p_tcb, tGATT_IF gatt_if, tGATT_STATUS ret_code = GATT_SUCCESS; UNUSED(trans_id); - GATT_TRACE_DEBUG("gatt_sr_process_app_rsp gatt_if=%d\n", gatt_if); + GATT_TRACE_DEBUG("gatt_sr_process_app_rsp gatt_if=%d opcode=%x\n", gatt_if, op_code); gatt_sr_update_cback_cnt(p_tcb, gatt_if, FALSE, FALSE); @@ -1827,6 +1827,7 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code, { /* there is pending command, discard this one */ if (!gatt_sr_cmd_empty(p_tcb) && op_code != GATT_HANDLE_VALUE_CONF) { + GATT_TRACE_WARNING("%s discard command opcode=%02x", __func__, op_code); return; } @@ -1891,6 +1892,7 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code, break; default: + GATT_TRACE_ERROR("%s unknown command opcode=%02x", __func__, op_code); break; } } diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c index 5f4afcfd95..ae99c39a9f 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c @@ -1364,7 +1364,8 @@ void gatt_rsp_timeout(TIMER_LIST_ENT *p_tle) } } - GATT_TRACE_WARNING("gatt_rsp_timeout disconnecting..."); + GATT_TRACE_WARNING("gatt_rsp_timeout conn_id=%x op=%u op_sub=%u retry_count=%u disconnecting...", + p_clcb->conn_id, p_clcb->operation, p_clcb->op_subtype, p_clcb->retry_count); gatt_disconnect (p_clcb->p_tcb); } @@ -1806,7 +1807,7 @@ void gatt_clcb_dealloc (tGATT_CLCB *p_clcb) btu_free_timer(&p_clcb->rsp_timer_ent); memset(p_clcb, 0, sizeof(tGATT_CLCB)); list_remove(gatt_cb.p_clcb_list, p_clcb); - p_clcb = NULL; + p_clcb = NULL; } } diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index c44e974fff..9ddbc6271a 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -618,6 +618,8 @@ BOOLEAN btsnd_hcic_ble_start_enc (UINT16 handle, UINT8 rand[HCIC_BLE_RAND_DI_SIZ BT_HDR *p; UINT8 *pp; + HCI_TRACE_DEBUG("%s handle=%u LTK=%s", __func__, handle, bt_hex2str(ltk, HCIC_BLE_ENCRYT_KEY_SIZE)); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_START_ENC)) == NULL) { return (FALSE); } @@ -644,6 +646,8 @@ BOOLEAN btsnd_hcic_ble_ltk_req_reply (UINT16 handle, UINT8 ltk[HCIC_BLE_ENCRYT_K BT_HDR *p; UINT8 *pp; + HCI_TRACE_DEBUG("%s handle=%u LTK=%s", __func__, handle, bt_hex2str(ltk, HCIC_BLE_ENCRYT_KEY_SIZE)); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_LTK_REQ_REPLY)) == NULL) { return (FALSE); } @@ -668,6 +672,8 @@ BOOLEAN btsnd_hcic_ble_ltk_req_neg_reply (UINT16 handle) BT_HDR *p; UINT8 *pp; + HCI_TRACE_WARNING("%s handle=%u", __func__, handle); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_LTK_REQ_NEG_REPLY)) == NULL) { return (FALSE); } diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c index 8030df8078..b7fbbbdcfc 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c @@ -1907,6 +1907,8 @@ BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda) tL2C_CCB *p_ccb; tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; + L2CAP_TRACE_DEBUG("%s cid=%04x bda="MACSTR"", __func__, fixed_cid, MAC2STR(rem_bda)); + /* Check CID is valid and registered */ if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL) || (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL) ) { diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c index 88d18b08a2..39ba389451 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c @@ -92,6 +92,8 @@ BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda) { tL2C_LCB *p_lcb; + L2CAP_TRACE_DEBUG("%s rem_bda="MACSTR"", __func__, MAC2STR(rem_bda)); + /* There can be only one BLE connection request outstanding at a time */ if (btm_ble_get_conn_st() == BLE_CONN_IDLE) { L2CAP_TRACE_WARNING ("L2CA_CancelBleConnectReq - no connection pending"); @@ -99,10 +101,8 @@ BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda) } if (memcmp (rem_bda, l2cb.ble_connecting_bda, BD_ADDR_LEN)) { - L2CAP_TRACE_WARNING ("L2CA_CancelBleConnectReq - different BDA Connecting: %08x%04x Cancel: %08x%04x", - (l2cb.ble_connecting_bda[0] << 24) + (l2cb.ble_connecting_bda[1] << 16) + (l2cb.ble_connecting_bda[2] << 8) + l2cb.ble_connecting_bda[3], - (l2cb.ble_connecting_bda[4] << 8) + l2cb.ble_connecting_bda[5], - (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3], (rem_bda[4] << 8) + rem_bda[5]); + L2CAP_TRACE_WARNING ("L2CA_CancelBleConnectReq - different BDA Connecting: "MACSTR" Cancel: "MACSTR"", + MAC2STR(l2cb.ble_connecting_bda), MAC2STR(rem_bda)); return (FALSE); } @@ -148,16 +148,12 @@ BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_in /* If we don't have one, create one and accept the connection. */ if (!p_lcb || !p_acl_cb) { - L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x", - (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3], - (rem_bda[4] << 8) + rem_bda[5]); + L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - unknown BD_ADDR "MACSTR"", MAC2STR(rem_bda)); return (FALSE); } if (p_lcb->transport != BT_TRANSPORT_LE) { - L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE", - (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3], - (rem_bda[4] << 8) + rem_bda[5]); + L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - BD_ADDR "MACSTR" not LE", MAC2STR(rem_bda)); return (FALSE); } @@ -172,7 +168,7 @@ BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_in if (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PARAM_FULL){ status = HCI_ERR_ILLEGAL_COMMAND; need_cb = true; - L2CAP_TRACE_ERROR("There are two connection parameter requests that are being updated, please try later "); + L2CAP_TRACE_ERROR("%s connection parameter update in progress, please try later", __func__); } if ((need_cb == TRUE) && (conn_callback_func.update_conn_param_cb != NULL)) { @@ -221,20 +217,16 @@ BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable) p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE); if (!p_lcb) { - L2CAP_TRACE_WARNING ("L2CA_EnableUpdateBleConnParams - unknown BD_ADDR %08x%04x", - (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3], - (rem_bda[4] << 8) + rem_bda[5]); + L2CAP_TRACE_WARNING ("L2CA_EnableUpdateBleConnParams - unknown BD_ADDR "MACSTR"", MAC2STR(rem_bda)); return (FALSE); } - L2CAP_TRACE_API ("%s - BD_ADDR %08x%04x enable %d current upd state 0x%02x", __FUNCTION__, - (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3], - (rem_bda[4] << 8) + rem_bda[5], enable, p_lcb->conn_update_mask); + L2CAP_TRACE_API ("%s - BD_ADDR "MACSTR" enable %d current upd state 0x%02x", + __func__, MAC2STR(rem_bda), enable, p_lcb->conn_update_mask); if (p_lcb->transport != BT_TRANSPORT_LE) { - L2CAP_TRACE_WARNING ("%s - BD_ADDR %08x%04x not LE (link role %d)", __FUNCTION__, - (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3], - (rem_bda[4] << 8) + rem_bda[5], p_lcb->link_role); + L2CAP_TRACE_WARNING ("%s - BD_ADDR "MACSTR" not LE (link role %d)", + __func__, MAC2STR(rem_bda), p_lcb->link_role); return (FALSE); } diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c index 97cae231f7..0d3fed93d1 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c @@ -158,6 +158,9 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb) { tL2C_CCB *p_ccb; + L2CAP_TRACE_DEBUG("%s handle=%u bda="MACSTR"", + __func__, p_lcb->handle, MAC2STR(p_lcb->remote_bd_addr)); + p_lcb->in_use = FALSE; p_lcb->is_bonding = FALSE; #if (BLE_INCLUDED == TRUE) diff --git a/components/bt/host/bluedroid/stack/smp/smp_act.c b/components/bt/host/bluedroid/stack/smp/smp_act.c index b467a1c13d..d05e1a7f7d 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_act.c +++ b/components/bt/host/bluedroid/stack/smp/smp_act.c @@ -79,7 +79,7 @@ static bool lmp_version_below(BD_ADDR bda, uint8_t version) *******************************************************************************/ static void smp_update_key_mask (tSMP_CB *p_cb, UINT8 key_type, BOOLEAN recv) { - SMP_TRACE_DEBUG("%s before update role=%d recv=%d local_i_key = %02x, local_r_key = %02x\n", + SMP_TRACE_DEBUG("%s before update role=%d recv=%d local_i_key = %02x, local_r_key = %02x", __func__, p_cb->role, recv, p_cb->local_i_key, p_cb->local_r_key); if (((p_cb->le_secure_connections_mode_is_used) || @@ -103,8 +103,8 @@ static void smp_update_key_mask (tSMP_CB *p_cb, UINT8 key_type, BOOLEAN recv) } } - SMP_TRACE_DEBUG("updated local_i_key = %02x, local_r_key = %02x\n", p_cb->local_i_key, - p_cb->local_r_key); + SMP_TRACE_DEBUG("updated local_i_key = %02x, local_r_key = %02x", + p_cb->local_i_key, p_cb->local_r_key); } /******************************************************************************* @@ -115,7 +115,7 @@ void smp_send_app_cback(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { tSMP_EVT_DATA cb_data; tSMP_STATUS callback_rc; - SMP_TRACE_DEBUG("%s p_cb->cb_evt=%d\n", __func__, p_cb->cb_evt); + SMP_TRACE_DEBUG("%s cb_evt=%d", __func__, p_cb->cb_evt); if (p_cb->p_callback && p_cb->cb_evt != 0) { switch (p_cb->cb_evt) { case SMP_IO_CAP_REQ_EVT: @@ -171,11 +171,11 @@ void smp_send_app_cback(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) p_cb->local_r_key = 0; } - SMP_TRACE_DEBUG ("rcvd auth_req: 0x%02x, io_cap: %d \ - loc_oob_flag: %d loc_enc_size: %d," - "local_i_key: 0x%02x, local_r_key: 0x%02x\n", - p_cb->loc_auth_req, p_cb->local_io_capability, p_cb->loc_oob_flag, - p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key); + SMP_TRACE_DEBUG ("rcvd auth_req: 0x%02x, io_cap: %d," + "loc_oob_flag: %d loc_enc_size: %d," + "local_i_key: 0x%02x, local_r_key: 0x%02x", + p_cb->loc_auth_req, p_cb->local_io_capability, p_cb->loc_oob_flag, + p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key); p_cb->secure_connections_only_mode_required = (btm_cb.security_mode == BTM_SEC_MODE_SC) ? TRUE : FALSE; @@ -222,8 +222,6 @@ void smp_send_app_cback(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) p_cb->discard_sec_req = FALSE; smp_sm_event(p_cb, SMP_DISCARD_SEC_REQ_EVT, NULL); } - - SMP_TRACE_DEBUG("%s return\n", __func__); } /******************************************************************************* @@ -249,7 +247,7 @@ void smp_send_pair_fail(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) *******************************************************************************/ void smp_send_pair_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { - SMP_TRACE_DEBUG("%s\n", __func__); + SMP_TRACE_DEBUG("%s", __func__); #if (BLE_INCLUDED == TRUE) tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (p_cb->pairing_bda); @@ -269,7 +267,7 @@ void smp_send_pair_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) *******************************************************************************/ void smp_send_pair_rsp(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { - SMP_TRACE_DEBUG("%s\n", __func__); + SMP_TRACE_DEBUG("%s", __func__); #if (BLE_INCLUDED == TRUE) p_cb->local_i_key &= p_cb->peer_i_key; @@ -291,7 +289,7 @@ void smp_send_pair_rsp(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) *******************************************************************************/ void smp_send_confirm(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { - SMP_TRACE_DEBUG("%s\n", __func__); + SMP_TRACE_DEBUG("%s", __func__); smp_send_cmd(SMP_OPCODE_CONFIRM, p_cb); } @@ -313,7 +311,7 @@ void smp_send_init(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) *******************************************************************************/ void smp_send_rand(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { - SMP_TRACE_DEBUG("%s\n", __func__); + SMP_TRACE_DEBUG("%s", __func__); smp_send_cmd(SMP_OPCODE_RAND, p_cb); } @@ -323,7 +321,7 @@ void smp_send_rand(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) *******************************************************************************/ void smp_send_pair_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { - SMP_TRACE_DEBUG("%s\n", __func__); + SMP_TRACE_DEBUG("%s", __func__); smp_send_cmd(SMP_OPCODE_PAIR_PUBLIC_KEY, p_cb); } @@ -365,7 +363,7 @@ void smp_send_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { tBTM_LE_LENC_KEYS le_key; - SMP_TRACE_DEBUG("%s p_cb->loc_enc_size = %d\n", __func__, p_cb->loc_enc_size); + SMP_TRACE_DEBUG("%s loc_enc_size = %d", __func__, p_cb->loc_enc_size); smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ENC, FALSE); smp_send_cmd(SMP_OPCODE_ENCRYPT_INFO, p_cb); @@ -383,8 +381,6 @@ void smp_send_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) (tBTM_LE_KEY_VALUE *)&le_key, TRUE); } - SMP_TRACE_DEBUG ("%s\n", __func__); - smp_key_distribution(p_cb, NULL); #endif ///BLE_INCLUDED == TRUE } @@ -395,7 +391,7 @@ void smp_send_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) *******************************************************************************/ void smp_send_id_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { - SMP_TRACE_DEBUG("%s\n", __func__); + SMP_TRACE_DEBUG("%s", __func__); smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ID, FALSE); smp_send_cmd(SMP_OPCODE_IDENTITY_INFO, p_cb); @@ -420,7 +416,7 @@ void smp_send_id_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) void smp_send_csrk_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { tBTM_LE_LCSRK_KEYS key; - SMP_TRACE_DEBUG("%s\n", __func__); + SMP_TRACE_DEBUG("%s", __func__); smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_CSRK, FALSE); if (smp_send_cmd(SMP_OPCODE_SIGN_INFO, p_cb)) { @@ -455,12 +451,10 @@ void smp_proc_sec_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) tBTM_BLE_SEC_REQ_ACT sec_req_act; UINT8 reason; - SMP_TRACE_DEBUG("%s auth_req=0x%x", __func__, auth_req); - p_cb->cb_evt = 0; btm_ble_link_sec_check(p_cb->pairing_bda, auth_req, &sec_req_act); - SMP_TRACE_DEBUG("%s sec_req_act=0x%x", __func__, sec_req_act); + SMP_TRACE_DEBUG("%s auth_req=0x%x sec_req_act=0x%x", __func__, auth_req, sec_req_act); switch (sec_req_act) { case BTM_BLE_SEC_REQ_ACT_ENCRYPT: @@ -475,6 +469,8 @@ void smp_proc_sec_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) /* respond to non SC pairing request as failure in SC only mode */ if (p_cb->secure_connections_only_mode_required && (auth_req & SMP_SC_SUPPORT_BIT) == 0) { + SMP_TRACE_ERROR("%s SC mode not support, auth_req=0x%x", + __func__, auth_req); reason = SMP_PAIR_AUTH_FAIL; smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); } else { @@ -503,7 +499,7 @@ void smp_proc_sec_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) void smp_proc_sec_grant(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { UINT8 res = *(UINT8 *)p_data; - SMP_TRACE_DEBUG("%s", __func__); + SMP_TRACE_DEBUG("%s res=0x%x", __func__, res); if (res != SMP_SUCCESS) { smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, p_data); } else { /*otherwise, start pairing */ @@ -560,7 +556,7 @@ void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) UINT8 reason = SMP_ENC_KEY_SIZE; tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (p_cb->pairing_bda); - SMP_TRACE_DEBUG("%s\n", __func__); + SMP_TRACE_DEBUG("%s", __func__); /* erase all keys if it is slave proc pairing req*/ if (p_dev_rec && (p_cb->role == HCI_ROLE_SLAVE)) { btm_sec_clear_ble_keys(p_dev_rec); @@ -682,7 +678,7 @@ void smp_proc_confirm(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) UINT8 *p = (UINT8 *)p_data; UINT8 reason = SMP_INVALID_PARAMETERS; - SMP_TRACE_DEBUG("%s\n", __func__); + SMP_TRACE_DEBUG("%s", __func__); if (smp_command_has_invalid_parameters(p_cb)) { smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); @@ -1170,6 +1166,7 @@ void smp_proc_compare(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) } } else { + SMP_TRACE_ERROR("%s pairing failed - check confirm value error", __func__); reason = p_cb->failure = SMP_CONFIRM_VALUE_ERR; smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); } @@ -1213,6 +1210,7 @@ void smp_start_enc(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) } if (cmd != BTM_CMD_STARTED && cmd != BTM_BUSY) { + SMP_TRACE_ERROR("%s start encryption failed, cmd=0x%x", __func__, cmd); smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); } } @@ -1239,7 +1237,7 @@ void smp_enc_cmpl(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) UINT8 enc_enable = *(UINT8 *)p_data; UINT8 reason = enc_enable ? SMP_SUCCESS : SMP_ENC_FAIL; - SMP_TRACE_DEBUG("%s\n", __func__); + SMP_TRACE_DEBUG("%s %u", __func__, enc_enable); smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); } diff --git a/components/bt/host/bluedroid/stack/smp/smp_api.c b/components/bt/host/bluedroid/stack/smp/smp_api.c index b99c94abd8..4ae836e0a9 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_api.c +++ b/components/bt/host/bluedroid/stack/smp/smp_api.c @@ -236,7 +236,7 @@ BOOLEAN SMP_PairCancel (BD_ADDR bd_addr) if ( (p_cb->state != SMP_STATE_IDLE) && (!memcmp (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN)) ) { p_cb->is_pair_cancel = TRUE; - SMP_TRACE_DEBUG("Cancel Pairing: set fail reason Unknown"); + SMP_TRACE_ERROR("%s Cancel Pairing: set fail reason Unknown", __func__); smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &err_code); status = TRUE; } @@ -434,6 +434,8 @@ void SMP_OobDataReply(BD_ADDR bd_addr, tSMP_STATUS res, UINT8 len, UINT8 *p_data } if (res != SMP_SUCCESS || len == 0 || !p_data) { + SMP_TRACE_ERROR("%s pairing failed, res=0x%x len=%u p_data=%p", + __func__, res, len, p_data); smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure); } else { if (len > BT_OCTET16_LEN) { diff --git a/components/bt/host/bluedroid/stack/smp/smp_keys.c b/components/bt/host/bluedroid/stack/smp/smp_keys.c index 24ef814279..3b1d4ee8f1 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_keys.c +++ b/components/bt/host/bluedroid/stack/smp/smp_keys.c @@ -332,7 +332,7 @@ void smp_generate_stk(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) output.opcode = HCI_BLE_ENCRYPT; memcpy(output.param_buf, p_cb->ltk, SMP_ENCRYT_DATA_SIZE); } else if (!smp_calculate_legacy_short_term_key(p_cb, &output)) { - SMP_TRACE_ERROR("%s failed", __func__); + SMP_TRACE_ERROR("%s pairing failed", __func__); smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status); return; } @@ -459,7 +459,7 @@ void smp_compute_csrk(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) UINT16_TO_STREAM(p, r); if (!SMP_Encrypt(er, BT_OCTET16_LEN, buffer, 4, &output)) { - SMP_TRACE_ERROR("smp_generate_csrk failed\n"); + SMP_TRACE_ERROR("%s pairing failed", __func__); if (p_cb->smp_over_br) { #if (CLASSIC_BT_INCLUDED == TRUE) smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &status); @@ -664,7 +664,7 @@ void smp_calculate_comfirm (tSMP_CB *p_cb, BT_OCTET16 rand, BD_ADDR bda) /* calculate e(k, r XOR p1), where k = TK */ if (!SMP_Encrypt(p_cb->tk, BT_OCTET16_LEN, p1, BT_OCTET16_LEN, &output)) { - SMP_TRACE_ERROR("smp_generate_csrk failed"); + SMP_TRACE_ERROR("%s calculate TK failed", __func__); smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status); } else { smp_calculate_comfirm_cont(p_cb, &output); @@ -701,7 +701,7 @@ static void smp_calculate_comfirm_cont(tSMP_CB *p_cb, tSMP_ENC *p) /* calculate: Confirm = E(k, p1' XOR p2) */ if (!SMP_Encrypt(p_cb->tk, BT_OCTET16_LEN, p2, BT_OCTET16_LEN, &output)) { - SMP_TRACE_ERROR("smp_calculate_comfirm_cont failed\n"); + SMP_TRACE_ERROR("%s pairing failed", __func__); smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status); } else { SMP_TRACE_DEBUG("p_cb->rand_enc_proc_state=%d\n", p_cb->rand_enc_proc_state); @@ -861,7 +861,7 @@ static void smp_generate_ltk_cont(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) /* LTK = d1(ER, DIV, 0)= e(ER, DIV)*/ if (!SMP_Encrypt(er, BT_OCTET16_LEN, (UINT8 *)&p_cb->div, sizeof(UINT16), &output)) { - SMP_TRACE_ERROR("%s failed\n", __func__); + SMP_TRACE_ERROR("%s failed", __func__); smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status); } else { /* mask the LTK */ @@ -1373,6 +1373,8 @@ void smp_calculate_numeric_comparison_display_number(tSMP_CB *p_cb, } if (p_cb->number_to_display >= (BTM_MAX_PASSKEY_VAL + 1)) { + SMP_TRACE_ERROR("%s pairing failed - invalid number to display %u", + __func__, p_cb->number_to_display); UINT8 reason; reason = p_cb->failure = SMP_PAIR_FAIL_UNKNOWN; smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); diff --git a/components/bt/host/bluedroid/stack/smp/smp_utils.c b/components/bt/host/bluedroid/stack/smp/smp_utils.c index 8ec4d548ac..f4d0987029 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_utils.c +++ b/components/bt/host/bluedroid/stack/smp/smp_utils.c @@ -366,6 +366,7 @@ BOOLEAN smp_send_cmd(UINT8 cmd_code, tSMP_CB *p_cb) } if (!sent) { + SMP_TRACE_ERROR("%s failed, cmd_code=0x%02x", __func__, cmd_code); if (p_cb->smp_over_br) { #if (CLASSIC_BT_INCLUDED == TRUE) smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &failure); @@ -392,7 +393,7 @@ void smp_rsp_timeout(TIMER_LIST_ENT *p_tle) UINT8 failure = SMP_RSP_TIMEOUT; UNUSED(p_tle); - SMP_TRACE_EVENT("%s state:%d br_state:%d", __FUNCTION__, p_cb->state, p_cb->br_state); + SMP_TRACE_ERROR("%s state=%d br_state=%d", __func__, p_cb->state, p_cb->br_state); if (p_cb->smp_over_br) { #if (CLASSIC_BT_INCLUDED == TRUE) From 8d9343f807d18b768b984513766fcaf92fc6561d Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Tue, 16 Sep 2025 19:13:32 +0800 Subject: [PATCH 066/226] fix(bt/bluedroid): Fixed memory debug error --- components/bt/common/osi/include/osi/allocator.h | 1 + 1 file changed, 1 insertion(+) diff --git a/components/bt/common/osi/include/osi/allocator.h b/components/bt/common/osi/include/osi/allocator.h index d95040538d..071892ffaf 100644 --- a/components/bt/common/osi/include/osi/allocator.h +++ b/components/bt/common/osi/include/osi/allocator.h @@ -21,6 +21,7 @@ #include #include +#include "bt_common.h" #include "esp_heap_caps.h" char *osi_strdup(const char *str); From ad4943ee24d1eb04f441395e8934da4f4b9cdac7 Mon Sep 17 00:00:00 2001 From: yangfeng Date: Fri, 7 Nov 2025 16:42:16 +0800 Subject: [PATCH 067/226] fix(bt/example): Fixed hf_ag build error --- .../bluetooth/bluedroid/classic_bt/hfp_ag/main/bt_app_hf.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/bt_app_hf.c b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/bt_app_hf.c index c60bde9997..d4b0defcc4 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/bt_app_hf.c +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/bt_app_hf.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -25,7 +25,6 @@ #include "sdkconfig.h" #include "bt_app_core.h" #include "bt_app_hf.h" -#include "osi/allocator.h" const char *c_hf_evt_str[] = { "CONNECTION_STATE_EVT", /*!< SERVICE LEVEL CONNECTION STATE CONTROL */ @@ -231,7 +230,7 @@ static void bt_app_send_data_task(void *arg) if (frame_data_num == 0) { continue; } - buf = osi_malloc(frame_data_num); + buf = (uint8_t *)malloc(frame_data_num); if (!buf) { ESP_LOGE(BT_HF_TAG, "%s, no mem", __FUNCTION__); continue; @@ -241,7 +240,7 @@ static void bt_app_send_data_task(void *arg) if (!done) { ESP_LOGE(BT_HF_TAG, "rb send fail"); } - osi_free(buf); + free(buf); vRingbufferGetInfo(s_m_rb, NULL, NULL, NULL, NULL, &item_size); if(s_audio_code == ESP_HF_AUDIO_STATE_CONNECTED_MSBC) { From 2507849b6abfc654d9a2a88d132e30e4d3df44c6 Mon Sep 17 00:00:00 2001 From: Luo Xu Date: Tue, 30 Dec 2025 17:43:18 +0800 Subject: [PATCH 068/226] feat(ble_mesh): adapt blob cli&srv to long packet (cherry picked from commit a232b7c7af2672e0c3fecd7848824c39b3edbe63) Co-authored-by: luoxu --- .../include/esp_ble_mesh_blob_model_api.h | 2 ++ .../include/esp_ble_mesh_dfu_model_api.h | 2 ++ components/bt/esp_ble_mesh/v1.1/dfu/dfu_cli.c | 11 +++++++--- .../v1.1/include/mesh_v1.1/dfu/dfu_cli.h | 2 ++ .../v1.1/include/mesh_v1.1/mbt/blob.h | 2 ++ components/bt/esp_ble_mesh/v1.1/mbt/blob.h | 18 +++++++++++++++ .../bt/esp_ble_mesh/v1.1/mbt/blob_cli.c | 22 ++++++++++++++++++- .../bt/esp_ble_mesh/v1.1/mbt/blob_srv.c | 4 ++++ 8 files changed, 59 insertions(+), 4 deletions(-) diff --git a/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_blob_model_api.h b/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_blob_model_api.h index 165450ed56..0f9097262a 100644 --- a/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_blob_model_api.h +++ b/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_blob_model_api.h @@ -186,6 +186,8 @@ struct esp_ble_mesh_blob_xfer { esp_ble_mesh_blob_xfer_mode_t mode; /*!< BLOB transfer mode. */ uint8_t block_size_log; /*!< Logarithmic representation of the block size. */ uint16_t chunk_size; /*!< Base chunk size. May be smaller for the last chunk. */ + /* Enhanced parameters for message context in blob chunks */ + esp_ble_mesh_msg_enh_params_t chunk_enh_params; }; /** BLOB transfer data block. */ diff --git a/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_dfu_model_api.h b/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_dfu_model_api.h index 6ef42d3dd8..f2b2d121c1 100644 --- a/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_dfu_model_api.h +++ b/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_dfu_model_api.h @@ -782,6 +782,8 @@ struct esp_ble_mesh_dfu_cli_xfer_blob_params { uint8_t block_size_log; /** Base chunk size. May be smaller for the last chunk. */ uint16_t chunk_size; + /* Enhanced parameters for message context in blob chunks */ + esp_ble_mesh_msg_enh_params_t chunk_enh_params; }; /** Firmware Update Client transfer parameters */ diff --git a/components/bt/esp_ble_mesh/v1.1/dfu/dfu_cli.c b/components/bt/esp_ble_mesh/v1.1/dfu/dfu_cli.c index e5ff20c328..21eea26d43 100644 --- a/components/bt/esp_ble_mesh/v1.1/dfu/dfu_cli.c +++ b/components/bt/esp_ble_mesh/v1.1/dfu/dfu_cli.c @@ -1236,9 +1236,14 @@ int bt_mesh_dfu_cli_send(struct bt_mesh_dfu_cli *cli, cli->xfer.flags = 0U; if (xfer->blob_params) { - cli->xfer.flags |= FLAG_SKIP_CAPS_GET; - cli->xfer.blob.block_size_log = xfer->blob_params->block_size_log; - cli->xfer.blob.chunk_size = xfer->blob_params->chunk_size; + if (xfer->blob_params->block_size_log && + xfer->blob_params->chunk_size) { + cli->xfer.flags |= FLAG_SKIP_CAPS_GET; + cli->xfer.blob.block_size_log = xfer->blob_params->block_size_log; + cli->xfer.blob.chunk_size = xfer->blob_params->chunk_size; + } + memcpy(&cli->xfer.blob.chunk_enh_params, &xfer->blob_params->chunk_enh_params, + sizeof(bt_mesh_msg_enh_params_t)); } /* Phase will be set based on target status messages: */ diff --git a/components/bt/esp_ble_mesh/v1.1/include/mesh_v1.1/dfu/dfu_cli.h b/components/bt/esp_ble_mesh/v1.1/include/mesh_v1.1/dfu/dfu_cli.h index 531e359994..306af5fbad 100644 --- a/components/bt/esp_ble_mesh/v1.1/include/mesh_v1.1/dfu/dfu_cli.h +++ b/components/bt/esp_ble_mesh/v1.1/include/mesh_v1.1/dfu/dfu_cli.h @@ -243,6 +243,8 @@ struct bt_mesh_dfu_cli_xfer_blob_params { uint8_t block_size_log; /** Base chunk size. May be smaller for the last chunk. */ uint16_t chunk_size; + /* Enhanced parameters for message context in blob chunks */ + bt_mesh_msg_enh_params_t chunk_enh_params; }; /** Firmware Update Client transfer parameters: */ diff --git a/components/bt/esp_ble_mesh/v1.1/include/mesh_v1.1/mbt/blob.h b/components/bt/esp_ble_mesh/v1.1/include/mesh_v1.1/mbt/blob.h index 29199360a4..bd797e41ff 100644 --- a/components/bt/esp_ble_mesh/v1.1/include/mesh_v1.1/mbt/blob.h +++ b/components/bt/esp_ble_mesh/v1.1/include/mesh_v1.1/mbt/blob.h @@ -141,6 +141,8 @@ struct bt_mesh_blob_xfer { uint8_t block_size_log; /** Base chunk size. May be smaller for the last chunk. */ uint16_t chunk_size; + /* Enhanced parameters for message context in blob chunks */ + bt_mesh_msg_enh_params_t chunk_enh_params; }; /** BLOB stream interaction mode. */ diff --git a/components/bt/esp_ble_mesh/v1.1/mbt/blob.h b/components/bt/esp_ble_mesh/v1.1/mbt/blob.h index c539219d9e..79d09d89f4 100644 --- a/components/bt/esp_ble_mesh/v1.1/mbt/blob.h +++ b/components/bt/esp_ble_mesh/v1.1/mbt/blob.h @@ -34,19 +34,37 @@ #define BLOB_CHUNK_SIZE_MAX(sdu_max) ((sdu_max) - BLOB_CHUNK_SDU_OVERHEAD) #define BLOB_CHUNK_SDU_LEN(chunk_size) (BLOB_CHUNK_SDU_OVERHEAD + (chunk_size)) +#if CONFIG_BLE_MESH_LONG_PACKET +#if CONFIG_BLE_MESH_ALIGN_CHUNK_SIZE_TO_MAX_SEGMENT || \ + CONFIG_BLE_MESH_RX_BLOB_CHUNK_SIZE > BLOB_CHUNK_SIZE_MAX(BLE_MESH_EXT_RX_SDU_MAX) +#define BLOB_RX_CHUNK_SIZE BLOB_CHUNK_SIZE_MAX(BLE_MESH_EXT_RX_SDU_MAX) +#else +#define BLOB_RX_CHUNK_SIZE CONFIG_BLE_MESH_RX_BLOB_CHUNK_SIZE +#endif +#else // CONFIG_BLE_MESH_LONG_PACKET #if CONFIG_BLE_MESH_ALIGN_CHUNK_SIZE_TO_MAX_SEGMENT || \ CONFIG_BLE_MESH_RX_BLOB_CHUNK_SIZE > BLOB_CHUNK_SIZE_MAX(BLE_MESH_RX_SDU_MAX) #define BLOB_RX_CHUNK_SIZE BLOB_CHUNK_SIZE_MAX(BLE_MESH_RX_SDU_MAX) #else #define BLOB_RX_CHUNK_SIZE CONFIG_BLE_MESH_RX_BLOB_CHUNK_SIZE #endif +#endif +#if CONFIG_BLE_MESH_LONG_PACKET +#if CONFIG_BLE_MESH_ALIGN_CHUNK_SIZE_TO_MAX_SEGMENT || \ + CONFIG_BLE_MESH_TX_BLOB_CHUNK_SIZE > BLOB_CHUNK_SIZE_MAX(BLE_MESH_EXT_TX_SDU_MAX) +#define BLOB_TX_CHUNK_SIZE BLOB_CHUNK_SIZE_MAX(BLE_MESH_EXT_TX_SDU_MAX) +#else +#define BLOB_TX_CHUNK_SIZE CONFIG_BLE_MESH_TX_BLOB_CHUNK_SIZE +#endif +#else // CONFIG_BLE_MESH_LONG_PACKET #if CONFIG_BLE_MESH_ALIGN_CHUNK_SIZE_TO_MAX_SEGMENT || \ CONFIG_BLE_MESH_TX_BLOB_CHUNK_SIZE > BLOB_CHUNK_SIZE_MAX(BLE_MESH_TX_SDU_MAX) #define BLOB_TX_CHUNK_SIZE BLOB_CHUNK_SIZE_MAX(BLE_MESH_TX_SDU_MAX) #else #define BLOB_TX_CHUNK_SIZE CONFIG_BLE_MESH_TX_BLOB_CHUNK_SIZE #endif +#endif // CONFIG_BLE_MESH_LONG_PACKET /* Utility macros for calculating log2 of a number at compile time. * Used to determine the log2 representation of the block size, which diff --git a/components/bt/esp_ble_mesh/v1.1/mbt/blob_cli.c b/components/bt/esp_ble_mesh/v1.1/mbt/blob_cli.c index 9132829a23..435ef3b5bc 100644 --- a/components/bt/esp_ble_mesh/v1.1/mbt/blob_cli.c +++ b/components/bt/esp_ble_mesh/v1.1/mbt/blob_cli.c @@ -18,6 +18,8 @@ #if CONFIG_BLE_MESH_BLOB_CLI +#define CHUNK_SIZE_MAX BLOB_TX_CHUNK_SIZE + #define TARGETS_FOR_EACH(cli, target) \ SYS_SLIST_FOR_EACH_CONTAINER((sys_slist_t *)&(cli)->inputs->targets, \ target, n) @@ -49,7 +51,8 @@ _Static_assert((BLOB_BLOCK_STATUS_MSG_MAXLEN + BLE_MESH_MODEL_OP_LEN(BT_MESH_BLO BLE_MESH_MIC_SHORT) <= BLE_MESH_RX_SDU_MAX, "The BLOB Block Status message does not fit into the maximum incoming SDU size."); -NET_BUF_SIMPLE_DEFINE_STATIC(chunk_buf, BLE_MESH_TX_SDU_MAX); +NET_BUF_SIMPLE_DEFINE_STATIC(chunk_buf, BLOB_CHUNK_SDU_LEN(CHUNK_SIZE_MAX)); +static bool chunk_sending; struct block_status { enum bt_mesh_blob_status status; @@ -591,6 +594,12 @@ static int tx(struct bt_mesh_blob_cli *cli, uint16_t addr, .addr = addr, .send_ttl = cli->inputs->ttl, }; + + if (chunk_sending) { + memcpy(&ctx.enh, &cli->xfer->chunk_enh_params, + sizeof(bt_mesh_msg_enh_params_t)); + } + int err; err = bt_mesh_model_send((struct bt_mesh_model *)cli->mod, &ctx, buf, &end_cb, cli); @@ -615,6 +624,10 @@ static void send_end(int err, void *user_data) { struct bt_mesh_blob_cli *cli = user_data; + if (chunk_sending) { + chunk_sending = false; + } + if (!cli->tx.ctx.is_inited) { return; } @@ -642,7 +655,12 @@ static void xfer_start_tx(struct bt_mesh_blob_cli *cli, uint16_t dst) net_buf_simple_add_le64(&buf, cli->xfer->id); net_buf_simple_add_le32(&buf, cli->xfer->size); net_buf_simple_add_u8(&buf, cli->xfer->block_size_log); +#if CONFIG_BLE_MESH_LONG_PACKET + /* todo: could let user select methold */ + net_buf_simple_add_le16(&buf, BLE_MESH_EXT_TX_SDU_MAX); +#else net_buf_simple_add_le16(&buf, BLE_MESH_TX_SDU_MAX); +#endif tx(cli, dst, &buf); } @@ -959,6 +977,8 @@ static void chunk_send(struct bt_mesh_blob_cli *cli) chunk_size(cli->xfer, &cli->block, cli->chunk_idx)); cli->state = BT_MESH_BLOB_CLI_STATE_BLOCK_SEND; + chunk_sending = true; + blob_cli_broadcast(cli, &ctx); } diff --git a/components/bt/esp_ble_mesh/v1.1/mbt/blob_srv.c b/components/bt/esp_ble_mesh/v1.1/mbt/blob_srv.c index 3540a6abea..88fe61ad0b 100644 --- a/components/bt/esp_ble_mesh/v1.1/mbt/blob_srv.c +++ b/components/bt/esp_ble_mesh/v1.1/mbt/blob_srv.c @@ -25,7 +25,11 @@ #if CONFIG_BLE_MESH_BLOB_SRV +#if CONFIG_BLE_MESH_LONG_PACKET +#define MTU_SIZE_MAX (BLE_MESH_EXT_RX_SDU_MAX - BLE_MESH_MIC_SHORT) +#else #define MTU_SIZE_MAX (BLE_MESH_RX_SDU_MAX - BLE_MESH_MIC_SHORT) +#endif /* The Receive BLOB Timeout Timer */ #define SERVER_TIMEOUT_SECS(srv) (10 * (1 + (srv)->state.timeout_base)) From 314fa586f52b8b62faf6abbab04ef1a64aeca184 Mon Sep 17 00:00:00 2001 From: Luo Xu Date: Mon, 29 Dec 2025 13:43:28 +0800 Subject: [PATCH 069/226] fix(ble_mesh): eliminate deprecated warning for mbt (cherry picked from commit b9d834edc70ac868e48c9df0f827240e93b4cd17) Co-authored-by: luoxu --- .../include/esp_ble_mesh_mbt_model_api.h | 2 +- .../v1.1/btc/include/btc_ble_mesh_mbt_model.h | 91 ++++++++++--------- 2 files changed, 49 insertions(+), 44 deletions(-) diff --git a/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_mbt_model_api.h b/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_mbt_model_api.h index 54b4f20aa8..38bfa103cf 100644 --- a/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_mbt_model_api.h +++ b/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_mbt_model_api.h @@ -14,7 +14,6 @@ #define _BLE_MESH_MBT_DEPRECATE_WARN #warning "warning: 'All content in this document, including data structures and APIs, will be deprecated." #endif -#endif /* CONFIG_BLE_MESH_MBT_SRV || CONFIG_BLE_MESH_MBT_CLI */ #ifdef __cplusplus extern "C" { @@ -773,4 +772,5 @@ esp_err_t esp_ble_mesh_mbt_server_get_blob_reception_progress(esp_ble_mesh_model } #endif +#endif /* CONFIG_BLE_MESH_MBT_SRV || CONFIG_BLE_MESH_MBT_CLI */ #endif /* _ESP_BLE_MESH_MBT_MODEL_API_H_ */ diff --git a/components/bt/esp_ble_mesh/v1.1/btc/include/btc_ble_mesh_mbt_model.h b/components/bt/esp_ble_mesh/v1.1/btc/include/btc_ble_mesh_mbt_model.h index 4bb82ed1a3..3a90a7739e 100644 --- a/components/bt/esp_ble_mesh/v1.1/btc/include/btc_ble_mesh_mbt_model.h +++ b/components/bt/esp_ble_mesh/v1.1/btc/include/btc_ble_mesh_mbt_model.h @@ -19,6 +19,9 @@ extern "C" { #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif +#define BTC_BLE_MESH_MBT_CLIENT_RESULT_COMPLETE 0x00 +#define BTC_BLE_MESH_MBT_CLIENT_RESULT_FAIL 0x01 + typedef enum { BTC_BLE_MESH_ACT_MBT_CLIENT_RETRIEVE_CAPABILITIES, BTC_BLE_MESH_ACT_MBT_CLIENT_TRANSFER_BLOB, @@ -36,6 +39,49 @@ typedef enum { BTC_BLE_MESH_ACT_MBT_CLIENT_MAX, } btc_ble_mesh_mbt_client_act_t; +typedef enum { + BTC_BLE_MESH_EVT_MBT_CLIENT_RETRIEVE_CAPABILITIES_COMP, + BTC_BLE_MESH_EVT_MBT_CLIENT_TRANSFER_BLOB_COMP, + BTC_BLE_MESH_EVT_MBT_CLIENT_SEND_BLOCK_COMP, + BTC_BLE_MESH_EVT_MBT_CLIENT_SEND_DATA_COMP, + BTC_BLE_MESH_EVT_MBT_CLIENT_DETERMINE_BLOCK_STATUS_COMP, + BTC_BLE_MESH_EVT_MBT_CLIENT_DETERMINE_TRANSFER_STATUS_COMP, + BTC_BLE_MESH_EVT_MBT_CLIENT_CANCEL_TRANSFER_COMP, + BTC_BLE_MESH_EVT_MBT_CLIENT_SET_TRANSFER_TTL_COMP, + BTC_BLE_MESH_EVT_MBT_CLIENT_CLEAR_TRANSFER_TTL_COMP, + BTC_BLE_MESH_EVT_MBT_CLIENT_SET_APP_IDX_COMP, + BTC_BLE_MESH_EVT_MBT_CLIENT_CLEAR_APP_IDX_COMP, + BTC_BLE_MESH_EVT_MBT_CLIENT_SET_MULTICAST_ADDR_COMP, + BTC_BLE_MESH_EVT_MBT_CLIENT_CLEAR_MULTICAST_ADDR_COMP, + BTC_BLE_MESH_EVT_MBT_CLIENT_MAX, +} btc_ble_mesh_mbt_client_evt_t; + +typedef enum { + BTC_BLE_MESH_ACT_MBT_SERVER_INITIALIZE_BLOB_RECEIVE, + BTC_BLE_MESH_ACT_MBT_SERVER_CANCEL_BLOB_RECEIVE, + BTC_BLE_MESH_ACT_MBT_SERVER_SET_BLOB_CAPABILITIES, + BTC_BLE_MESH_ACT_MBT_SERVER_MAX, +} btc_ble_mesh_mbt_server_act_t; + +typedef enum { + BTC_BLE_MESH_EVT_MBT_SERVER_INITIALIZE_BLOB_RECEIVE_COMP, + BTC_BLE_MESH_EVT_MBT_SERVER_CANCEL_BLOB_RECEIVE_COMP, + BTC_BLE_MESH_EVT_MBT_SERVER_SET_BLOB_CAPABILITIES_COMP, + BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_TRANSFER_GET, + BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_TRANSFER_START, + BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_TRANSFER_CANCEL, + BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_BLOCK_GET, + BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_BLOCK_START, + BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_CHUNK_TRANSFER, + BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_INFORMATION_GET, + BTC_BLE_MESH_EVT_MBT_SERVER_BLOCK_RECEIVE_COMP, + BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_RECEIVE_COMP, + BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_RECEIVE_TIMEOUT, + BTC_BLE_MESH_EVT_MBT_SERVER_MAX, +} btc_ble_mesh_mbt_server_evt_t; + +#if CONFIG_BLE_MESH_MBT_SRV || CONFIG_BLE_MESH_MBT_CLI + typedef union { esp_ble_mesh_retrieve_capabilities_t retrieve_capabilities; esp_ble_mesh_transfer_blob_t transfer_blob; @@ -67,26 +113,6 @@ typedef union { } clear_multicast_addr; } btc_ble_mesh_mbt_client_args_t; -#define BTC_BLE_MESH_MBT_CLIENT_RESULT_COMPLETE 0x00 -#define BTC_BLE_MESH_MBT_CLIENT_RESULT_FAIL 0x01 - -typedef enum { - BTC_BLE_MESH_EVT_MBT_CLIENT_RETRIEVE_CAPABILITIES_COMP, - BTC_BLE_MESH_EVT_MBT_CLIENT_TRANSFER_BLOB_COMP, - BTC_BLE_MESH_EVT_MBT_CLIENT_SEND_BLOCK_COMP, - BTC_BLE_MESH_EVT_MBT_CLIENT_SEND_DATA_COMP, - BTC_BLE_MESH_EVT_MBT_CLIENT_DETERMINE_BLOCK_STATUS_COMP, - BTC_BLE_MESH_EVT_MBT_CLIENT_DETERMINE_TRANSFER_STATUS_COMP, - BTC_BLE_MESH_EVT_MBT_CLIENT_CANCEL_TRANSFER_COMP, - BTC_BLE_MESH_EVT_MBT_CLIENT_SET_TRANSFER_TTL_COMP, - BTC_BLE_MESH_EVT_MBT_CLIENT_CLEAR_TRANSFER_TTL_COMP, - BTC_BLE_MESH_EVT_MBT_CLIENT_SET_APP_IDX_COMP, - BTC_BLE_MESH_EVT_MBT_CLIENT_CLEAR_APP_IDX_COMP, - BTC_BLE_MESH_EVT_MBT_CLIENT_SET_MULTICAST_ADDR_COMP, - BTC_BLE_MESH_EVT_MBT_CLIENT_CLEAR_MULTICAST_ADDR_COMP, - BTC_BLE_MESH_EVT_MBT_CLIENT_MAX, -} btc_ble_mesh_mbt_client_evt_t; - void btc_ble_mesh_mbt_client_call_handler(btc_msg_t *msg); void btc_ble_mesh_mbt_client_cb_handler(btc_msg_t *msg); @@ -103,12 +129,6 @@ void btc_ble_mesh_mbt_client_publish_callback(uint32_t opcode, void bt_mesh_mbt_client_cb_evt_to_btc(uint8_t event, uint8_t result, struct bt_mesh_model *model); -typedef enum { - BTC_BLE_MESH_ACT_MBT_SERVER_INITIALIZE_BLOB_RECEIVE, - BTC_BLE_MESH_ACT_MBT_SERVER_CANCEL_BLOB_RECEIVE, - BTC_BLE_MESH_ACT_MBT_SERVER_SET_BLOB_CAPABILITIES, - BTC_BLE_MESH_ACT_MBT_SERVER_MAX, -} btc_ble_mesh_mbt_server_act_t; typedef union { esp_ble_mesh_initialize_blob_receive_t initialize_blob_receive; @@ -116,23 +136,6 @@ typedef union { esp_ble_mesh_set_blob_capabilities_t set_blob_capabilities; } btc_ble_mesh_mbt_server_args_t; -typedef enum { - BTC_BLE_MESH_EVT_MBT_SERVER_INITIALIZE_BLOB_RECEIVE_COMP, - BTC_BLE_MESH_EVT_MBT_SERVER_CANCEL_BLOB_RECEIVE_COMP, - BTC_BLE_MESH_EVT_MBT_SERVER_SET_BLOB_CAPABILITIES_COMP, - BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_TRANSFER_GET, - BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_TRANSFER_START, - BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_TRANSFER_CANCEL, - BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_BLOCK_GET, - BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_BLOCK_START, - BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_CHUNK_TRANSFER, - BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_INFORMATION_GET, - BTC_BLE_MESH_EVT_MBT_SERVER_BLOCK_RECEIVE_COMP, - BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_RECEIVE_COMP, - BTC_BLE_MESH_EVT_MBT_SERVER_BLOB_RECEIVE_TIMEOUT, - BTC_BLE_MESH_EVT_MBT_SERVER_MAX, -} btc_ble_mesh_mbt_server_evt_t; - void btc_ble_mesh_mbt_server_call_handler(btc_msg_t *msg); void btc_ble_mesh_mbt_server_cb_handler(btc_msg_t *msg); @@ -141,6 +144,8 @@ void bt_mesh_mbt_server_cb_evt_to_btc(uint8_t event, struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx); +#endif /* CONFIG_BLE_MESH_MBT_SRV || CONFIG_BLE_MESH_MBT_CLI */ + #if CONFIG_IDF_CI_BUILD #pragma GCC diagnostic pop #endif From e703935a89dc770dfd2564ed24847f5938a0e63d Mon Sep 17 00:00:00 2001 From: Luo Xu Date: Fri, 19 Dec 2025 13:43:27 +0800 Subject: [PATCH 070/226] feat(ble_mesh): update ble mesh multi connections config (cherry picked from commit b63a0c2b78edb8cea296a7160266966b75307456) Co-authored-by: luoxu --- .../esp_ble_mesh/core/include/mesh/adapter.h | 32 ++++++------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/components/bt/esp_ble_mesh/core/include/mesh/adapter.h b/components/bt/esp_ble_mesh/core/include/mesh/adapter.h index 39c359d695..20c656e690 100644 --- a/components/bt/esp_ble_mesh/core/include/mesh/adapter.h +++ b/components/bt/esp_ble_mesh/core/include/mesh/adapter.h @@ -37,21 +37,12 @@ extern "C" { */ #ifdef CONFIG_BT_BLUEDROID_ENABLED #if CONFIG_IDF_TARGET_ESP32 -#define BLE_MESH_MAX_CONN 1 +#define BLE_MESH_MAX_CONN MIN(CONFIG_BT_ACL_CONNECTIONS, CONFIG_BTDM_CTRL_BLE_MAX_CONN) #elif (CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3) -/* @todo: must ensure CONFIG_BT_CTRL_BLE_MAX_ACT is greater than 2 */ -#if CONFIG_BT_ACL_CONNECTIONS > (CONFIG_BT_CTRL_BLE_MAX_ACT - 2) -/* decrease the adv,scan */ -#define BLE_MESH_MAX_CONN (CONFIG_BT_CTRL_BLE_MAX_ACT - 2) -#else -#define BLE_MESH_MAX_CONN CONFIG_BT_ACL_CONNECTIONS -#endif /* CONFIG_BT_ACL_CONNECTIONS > (CONFIG_BT_CTRL_BLE_MAX_ACT - 2) */ -#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5 -#if CONFIG_BT_ACL_CONNECTIONS > CONFIG_BT_LE_MAX_CONNECTIONS -#define BLE_MESH_MAX_CONN CONFIG_BT_LE_MAX_CONNECTIONS -#else -#define BLE_MESH_MAX_CONN CONFIG_BT_ACL_CONNECTIONS -#endif /* CONFIG_BT_ACL_CONNECTIONS > CONFIG_BT_LE_MAX_CONNECTIONS */ +#define BLE_MESH_MAX_CONN MIN(CONFIG_BT_ACL_CONNECTIONS, (CONFIG_BT_CTRL_BLE_MAX_ACT - 2)) +#elif (CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || \ + CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61) +#define BLE_MESH_MAX_CONN MIN(CONFIG_BT_ACL_CONNECTIONS, CONFIG_BT_LE_MAX_CONNECTIONS) #else /* default setting */ #define BLE_MESH_MAX_CONN 1 @@ -60,16 +51,11 @@ extern "C" { #ifdef CONFIG_BT_NIMBLE_ENABLED #if CONFIG_IDF_TARGET_ESP32 -#define BLE_MESH_MAX_CONN 1 +#define BLE_MESH_MAX_CONN MIN(CONFIG_BT_NIMBLE_MAX_CONNECTIONS, CONFIG_BTDM_CTRL_BLE_MAX_CONN) #elif (CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3) -/* @todo: must ensure CONFIG_BT_CTRL_BLE_MAX_ACT is greater than 2 */ -#if CONFIG_BT_NIMBLE_MAX_CONNECTIONS > (CONFIG_BT_CTRL_BLE_MAX_ACT - 2) -/* decrease the adv,scan */ -#define BLE_MESH_MAX_CONN (CONFIG_BT_CTRL_BLE_MAX_ACT - 2) -#else -#define BLE_MESH_MAX_CONN CONFIG_BT_NIMBLE_MAX_CONNECTIONS -#endif /* CONFIG_BT_NIMBLE_MAX_CONNECTIONS > (CONFIG_BT_CTRL_BLE_MAX_ACT - 2) */ -#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5 +#define BLE_MESH_MAX_CONN MIN(CONFIG_BT_NIMBLE_MAX_CONNECTIONS, (CONFIG_BT_CTRL_BLE_MAX_ACT - 2)) +#elif (CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || \ + CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61) #define BLE_MESH_MAX_CONN CONFIG_BT_NIMBLE_MAX_CONNECTIONS #else /* default setting */ From ca408103faf61f4e9fdf8848bed33f5317890ef4 Mon Sep 17 00:00:00 2001 From: luoxu Date: Thu, 11 Dec 2025 21:02:34 +0800 Subject: [PATCH 071/226] fix(ble_mesh): Fix start callback timing when GATT and ADV bearers coexist Add BLE_MESH_SEND_START_CB macro to ensure start callback is called exactly once when both GATT and ADV bearers are used. --- components/bt/esp_ble_mesh/core/adv.c | 8 +++-- components/bt/esp_ble_mesh/core/adv_common.h | 34 +++++++++++--------- components/bt/esp_ble_mesh/core/ext_adv.c | 6 ++-- components/bt/esp_ble_mesh/core/net.c | 13 ++++++-- 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/components/bt/esp_ble_mesh/core/adv.c b/components/bt/esp_ble_mesh/core/adv.c index 9a12e8c125..e35d34c993 100644 --- a/components/bt/esp_ble_mesh/core/adv.c +++ b/components/bt/esp_ble_mesh/core/adv.c @@ -42,6 +42,7 @@ static int adv_send(struct net_buf *buf) uint8_t adv_cnt = 0; struct bt_mesh_adv_data ad = {0}; int err = 0; + bool start_cb_called = (BLE_MESH_ADV(buf)->flags & BLE_MESH_ADV_FLAG_SKIP_START_CB); BT_DBG("LegacyAdvSend, Type %u", BLE_MESH_ADV(buf)->type); BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); @@ -175,7 +176,10 @@ static int adv_send(struct net_buf *buf) net_buf_unref(buf); - adv_send_start(duration, err, cb, cb_data); + if (!start_cb_called && cb && cb->start) { + cb->start(duration, err, cb_data); + } + if (err) { BT_ERR("Start advertising failed: err %d", err); return err; @@ -194,7 +198,7 @@ static int adv_send(struct net_buf *buf) err = bt_le_adv_stop(); #endif /* CONFIG_BLE_MESH_USE_BLE_50 */ - adv_send_end(err, cb, cb_data); + BLE_MESH_SEND_END_CB(err, cb, cb_data); if (err) { BT_ERR("Stop advertising failed: err %d", err); return 0; diff --git a/components/bt/esp_ble_mesh/core/adv_common.h b/components/bt/esp_ble_mesh/core/adv_common.h index 54267ee522..d7810c94d0 100644 --- a/components/bt/esp_ble_mesh/core/adv_common.h +++ b/components/bt/esp_ble_mesh/core/adv_common.h @@ -48,6 +48,9 @@ extern "C" { #define BLE_MESH_ADV_INST_UNUSED 0xFF +/* Flags for struct bt_mesh_adv */ +#define BLE_MESH_ADV_FLAG_SKIP_START_CB BIT(0) /* Skip start callback (already called by GATT) */ + struct bt_mesh_adv { const struct bt_mesh_send_cb *cb; void *cb_data; @@ -61,6 +64,7 @@ struct bt_mesh_adv { uint32_t adv_itvl; uint8_t adv_cnt; uint8_t channel_map; + uint8_t flags; /* See BLE_MESH_ADV_FLAG_* */ }; #if CONFIG_BLE_MESH_USE_BLE_50 @@ -214,22 +218,22 @@ static inline TickType_t K_WAIT(int32_t val) return (val == K_FOREVER) ? portMAX_DELAY : (val / portTICK_PERIOD_MS); } -static inline void adv_send_start(uint16_t duration, int err, - const struct bt_mesh_send_cb *cb, - void *cb_data) -{ - if (cb && cb->start) { - cb->start(duration, err, cb_data); - } -} +#define BLE_MESH_SEND_START_CB(_buf, _duration, _err, _cb, _cb_data) \ + do { \ + if (!(BLE_MESH_ADV(_buf)->flags & BLE_MESH_ADV_FLAG_SKIP_START_CB)) { \ + if ((_cb) && (_cb)->start) { \ + (_cb)->start((_duration), (_err), (_cb_data)); \ + } \ + BLE_MESH_ADV(_buf)->flags |= BLE_MESH_ADV_FLAG_SKIP_START_CB; \ + } \ + } while (0) -static inline void adv_send_end(int err, const struct bt_mesh_send_cb *cb, - void *cb_data) -{ - if (cb && cb->end) { - cb->end(err, cb_data); - } -} +#define BLE_MESH_SEND_END_CB(_err, _cb, _cb_data) \ + do { \ + if ((_cb) && (_cb)->end) { \ + (_cb)->end((_err), (_cb_data)); \ + } \ + } while (0) struct bt_mesh_adv_queue *bt_mesh_adv_queue_get(void); diff --git a/components/bt/esp_ble_mesh/core/ext_adv.c b/components/bt/esp_ble_mesh/core/ext_adv.c index 8b85076aed..c4feaa7a4e 100644 --- a/components/bt/esp_ble_mesh/core/ext_adv.c +++ b/components/bt/esp_ble_mesh/core/ext_adv.c @@ -181,7 +181,7 @@ static int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration) break; } - adv_send_start(duration, err, cb, cb_data); + BLE_MESH_SEND_START_CB(buf, duration, err, cb, cb_data); if (err) { BT_ERR("Start advertising failed: err %d", err); return err; @@ -381,8 +381,8 @@ static uint32_t received_adv_evts_handle(uint32_t recv_evts) } else #endif { - adv_send_end(0, BLE_MESH_ADV(adv_insts[i].sending_buf)->cb, - BLE_MESH_ADV(adv_insts[i].sending_buf)->cb_data); + BLE_MESH_SEND_END_CB(0, BLE_MESH_ADV(adv_insts[i].sending_buf)->cb, + BLE_MESH_ADV(adv_insts[i].sending_buf)->cb_data); bt_mesh_adv_buf_ref_debug(__func__, adv_insts[i].sending_buf, 4U, BLE_MESH_BUF_REF_SMALL); diff --git a/components/bt/esp_ble_mesh/core/net.c b/components/bt/esp_ble_mesh/core/net.c index fde5b5cdda..b436ce5d6b 100644 --- a/components/bt/esp_ble_mesh/core/net.c +++ b/components/bt/esp_ble_mesh/core/net.c @@ -1239,6 +1239,15 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, send_cb = NULL; goto done; } + + /* GATT bearer sends faster than ADV bearer, so the remote node + * may receive the message and respond before ADV bearer starts. + * To avoid issues where the start callback hasn't been called + * when the response arrives, we call the start callback here + * immediately after GATT bearer sends successfully. The ADV + * bearer will skip start callback since the flag is set. + */ + BLE_MESH_SEND_START_CB(buf, 0, 0, send_cb, cb_data); } } #endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */ @@ -1253,9 +1262,7 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, * See BLEMESH24-76 for more details. */ if (BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { - if (send_cb && send_cb->start) { - send_cb->start(0, 0, cb_data); - } + BLE_MESH_SEND_START_CB(buf, 0, 0, send_cb, cb_data); net_buf_slist_put(&bt_mesh.local_queue, net_buf_ref(buf)); From 923033ce6d523c817c578fbe52dbc89d4bc28334 Mon Sep 17 00:00:00 2001 From: luoxu Date: Wed, 17 Dec 2025 15:12:55 +0800 Subject: [PATCH 072/226] feat(ble_mesh): fix issues with advtypes --- components/bt/esp_ble_mesh/core/adv_common.c | 23 +++++++++++++++++++ components/bt/esp_ble_mesh/core/adv_common.h | 24 +------------------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/components/bt/esp_ble_mesh/core/adv_common.c b/components/bt/esp_ble_mesh/core/adv_common.c index ff4e50ac1c..cd6157e3bc 100644 --- a/components/bt/esp_ble_mesh/core/adv_common.c +++ b/components/bt/esp_ble_mesh/core/adv_common.c @@ -55,6 +55,29 @@ static bt_mesh_ext_adv_t ext_long_relay_adv_pool[CONFIG_BLE_MESH_LONG_PACKET_REL #endif /* CONFIG_BLE_MESH_LONG_PACKET */ #endif /* CONFIG_BLE_MESH_EXT_ADV */ +const uint8_t adv_type[] = { + [BLE_MESH_ADV_PROV] = BLE_MESH_DATA_MESH_PROV, + [BLE_MESH_ADV_DATA] = BLE_MESH_DATA_MESH_MESSAGE, +#if CONFIG_BLE_MESH_EXT_ADV + [BLE_MESH_ADV_EXT_PROV] = BLE_MESH_DATA_MESH_PROV, + [BLE_MESH_ADV_EXT_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE, + [BLE_MESH_ADV_EXT_DATA] = BLE_MESH_DATA_MESH_MESSAGE, +#if CONFIG_BLE_MESH_LONG_PACKET + [BLE_MESH_ADV_EXT_LONG_PROV] = BLE_MESH_DATA_MESH_PROV, + [BLE_MESH_ADV_EXT_LONG_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE, + [BLE_MESH_ADV_EXT_LONG_DATA] = BLE_MESH_DATA_MESH_MESSAGE, +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ +#if CONFIG_BLE_MESH_FRIEND + [BLE_MESH_ADV_FRIEND] = BLE_MESH_DATA_MESH_MESSAGE, +#endif +#if CONFIG_BLE_MESH_RELAY_ADV_BUF + [BLE_MESH_ADV_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE, +#endif + [BLE_MESH_ADV_BEACON] = BLE_MESH_DATA_MESH_BEACON, + [BLE_MESH_ADV_URI] = BLE_MESH_DATA_URI, +}; + static inline void init_adv_with_defaults(struct bt_mesh_adv *adv, enum bt_mesh_adv_type type) { diff --git a/components/bt/esp_ble_mesh/core/adv_common.h b/components/bt/esp_ble_mesh/core/adv_common.h index d7810c94d0..c52fc18cc3 100644 --- a/components/bt/esp_ble_mesh/core/adv_common.h +++ b/components/bt/esp_ble_mesh/core/adv_common.h @@ -175,29 +175,7 @@ typedef enum { BLE_MESH_BUF_REF_MAX, } bt_mesh_buf_ref_flag_t; - -static const uint8_t adv_type[] = { - [BLE_MESH_ADV_PROV] = BLE_MESH_DATA_MESH_PROV, - [BLE_MESH_ADV_DATA] = BLE_MESH_DATA_MESH_MESSAGE, -#if CONFIG_BLE_MESH_EXT_ADV - [BLE_MESH_ADV_EXT_PROV] = BLE_MESH_DATA_MESH_PROV, - [BLE_MESH_ADV_EXT_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE, - [BLE_MESH_ADV_EXT_DATA] = BLE_MESH_DATA_MESH_MESSAGE, -#if CONFIG_BLE_MESH_LONG_PACKET - [BLE_MESH_ADV_EXT_LONG_PROV] = BLE_MESH_DATA_MESH_PROV, - [BLE_MESH_ADV_EXT_LONG_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE, - [BLE_MESH_ADV_EXT_LONG_DATA] = BLE_MESH_DATA_MESH_MESSAGE, -#endif /* CONFIG_BLE_MESH_LONG_PACKET */ -#endif /* CONFIG_BLE_MESH_EXT_ADV */ -#if CONFIG_BLE_MESH_FRIEND - [BLE_MESH_ADV_FRIEND] = BLE_MESH_DATA_MESH_MESSAGE, -#endif -#if CONFIG_BLE_MESH_RELAY_ADV_BUF - [BLE_MESH_ADV_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE, -#endif - [BLE_MESH_ADV_BEACON] = BLE_MESH_DATA_MESH_BEACON, - [BLE_MESH_ADV_URI] = BLE_MESH_DATA_URI, -}; +extern const uint8_t adv_type[]; typedef struct bt_mesh_adv *(*bt_mesh_pool_allocator_t)(int id, enum bt_mesh_adv_type type); typedef void (*bt_mesh_adv_queue_send_cb_t)(bt_mesh_msg_t *msg, uint32_t timeout, bool front); From 07d4db1726c06a05b59ae9daa6981213cb3d1cba Mon Sep 17 00:00:00 2001 From: Luo Xu Date: Thu, 18 Dec 2025 17:43:16 +0800 Subject: [PATCH 073/226] fix(ble_mesh): fixed incorrect rpl behavior in transport enh (cherry picked from commit 29a722296f6de31cb96e47f8771dac7319fdb6dd) Co-authored-by: luoxu --- components/bt/esp_ble_mesh/core/transport.enh.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/bt/esp_ble_mesh/core/transport.enh.c b/components/bt/esp_ble_mesh/core/transport.enh.c index 967b523379..3147ee86a1 100644 --- a/components/bt/esp_ble_mesh/core/transport.enh.c +++ b/components/bt/esp_ble_mesh/core/transport.enh.c @@ -2528,10 +2528,6 @@ found_rx: } } - if (rpl) { - bt_mesh_update_rpl(rpl, net_rx); - } - /* Mark segment as received */ rx->block |= BIT(seg_o); @@ -2543,6 +2539,10 @@ found_rx: BT_DBG("Complete SDU"); + if (rpl) { + bt_mesh_update_rpl(rpl, net_rx); + } + *pdu_type = BLE_MESH_FRIEND_PDU_COMPLETE; /* Stop SAR Discard timer when processing result is Last Segment */ From 582267372931c0ac906d7d826146b13db404bbc7 Mon Sep 17 00:00:00 2001 From: Luo Xu Date: Wed, 26 Nov 2025 17:43:16 +0800 Subject: [PATCH 074/226] feat(ble_mesh): add ext log initialization functions (cherry picked from commit 7b7b9de28d2ba5c2ec3cb4930ec3cde5066e7eb9) Co-authored-by: luoxu --- components/bt/esp_ble_mesh/lib/ext.c | 109 ++++++++++++++++++++++++--- 1 file changed, 100 insertions(+), 9 deletions(-) diff --git a/components/bt/esp_ble_mesh/lib/ext.c b/components/bt/esp_ble_mesh/lib/ext.c index d9803b830a..3f654f82de 100644 --- a/components/bt/esp_ble_mesh/lib/ext.c +++ b/components/bt/esp_ble_mesh/lib/ext.c @@ -211,11 +211,6 @@ void bt_mesh_ext_mem_swap(void *buf, size_t length) sys_mem_swap(buf, length); } -uint32_t bt_mesh_ext_log_timestamp(void) -{ - return esp_log_timestamp(); -} - /* Net buf */ void bt_mesh_ext_buf_simple_init(struct net_buf_simple *buf, size_t reserve_head) { @@ -4006,8 +4001,6 @@ void bt_mesh_ext_mbt_server_cb_evt_to_btc(uint8_t event, void *model, void *ctx) } typedef struct { - uint64_t config_ble_mesh_stack_trace_level : 3; - uint64_t config_ble_mesh_use_ble_50: 1; uint64_t config_ble_mesh_use_duplicate_scan : 1; uint64_t config_ble_mesh_pb_adv : 1; @@ -4172,8 +4165,6 @@ typedef struct { } bt_mesh_ext_config_t; static const bt_mesh_ext_config_t bt_mesh_ext_cfg = { - .config_ble_mesh_stack_trace_level = BLE_MESH_LOG_LEVEL, - .config_ble_mesh_use_ble_50 = IS_ENABLED(CONFIG_BLE_MESH_USE_BLE_50), .config_ble_mesh_use_duplicate_scan = IS_ENABLED(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN), .config_ble_mesh_pb_adv = IS_ENABLED(CONFIG_BLE_MESH_PB_ADV), @@ -4963,6 +4954,106 @@ static const bt_mesh_ext_funcs_t bt_mesh_ext_func = { /* CONFIG_BLE_MESH_MBT_SRV */ }; +#define BLE_MESH_LIB_TRACE_TAG "BLE_MESH(lib)" +#define BLE_MESH_LOG_FORMAT_START(level) LOG_COLOR_ ## level #level " (%" PRIu32 ") %s: " +#define BLE_MESH_LOG_FORMAT_END LOG_RESET_COLOR "\n" + +void bt_mesh_lib_log_error(const char *format, ...) +{ +#if (CONFIG_BLE_MESH_NO_LOG ||\ + /* Disable log output when compressed logging + * is enabled but ERR logs are not preserved */\ + (CONFIG_BLE_MESH_STACK_ERR_LOG_COMPRESSION &&\ + !CONFIG_BLE_MESH_STACK_ERR_LOG_PRESERVE)) + return; +#else + if ((BLE_MESH_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_ERROR) && + BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH, ERROR)) { + va_list args = {0}; + va_start(args, format); + esp_log_write(ESP_LOG_ERROR, BLE_MESH_LIB_TRACE_TAG, BLE_MESH_LOG_FORMAT_START(E), esp_log_timestamp(), BLE_MESH_LIB_TRACE_TAG); + esp_log_writev(ESP_LOG_ERROR, BLE_MESH_LIB_TRACE_TAG, format, args); + esp_log_write(ESP_LOG_ERROR, BLE_MESH_LIB_TRACE_TAG, BLE_MESH_LOG_FORMAT_END); + va_end(args); + } +#endif +} + +void bt_mesh_lib_log_warn(const char *format, ...) +{ +#if (CONFIG_BLE_MESH_NO_LOG ||\ + /* Disable log output when compressed logging + * is enabled but WARN logs are not preserved */\ + (CONFIG_BLE_MESH_STACK_WARN_LOG_COMPRESSION &&\ + !CONFIG_BLE_MESH_STACK_WARN_LOG_PRESERVE)) + return; +#else + if ((BLE_MESH_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_WARN) && + BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH, WARN)) { + va_list args = {0}; + va_start(args, format); + esp_log_write(ESP_LOG_WARN, BLE_MESH_LIB_TRACE_TAG, BLE_MESH_LOG_FORMAT_START(W), esp_log_timestamp(), BLE_MESH_LIB_TRACE_TAG); + esp_log_writev(ESP_LOG_WARN, BLE_MESH_LIB_TRACE_TAG, format, args); + esp_log_write(ESP_LOG_WARN, BLE_MESH_LIB_TRACE_TAG, BLE_MESH_LOG_FORMAT_END); + va_end(args); + } +#endif +} + +void bt_mesh_lib_log_info(const char *format, ...) +{ +#if (CONFIG_BLE_MESH_NO_LOG ||\ + /* Disable log output when compressed logging + * is enabled but INFO logs are not preserved */\ + (CONFIG_BLE_MESH_STACK_INFO_LOG_COMPRESSION &&\ + !CONFIG_BLE_MESH_STACK_INFO_LOG_PRESERVE)) + return; +#else + if ((BLE_MESH_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_INFO) && + BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH, INFO)) { + va_list args = {0}; + va_start(args, format); + esp_log_write(ESP_LOG_INFO, BLE_MESH_LIB_TRACE_TAG, BLE_MESH_LOG_FORMAT_START(I), esp_log_timestamp(), BLE_MESH_LIB_TRACE_TAG); + esp_log_writev(ESP_LOG_INFO, BLE_MESH_LIB_TRACE_TAG, format, args); + esp_log_write(ESP_LOG_INFO, BLE_MESH_LIB_TRACE_TAG, BLE_MESH_LOG_FORMAT_END); + va_end(args); + } +#endif +} + +void bt_mesh_lib_log_debug(const char *format, ...) +{ +#if (CONFIG_BLE_MESH_NO_LOG ||\ + /* Disable log output when compressed logging + * is enabled but DEBUG logs are not preserved */\ + (CONFIG_BLE_MESH_STACK_DEBUG_LOG_COMPRESSION &&\ + !CONFIG_BLE_MESH_STACK_DEBUG_LOG_PRESERVE)) + return; +#else + if ((BLE_MESH_LOG_LEVEL >= BLE_MESH_LOG_LEVEL_DEBUG) && + BLE_MESH_LOG_LEVEL_CHECK(BLE_MESH, DEBUG)) { + va_list args = {0}; + va_start(args, format); + esp_log_write(ESP_LOG_DEBUG, BLE_MESH_LIB_TRACE_TAG, BLE_MESH_LOG_FORMAT_START(D), esp_log_timestamp(), BLE_MESH_LIB_TRACE_TAG); + esp_log_writev(ESP_LOG_DEBUG, BLE_MESH_LIB_TRACE_TAG, format, args); + esp_log_write(ESP_LOG_DEBUG, BLE_MESH_LIB_TRACE_TAG, BLE_MESH_LOG_FORMAT_END); + va_end(args); + } +#endif +} + +/** + * @brief Keep symbols alive. + * @note Dummy function to stop the linker from + * optimizing away unused code.The dummy + * function is discarded after linking, + * so it adds zero bytes to the final binary. + */ +void bt_mesh_lib_ext_func_dummy_call(void) +{ + (void *)bt_hex(NULL, 0); +} + int bt_mesh_v11_ext_init(void) { return bt_mesh_v11_init(&bt_mesh_ext_cfg, sizeof(bt_mesh_ext_cfg), From 97d4a47996d5a8f8548aea4da5dbabdb5380afae Mon Sep 17 00:00:00 2001 From: luoxu Date: Tue, 9 Dec 2025 17:09:26 +0800 Subject: [PATCH 075/226] feat(ble_mesh): update lib commit to 4446669404 --- components/bt/esp_ble_mesh/lib/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/esp_ble_mesh/lib/lib b/components/bt/esp_ble_mesh/lib/lib index d9fe7de9a9..85e64e61f8 160000 --- a/components/bt/esp_ble_mesh/lib/lib +++ b/components/bt/esp_ble_mesh/lib/lib @@ -1 +1 @@ -Subproject commit d9fe7de9a9eb2a4e4c51172b9c303f9d800706fa +Subproject commit 85e64e61f8471f34bd940e1fe1bdc92f58ed6bef From 6fea5c66edf31ac8c34bcdbf374d5911b3a6e045 Mon Sep 17 00:00:00 2001 From: Luo Xu Date: Mon, 17 Nov 2025 21:43:13 +0800 Subject: [PATCH 076/226] fix(ble_mesh): resolve C++ compilation issue in net.h Closes https://github.com/espressif/esp-idf/issues/17868 (cherry picked from commit 7ae9d8deb641c3f9f14ea7bcda64ecf6da581436) Co-authored-by: luoxu --- components/bt/esp_ble_mesh/core/net.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/bt/esp_ble_mesh/core/net.h b/components/bt/esp_ble_mesh/core/net.h index 1141bd2bd9..b5f5ff0a78 100644 --- a/components/bt/esp_ble_mesh/core/net.h +++ b/components/bt/esp_ble_mesh/core/net.h @@ -472,7 +472,8 @@ void bt_mesh_generic_net_recv(struct net_buf_simple *data, static inline void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi, enum bt_mesh_net_if net_if) { - struct bt_mesh_net_rx rx = { .ctx.recv_rssi = rssi }; + struct bt_mesh_net_rx rx = {0}; + rx.ctx.recv_rssi = rssi; #if CONFIG_BLE_MESH_EXT_ADV rx.ctx.enh.adv_cfg_used = false; rx.ctx.enh.ext_adv_cfg_used = false; From 777ec2c2b5178b6f8be461ad1abe88e7d8f6313e Mon Sep 17 00:00:00 2001 From: Luo Xu Date: Mon, 17 Nov 2025 21:43:14 +0800 Subject: [PATCH 077/226] fix(ble_mesh): add type casting for adv data pointer (cherry picked from commit e4f514ae108538050ff393eb961c1bb0adf8bdac) Co-authored-by: luoxu --- components/bt/esp_ble_mesh/core/nimble_host/adapter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/esp_ble_mesh/core/nimble_host/adapter.c b/components/bt/esp_ble_mesh/core/nimble_host/adapter.c index 4d598a333e..1992fb87b3 100644 --- a/components/bt/esp_ble_mesh/core/nimble_host/adapter.c +++ b/components/bt/esp_ble_mesh/core/nimble_host/adapter.c @@ -474,7 +474,7 @@ void bt_mesh_ble_ext_adv_report(struct ble_gap_ext_disc_desc *desc) /* Here, only a shallow copy needs to be implemented; * deep copying behavior occurs in btc_ble_mesh_ble_copy_req_data. */ - adv_rpt.data = desc->length_data ? desc->data : NULL; + adv_rpt.data = desc->length_data ? (uint8_t *)desc->data : NULL; adv_rpt.event_type = desc->props; adv_rpt.addr_type = desc->addr.type; From d76ad391eca2ef51627b1c6f4f609f29db662702 Mon Sep 17 00:00:00 2001 From: Chen Jian Hua Date: Mon, 5 Jan 2026 09:33:22 +0800 Subject: [PATCH 078/226] feat(bt): Update bt lib for ESP32-C3 and ESP32-S3(1bb2f50) - Support fixed log id for log compression - Support parsing log with synced timestamp (cherry picked from commit 2ccf3123739bb1d68fc3ba3d43e54dd859da7fab) Co-authored-by: chenjianhua --- components/bt/controller/lib_esp32c3_family | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32c3_family b/components/bt/controller/lib_esp32c3_family index 9b50531537..16cda80aab 160000 --- a/components/bt/controller/lib_esp32c3_family +++ b/components/bt/controller/lib_esp32c3_family @@ -1 +1 @@ -Subproject commit 9b50531537e755792ac827d00d233eab499a0b37 +Subproject commit 16cda80aab0a008093592b7e304c77dcb3ac9ea4 From 267368bbcc4f9d28c85e97dcdea08617c33071b8 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Mon, 5 Jan 2026 10:07:28 +0800 Subject: [PATCH 079/226] fix(ble/bluedroid): optimize bluedroid some code (cherry picked from commit 6b09de6dbf4039b1e489aff6869ce40ee70de3a3) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/api/esp_ble_iso_api.c | 8 ++ .../bt/host/bluedroid/api/esp_gap_ble_api.c | 8 +- .../btc/profile/std/gap/btc_gap_ble.c | 13 ++- .../common/include/common/bt_target.h | 4 +- .../bt/host/bluedroid/hci/ble_hci_iso.c | 18 ++-- .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 1 + .../bt/host/bluedroid/stack/btm/btm_ble_cte.c | 2 - .../bt/host/bluedroid/stack/btm/btm_ble_iso.c | 89 +++++++++++++++-- .../bt/host/bluedroid/stack/btu/btu_hcif.c | 96 ++++++++++++++++--- 9 files changed, 197 insertions(+), 42 deletions(-) diff --git a/components/bt/host/bluedroid/api/esp_ble_iso_api.c b/components/bt/host/bluedroid/api/esp_ble_iso_api.c index 826991e6bf..d2239844f0 100644 --- a/components/bt/host/bluedroid/api/esp_ble_iso_api.c +++ b/components/bt/host/bluedroid/api/esp_ble_iso_api.c @@ -37,6 +37,10 @@ esp_err_t esp_ble_iso_create_big(esp_ble_iso_big_creat_params_t *big_creat_param return ESP_ERR_INVALID_ARG; } + if (big_creat_param->num_bis > BLE_ISO_BIS_MAX_COUNT) { + return ESP_ERR_INVALID_ARG; + } + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_ISO_BLE; msg.act = BTC_ISO_ACT_BIG_CREATE; @@ -58,6 +62,10 @@ esp_err_t esp_ble_iso_create_big_test(esp_ble_iso_big_creat_test_params_t *big_c return ESP_ERR_INVALID_ARG; } + if (big_creat_test_param->num_bis > BLE_ISO_BIS_MAX_COUNT) { + return ESP_ERR_INVALID_ARG; + } + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_ISO_BLE; msg.act = BTC_ISO_ACT_BIG_CREATE_TEST; 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 906e1280ba..2e60cf4dd4 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -1940,6 +1940,10 @@ esp_err_t esp_ble_gap_set_path_loss_reporting_params(esp_ble_path_loss_rpt_param return ESP_ERR_INVALID_STATE; } + if (path_loss_rpt_params == NULL) { + return ESP_ERR_INVALID_ARG; + } + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_SET_PATH_LOSS_REPORT_PARAMS; @@ -2006,7 +2010,7 @@ esp_err_t esp_ble_gap_set_default_subrate(esp_ble_default_subrate_param_t *defau } if (!default_subrate_params) { - return ESP_ERR_NOT_ALLOWED; + return ESP_ERR_INVALID_ARG; } msg.sig = BTC_SIG_API_CALL; @@ -2033,7 +2037,7 @@ esp_err_t esp_ble_gap_subrate_request(esp_ble_subrate_req_param_t *subrate_req_p } if (!subrate_req_params) { - return ESP_ERR_NOT_ALLOWED; + return ESP_ERR_INVALID_ARG; } msg.sig = BTC_SIG_API_CALL; 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 ff1f63cba8..a69547083c 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 @@ -2267,6 +2267,9 @@ void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) #if (BT_BLE_FEAT_PAWR_EN == TRUE) case ESP_GAP_BLE_PERIODIC_ADV_RESPONSE_REPORT_EVT: if (src->pa_rsp_rpt_evt.pa_rsp_info) { + // num_rsp is UINT8, range 0x00 to 0xFF (0 to 255), no need to validate + dst->pa_rsp_rpt_evt.num_rsp = src->pa_rsp_rpt_evt.num_rsp; + dst->pa_rsp_rpt_evt.pa_rsp_info = osi_malloc(src->pa_rsp_rpt_evt.num_rsp * sizeof(esp_ble_pa_rsp_info)); if (dst->pa_rsp_rpt_evt.pa_rsp_info) { for (UINT8 i = 0; i < src->pa_rsp_rpt_evt.num_rsp; i++) @@ -2276,18 +2279,22 @@ void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) dst->pa_rsp_rpt_evt.pa_rsp_info[i].cte_type = src->pa_rsp_rpt_evt.pa_rsp_info[i].cte_type; dst->pa_rsp_rpt_evt.pa_rsp_info[i].rsp_slot = src->pa_rsp_rpt_evt.pa_rsp_info[i].rsp_slot; dst->pa_rsp_rpt_evt.pa_rsp_info[i].data_status = src->pa_rsp_rpt_evt.pa_rsp_info[i].data_status; + // data_len is UINT8, range 0x00 to 0xFF (0 to 255), no need to validate dst->pa_rsp_rpt_evt.pa_rsp_info[i].data_len = src->pa_rsp_rpt_evt.pa_rsp_info[i].data_len; - if (src->pa_rsp_rpt_evt.pa_rsp_info[i].data_len) { + if (src->pa_rsp_rpt_evt.pa_rsp_info[i].data_len && src->pa_rsp_rpt_evt.pa_rsp_info[i].data) { dst->pa_rsp_rpt_evt.pa_rsp_info[i].data = osi_malloc(src->pa_rsp_rpt_evt.pa_rsp_info[i].data_len); if (dst->pa_rsp_rpt_evt.pa_rsp_info[i].data) { memcpy(dst->pa_rsp_rpt_evt.pa_rsp_info[i].data, src->pa_rsp_rpt_evt.pa_rsp_info[i].data, src->pa_rsp_rpt_evt.pa_rsp_info[i].data_len); } else { - BTC_TRACE_ERROR("%s, data, no enough memory.", __func__); + BTC_TRACE_ERROR("%s, data, no enough memory for data_len %d at index %d", __func__, dst->pa_rsp_rpt_evt.pa_rsp_info[i].data_len, i); + dst->pa_rsp_rpt_evt.pa_rsp_info[i].data_len = 0; } + } else { + dst->pa_rsp_rpt_evt.pa_rsp_info[i].data = NULL; } } } else { - BTC_TRACE_ERROR("%s, pa_rsp_info, no enough memory.", __func__); + BTC_TRACE_ERROR("%s, pa_rsp_info, no enough memory for array size %d", __func__, src->pa_rsp_rpt_evt.num_rsp); } } break; 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 412ca9dd06..a25985b202 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -367,8 +367,8 @@ #define BLE_ISO_CIS_MAX_COUNT (0) #endif -#ifdef CONFIG_BT_BLE_ISO_BIS_MAX_COUNT -#define BLE_ISO_BIS_MAX_COUNT CONFIG_BT_BLE_ISO_BIS_MAX_COUNT +#ifdef UC_BT_BLE_ISO_BIS_MAX_COUNT +#define BLE_ISO_BIS_MAX_COUNT UC_BT_BLE_ISO_BIS_MAX_COUNT #else #define BLE_ISO_BIS_MAX_COUNT (0) #endif diff --git a/components/bt/host/bluedroid/hci/ble_hci_iso.c b/components/bt/host/bluedroid/hci/ble_hci_iso.c index 9c73fae237..6a61836ef2 100644 --- a/components/bt/host/bluedroid/hci/ble_hci_iso.c +++ b/components/bt/host/bluedroid/hci/ble_hci_iso.c @@ -64,16 +64,16 @@ ble_hci_set_iso_buf_sz(uint16_t pktlen, uint8_t max_pkts) ble_hs_iso_avail_pkts = max_pkts; #endif /* (BLE_ISO_STD_FLOW_CTRL) */ - HCI_TRACE_WARNING("ISO Flow Control:\n"); - HCI_TRACE_WARNING(" Length: %u\n", pktlen); - HCI_TRACE_WARNING(" Count: %u\n", max_pkts); - HCI_TRACE_WARNING(" Status: "); + HCI_TRACE_DEBUG("ISO Flow Control:"); + HCI_TRACE_DEBUG("Length: %u\n", pktlen); + HCI_TRACE_DEBUG("Count: %u\n", max_pkts); + HCI_TRACE_DEBUG("Status: "); #if (BLE_ISO_STD_FLOW_CTRL == TRUE) - HCI_TRACE_WARNING("%s\n", "Standard"); + HCI_TRACE_DEBUG("%s", "Standard"); #elif (BLE_ISO_NON_STD_FLOW_CTRL == TRUE) - HCI_TRACE_WARNING("%s\n", "Non-standard"); + HCI_TRACE_DEBUG("%s\n", "Non-standard"); #else - HCI_TRACE_WARNING("%s\n", "Not support"); + HCI_TRACE_DEBUG("%s\n", "Not support"); #endif return 0; @@ -261,7 +261,7 @@ ble_hci_iso_tx_now(struct ble_hci_iso_conn *conn, const uint8_t *sdu, #endif dlh_len = (conn->ts_flag ? BLE_HCI_ISO_DATA_LOAD_TS_SZ : 0) + BLE_HCI_ISO_DATA_LOAD_HDR_SZ; - + // free in controller frag = malloc(BLE_HCI_ISO_DATA_HDR_SZ + dlh_len + conn->sdu_len); if (frag == NULL) { HCI_TRACE_ERROR("frag is null\n"); @@ -279,7 +279,7 @@ ble_hci_iso_tx_now(struct ble_hci_iso_conn *conn, const uint8_t *sdu, rc = ble_hci_tx_iso_data(frag, BLE_HCI_ISO_DATA_HDR_SZ + dlh_len + conn->sdu_len, NULL); if (rc) { - HCI_TRACE_ERROR("iso tx failed\n"); + HCI_TRACE_ERROR("iso tx failed_%d\n", rc); return 14; } diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index b87c9d35f6..81eb92414b 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -17,6 +17,7 @@ tBTM_BLE_EXTENDED_CB extend_adv_cb; tBTM_BLE_5_HCI_CBACK ble_5_hci_cb; #define INVALID_VALUE 0XFF + extern BOOLEAN BTM_GetLocalResolvablePrivateAddr(BD_ADDR bda); extern void BTM_UpdateAddrInfor(uint8_t addr_type, BD_ADDR bda); extern void BTM_BleSetStaticAddr(BD_ADDR rand_addr); diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_cte.c b/components/bt/host/bluedroid/stack/btm/btm_ble_cte.c index a79932de2f..2e9c06da45 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_cte.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_cte.c @@ -38,8 +38,6 @@ void BTM_CteBleCallbackTrigger(tBTM_BLE_5_GAP_EVENT event, tBTM_BLE_CTE_CB_PARAM #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) tBTM_STATUS BTM_BleSetCteTransParams(uint8_t adv_handle, uint8_t cte_len, uint8_t cte_type, uint8_t cte_count, uint8_t switching_pattern_len, uint8_t *antenna_ids) { - - tHCI_STATUS err = HCI_SUCCESS; tBTM_STATUS status = BTM_SUCCESS; tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_iso.c b/components/bt/host/bluedroid/stack/btm/btm_ble_iso.c index c66f10b9c0..f0aa7ca56c 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_iso.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_iso.c @@ -85,11 +85,20 @@ void btm_ble_iso_read_iso_link_quality_complete(UINT8 *p) void btm_ble_iso_set_cig_params_complete(UINT8 *p) { tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + UINT8 cis_count; STREAM_TO_UINT8(cb_params.btm_set_cig_params.status, p); STREAM_TO_UINT8(cb_params.btm_set_cig_params.cig_id, p); - STREAM_TO_UINT8(cb_params.btm_set_cig_params.cis_count, p); - for (uint8_t i = 0; i < cb_params.btm_set_cig_params.cis_count; i++) + STREAM_TO_UINT8(cis_count, p); + + // Validate cis_count to prevent buffer overflow + if (cis_count > BLE_ISO_CIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, cis_count %d exceeds BLE_ISO_CIS_MAX_COUNT %d", __func__, cis_count, BLE_ISO_CIS_MAX_COUNT); + cis_count = BLE_ISO_CIS_MAX_COUNT; + } + cb_params.btm_set_cig_params.cis_count = cis_count; + + for (uint8_t i = 0; i < cis_count; i++) { STREAM_TO_UINT16(cb_params.btm_set_cig_params.conn_hdl[i], p); BTM_TRACE_DEBUG("i = %d, conn_hdl = %d", i, cb_params.btm_set_cig_params.conn_hdl[i]); @@ -158,6 +167,8 @@ void btm_ble_big_create_cmpl_evt(tBTM_BLE_BIG_CREATE_CMPL *params) { BTM_TRACE_DEBUG("%s", __func__); tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + UINT8 num_bis; + if (!params) { BTM_TRACE_ERROR("%s, Invalid params.", __func__); return; @@ -167,6 +178,13 @@ void btm_ble_big_create_cmpl_evt(tBTM_BLE_BIG_CREATE_CMPL *params) params->status = (params->status | BTM_HCI_ERROR); } + // Validate num_bis to prevent buffer overflow + num_bis = params->num_bis; + if (num_bis > BLE_ISO_BIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, num_bis %d exceeds BLE_ISO_BIS_MAX_COUNT %d", __func__, num_bis, BLE_ISO_BIS_MAX_COUNT); + num_bis = BLE_ISO_BIS_MAX_COUNT; + } + cb_params.btm_big_cmpl.status = params->status; cb_params.btm_big_cmpl.big_handle = params->big_handle; cb_params.btm_big_cmpl.big_sync_delay = params->big_sync_delay; @@ -178,14 +196,12 @@ void btm_ble_big_create_cmpl_evt(tBTM_BLE_BIG_CREATE_CMPL *params) cb_params.btm_big_cmpl.irc = params->irc; cb_params.btm_big_cmpl.max_pdu = params->max_pdu; cb_params.btm_big_cmpl.iso_interval = params->iso_interval; - cb_params.btm_big_cmpl.num_bis = params->num_bis; - // for (uint8_t i = 0; i < params->num_bis; i++) - // { - // cb_params.btm_big_cmpl.bis_handle[i] = params->bis_handle[i]; - // } - memcpy(&cb_params.btm_big_cmpl.bis_handle[0], ¶ms->bis_handle[0], params->num_bis * 2); + cb_params.btm_big_cmpl.num_bis = num_bis; - //memcpy(&cb_params.btm_big_cmpl, params, sizeof(tBTM_BLE_BIG_CREATE_CMPL)); + // Copy bis_handle array with bounds checking + if (num_bis > 0) { + memcpy(&cb_params.btm_big_cmpl.bis_handle[0], ¶ms->bis_handle[0], num_bis * sizeof(UINT16)); + } BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_CREATE_COMPLETE_EVT, &cb_params); } @@ -207,6 +223,8 @@ void btm_ble_big_terminate_cmpl_evt(tBTM_BLE_BIG_TERMINATE_CMPL *params) void btm_ble_big_sync_estab_evt(tBTM_BLE_BIG_SYNC_ESTAB_CMPL *params) { tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + UINT8 num_bis; + if (!params) { BTM_TRACE_ERROR("%s, Invalid params.", __func__); return; @@ -216,7 +234,28 @@ void btm_ble_big_sync_estab_evt(tBTM_BLE_BIG_SYNC_ESTAB_CMPL *params) params->status = (params->status | BTM_HCI_ERROR); } - memcpy(&cb_params.btm_big_sync_estab, params, sizeof(tBTM_BLE_BIG_SYNC_ESTAB_CMPL)); + // Validate num_bis to prevent buffer overflow + num_bis = params->num_bis; + if (num_bis > BLE_ISO_BIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, num_bis %d exceeds BLE_ISO_BIS_MAX_COUNT %d", __func__, num_bis, BLE_ISO_BIS_MAX_COUNT); + num_bis = BLE_ISO_BIS_MAX_COUNT; + } + + cb_params.btm_big_sync_estab.status = params->status; + cb_params.btm_big_sync_estab.big_handle = params->big_handle; + cb_params.btm_big_sync_estab.transport_latency_big = params->transport_latency_big; + cb_params.btm_big_sync_estab.nse = params->nse; + cb_params.btm_big_sync_estab.bn = params->bn; + cb_params.btm_big_sync_estab.pto = params->pto; + cb_params.btm_big_sync_estab.irc = params->irc; + cb_params.btm_big_sync_estab.max_pdu = params->max_pdu; + cb_params.btm_big_sync_estab.iso_interval = params->iso_interval; + cb_params.btm_big_sync_estab.num_bis = num_bis; + + // Copy bis_handle array with bounds checking + if (num_bis > 0) { + memcpy(&cb_params.btm_big_sync_estab.bis_handle[0], ¶ms->bis_handle[0], num_bis * sizeof(uint16_t)); + } BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT, &cb_params); } @@ -286,6 +325,11 @@ tBTM_STATUS BTM_BleBigCreate(uint8_t big_handle, uint8_t adv_handle, uint8_t num rtn %d phy %d packing %d framing %d encryption %d broadcast_code %d", big_handle, adv_handle, num_bis, sdu_interval, max_sdu, max_transport_latency,\ rtn, phy, packing, framing, encryption, broadcast_code); + if (num_bis > BLE_ISO_BIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, num_bis %d exceeds BLE_ISO_BIS_MAX_COUNT %d", __func__, num_bis, BLE_ISO_BIS_MAX_COUNT); + return BTM_ILLEGAL_VALUE; + } + btsnd_hcic_ble_big_create(big_handle, adv_handle, num_bis, sdu_interval, max_sdu, max_transport_latency, rtn, phy, packing, framing, encryption, broadcast_code); @@ -299,6 +343,11 @@ tBTM_STATUS BTM_BleBigCreateTest(uint8_t big_handle, uint8_t adv_handle, uint8_t uint8_t packing, uint8_t framing, uint8_t bn, uint8_t irc, uint8_t pto, uint8_t encryption, uint8_t *broadcast_code) { + if (num_bis > BLE_ISO_BIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, num_bis %d exceeds BLE_ISO_BIS_MAX_COUNT %d", __func__, num_bis, BLE_ISO_BIS_MAX_COUNT); + return BTM_ILLEGAL_VALUE; + } + btsnd_hcic_ble_big_create_test(big_handle, adv_handle, num_bis, sdu_interval, iso_interval, nse, max_sdu, max_pdu, phy, packing, framing, bn, irc, pto, encryption, broadcast_code); @@ -331,6 +380,11 @@ tBTM_STATUS BTM_BleBigSyncCreate(uint8_t big_handle, uint16_t sync_handle, uint8_t mse, uint16_t big_sync_timeout, uint8_t num_bis, uint8_t *bis) { + if (num_bis > BLE_ISO_BIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, num_bis %d exceeds BLE_ISO_BIS_MAX_COUNT %d", __func__, num_bis, BLE_ISO_BIS_MAX_COUNT); + return BTM_ILLEGAL_VALUE; + } + btsnd_hcic_ble_big_sync_create(big_handle, sync_handle, encryption, bc_code, mse, big_sync_timeout, num_bis, bis); return BTM_SUCCESS; @@ -430,6 +484,11 @@ tBTM_STATUS BTM_BleSetCigParams(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_ tHCI_STATUS err = HCI_SUCCESS; tBTM_STATUS status = BTM_SUCCESS; + if (cis_cnt > BLE_ISO_CIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, cis_cnt %d exceeds BLE_ISO_CIS_MAX_COUNT %d", __func__, cis_cnt, BLE_ISO_CIS_MAX_COUNT); + return BTM_ILLEGAL_VALUE; + } + if ((err = btsnd_hcic_ble_iso_set_cig_params(cig_id, sdu_int_c_to_p, sdu_int_p_to_c, worse_case_SCA, packing, framing, mtl_c_to_p, mtl_p_to_c, cis_cnt, (struct ble_hci_le_cis_params *)cis_params)) != HCI_SUCCESS) { BTM_TRACE_ERROR("iso set cig params, cmd err=0x%x", err); @@ -445,6 +504,11 @@ tBTM_STATUS BTM_BleSetCigParamsTest(uint8_t cig_id, uint32_t sdu_int_c_to_p, uin tHCI_STATUS err = HCI_SUCCESS; tBTM_STATUS status = BTM_SUCCESS; + if (cis_cnt > BLE_ISO_CIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, cis_cnt %d exceeds BLE_ISO_CIS_MAX_COUNT %d", __func__, cis_cnt, BLE_ISO_CIS_MAX_COUNT); + return BTM_ILLEGAL_VALUE; + } + if ((err = btsnd_hcic_ble_iso_set_cig_params_test(cig_id, sdu_int_c_to_p, sdu_int_p_to_c,ft_c_to_p, ft_p_to_c, iso_interval, worse_case_SCA, packing, framing, cis_cnt, (struct ble_hci_le_cis_params_test *)cis_params)) != HCI_SUCCESS) { BTM_TRACE_ERROR("iso set cig params test, cmd err=0x%x", err); @@ -461,6 +525,11 @@ void btm_ble_create_cis_cmd_status(tBTM_BLE_ISO_CB_PARAMS *cb_params) tBTM_STATUS BTM_BleCreateCis(uint8_t cis_count, uint8_t *cis_hdls) { + if (cis_count > BLE_ISO_CIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, cis_count %d exceeds BLE_ISO_CIS_MAX_COUNT %d", __func__, cis_count, BLE_ISO_CIS_MAX_COUNT); + return BTM_ILLEGAL_VALUE; + } + btsnd_hcic_ble_iso_create_cis(cis_count, (struct ble_hci_cis_hdls *)cis_hdls); return BTM_SUCCESS; diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 4aa1701294..52365cf62c 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -52,6 +52,17 @@ extern void btm_process_cancel_complete(UINT8 status, UINT8 mode); extern void btm_ble_test_command_complete(UINT8 *p); +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +// BLE Channel Sounding parameter validation macros per BLE spec +#define BTM_BLE_CS_MAX_STEPS_REPORTED 0xA0 // Range: 0x00 to 0xA0 (0 to 160) +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) +// BLE CTE parameter validation macros per BLE spec +#define BTM_BLE_CTE_MAX_SAMPLE_COUNT 0x52 // Maximum sample count per BLE spec: 0x52 (82) +#endif // (BLE_FEAT_CTE_EN == TRUE) + + /********************************************************************************/ /* L O C A L F U N C T I O N P R O T O T Y P E S */ /********************************************************************************/ @@ -2909,6 +2920,7 @@ static void btu_ble_big_create_complete_evt(UINT8 *p) { HCI_TRACE_DEBUG("%s", __func__); tBTM_BLE_BIG_CREATE_CMPL big_cmpl = {0}; + UINT8 num_bis; if (!p) { HCI_TRACE_ERROR("%s, Invalid params.", __func__); @@ -2926,8 +2938,16 @@ static void btu_ble_big_create_complete_evt(UINT8 *p) STREAM_TO_UINT8(big_cmpl.irc, p); STREAM_TO_UINT16(big_cmpl.max_pdu, p); STREAM_TO_UINT16(big_cmpl.iso_interval, p); - STREAM_TO_UINT8(big_cmpl.num_bis, p); - for (uint8_t i = 0; i < big_cmpl.num_bis; i++) + STREAM_TO_UINT8(num_bis, p); + + // Validate num_bis to prevent buffer overflow + if (num_bis > BLE_ISO_BIS_MAX_COUNT) { + HCI_TRACE_ERROR("%s, num_bis %d exceeds BLE_ISO_BIS_MAX_COUNT %d", __func__, num_bis, BLE_ISO_BIS_MAX_COUNT); + num_bis = BLE_ISO_BIS_MAX_COUNT; + } + big_cmpl.num_bis = num_bis; + + for (uint8_t i = 0; i < num_bis; i++) { STREAM_TO_UINT16(big_cmpl.bis_handle[i], p); // only 12 bits meaningful @@ -2976,6 +2996,7 @@ void btu_ble_create_big_sync_cmd_status(UINT8 status) static void btu_ble_big_sync_establish_evt(UINT8 *p) { tBTM_BLE_BIG_SYNC_ESTAB_CMPL big_estb = {0}; + UINT8 num_bis; if (!p) { HCI_TRACE_ERROR("%s, Invalid params.", __func__); @@ -2991,8 +3012,16 @@ static void btu_ble_big_sync_establish_evt(UINT8 *p) STREAM_TO_UINT8(big_estb.irc, p); STREAM_TO_UINT16(big_estb.max_pdu, p); STREAM_TO_UINT16(big_estb.iso_interval, p); - STREAM_TO_UINT8(big_estb.num_bis, p); - for (uint8_t i = 0; i < big_estb.num_bis; i++) + STREAM_TO_UINT8(num_bis, p); + + // Validate num_bis to prevent buffer overflow + if (num_bis > BLE_ISO_BIS_MAX_COUNT) { + HCI_TRACE_ERROR("%s, num_bis %d exceeds BLE_ISO_BIS_MAX_COUNT %d", __func__, num_bis, BLE_ISO_BIS_MAX_COUNT); + num_bis = BLE_ISO_BIS_MAX_COUNT; + } + big_estb.num_bis = num_bis; + + for (uint8_t i = 0; i < num_bis; i++) { STREAM_TO_UINT16(big_estb.bis_handle[i], p); } @@ -3048,6 +3077,7 @@ static void btu_ble_biginfo_adv_report_evt(UINT8 *p) static void btu_ble_cte_connless_iq_report_evt(UINT8 *p) { tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT connless_iq_rpt = {0}; + UINT8 sample_count; if (!p) { HCI_TRACE_ERROR("%s, Invalid params.", __func__); @@ -3062,14 +3092,21 @@ static void btu_ble_cte_connless_iq_report_evt(UINT8 *p) STREAM_TO_UINT8(connless_iq_rpt.slot_dur, p); STREAM_TO_UINT8(connless_iq_rpt.pkt_status, p); STREAM_TO_UINT16(connless_iq_rpt.periodic_evt_counter, p); - STREAM_TO_UINT8(connless_iq_rpt.sample_count, p); + STREAM_TO_UINT8(sample_count, p); - for (uint8_t i = 0; i < connless_iq_rpt.sample_count; i++) + // Validate sample_count to prevent buffer overflow + if (sample_count > BTM_BLE_CTE_MAX_SAMPLE_COUNT) { + HCI_TRACE_ERROR("%s, sample_count %d exceeds maximum %d", __func__, sample_count, BTM_BLE_CTE_MAX_SAMPLE_COUNT); + sample_count = BTM_BLE_CTE_MAX_SAMPLE_COUNT; + } + connless_iq_rpt.sample_count = sample_count; + + for (uint8_t i = 0; i < sample_count; i++) { STREAM_TO_UINT8(connless_iq_rpt.i_sample[i], p); } - for (uint8_t i = 0; i < connless_iq_rpt.sample_count; i++) + for (uint8_t i = 0; i < sample_count; i++) { STREAM_TO_UINT8(connless_iq_rpt.q_sample[i], p); } @@ -3082,6 +3119,7 @@ static void btu_ble_cte_connless_iq_report_evt(UINT8 *p) static void btu_ble_cte_conn_iq_report_evt(UINT8 *p) { tBTM_BLE_CTE_CONN_IQ_REPORT_EVT conn_iq_rpt = {0}; + UINT8 sample_count; if (!p) { HCI_TRACE_ERROR("%s, Invalid params.", __func__); @@ -3097,14 +3135,21 @@ static void btu_ble_cte_conn_iq_report_evt(UINT8 *p) STREAM_TO_UINT8(conn_iq_rpt.slot_dur, p); STREAM_TO_UINT8(conn_iq_rpt.pkt_status, p); STREAM_TO_UINT16(conn_iq_rpt.conn_evt_counter, p); - STREAM_TO_UINT8(conn_iq_rpt.sample_count, p); + STREAM_TO_UINT8(sample_count, p); - for (uint8_t i = 0; i < conn_iq_rpt.sample_count; i++) + // Validate sample_count to prevent buffer overflow + if (sample_count > BTM_BLE_CTE_MAX_SAMPLE_COUNT) { + HCI_TRACE_ERROR("%s, sample_count %d exceeds maximum %d", __func__, sample_count, BTM_BLE_CTE_MAX_SAMPLE_COUNT); + sample_count = BTM_BLE_CTE_MAX_SAMPLE_COUNT; + } + conn_iq_rpt.sample_count = sample_count; + + for (uint8_t i = 0; i < sample_count; i++) { STREAM_TO_UINT8(conn_iq_rpt.i_sample[i], p); } - for (uint8_t i = 0; i < conn_iq_rpt.sample_count; i++) + for (uint8_t i = 0; i < sample_count; i++) { STREAM_TO_UINT8(conn_iq_rpt.q_sample[i], p); } @@ -3215,6 +3260,7 @@ static void btu_ble_pa_response_report_evt(UINT8 *p) STREAM_TO_UINT8(pa_rsp_rpt_evt.tx_status, p); STREAM_TO_UINT8(pa_rsp_rpt_evt.num_rsp, p); + // num_rsp is UINT8, range 0x00 to 0xFF (0 to 255), no need to validate if (pa_rsp_rpt_evt.num_rsp) { pa_rsp_rpt_evt.rsp_data_info = osi_malloc(pa_rsp_rpt_evt.num_rsp * sizeof(tBTM_BLE_PA_RSP_DATA_INFO)); if (pa_rsp_rpt_evt.rsp_data_info) @@ -3227,17 +3273,21 @@ static void btu_ble_pa_response_report_evt(UINT8 *p) STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].rsp_slot, p); STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].data_status, p); STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].data_len, p); + // data_len is UINT8, range 0x00 to 0xFF (0 to 255), no need to validate if (pa_rsp_rpt_evt.rsp_data_info[i].data_len) { pa_rsp_rpt_evt.rsp_data_info[i].data = osi_malloc(pa_rsp_rpt_evt.rsp_data_info[i].data_len); if (pa_rsp_rpt_evt.rsp_data_info[i].data) { STREAM_TO_ARRAY(pa_rsp_rpt_evt.rsp_data_info[i].data, p, pa_rsp_rpt_evt.rsp_data_info[i].data_len); } else { - HCI_TRACE_ERROR("%s, no enough memory.", __func__); + HCI_TRACE_ERROR("%s, no enough memory for data_len %d at index %d", __func__, pa_rsp_rpt_evt.rsp_data_info[i].data_len, i); + pa_rsp_rpt_evt.rsp_data_info[i].data_len = 0; } + } else { + pa_rsp_rpt_evt.rsp_data_info[i].data = NULL; } } } else { - HCI_TRACE_ERROR("%s, no memory.", __func__); + HCI_TRACE_ERROR("%s, no memory for rsp_data_info", __func__); } } @@ -3397,7 +3447,15 @@ static void btu_ble_cs_subevt_result_evt(UINT8 *p) STREAM_TO_UINT8(subevt_result.subevent_done_status, p); STREAM_TO_UINT8(subevt_result.abort_reason, p); STREAM_TO_UINT8(subevt_result.num_ant_paths, p); - STREAM_TO_UINT8(subevt_result.num_steps_reported, p); + UINT8 num_steps_reported; + STREAM_TO_UINT8(num_steps_reported, p); + + // Validate num_steps_reported per BLE spec: Range 0x00 to 0xA0 (0 to 160) + if (num_steps_reported > BTM_BLE_CS_MAX_STEPS_REPORTED) { + HCI_TRACE_ERROR("%s, num_steps_reported %d exceeds maximum %d", __func__, num_steps_reported, BTM_BLE_CS_MAX_STEPS_REPORTED); + num_steps_reported = BTM_BLE_CS_MAX_STEPS_REPORTED; + } + subevt_result.num_steps_reported = num_steps_reported; subevt_result.step_info = osi_malloc(subevt_result.num_steps_reported * sizeof(tBTM_BLE_CS_STEP_INFO)); if (subevt_result.step_info) { @@ -3406,6 +3464,7 @@ static void btu_ble_cs_subevt_result_evt(UINT8 *p) STREAM_TO_UINT8(subevt_result.step_info[i].step_mode, p); STREAM_TO_UINT8(subevt_result.step_info[i].step_channel, p); STREAM_TO_UINT8(subevt_result.step_info[i].step_data_len, p); + // step_data_len is UINT8, range 0x00 to 0xFF (0 to 255), no need to validate subevt_result.step_info[i].data = osi_malloc(subevt_result.step_info[i].step_data_len); if (subevt_result.step_info[i].data) { STREAM_TO_ARRAY(subevt_result.step_info[i].data, p, subevt_result.step_info[i].step_data_len); @@ -3445,7 +3504,15 @@ static void btu_ble_cs_subevt_result_continue_evt(UINT8 *p) STREAM_TO_UINT8(subevt_continue_result.subevt_done_status, p); STREAM_TO_UINT8(subevt_continue_result.abort_reason, p); STREAM_TO_UINT8(subevt_continue_result.num_ant_paths, p); - STREAM_TO_UINT8(subevt_continue_result.num_steps_reported, p); + UINT8 num_steps_reported; + STREAM_TO_UINT8(num_steps_reported, p); + + // Validate num_steps_reported per BLE spec: Range 0x00 to 0xA0 (0 to 160) + if (num_steps_reported > BTM_BLE_CS_MAX_STEPS_REPORTED) { + HCI_TRACE_ERROR("%s, num_steps_reported %d exceeds maximum %d", __func__, num_steps_reported, BTM_BLE_CS_MAX_STEPS_REPORTED); + num_steps_reported = BTM_BLE_CS_MAX_STEPS_REPORTED; + } + subevt_continue_result.num_steps_reported = num_steps_reported; subevt_continue_result.step_info = osi_malloc(subevt_continue_result.num_steps_reported * sizeof(tBTM_BLE_CS_STEP_INFO)); if (subevt_continue_result.step_info) { @@ -3453,6 +3520,7 @@ static void btu_ble_cs_subevt_result_continue_evt(UINT8 *p) STREAM_TO_UINT8(subevt_continue_result.step_info[i].step_mode, p); STREAM_TO_UINT8(subevt_continue_result.step_info[i].step_channel, p); STREAM_TO_UINT8(subevt_continue_result.step_info[i].step_data_len, p); + // step_data_len is UINT8, range 0x00 to 0xFF (0 to 255), no need to validate subevt_continue_result.step_info[i].data = osi_malloc(subevt_continue_result.step_info[i].step_data_len); if (subevt_continue_result.step_info[i].data) { STREAM_TO_ARRAY(subevt_continue_result.step_info[i].data, p, subevt_continue_result.step_info[i].step_data_len); From 9825b32ce2a14ce62e06af9d6ac3377a3ca1ef1c Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Wed, 10 Dec 2025 20:36:18 +0800 Subject: [PATCH 080/226] fix(ble/bluedroid): Fix heap buffer overflow in BTC_GAP_BLE_SET_PA_SUBEVT_DATA deep copy --- .../host/bluedroid/btc/profile/std/gap/btc_gap_ble.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) 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 a69547083c..92a6ec9ff2 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 @@ -2182,14 +2182,12 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) uint16_t params_len = src->per_adv_subevent_data_params.num_subevents_with_data * sizeof(esp_ble_subevent_params); dst->per_adv_subevent_data_params.subevent_params = osi_malloc(params_len); if (dst->per_adv_subevent_data_params.subevent_params) { - for (uint8_t i = 0; i < src->per_adv_subevent_data_params.num_subevents_with_data; i++) { - memcpy(&dst->per_adv_subevent_data_params.subevent_params[i], &src->per_adv_subevent_data_params.subevent_params[i], params_len); - // dst->per_adv_subevent_data_params.subevent_params[i].subevent = src->per_adv_subevent_data_params.subevent_params[i].subevent; - // dst->per_adv_subevent_data_params.subevent_params[i].response_slot_start = src->per_adv_subevent_data_params.subevent_params[i].response_slot_start; - // dst->per_adv_subevent_data_params.subevent_params[i].response_slot_count = src->per_adv_subevent_data_params.subevent_params[i].response_slot_count; - // dst->per_adv_subevent_data_params.subevent_params[i].subevent_data_len = src->per_adv_subevent_data_params.subevent_params[i].subevent_data_len; + /* Fix: Use sizeof(esp_ble_subevent_params) instead of params_len to prevent buffer overflow */ + memcpy(&dst->per_adv_subevent_data_params.subevent_params[i], + &src->per_adv_subevent_data_params.subevent_params[i], + sizeof(esp_ble_subevent_params)); dst->per_adv_subevent_data_params.subevent_params[i].subevent_data = osi_malloc(src->per_adv_subevent_data_params.subevent_params[i].subevent_data_len); if (dst->per_adv_subevent_data_params.subevent_params[i].subevent_data) { memcpy(dst->per_adv_subevent_data_params.subevent_params[i].subevent_data, src->per_adv_subevent_data_params.subevent_params[i].subevent_data, src->per_adv_subevent_data_params.subevent_params[i].subevent_data_len); From 1c56fad5d08143354c1c714a6b7b59d375c70cdc Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Thu, 11 Dec 2025 11:00:11 +0800 Subject: [PATCH 081/226] fix(ble/bluedroid): Remove duplicate filter_policy in ext_conn_v2 HCI cmd --- components/bt/host/bluedroid/stack/hcic/hciblecmds.c | 1 - 1 file changed, 1 deletion(-) diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index c44e974fff..306e23b47c 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -1725,7 +1725,6 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn_v2(tHCI_CreatExtConn *p_conn) UINT8_TO_STREAM(pp, p_conn->adv_handle); UINT8_TO_STREAM(pp, p_conn->subevent); UINT8_TO_STREAM(pp, p_conn->filter_policy); - UINT8_TO_STREAM(pp, p_conn->filter_policy); UINT8_TO_STREAM(pp, p_conn->own_addr_type); UINT8_TO_STREAM(pp, p_conn->peer_addr_type); BDADDR_TO_STREAM(pp, p_conn->peer_addr); From f1f1392a4dab7c9957948841625d361584909957 Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Thu, 11 Dec 2025 11:01:34 +0800 Subject: [PATCH 082/226] fix(ble/bluedroid): Fix array index in set_periodic_adv_subevt_data --- components/bt/host/bluedroid/stack/hcic/hciblecmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 306e23b47c..b74fdc2227 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -2988,7 +2988,7 @@ UINT8 btsnd_hcic_ble_set_periodic_adv_subevt_data(UINT8 adv_handle, UINT8 num_su esp_log_buffer_hex_internal("data", subevent_params[i].data, subevent_params[i].subevent_data_len, ESP_LOG_DEBUG); } - param_len += (4 + subevent_params->subevent_data_len); + param_len += (4 + subevent_params[i].subevent_data_len); } HCIC_BLE_CMD_CREATED(p, pp, param_len); From 1906584c895ebf13276c4ef16c6778d974bffe66 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Thu, 18 Dec 2025 14:31:03 +0800 Subject: [PATCH 083/226] feat(ble/bluedroid): Supported Bludroid host encryption using mbedtls --- components/bt/host/bluedroid/Kconfig.in | 20 +++ .../include/common/bluedroid_user_config.h | 6 + .../common/include/common/bt_target.h | 6 + components/bt/host/bluedroid/stack/smp/aes.c | 6 +- .../bt/host/bluedroid/stack/smp/include/aes.h | 10 +- .../stack/smp/include/p_256_ecc_pp.h | 7 +- .../stack/smp/include/p_256_multprecision.h | 5 + .../bluedroid/stack/smp/p_256_curvepara.c | 6 + .../host/bluedroid/stack/smp/p_256_ecc_pp.c | 7 +- .../bluedroid/stack/smp/p_256_multprecision.c | 15 +- .../bt/host/bluedroid/stack/smp/smp_act.c | 44 +++++ .../bt/host/bluedroid/stack/smp/smp_api.c | 10 ++ .../bt/host/bluedroid/stack/smp/smp_cmac.c | 160 ++++++++++++++--- .../bt/host/bluedroid/stack/smp/smp_keys.c | 166 ++++++++++++++++-- 14 files changed, 417 insertions(+), 51 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 929e539919..1c762a559a 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -464,6 +464,26 @@ config BT_BLE_SMP_BOND_NVS_FLASH help This select can save SMP bonding keys to nvs flash +config BT_SMP_CRYPTO_MBEDTLS + bool "Use mbedTLS for SMP cryptographic functions" + depends on BT_BLE_SMP_ENABLE + depends on !BLE_MESH + select MBEDTLS_AES_C + select MBEDTLS_CMAC_C + select MBEDTLS_ECDH_C + select MBEDTLS_ECP_C + select MBEDTLS_ECP_DP_SECP256R1_ENABLED + default n + help + If enabled, the SMP layer will use mbedTLS library for cryptographic + operations (AES, AES-CMAC, ECDH P-256) instead of the built-in + Bluedroid implementation. This can provide hardware acceleration + on supported platforms and reduce code size by sharing crypto + implementations with other components. + + Note: This option is not compatible with BLE Mesh, as BLE Mesh + uses the native Bluedroid ECC implementation directly. + config BT_BLE_RPA_SUPPORTED bool "Update RPA to Controller" depends on (BT_BLE_SMP_ENABLE && ((BT_CONTROLLER_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR 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 70e967b44b..602042bdab 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 @@ -467,6 +467,12 @@ #define UC_BT_BLE_SMP_BOND_NVS_FLASH FALSE #endif +#ifdef CONFIG_BT_SMP_CRYPTO_MBEDTLS +#define UC_BT_SMP_CRYPTO_MBEDTLS CONFIG_BT_SMP_CRYPTO_MBEDTLS +#else +#define UC_BT_SMP_CRYPTO_MBEDTLS FALSE +#endif + //Device Name Maximum Length #ifdef CONFIG_BT_MAX_DEVICE_NAME_LEN #define UC_MAX_LOC_BD_NAME_LEN CONFIG_BT_MAX_DEVICE_NAME_LEN 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 412ca9dd06..6f58d12930 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -517,6 +517,12 @@ #define BLE_SMP_BOND_NVS_FLASH FALSE #endif +#if (UC_BT_SMP_CRYPTO_MBEDTLS) +#define SMP_CRYPTO_MBEDTLS TRUE +#else +#define SMP_CRYPTO_MBEDTLS FALSE +#endif /* UC_BT_SMP_CRYPTO_MBEDTLS */ + #ifdef UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP #define BLE_ADV_REPORT_FLOW_CONTROL (UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP && BLE_INCLUDED) #endif /* UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP */ diff --git a/components/bt/host/bluedroid/stack/smp/aes.c b/components/bt/host/bluedroid/stack/smp/aes.c index 18b56b877d..0a4bcdd747 100644 --- a/components/bt/host/bluedroid/stack/smp/aes.c +++ b/components/bt/host/bluedroid/stack/smp/aes.c @@ -48,6 +48,8 @@ /* add the target configuration to allow using internal data types and compilation options */ #include "common/bt_target.h" +#if (SMP_CRYPTO_MBEDTLS == FALSE) + /* define if you have fast 32-bit types on your system */ #if 1 # define HAVE_UINT_32T @@ -569,7 +571,7 @@ return_type aes_set_key( const unsigned char key[], length_type keylen, aes_cont /* Encrypt a single block of 16 bytes */ -/* @breif change the name by snake for avoid the conflict with libcrypto */ +/* @brief change the name by snake for avoid the conflict with libcrypto */ return_type bluedroid_aes_encrypt( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK], const aes_context ctx[1] ) { if ( ctx->rnd ) { @@ -935,4 +937,6 @@ void bluedroid_aes_decrypt_256( const unsigned char in[N_BLOCK], unsigned char o copy_and_key( out, s1, o_key ); } +#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ + #endif diff --git a/components/bt/host/bluedroid/stack/smp/include/aes.h b/components/bt/host/bluedroid/stack/smp/include/aes.h index 48495bb174..508ab59796 100644 --- a/components/bt/host/bluedroid/stack/smp/include/aes.h +++ b/components/bt/host/bluedroid/stack/smp/include/aes.h @@ -31,6 +31,10 @@ #ifndef AES_H #define AES_H +#include "common/bt_target.h" + +#if (SMP_CRYPTO_MBEDTLS == FALSE) + #if 1 # define AES_ENC_PREKEYED /* AES encryption with a precomputed key schedule */ #endif @@ -117,7 +121,7 @@ return_type aes_cbc_decrypt( const unsigned char *in, The encryption subroutines take a key in an array of bytes in key[L] where L is 16, 24 or 32 bytes for key lengths of 128, 192, and 256 bits respectively. They then encrypts the input - data, in[] with this key and put the reult in the output array + data, in[] with this key and put the result in the output array out[]. In addition, the second key array, o_key[L], is used to output the key that is needed by the decryption subroutine to reverse the encryption operation. The two key arrays can @@ -159,4 +163,6 @@ void bluedroid_aes_decrypt_256( const unsigned char in[N_BLOCK], unsigned char o_key[2 * N_BLOCK] ); #endif -#endif +#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ + +#endif /* AES_H */ diff --git a/components/bt/host/bluedroid/stack/smp/include/p_256_ecc_pp.h b/components/bt/host/bluedroid/stack/smp/include/p_256_ecc_pp.h index 3b28e0c99a..acf1af8b3c 100644 --- a/components/bt/host/bluedroid/stack/smp/include/p_256_ecc_pp.h +++ b/components/bt/host/bluedroid/stack/smp/include/p_256_ecc_pp.h @@ -24,9 +24,12 @@ #pragma once -#include "p_256_multprecision.h" #include "common/bt_target.h" +#if (SMP_CRYPTO_MBEDTLS == FALSE) + +#include "p_256_multprecision.h" + typedef unsigned long DWORD; typedef struct { @@ -72,3 +75,5 @@ bool ECC_CheckPointIsInElliCur_P256(Point *p); #define ECC_PointMult(q, p, n, keyLength) ECC_PointMult_Bin_NAF(q, p, n, keyLength) void p_256_init_curve(UINT32 keyLength); + +#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ diff --git a/components/bt/host/bluedroid/stack/smp/include/p_256_multprecision.h b/components/bt/host/bluedroid/stack/smp/include/p_256_multprecision.h index 0a33b4e24f..6bf4c32289 100644 --- a/components/bt/host/bluedroid/stack/smp/include/p_256_multprecision.h +++ b/components/bt/host/bluedroid/stack/smp/include/p_256_multprecision.h @@ -24,6 +24,9 @@ #pragma once #include "stack/bt_types.h" +#include "common/bt_target.h" + +#if (SMP_CRYPTO_MBEDTLS == FALSE) /* Type definitions */ typedef unsigned long DWORD; @@ -58,3 +61,5 @@ DWORD multiprecision_lshift(DWORD *c, DWORD *a, uint32_t keyLength); void multiprecision_mult(DWORD *c, DWORD *a, DWORD *b, uint32_t keyLength); void multiprecision_fast_mod(DWORD *c, DWORD *a); void multiprecision_fast_mod_P256(DWORD *c, DWORD *a); + +#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ diff --git a/components/bt/host/bluedroid/stack/smp/p_256_curvepara.c b/components/bt/host/bluedroid/stack/smp/p_256_curvepara.c index abf9a8eecc..b284237f70 100644 --- a/components/bt/host/bluedroid/stack/smp/p_256_curvepara.c +++ b/components/bt/host/bluedroid/stack/smp/p_256_curvepara.c @@ -23,6 +23,10 @@ ******************************************************************************/ #include +#include "common/bt_target.h" + +#if (SMP_CRYPTO_MBEDTLS == FALSE) + #include "p_256_ecc_pp.h" void p_256_init_curve(UINT32 keyLength) @@ -76,3 +80,5 @@ void p_256_init_curve(UINT32 keyLength) ec->G.y[0] = 0x37bf51f5; } } + +#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ diff --git a/components/bt/host/bluedroid/stack/smp/p_256_ecc_pp.c b/components/bt/host/bluedroid/stack/smp/p_256_ecc_pp.c index 1f49c652bd..1bba53bca5 100644 --- a/components/bt/host/bluedroid/stack/smp/p_256_ecc_pp.c +++ b/components/bt/host/bluedroid/stack/smp/p_256_ecc_pp.c @@ -24,9 +24,12 @@ //#include //#include #include +#include "common/bt_target.h" + +#if (SMP_CRYPTO_MBEDTLS == FALSE) + #include "p_256_ecc_pp.h" #include "p_256_multprecision.h" -#include "common/bt_target.h" #if SMP_DYNAMIC_MEMORY == FALSE elliptic_curve_t curve; @@ -281,3 +284,5 @@ bool ECC_CheckPointIsInElliCur_P256(Point *p) return true; } } + +#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ diff --git a/components/bt/host/bluedroid/stack/smp/p_256_multprecision.c b/components/bt/host/bluedroid/stack/smp/p_256_multprecision.c index 1dbca13756..6416f8ff22 100644 --- a/components/bt/host/bluedroid/stack/smp/p_256_multprecision.c +++ b/components/bt/host/bluedroid/stack/smp/p_256_multprecision.c @@ -24,6 +24,9 @@ #include #include "common/bt_target.h" + +#if (SMP_CRYPTO_MBEDTLS == FALSE) + #include "p_256_ecc_pp.h" #include "p_256_multprecision.h" @@ -365,7 +368,7 @@ void multiprecision_fast_mod_P256(DWORD *c, DWORD *a) uint8_t UB; uint8_t UC; uint8_t UD; - uint8_t UE; + uint8_t U_E; uint8_t UF; uint8_t UG; DWORD U; @@ -381,7 +384,7 @@ void multiprecision_fast_mod_P256(DWORD *c, DWORD *a) // E = a[8] + a[9]; E = a[8]; E += a[9]; - UE = (E < a[9]); + U_E = (E < a[9]); // F = a[9] + a[10]; F = a[9]; @@ -418,7 +421,7 @@ void multiprecision_fast_mod_P256(DWORD *c, DWORD *a) c[0] = a[0]; c[0] += E; U = (c[0] < E); - U += UE; + U += U_E; U -= (c[0] < A); U -= UA; c[0] -= A; @@ -479,7 +482,7 @@ void multiprecision_fast_mod_P256(DWORD *c, DWORD *a) U -= (c[3] < a[15]); c[3] -= a[15]; U -= (c[3] < E); - U -= UE; + U -= U_E; c[3] -= E; if (U & 0x80000000) { @@ -546,7 +549,7 @@ void multiprecision_fast_mod_P256(DWORD *c, DWORD *a) c[6] += a[15]; U += (c[6] < a[15]); U -= (c[6] < E); - U -= UE; + U -= U_E; c[6] -= E; if (U & 0x80000000) { @@ -645,3 +648,5 @@ void multiprecision_inv_mod(DWORD *aminus, DWORD *u, uint32_t keyLength) multiprecision_copy(aminus, C, keyLength); } } + +#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ diff --git a/components/bt/host/bluedroid/stack/smp/smp_act.c b/components/bt/host/bluedroid/stack/smp/smp_act.c index b467a1c13d..e0a55a5771 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_act.c +++ b/components/bt/host/bluedroid/stack/smp/smp_act.c @@ -22,7 +22,11 @@ #include "btm_int.h" #include "stack/l2c_api.h" #include "smp_int.h" +#if (SMP_CRYPTO_MBEDTLS == TRUE) +#include "psa/crypto.h" +#else #include "p_256_ecc_pp.h" +#endif //#include "utils/include/bt_utils.h" #if SMP_INCLUDED == TRUE @@ -775,10 +779,50 @@ void smp_process_pairing_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) } /* In order to prevent the x and y coordinates of the public key from being modified, we need to check whether the x and y coordinates are on the given elliptic curve. */ +#if (SMP_CRYPTO_MBEDTLS == TRUE) + { + /* + * PSA Crypto validates the public key when importing. + * We try to import the peer's public key as a ECC public key. + * If import fails, the key is invalid. + */ + psa_status_t status; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + UINT8 pub_be[BT_OCTET32_LEN + BT_OCTET32_LEN + 1]; /* 0x04 || X (32 bytes) || Y (32 bytes) */ + + /* Construct peer public key in uncompressed format (0x04 || X || Y) */ + pub_be[0] = 0x04; + for (int i = 0; i < BT_OCTET32_LEN; i++) { + pub_be[1 + i] = p_cb->peer_publ_key.x[BT_OCTET32_LEN - 1 - i]; + pub_be[33 + i] = p_cb->peer_publ_key.y[BT_OCTET32_LEN - 1 - i]; + } + + /* Try to import as public key - PSA will validate it's on the curve */ + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&key_attributes, 256); + psa_set_key_usage_flags(&key_attributes, 0); /* No usage needed, just validating */ + + status = psa_import_key(&key_attributes, pub_be, sizeof(pub_be), &key_id); + psa_reset_key_attributes(&key_attributes); + + if (status != PSA_SUCCESS) { + SMP_TRACE_ERROR("%s, Invalid Public key. psa_import_key failed: %d\n", __func__, status); + reason = SMP_INVALID_PARAMETERS; + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + return; + } + + /* Key is valid, clean up */ + psa_destroy_key(key_id); + } +#else if (!ECC_CheckPointIsInElliCur_P256((Point *)&p_cb->peer_publ_key)) { SMP_TRACE_ERROR("%s, Invalid Public key.", __func__); smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + return; } +#endif /* SMP_CRYPTO_MBEDTLS */ p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY; smp_wait_for_both_public_keys(p_cb, NULL); diff --git a/components/bt/host/bluedroid/stack/smp/smp_api.c b/components/bt/host/bluedroid/stack/smp/smp_api.c index b99c94abd8..c95dd5d739 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_api.c +++ b/components/bt/host/bluedroid/stack/smp/smp_api.c @@ -35,7 +35,9 @@ #include "stack/hcimsgs.h" #include "stack/btu.h" +#if (SMP_CRYPTO_MBEDTLS == FALSE) #include "p_256_ecc_pp.h" +#endif #include "osi/allocator.h" /******************************************************************************* @@ -51,12 +53,16 @@ void SMP_Init(void) { #if SMP_DYNAMIC_MEMORY smp_cb_ptr = (tSMP_CB *)osi_malloc(sizeof(tSMP_CB)); +#if (SMP_CRYPTO_MBEDTLS == FALSE) curve_ptr = (elliptic_curve_t *)osi_malloc(sizeof(elliptic_curve_t)); curve_p256_ptr = (elliptic_curve_t *)osi_malloc(sizeof(elliptic_curve_t)); +#endif #endif memset(&smp_cb, 0, sizeof(tSMP_CB)); +#if (SMP_CRYPTO_MBEDTLS == FALSE) memset(&curve, 0, sizeof(elliptic_curve_t)); memset(&curve_p256, 0, sizeof(elliptic_curve_t)); +#endif #if defined(SMP_INITIAL_TRACE_LEVEL) smp_cb.trace_level = SMP_INITIAL_TRACE_LEVEL; @@ -66,8 +72,10 @@ void SMP_Init(void) SMP_TRACE_EVENT ("%s", __FUNCTION__); smp_l2cap_if_init(); +#if (SMP_CRYPTO_MBEDTLS == FALSE) /* initialization of P-256 parameters */ p_256_init_curve(KEY_LENGTH_DWORDS_P256); +#endif } void SMP_Free(void) @@ -75,8 +83,10 @@ void SMP_Free(void) memset(&smp_cb, 0, sizeof(tSMP_CB)); #if SMP_DYNAMIC_MEMORY FREE_AND_RESET(smp_cb_ptr); +#if (SMP_CRYPTO_MBEDTLS == FALSE) FREE_AND_RESET(curve_ptr); FREE_AND_RESET(curve_p256_ptr); +#endif #endif /* #if SMP_DYNAMIC_MEMORY */ } diff --git a/components/bt/host/bluedroid/stack/smp/smp_cmac.c b/components/bt/host/bluedroid/stack/smp/smp_cmac.c index e47c56b71f..39aeccf23e 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_cmac.c +++ b/components/bt/host/bluedroid/stack/smp/smp_cmac.c @@ -32,7 +32,11 @@ #include "stack/btm_ble_api.h" #include "smp_int.h" #include "stack/hcimsgs.h" +#if (SMP_CRYPTO_MBEDTLS == TRUE) +#include "psa/crypto.h" +#endif +#if (SMP_CRYPTO_MBEDTLS == FALSE) typedef struct { UINT8 *text; UINT16 len; @@ -46,6 +50,7 @@ const BT_OCTET16 const_Rb = { 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ void print128(BT_OCTET16 x, const UINT8 *key_name) { @@ -75,6 +80,7 @@ void print128(BT_OCTET16 x, const UINT8 *key_name) ** Returns void ** *******************************************************************************/ +#if (SMP_CRYPTO_MBEDTLS == FALSE) static void padding ( BT_OCTET16 dest, UINT8 length ) { UINT8 i, *p = dest; @@ -171,7 +177,7 @@ static BOOLEAN cmac_aes_k_calculate(BT_OCTET16 key, UINT8 *p_signature, UINT16 t ** ** Function cmac_prepare_last_block ** -** Description This function proceeed to prepare the last block of message +** Description This function proceed to prepare the last block of message ** Mn depending on the size of the message. ** ** Returns void @@ -262,6 +268,8 @@ static BOOLEAN cmac_generate_subkey(BT_OCTET16 key) return ret; } +#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ + /******************************************************************************* ** ** Function aes_cipher_msg_auth_code @@ -271,7 +279,7 @@ static BOOLEAN cmac_generate_subkey(BT_OCTET16 key) ** Parameters key - CMAC key in little endian order, expect SRK when used by SMP. ** input - text to be signed in little endian byte order. ** length - length of the input in byte. -** tlen - lenth of mac desired +** tlen - length of mac desired ** p_signature - data pointer to where signed data to be stored, tlen long. ** ** Returns FALSE if out of resources, TRUE in other cases. @@ -280,43 +288,139 @@ static BOOLEAN cmac_generate_subkey(BT_OCTET16 key) BOOLEAN aes_cipher_msg_auth_code(BT_OCTET16 key, UINT8 *input, UINT16 length, UINT16 tlen, UINT8 *p_signature) { - UINT16 len, diff; - UINT16 n = (length + BT_OCTET16_LEN - 1) / BT_OCTET16_LEN; /* n is number of rounds */ BOOLEAN ret = FALSE; SMP_TRACE_EVENT ("%s", __func__); - if (n == 0) { - n = 1; +#if (SMP_CRYPTO_MBEDTLS == TRUE) + { + /* + * PSA Crypto CMAC implementation. + * Bluedroid uses little-endian, PSA uses big-endian. + * We reverse the key and input, then reverse the output. + */ + psa_status_t status; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + UINT8 key_be[BT_OCTET16_LEN]; + UINT8 *input_be = NULL; + UINT8 mac_be[BT_OCTET16_LEN]; + size_t mac_len = 0; + + SMP_TRACE_DEBUG("AES128_CMAC (PSA) started, length = %d", length); + + /* Convert key from little-endian to big-endian */ + for (int i = 0; i < BT_OCTET16_LEN; i++) { + key_be[i] = key[BT_OCTET16_LEN - 1 - i]; + } + + /* Allocate and convert input from little-endian to big-endian */ + if (length > 0) { + input_be = (UINT8 *)osi_malloc(length); + if (input_be == NULL) { + SMP_TRACE_ERROR("No resources for input_be"); + return FALSE; + } + for (UINT16 i = 0; i < length; i++) { + input_be[i] = input[length - 1 - i]; + } + } + + /* Import the key */ + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_MESSAGE); + psa_set_key_algorithm(&key_attributes, PSA_ALG_CMAC); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&key_attributes, 128); + + status = psa_import_key(&key_attributes, key_be, BT_OCTET16_LEN, &key_id); + if (status != PSA_SUCCESS) { + SMP_TRACE_ERROR("psa_import_key failed: %d", status); + if (input_be) osi_free(input_be); + return FALSE; + } + psa_reset_key_attributes(&key_attributes); + + /* Setup MAC operation */ + status = psa_mac_sign_setup(&operation, key_id, PSA_ALG_CMAC); + if (status != PSA_SUCCESS) { + SMP_TRACE_ERROR("psa_mac_sign_setup failed: %d", status); + psa_destroy_key(key_id); + if (input_be) osi_free(input_be); + return FALSE; + } + + /* Update with input data */ + if (length > 0 && input_be != NULL) { + status = psa_mac_update(&operation, input_be, length); + if (status != PSA_SUCCESS) { + SMP_TRACE_ERROR("psa_mac_update failed: %d", status); + psa_mac_abort(&operation); + psa_destroy_key(key_id); + osi_free(input_be); + return FALSE; + } + osi_free(input_be); + } + + /* Finish and get MAC */ + status = psa_mac_sign_finish(&operation, mac_be, sizeof(mac_be), &mac_len); + psa_destroy_key(key_id); + + if (status != PSA_SUCCESS) { + SMP_TRACE_ERROR("psa_mac_sign_finish failed: %d", status); + psa_mac_abort(&operation); + return FALSE; + } + + /* Convert MAC from big-endian to little-endian and truncate to tlen bytes */ + for (UINT16 i = 0; i < tlen && i < BT_OCTET16_LEN; i++) { + p_signature[i] = mac_be[BT_OCTET16_LEN - 1 - i]; + } + + /* Clear sensitive data from stack */ + memset(key_be, 0, sizeof(key_be)); + + ret = TRUE; } - len = n * BT_OCTET16_LEN; +#else + { + UINT16 len, diff; + UINT16 n = (length + BT_OCTET16_LEN - 1) / BT_OCTET16_LEN; - SMP_TRACE_DEBUG("AES128_CMAC started, allocate buffer size = %d", len); - /* allocate a memory space of multiple of 16 bytes to hold text */ - if ((cmac_cb.text = (UINT8 *)osi_malloc(len)) != NULL) { - cmac_cb.round = n; + if (n == 0) { + n = 1; + } + len = n * BT_OCTET16_LEN; - memset(cmac_cb.text, 0, len); - diff = len - length; + SMP_TRACE_DEBUG("AES128_CMAC started, allocate buffer size = %d", len); + /* allocate a memory space of multiple of 16 bytes to hold text */ + if ((cmac_cb.text = (UINT8 *)osi_malloc(len)) != NULL) { + cmac_cb.round = n; - if (input != NULL && length > 0) { - memcpy(&cmac_cb.text[diff] , input, (int)length); - cmac_cb.len = length; + memset(cmac_cb.text, 0, len); + diff = len - length; + + if (input != NULL && length > 0) { + memcpy(&cmac_cb.text[diff] , input, (int)length); + cmac_cb.len = length; + } else { + cmac_cb.len = 0; + } + + /* prepare calculation for subkey s and last block of data */ + if (cmac_generate_subkey(key)) { + /* start calculation */ + ret = cmac_aes_k_calculate(key, p_signature, tlen); + } + /* clean up */ + cmac_aes_cleanup(); } else { - cmac_cb.len = 0; + ret = FALSE; + SMP_TRACE_ERROR("No resources"); } - - /* prepare calculation for subkey s and last block of data */ - if (cmac_generate_subkey(key)) { - /* start calculation */ - ret = cmac_aes_k_calculate(key, p_signature, tlen); - } - /* clean up */ - cmac_aes_cleanup(); - } else { - ret = FALSE; - SMP_TRACE_ERROR("No resources"); } +#endif /* SMP_CRYPTO_MBEDTLS */ return ret; } diff --git a/components/bt/host/bluedroid/stack/smp/smp_keys.c b/components/bt/host/bluedroid/stack/smp/smp_keys.c index 24ef814279..01652fd89f 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_keys.c +++ b/components/bt/host/bluedroid/stack/smp/smp_keys.c @@ -34,7 +34,11 @@ #include "btm_int.h" #include "btm_ble_int.h" #include "stack/hcimsgs.h" +#if (SMP_CRYPTO_MBEDTLS == TRUE) +#include "psa/crypto.h" +#else #include "aes.h" +#endif /* SMP_CRYPTO_MBEDTLS */ #include "p_256_ecc_pp.h" #include "device/controller.h" @@ -159,12 +163,11 @@ BOOLEAN smp_encrypt_data (UINT8 *key, UINT8 key_len, UINT8 *plain_text, UINT8 pt_len, tSMP_ENC *p_out) { - aes_context ctx; UINT8 *p_start = NULL; UINT8 *p = NULL; - UINT8 *p_rev_data = NULL; /* input data in big endilan format */ - UINT8 *p_rev_key = NULL; /* input key in big endilan format */ - UINT8 *p_rev_output = NULL; /* encrypted output in big endilan format */ + UINT8 *p_rev_data = NULL; /* input data in big endian format */ + UINT8 *p_rev_key = NULL; /* input key in big endian format */ + UINT8 *p_rev_output = NULL; /* encrypted output in big endian format */ SMP_TRACE_DEBUG ("%s\n", __func__); if ( (p_out == NULL ) || (key_len != SMP_ENCRYT_KEY_SIZE) ) { @@ -194,8 +197,44 @@ BOOLEAN smp_encrypt_data (UINT8 *key, UINT8 key_len, smp_debug_print_nbyte_little_endian(p_start, (const UINT8 *)"Plain text", SMP_ENCRYT_DATA_SIZE); #endif p_rev_output = p; - aes_set_key(p_rev_key, SMP_ENCRYT_KEY_SIZE, &ctx); - bluedroid_aes_encrypt(p_rev_data, p, &ctx); /* outputs in byte 48 to byte 63 */ + +#if (SMP_CRYPTO_MBEDTLS == TRUE) + { + psa_status_t status; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + size_t output_len = 0; + + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECB_NO_PADDING); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&key_attributes, 128); + + status = psa_import_key(&key_attributes, p_rev_key, SMP_ENCRYT_KEY_SIZE, &key_id); + if (status != PSA_SUCCESS) { + SMP_TRACE_ERROR("%s psa_import_key failed: %d\n", __func__, status); + osi_free(p_start); + return FALSE; + } + psa_reset_key_attributes(&key_attributes); + + status = psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING, p_rev_data, + SMP_ENCRYT_DATA_SIZE, p_rev_output, SMP_ENCRYT_DATA_SIZE, &output_len); + psa_destroy_key(key_id); + + if (status != PSA_SUCCESS || output_len != SMP_ENCRYT_DATA_SIZE) { + SMP_TRACE_ERROR("%s psa_cipher_encrypt failed: %d\n", __func__, status); + osi_free(p_start); + return FALSE; + } + } +#else + { + aes_context ctx; + aes_set_key(p_rev_key, SMP_ENCRYT_KEY_SIZE, &ctx); + bluedroid_aes_encrypt(p_rev_data, p_rev_output, &ctx); /* outputs in byte 48 to byte 63 */ + } +#endif /* SMP_CRYPTO_MBEDTLS */ p = p_out->param_buf; REVERSE_ARRAY_TO_STREAM (p, p_rev_output, SMP_ENCRYT_DATA_SIZE); @@ -207,6 +246,8 @@ BOOLEAN smp_encrypt_data (UINT8 *key, UINT8 key_len, p_out->status = HCI_SUCCESS; p_out->opcode = HCI_BLE_ENCRYPT; + /* Clear sensitive data (including key at byte 32-47) before freeing */ + memset(p_start, 0, SMP_ENCRYT_DATA_SIZE * 4); osi_free(p_start); return TRUE; @@ -1118,8 +1159,6 @@ void smp_continue_private_key_creation (tSMP_CB *p_cb, tBTM_RAND_ENC *p) *******************************************************************************/ void smp_process_private_key(tSMP_CB *p_cb) { - Point public_key; - BT_OCTET32 private_key; tSMP_LOC_OOB_DATA *p_loc_oob = &p_cb->sc_oob_data.loc_oob_data; SMP_TRACE_DEBUG ("%s", __FUNCTION__); @@ -1131,10 +1170,59 @@ void smp_process_private_key(tSMP_CB *p_cb) memcpy(p_cb->loc_publ_key.y, p_loc_oob->publ_key_used.y, BT_OCTET32_LEN); memcpy(p_cb->local_random, p_loc_oob->randomizer, BT_OCTET16_LEN); } else { +#if (SMP_CRYPTO_MBEDTLS == TRUE) + psa_status_t status; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + UINT8 priv_be[BT_OCTET32_LEN]; + UINT8 pub_be[BT_OCTET32_LEN + BT_OCTET32_LEN + 1]; /* 0x04 || X (32 bytes) || Y (32 bytes) */ + size_t pub_len = 0; + + /* Convert private key from little-endian to big-endian */ + for (int i = 0; i < BT_OCTET32_LEN; i++) { + priv_be[i] = p_cb->private_key[BT_OCTET32_LEN - 1 - i]; + } + + /* Import the private key */ + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&key_attributes, 256); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT); + + status = psa_import_key(&key_attributes, priv_be, BT_OCTET32_LEN, &key_id); + if (status != PSA_SUCCESS) { + SMP_TRACE_ERROR("%s psa_import_key failed: %d\n", __FUNCTION__, status); + goto psa_pubkey_cleanup; + } + psa_reset_key_attributes(&key_attributes); + + /* Export public key */ + status = psa_export_public_key(key_id, pub_be, sizeof(pub_be), &pub_len); + if (status != PSA_SUCCESS || pub_len != (BT_OCTET32_LEN + BT_OCTET32_LEN + 1)) { + SMP_TRACE_ERROR("%s psa_export_public_key failed: %d\n", __FUNCTION__, status); + goto psa_pubkey_cleanup; + } + + /* Convert X and Y from big-endian to little-endian */ + /* pub_be: 0x04 || X (32 bytes) || Y (32 bytes) */ + for (int i = 0; i < BT_OCTET32_LEN; i++) { + p_cb->loc_publ_key.x[i] = pub_be[1 + BT_OCTET32_LEN - 1 - i]; + p_cb->loc_publ_key.y[i] = pub_be[33 + BT_OCTET32_LEN - 1 - i]; + } + +psa_pubkey_cleanup: + psa_destroy_key(key_id); + /* Clear sensitive data from stack */ + memset(priv_be, 0, sizeof(priv_be)); +#else + Point public_key; + BT_OCTET32 private_key; + memcpy(private_key, p_cb->private_key, BT_OCTET32_LEN); ECC_PointMult(&public_key, &(curve_p256.G), (DWORD *) private_key, KEY_LENGTH_DWORDS_P256); memcpy(p_cb->loc_publ_key.x, public_key.x, BT_OCTET32_LEN); memcpy(p_cb->loc_publ_key.y, public_key.y, BT_OCTET32_LEN); +#endif /* SMP_CRYPTO_MBEDTLS */ } smp_debug_print_nbyte_little_endian (p_cb->private_key, (const UINT8 *)"private", @@ -1161,11 +1249,64 @@ void smp_process_private_key(tSMP_CB *p_cb) *******************************************************************************/ void smp_compute_dhkey (tSMP_CB *p_cb) { + SMP_TRACE_DEBUG ("%s\n", __FUNCTION__); + +#if (SMP_CRYPTO_MBEDTLS == TRUE) + psa_status_t status; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + UINT8 priv_be[BT_OCTET32_LEN]; + UINT8 peer_pub_be[BT_OCTET32_LEN + BT_OCTET32_LEN + 1]; /* 0x04 || X (32 bytes) || Y (32 bytes) */ + UINT8 shared_secret[BT_OCTET32_LEN]; + size_t output_len = 0; + + /* Convert private key from little-endian to big-endian */ + for (int i = 0; i < BT_OCTET32_LEN; i++) { + priv_be[i] = p_cb->private_key[BT_OCTET32_LEN - 1 - i]; + } + + /* Import the private key */ + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&key_attributes, 256); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); + + status = psa_import_key(&key_attributes, priv_be, BT_OCTET32_LEN, &key_id); + if (status != PSA_SUCCESS) { + SMP_TRACE_ERROR("%s psa_import_key failed: %d\n", __FUNCTION__, status); + goto psa_dhkey_cleanup; + } + psa_reset_key_attributes(&key_attributes); + + /* Construct peer public key in uncompressed format: 0x04 || X || Y */ + peer_pub_be[0] = 0x04; + for (int i = 0; i < BT_OCTET32_LEN; i++) { + peer_pub_be[1 + i] = p_cb->peer_publ_key.x[BT_OCTET32_LEN - 1 - i]; + peer_pub_be[33 + i] = p_cb->peer_publ_key.y[BT_OCTET32_LEN - 1 - i]; + } + + /* Compute ECDH shared secret */ + status = psa_raw_key_agreement(PSA_ALG_ECDH, key_id, peer_pub_be, sizeof(peer_pub_be), + shared_secret, sizeof(shared_secret), &output_len); + if (status != PSA_SUCCESS || output_len != BT_OCTET32_LEN) { + SMP_TRACE_ERROR("%s psa_raw_key_agreement failed: %d\n", __FUNCTION__, status); + goto psa_dhkey_cleanup; + } + + /* Convert shared secret from big-endian to little-endian for DHKey */ + for (int i = 0; i < BT_OCTET32_LEN; i++) { + p_cb->dhkey[i] = shared_secret[BT_OCTET32_LEN - 1 - i]; + } + +psa_dhkey_cleanup: + psa_destroy_key(key_id); + /* Clear sensitive data from stack */ + memset(priv_be, 0, sizeof(priv_be)); + memset(shared_secret, 0, sizeof(shared_secret)); +#else Point peer_publ_key, new_publ_key; BT_OCTET32 private_key; - SMP_TRACE_DEBUG ("%s\n", __FUNCTION__); - memcpy(private_key, p_cb->private_key, BT_OCTET32_LEN); memcpy(peer_publ_key.x, p_cb->peer_publ_key.x, BT_OCTET32_LEN); memcpy(peer_publ_key.y, p_cb->peer_publ_key.y, BT_OCTET32_LEN); @@ -1173,8 +1314,9 @@ void smp_compute_dhkey (tSMP_CB *p_cb) ECC_PointMult(&new_publ_key, &peer_publ_key, (DWORD *) private_key, KEY_LENGTH_DWORDS_P256); memcpy(p_cb->dhkey, new_publ_key.x, BT_OCTET32_LEN); +#endif /* SMP_CRYPTO_MBEDTLS */ - smp_debug_print_nbyte_little_endian (p_cb->dhkey, (const UINT8 *)"Old DHKey", + smp_debug_print_nbyte_little_endian (p_cb->dhkey, (const UINT8 *)"DHKey", BT_OCTET32_LEN); smp_debug_print_nbyte_little_endian (p_cb->private_key, (const UINT8 *)"private", @@ -1183,8 +1325,6 @@ void smp_compute_dhkey (tSMP_CB *p_cb) BT_OCTET32_LEN); smp_debug_print_nbyte_little_endian (p_cb->peer_publ_key.y, (const UINT8 *)"rem public(y)", BT_OCTET32_LEN); - smp_debug_print_nbyte_little_endian (p_cb->dhkey, (const UINT8 *)"Reverted DHKey", - BT_OCTET32_LEN); } /******************************************************************************* From c04036d6bfbfc7567e143146acd7aded903eb376 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Mon, 22 Dec 2025 12:01:09 +0800 Subject: [PATCH 084/226] feat(ble/bluedroid): Supported Bludroid host encryption using TinyCrypt --- components/bt/CMakeLists.txt | 7 +- components/bt/host/bluedroid/Kconfig.in | 45 +++++--- .../include/common/bluedroid_user_config.h | 16 ++- .../common/include/common/bt_target.h | 12 ++ components/bt/host/bluedroid/stack/smp/aes.c | 4 +- .../bt/host/bluedroid/stack/smp/include/aes.h | 4 +- .../stack/smp/include/p_256_ecc_pp.h | 4 +- .../stack/smp/include/p_256_multprecision.h | 4 +- .../bluedroid/stack/smp/p_256_curvepara.c | 4 +- .../host/bluedroid/stack/smp/p_256_ecc_pp.c | 4 +- .../bluedroid/stack/smp/p_256_multprecision.c | 4 +- .../bt/host/bluedroid/stack/smp/smp_act.c | 32 ++++++ .../bt/host/bluedroid/stack/smp/smp_api.c | 10 +- .../bt/host/bluedroid/stack/smp/smp_cmac.c | 96 +++++++++++++++- .../bt/host/bluedroid/stack/smp/smp_keys.c | 107 +++++++++++++++++- 15 files changed, 312 insertions(+), 41 deletions(-) diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 9caf183ff7..af71a578fa 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -720,7 +720,12 @@ if(CONFIG_BT_ENABLED) ) endif() - if(NOT (CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS OR CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS)) + # Compile TinyCrypt if: + # 1. Controller uses TinyCrypt (not mbedTLS), OR + # 2. NimBLE uses TinyCrypt (not mbedTLS), OR + # 3. Bluedroid Host SMP uses TinyCrypt + if(CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT OR + (NOT CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS AND NOT CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS)) list(APPEND include_dirs common/tinycrypt/include common/tinycrypt/port diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 1c762a559a..6fb37d96f8 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -464,26 +464,43 @@ config BT_BLE_SMP_BOND_NVS_FLASH help This select can save SMP bonding keys to nvs flash -config BT_SMP_CRYPTO_MBEDTLS - bool "Use mbedTLS for SMP cryptographic functions" +choice BT_SMP_CRYPTO_STACK + prompt "SMP cryptographic stack" depends on BT_BLE_SMP_ENABLE - depends on !BLE_MESH - select MBEDTLS_AES_C - select MBEDTLS_CMAC_C - select MBEDTLS_ECDH_C - select MBEDTLS_ECP_C - select MBEDTLS_ECP_DP_SECP256R1_ENABLED - default n + default BT_SMP_CRYPTO_STACK_NATIVE help - If enabled, the SMP layer will use mbedTLS library for cryptographic - operations (AES, AES-CMAC, ECDH P-256) instead of the built-in - Bluedroid implementation. This can provide hardware acceleration - on supported platforms and reduce code size by sharing crypto - implementations with other components. + Select the cryptographic library to use for SMP operations (AES, AES-CMAC, ECDH P-256). Note: This option is not compatible with BLE Mesh, as BLE Mesh uses the native Bluedroid ECC implementation directly. + config BT_SMP_CRYPTO_STACK_NATIVE + bool "Native Bluedroid implementation" + help + Use the built-in Bluedroid cryptographic implementation. + This is the default option and provides compatibility with all features. + + config BT_SMP_CRYPTO_STACK_TINYCRYPT + bool "TinyCrypt" + help + Use TinyCrypt library for cryptographic operations. + TinyCrypt is a lightweight cryptographic library designed for constrained devices. + This can reduce code size compared to the native implementation. + + config BT_SMP_CRYPTO_STACK_MBEDTLS + bool "mbedTLS" + select MBEDTLS_AES_C + select MBEDTLS_CMAC_C + select MBEDTLS_ECDH_C + select MBEDTLS_ECP_C + select MBEDTLS_ECP_DP_SECP256R1_ENABLED + help + Use mbedTLS library for cryptographic operations. + This can provide hardware acceleration on supported platforms and reduce code size + by sharing crypto implementations with other components. + +endchoice + config BT_BLE_RPA_SUPPORTED bool "Update RPA to Controller" depends on (BT_BLE_SMP_ENABLE && ((BT_CONTROLLER_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR 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 602042bdab..52b82891e2 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 @@ -467,12 +467,24 @@ #define UC_BT_BLE_SMP_BOND_NVS_FLASH FALSE #endif -#ifdef CONFIG_BT_SMP_CRYPTO_MBEDTLS -#define UC_BT_SMP_CRYPTO_MBEDTLS CONFIG_BT_SMP_CRYPTO_MBEDTLS +#ifdef CONFIG_BT_SMP_CRYPTO_STACK_NATIVE +#define UC_BT_SMP_CRYPTO_STACK_NATIVE TRUE +#else +#define UC_BT_SMP_CRYPTO_STACK_NATIVE FALSE +#endif + +#ifdef CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS +#define UC_BT_SMP_CRYPTO_MBEDTLS TRUE #else #define UC_BT_SMP_CRYPTO_MBEDTLS FALSE #endif +#ifdef CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT +#define UC_BT_SMP_CRYPTO_TINYCRYPT TRUE +#else +#define UC_BT_SMP_CRYPTO_TINYCRYPT FALSE +#endif + //Device Name Maximum Length #ifdef CONFIG_BT_MAX_DEVICE_NAME_LEN #define UC_MAX_LOC_BD_NAME_LEN CONFIG_BT_MAX_DEVICE_NAME_LEN 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 6f58d12930..36b596fb39 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -517,12 +517,24 @@ #define BLE_SMP_BOND_NVS_FLASH FALSE #endif +#if (UC_BT_SMP_CRYPTO_STACK_NATIVE) +#define SMP_CRYPTO_STACK_NATIVE TRUE +#else +#define SMP_CRYPTO_STACK_NATIVE FALSE +#endif /* UC_BT_SMP_CRYPTO_STACK_NATIVE */ + #if (UC_BT_SMP_CRYPTO_MBEDTLS) #define SMP_CRYPTO_MBEDTLS TRUE #else #define SMP_CRYPTO_MBEDTLS FALSE #endif /* UC_BT_SMP_CRYPTO_MBEDTLS */ +#if (UC_BT_SMP_CRYPTO_TINYCRYPT) +#define SMP_CRYPTO_TINYCRYPT TRUE +#else +#define SMP_CRYPTO_TINYCRYPT FALSE +#endif /* UC_BT_SMP_CRYPTO_TINYCRYPT */ + #ifdef UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP #define BLE_ADV_REPORT_FLOW_CONTROL (UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP && BLE_INCLUDED) #endif /* UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP */ diff --git a/components/bt/host/bluedroid/stack/smp/aes.c b/components/bt/host/bluedroid/stack/smp/aes.c index 0a4bcdd747..6555b6af97 100644 --- a/components/bt/host/bluedroid/stack/smp/aes.c +++ b/components/bt/host/bluedroid/stack/smp/aes.c @@ -48,7 +48,7 @@ /* add the target configuration to allow using internal data types and compilation options */ #include "common/bt_target.h" -#if (SMP_CRYPTO_MBEDTLS == FALSE) +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) /* define if you have fast 32-bit types on your system */ #if 1 @@ -937,6 +937,6 @@ void bluedroid_aes_decrypt_256( const unsigned char in[N_BLOCK], unsigned char o copy_and_key( out, s1, o_key ); } -#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ +#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */ #endif diff --git a/components/bt/host/bluedroid/stack/smp/include/aes.h b/components/bt/host/bluedroid/stack/smp/include/aes.h index 508ab59796..9c14e22dcf 100644 --- a/components/bt/host/bluedroid/stack/smp/include/aes.h +++ b/components/bt/host/bluedroid/stack/smp/include/aes.h @@ -33,7 +33,7 @@ #include "common/bt_target.h" -#if (SMP_CRYPTO_MBEDTLS == FALSE) +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) #if 1 # define AES_ENC_PREKEYED /* AES encryption with a precomputed key schedule */ @@ -163,6 +163,6 @@ void bluedroid_aes_decrypt_256( const unsigned char in[N_BLOCK], unsigned char o_key[2 * N_BLOCK] ); #endif -#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ +#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */ #endif /* AES_H */ diff --git a/components/bt/host/bluedroid/stack/smp/include/p_256_ecc_pp.h b/components/bt/host/bluedroid/stack/smp/include/p_256_ecc_pp.h index acf1af8b3c..7c2f7279eb 100644 --- a/components/bt/host/bluedroid/stack/smp/include/p_256_ecc_pp.h +++ b/components/bt/host/bluedroid/stack/smp/include/p_256_ecc_pp.h @@ -26,7 +26,7 @@ #include "common/bt_target.h" -#if (SMP_CRYPTO_MBEDTLS == FALSE) +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) #include "p_256_multprecision.h" @@ -76,4 +76,4 @@ bool ECC_CheckPointIsInElliCur_P256(Point *p); void p_256_init_curve(UINT32 keyLength); -#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ +#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */ diff --git a/components/bt/host/bluedroid/stack/smp/include/p_256_multprecision.h b/components/bt/host/bluedroid/stack/smp/include/p_256_multprecision.h index 6bf4c32289..83b7f1876f 100644 --- a/components/bt/host/bluedroid/stack/smp/include/p_256_multprecision.h +++ b/components/bt/host/bluedroid/stack/smp/include/p_256_multprecision.h @@ -26,7 +26,7 @@ #include "stack/bt_types.h" #include "common/bt_target.h" -#if (SMP_CRYPTO_MBEDTLS == FALSE) +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) /* Type definitions */ typedef unsigned long DWORD; @@ -62,4 +62,4 @@ void multiprecision_mult(DWORD *c, DWORD *a, DWORD *b, uint32_t keyLength); void multiprecision_fast_mod(DWORD *c, DWORD *a); void multiprecision_fast_mod_P256(DWORD *c, DWORD *a); -#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ +#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */ diff --git a/components/bt/host/bluedroid/stack/smp/p_256_curvepara.c b/components/bt/host/bluedroid/stack/smp/p_256_curvepara.c index b284237f70..b3fca522de 100644 --- a/components/bt/host/bluedroid/stack/smp/p_256_curvepara.c +++ b/components/bt/host/bluedroid/stack/smp/p_256_curvepara.c @@ -25,7 +25,7 @@ #include #include "common/bt_target.h" -#if (SMP_CRYPTO_MBEDTLS == FALSE) +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) #include "p_256_ecc_pp.h" @@ -81,4 +81,4 @@ void p_256_init_curve(UINT32 keyLength) } } -#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ +#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */ diff --git a/components/bt/host/bluedroid/stack/smp/p_256_ecc_pp.c b/components/bt/host/bluedroid/stack/smp/p_256_ecc_pp.c index 1bba53bca5..d3b9452c1e 100644 --- a/components/bt/host/bluedroid/stack/smp/p_256_ecc_pp.c +++ b/components/bt/host/bluedroid/stack/smp/p_256_ecc_pp.c @@ -26,7 +26,7 @@ #include #include "common/bt_target.h" -#if (SMP_CRYPTO_MBEDTLS == FALSE) +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) #include "p_256_ecc_pp.h" #include "p_256_multprecision.h" @@ -285,4 +285,4 @@ bool ECC_CheckPointIsInElliCur_P256(Point *p) } } -#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ +#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */ diff --git a/components/bt/host/bluedroid/stack/smp/p_256_multprecision.c b/components/bt/host/bluedroid/stack/smp/p_256_multprecision.c index 6416f8ff22..92291d98b3 100644 --- a/components/bt/host/bluedroid/stack/smp/p_256_multprecision.c +++ b/components/bt/host/bluedroid/stack/smp/p_256_multprecision.c @@ -25,7 +25,7 @@ #include #include "common/bt_target.h" -#if (SMP_CRYPTO_MBEDTLS == FALSE) +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) #include "p_256_ecc_pp.h" #include "p_256_multprecision.h" @@ -649,4 +649,4 @@ void multiprecision_inv_mod(DWORD *aminus, DWORD *u, uint32_t keyLength) } } -#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ +#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */ diff --git a/components/bt/host/bluedroid/stack/smp/smp_act.c b/components/bt/host/bluedroid/stack/smp/smp_act.c index e0a55a5771..e6cbc9c02b 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_act.c +++ b/components/bt/host/bluedroid/stack/smp/smp_act.c @@ -24,6 +24,10 @@ #include "smp_int.h" #if (SMP_CRYPTO_MBEDTLS == TRUE) #include "psa/crypto.h" +#elif (SMP_CRYPTO_TINYCRYPT == TRUE) +#include "tinycrypt/ecc_dh.h" +#include "tinycrypt/ecc.h" +#include "tinycrypt/constants.h" #else #include "p_256_ecc_pp.h" #endif @@ -816,6 +820,34 @@ void smp_process_pairing_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) /* Key is valid, clean up */ psa_destroy_key(key_id); } +#elif (SMP_CRYPTO_TINYCRYPT == TRUE) + { + /* + * TinyCrypt validates the public key using uECC_valid_public_key. + * TinyCrypt expects public key in format: X (32 bytes) || Y (32 bytes), no prefix. + */ + UINT8 pub_be[64]; /* TinyCrypt format: X (32 bytes) || Y (32 bytes), no prefix */ + + /* Convert peer public key from little-endian to big-endian */ + /* TinyCrypt format: X (32 bytes) || Y (32 bytes), no prefix */ + for (int i = 0; i < BT_OCTET32_LEN; i++) { + pub_be[i] = p_cb->peer_publ_key.x[BT_OCTET32_LEN - 1 - i]; + pub_be[BT_OCTET32_LEN + i] = p_cb->peer_publ_key.y[BT_OCTET32_LEN - 1 - i]; + } + + /* Validate public key - TinyCrypt will check if it's on the curve */ + /* uECC_valid_public_key returns 0 if valid, negative value if invalid */ + if (uECC_valid_public_key(pub_be, uECC_secp256r1()) < 0) { + SMP_TRACE_ERROR("%s, Invalid Public key. uECC_valid_public_key failed\n", __func__); + reason = SMP_INVALID_PARAMETERS; + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + memset(pub_be, 0, sizeof(pub_be)); + return; + } + + /* Clear sensitive data from stack */ + memset(pub_be, 0, sizeof(pub_be)); + } #else if (!ECC_CheckPointIsInElliCur_P256((Point *)&p_cb->peer_publ_key)) { SMP_TRACE_ERROR("%s, Invalid Public key.", __func__); diff --git a/components/bt/host/bluedroid/stack/smp/smp_api.c b/components/bt/host/bluedroid/stack/smp/smp_api.c index c95dd5d739..0789666f6c 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_api.c +++ b/components/bt/host/bluedroid/stack/smp/smp_api.c @@ -35,7 +35,7 @@ #include "stack/hcimsgs.h" #include "stack/btu.h" -#if (SMP_CRYPTO_MBEDTLS == FALSE) +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) #include "p_256_ecc_pp.h" #endif #include "osi/allocator.h" @@ -53,13 +53,13 @@ void SMP_Init(void) { #if SMP_DYNAMIC_MEMORY smp_cb_ptr = (tSMP_CB *)osi_malloc(sizeof(tSMP_CB)); -#if (SMP_CRYPTO_MBEDTLS == FALSE) +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) curve_ptr = (elliptic_curve_t *)osi_malloc(sizeof(elliptic_curve_t)); curve_p256_ptr = (elliptic_curve_t *)osi_malloc(sizeof(elliptic_curve_t)); #endif #endif memset(&smp_cb, 0, sizeof(tSMP_CB)); -#if (SMP_CRYPTO_MBEDTLS == FALSE) +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) memset(&curve, 0, sizeof(elliptic_curve_t)); memset(&curve_p256, 0, sizeof(elliptic_curve_t)); #endif @@ -72,7 +72,7 @@ void SMP_Init(void) SMP_TRACE_EVENT ("%s", __FUNCTION__); smp_l2cap_if_init(); -#if (SMP_CRYPTO_MBEDTLS == FALSE) +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) /* initialization of P-256 parameters */ p_256_init_curve(KEY_LENGTH_DWORDS_P256); #endif @@ -83,7 +83,7 @@ void SMP_Free(void) memset(&smp_cb, 0, sizeof(tSMP_CB)); #if SMP_DYNAMIC_MEMORY FREE_AND_RESET(smp_cb_ptr); -#if (SMP_CRYPTO_MBEDTLS == FALSE) +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) FREE_AND_RESET(curve_ptr); FREE_AND_RESET(curve_p256_ptr); #endif diff --git a/components/bt/host/bluedroid/stack/smp/smp_cmac.c b/components/bt/host/bluedroid/stack/smp/smp_cmac.c index 39aeccf23e..9d290af559 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_cmac.c +++ b/components/bt/host/bluedroid/stack/smp/smp_cmac.c @@ -34,9 +34,13 @@ #include "stack/hcimsgs.h" #if (SMP_CRYPTO_MBEDTLS == TRUE) #include "psa/crypto.h" +#elif (SMP_CRYPTO_TINYCRYPT == TRUE) +#include "tinycrypt/aes.h" +#include "tinycrypt/cmac_mode.h" +#include "tinycrypt/constants.h" #endif -#if (SMP_CRYPTO_MBEDTLS == FALSE) +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) typedef struct { UINT8 *text; UINT16 len; @@ -50,7 +54,7 @@ const BT_OCTET16 const_Rb = { 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ +#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */ void print128(BT_OCTET16 x, const UINT8 *key_name) { @@ -80,7 +84,7 @@ void print128(BT_OCTET16 x, const UINT8 *key_name) ** Returns void ** *******************************************************************************/ -#if (SMP_CRYPTO_MBEDTLS == FALSE) +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) static void padding ( BT_OCTET16 dest, UINT8 length ) { UINT8 i, *p = dest; @@ -89,6 +93,7 @@ static void padding ( BT_OCTET16 dest, UINT8 length ) p[BT_OCTET16_LEN - i - 1] = ( i == length ) ? 0x80 : 0; } } + /******************************************************************************* ** ** Function leftshift_onebit @@ -110,6 +115,8 @@ static void leftshift_onebit(UINT8 *input, UINT8 *output) } return; } +#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */ + /******************************************************************************* ** ** Function cmac_aes_cleanup @@ -119,6 +126,7 @@ static void leftshift_onebit(UINT8 *input, UINT8 *output) ** Returns void ** *******************************************************************************/ +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) static void cmac_aes_cleanup(void) { if (cmac_cb.text != NULL) { @@ -173,6 +181,7 @@ static BOOLEAN cmac_aes_k_calculate(BT_OCTET16 key, UINT8 *p_signature, UINT16 t return FALSE; } } + /******************************************************************************* ** ** Function cmac_prepare_last_block @@ -203,6 +212,8 @@ static void cmac_prepare_last_block (BT_OCTET16 k1, BT_OCTET16 k2) smp_xor_128(&cmac_cb.text[0], k2); } } +#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */ + /******************************************************************************* ** ** Function cmac_subkey_cont @@ -212,6 +223,7 @@ static void cmac_prepare_last_block (BT_OCTET16 k1, BT_OCTET16 k2) ** Returns void ** *******************************************************************************/ +#if (SMP_CRYPTO_STACK_NATIVE == TRUE) static void cmac_subkey_cont(tSMP_ENC *p) { UINT8 k1[BT_OCTET16_LEN], k2[BT_OCTET16_LEN]; @@ -268,7 +280,7 @@ static BOOLEAN cmac_generate_subkey(BT_OCTET16 key) return ret; } -#endif /* SMP_CRYPTO_MBEDTLS == FALSE */ +#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */ /******************************************************************************* ** @@ -381,6 +393,82 @@ BOOLEAN aes_cipher_msg_auth_code(BT_OCTET16 key, UINT8 *input, UINT16 length, /* Clear sensitive data from stack */ memset(key_be, 0, sizeof(key_be)); + ret = TRUE; + } +#elif (SMP_CRYPTO_TINYCRYPT == TRUE) + { + /* + * TinyCrypt CMAC implementation. + * Bluedroid uses little-endian, TinyCrypt uses big-endian. + * We reverse the key and input, then reverse the output. + */ + struct tc_aes_key_sched_struct sched; + struct tc_cmac_struct state; + UINT8 key_be[BT_OCTET16_LEN]; + UINT8 *input_be = NULL; + UINT8 mac_be[BT_OCTET16_LEN]; + + SMP_TRACE_DEBUG("AES128_CMAC (TinyCrypt) started, length = %d", length); + + /* Convert key from little-endian to big-endian */ + for (int i = 0; i < BT_OCTET16_LEN; i++) { + key_be[i] = key[BT_OCTET16_LEN - 1 - i]; + } + + /* Setup CMAC */ + if (tc_cmac_setup(&state, key_be, &sched) == TC_CRYPTO_FAIL) { + SMP_TRACE_ERROR("tc_cmac_setup failed"); + memset(key_be, 0, sizeof(key_be)); + memset(&sched, 0, sizeof(sched)); + return FALSE; + } + + /* Allocate and convert input from little-endian to big-endian */ + if (length > 0) { + input_be = (UINT8 *)osi_malloc(length); + if (input_be == NULL) { + SMP_TRACE_ERROR("No resources for input_be"); + tc_cmac_erase(&state); + memset(key_be, 0, sizeof(key_be)); + memset(&sched, 0, sizeof(sched)); + return FALSE; + } + for (UINT16 i = 0; i < length; i++) { + input_be[i] = input[length - 1 - i]; + } + + /* Update CMAC with input data */ + if (tc_cmac_update(&state, input_be, length) == TC_CRYPTO_FAIL) { + SMP_TRACE_ERROR("tc_cmac_update failed"); + osi_free(input_be); + tc_cmac_erase(&state); + memset(key_be, 0, sizeof(key_be)); + memset(&sched, 0, sizeof(sched)); + return FALSE; + } + osi_free(input_be); + } + + /* Finalize CMAC */ + if (tc_cmac_final(mac_be, &state) == TC_CRYPTO_FAIL) { + SMP_TRACE_ERROR("tc_cmac_final failed"); + tc_cmac_erase(&state); + memset(key_be, 0, sizeof(key_be)); + memset(&sched, 0, sizeof(sched)); + return FALSE; + } + + /* Convert MAC from big-endian to little-endian and truncate to tlen bytes */ + for (UINT16 i = 0; i < tlen && i < BT_OCTET16_LEN; i++) { + p_signature[i] = mac_be[BT_OCTET16_LEN - 1 - i]; + } + + /* Clear sensitive data from stack */ + tc_cmac_erase(&state); + memset(key_be, 0, sizeof(key_be)); + memset(mac_be, 0, sizeof(mac_be)); + memset(&sched, 0, sizeof(sched)); + ret = TRUE; } #else diff --git a/components/bt/host/bluedroid/stack/smp/smp_keys.c b/components/bt/host/bluedroid/stack/smp/smp_keys.c index 01652fd89f..4bddca52f5 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_keys.c +++ b/components/bt/host/bluedroid/stack/smp/smp_keys.c @@ -36,10 +36,16 @@ #include "stack/hcimsgs.h" #if (SMP_CRYPTO_MBEDTLS == TRUE) #include "psa/crypto.h" +#elif (SMP_CRYPTO_TINYCRYPT == TRUE) +#include "tinycrypt/aes.h" +#include "tinycrypt/cmac_mode.h" +#include "tinycrypt/ecc_dh.h" +#include "tinycrypt/ecc.h" +#include "tinycrypt/constants.h" #else #include "aes.h" -#endif /* SMP_CRYPTO_MBEDTLS */ #include "p_256_ecc_pp.h" +#endif /* SMP_CRYPTO_MBEDTLS */ #include "device/controller.h" #ifndef SMP_MAX_ENC_REPEAT @@ -228,6 +234,28 @@ BOOLEAN smp_encrypt_data (UINT8 *key, UINT8 key_len, return FALSE; } } +#elif (SMP_CRYPTO_TINYCRYPT == TRUE) + { + struct tc_aes_key_sched_struct sched; + + /* TinyCrypt expects big-endian key and data */ + if (tc_aes128_set_encrypt_key(&sched, p_rev_key) == TC_CRYPTO_FAIL) { + SMP_TRACE_ERROR("%s tc_aes128_set_encrypt_key failed\n", __func__); + memset(&sched, 0, sizeof(sched)); + osi_free(p_start); + return FALSE; + } + + if (tc_aes_encrypt(p_rev_output, p_rev_data, &sched) == TC_CRYPTO_FAIL) { + SMP_TRACE_ERROR("%s tc_aes_encrypt failed\n", __func__); + memset(&sched, 0, sizeof(sched)); + osi_free(p_start); + return FALSE; + } + + /* Clear sensitive data from key schedule */ + memset(&sched, 0, sizeof(sched)); + } #else { aes_context ctx; @@ -1214,6 +1242,36 @@ psa_pubkey_cleanup: psa_destroy_key(key_id); /* Clear sensitive data from stack */ memset(priv_be, 0, sizeof(priv_be)); +#elif (SMP_CRYPTO_TINYCRYPT == TRUE) + { + UINT8 pub_key[64]; /* TinyCrypt format: X (32 bytes) || Y (32 bytes), no prefix */ + UINT8 priv_be[BT_OCTET32_LEN]; + + /* Convert private key from little-endian to big-endian */ + for (int i = 0; i < BT_OCTET32_LEN; i++) { + priv_be[i] = p_cb->private_key[BT_OCTET32_LEN - 1 - i]; + } + + /* Compute public key from private key */ + /* uECC_compute_public_key returns 1 if successful, 0 if failed */ + if (uECC_compute_public_key(priv_be, pub_key, uECC_secp256r1()) != TC_CRYPTO_SUCCESS) { + SMP_TRACE_ERROR("%s uECC_compute_public_key failed\n", __FUNCTION__); + memset(priv_be, 0, sizeof(priv_be)); + memset(pub_key, 0, sizeof(pub_key)); + return; + } + + /* Convert X and Y from big-endian to little-endian */ + /* TinyCrypt format: X (32 bytes) || Y (32 bytes) */ + for (int i = 0; i < BT_OCTET32_LEN; i++) { + p_cb->loc_publ_key.x[i] = pub_key[BT_OCTET32_LEN - 1 - i]; + p_cb->loc_publ_key.y[i] = pub_key[BT_OCTET32_LEN + BT_OCTET32_LEN - 1 - i]; + } + + /* Clear sensitive data from stack */ + memset(priv_be, 0, sizeof(priv_be)); + memset(pub_key, 0, sizeof(pub_key)); + } #else Point public_key; BT_OCTET32 private_key; @@ -1303,6 +1361,53 @@ psa_dhkey_cleanup: /* Clear sensitive data from stack */ memset(priv_be, 0, sizeof(priv_be)); memset(shared_secret, 0, sizeof(shared_secret)); +#elif (SMP_CRYPTO_TINYCRYPT == TRUE) + { + UINT8 priv_be[BT_OCTET32_LEN]; + UINT8 peer_pub_be[64]; /* TinyCrypt format: X (32 bytes) || Y (32 bytes), no prefix */ + UINT8 shared_secret[BT_OCTET32_LEN]; + + /* Convert private key from little-endian to big-endian */ + for (int i = 0; i < BT_OCTET32_LEN; i++) { + priv_be[i] = p_cb->private_key[BT_OCTET32_LEN - 1 - i]; + } + + /* Convert peer public key from little-endian to big-endian */ + /* TinyCrypt format: X (32 bytes) || Y (32 bytes), no prefix */ + for (int i = 0; i < BT_OCTET32_LEN; i++) { + peer_pub_be[i] = p_cb->peer_publ_key.x[BT_OCTET32_LEN - 1 - i]; + peer_pub_be[BT_OCTET32_LEN + i] = p_cb->peer_publ_key.y[BT_OCTET32_LEN - 1 - i]; + } + + /* Validate peer public key */ + /* uECC_valid_public_key returns 0 if valid, negative value if invalid */ + if (uECC_valid_public_key(peer_pub_be, uECC_secp256r1()) < 0) { + SMP_TRACE_ERROR("%s Invalid peer public key\n", __FUNCTION__); + memset(priv_be, 0, sizeof(priv_be)); + memset(peer_pub_be, 0, sizeof(peer_pub_be)); + return; + } + + /* Compute ECDH shared secret */ + /* uECC_shared_secret returns TC_CRYPTO_SUCCESS (1) if successful, TC_CRYPTO_FAIL (0) if failed */ + if (uECC_shared_secret(peer_pub_be, priv_be, shared_secret, uECC_secp256r1()) != TC_CRYPTO_SUCCESS) { + SMP_TRACE_ERROR("%s uECC_shared_secret failed\n", __FUNCTION__); + memset(priv_be, 0, sizeof(priv_be)); + memset(peer_pub_be, 0, sizeof(peer_pub_be)); + memset(shared_secret, 0, sizeof(shared_secret)); + return; + } + + /* Convert shared secret from big-endian to little-endian for DHKey */ + for (int i = 0; i < BT_OCTET32_LEN; i++) { + p_cb->dhkey[i] = shared_secret[BT_OCTET32_LEN - 1 - i]; + } + + /* Clear sensitive data from stack */ + memset(priv_be, 0, sizeof(priv_be)); + memset(peer_pub_be, 0, sizeof(peer_pub_be)); + memset(shared_secret, 0, sizeof(shared_secret)); + } #else Point peer_publ_key, new_publ_key; BT_OCTET32 private_key; From 6b754fbfcfd51e0fa6fa1241b1563fb1097dbf16 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Tue, 23 Dec 2025 11:30:36 +0800 Subject: [PATCH 085/226] feat(ble/bluedroid): Move the TinyCrypt and mbedTLS configuration items to the bt common path --- components/bt/common/Kconfig.in | 37 +++++++++++++++++++ components/bt/host/bluedroid/Kconfig.in | 37 ------------------- .../bt/host/bluedroid/stack/smp/smp_cmac.c | 3 +- .../bt/host/bluedroid/stack/smp/smp_keys.c | 9 +++-- 4 files changed, 45 insertions(+), 41 deletions(-) diff --git a/components/bt/common/Kconfig.in b/components/bt/common/Kconfig.in index 4bcfaa79ce..0c0b040ab4 100644 --- a/components/bt/common/Kconfig.in +++ b/components/bt/common/Kconfig.in @@ -6,6 +6,43 @@ config BT_ALARM_MAX_NUM This option decides the maximum number of alarms which could be used by Bluetooth host. +choice BT_SMP_CRYPTO_STACK + prompt "SMP cryptographic stack" + depends on (BT_BLE_SMP_ENABLE || BT_SMP_ENABLE || BT_NIMBLE_SECURITY_ENABLE) + default BT_SMP_CRYPTO_STACK_NATIVE + help + Select the cryptographic library to use for SMP operations (AES, AES-CMAC, ECDH P-256). + + config BT_SMP_CRYPTO_STACK_NATIVE + bool "Native Bluedroid implementation" + depends on (BT_BLE_SMP_ENABLE || BT_SMP_ENABLE) + help + Use the built-in Bluedroid cryptographic implementation. + This provides compatibility with all features. + This option is only available for Bluedroid host. + + config BT_SMP_CRYPTO_STACK_TINYCRYPT + bool "TinyCrypt" + help + Use TinyCrypt library for cryptographic operations. + TinyCrypt is a lightweight cryptographic library designed for constrained devices. + This can reduce code size compared to the native implementation. + This is the default option. + + config BT_SMP_CRYPTO_STACK_MBEDTLS + bool "mbedTLS" + select MBEDTLS_AES_C + select MBEDTLS_CMAC_C + select MBEDTLS_ECDH_C + select MBEDTLS_ECP_C + select MBEDTLS_ECP_DP_SECP256R1_ENABLED + help + Use mbedTLS library for cryptographic operations. + This can provide hardware acceleration on supported platforms and reduce code size + by sharing crypto implementations with other components. + +endchoice + menu "BLE Log" source "$IDF_PATH/components/bt/common/ble_log/Kconfig.in" endmenu diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 6fb37d96f8..929e539919 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -464,43 +464,6 @@ config BT_BLE_SMP_BOND_NVS_FLASH help This select can save SMP bonding keys to nvs flash -choice BT_SMP_CRYPTO_STACK - prompt "SMP cryptographic stack" - depends on BT_BLE_SMP_ENABLE - default BT_SMP_CRYPTO_STACK_NATIVE - help - Select the cryptographic library to use for SMP operations (AES, AES-CMAC, ECDH P-256). - - Note: This option is not compatible with BLE Mesh, as BLE Mesh - uses the native Bluedroid ECC implementation directly. - - config BT_SMP_CRYPTO_STACK_NATIVE - bool "Native Bluedroid implementation" - help - Use the built-in Bluedroid cryptographic implementation. - This is the default option and provides compatibility with all features. - - config BT_SMP_CRYPTO_STACK_TINYCRYPT - bool "TinyCrypt" - help - Use TinyCrypt library for cryptographic operations. - TinyCrypt is a lightweight cryptographic library designed for constrained devices. - This can reduce code size compared to the native implementation. - - config BT_SMP_CRYPTO_STACK_MBEDTLS - bool "mbedTLS" - select MBEDTLS_AES_C - select MBEDTLS_CMAC_C - select MBEDTLS_ECDH_C - select MBEDTLS_ECP_C - select MBEDTLS_ECP_DP_SECP256R1_ENABLED - help - Use mbedTLS library for cryptographic operations. - This can provide hardware acceleration on supported platforms and reduce code size - by sharing crypto implementations with other components. - -endchoice - config BT_BLE_RPA_SUPPORTED bool "Update RPA to Controller" depends on (BT_BLE_SMP_ENABLE && ((BT_CONTROLLER_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR diff --git a/components/bt/host/bluedroid/stack/smp/smp_cmac.c b/components/bt/host/bluedroid/stack/smp/smp_cmac.c index 9d290af559..fd10e50760 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_cmac.c +++ b/components/bt/host/bluedroid/stack/smp/smp_cmac.c @@ -346,12 +346,13 @@ BOOLEAN aes_cipher_msg_auth_code(BT_OCTET16 key, UINT8 *input, UINT16 length, psa_set_key_bits(&key_attributes, 128); status = psa_import_key(&key_attributes, key_be, BT_OCTET16_LEN, &key_id); + psa_reset_key_attributes(&key_attributes); + if (status != PSA_SUCCESS) { SMP_TRACE_ERROR("psa_import_key failed: %d", status); if (input_be) osi_free(input_be); return FALSE; } - psa_reset_key_attributes(&key_attributes); /* Setup MAC operation */ status = psa_mac_sign_setup(&operation, key_id, PSA_ALG_CMAC); diff --git a/components/bt/host/bluedroid/stack/smp/smp_keys.c b/components/bt/host/bluedroid/stack/smp/smp_keys.c index 4bddca52f5..ee57dcad62 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_keys.c +++ b/components/bt/host/bluedroid/stack/smp/smp_keys.c @@ -217,12 +217,13 @@ BOOLEAN smp_encrypt_data (UINT8 *key, UINT8 key_len, psa_set_key_bits(&key_attributes, 128); status = psa_import_key(&key_attributes, p_rev_key, SMP_ENCRYT_KEY_SIZE, &key_id); + psa_reset_key_attributes(&key_attributes); + if (status != PSA_SUCCESS) { SMP_TRACE_ERROR("%s psa_import_key failed: %d\n", __func__, status); osi_free(p_start); return FALSE; } - psa_reset_key_attributes(&key_attributes); status = psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING, p_rev_data, SMP_ENCRYT_DATA_SIZE, p_rev_output, SMP_ENCRYT_DATA_SIZE, &output_len); @@ -1218,11 +1219,12 @@ void smp_process_private_key(tSMP_CB *p_cb) psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT); status = psa_import_key(&key_attributes, priv_be, BT_OCTET32_LEN, &key_id); + psa_reset_key_attributes(&key_attributes); + if (status != PSA_SUCCESS) { SMP_TRACE_ERROR("%s psa_import_key failed: %d\n", __FUNCTION__, status); goto psa_pubkey_cleanup; } - psa_reset_key_attributes(&key_attributes); /* Export public key */ status = psa_export_public_key(key_id, pub_be, sizeof(pub_be), &pub_len); @@ -1330,11 +1332,12 @@ void smp_compute_dhkey (tSMP_CB *p_cb) psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); status = psa_import_key(&key_attributes, priv_be, BT_OCTET32_LEN, &key_id); + psa_reset_key_attributes(&key_attributes); + if (status != PSA_SUCCESS) { SMP_TRACE_ERROR("%s psa_import_key failed: %d\n", __FUNCTION__, status); goto psa_dhkey_cleanup; } - psa_reset_key_attributes(&key_attributes); /* Construct peer public key in uncompressed format: 0x04 || X || Y */ peer_pub_be[0] = 0x04; From fe7b65865280540d12a26590133173d2cc6f1db1 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Thu, 18 Dec 2025 21:13:29 +0800 Subject: [PATCH 086/226] feat(ble/bluedroid): Support bluedroid encrypted advertising data --- components/bt/host/bluedroid/Kconfig.in | 10 + .../bt/host/bluedroid/api/esp_gap_ble_api.c | 22 + .../api/include/api/esp_gap_ble_api.h | 19 + .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 16 + .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 35 ++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 3 + .../bluedroid/bta/dm/include/bta_dm_int.h | 17 + .../host/bluedroid/bta/include/bta/bta_api.h | 16 + .../btc/profile/std/gap/btc_gap_ble.c | 5 + .../btc/profile/std/include/btc_gap_ble.h | 10 + .../include/common/bluedroid_user_config.h | 6 + .../common/include/common/bt_target.h | 6 + .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 33 ++ .../bt/host/bluedroid/stack/gap/gap_ble.c | 33 ++ .../bluedroid/stack/gap/include/gap_int.h | 4 + .../stack/include/stack/btm_ble_api.h | 16 + .../bluedroid/stack/include/stack/gap_api.h | 14 + .../bluedroid/stack/include/stack/gattdefs.h | 1 + .../enc_adv_data_cent/CMakeLists.txt | 8 + .../enc_adv_data_cent/README.md | 273 +++++++++ .../enc_adv_data_cent/main/CMakeLists.txt | 8 + .../enc_adv_data_cent/main/Kconfig.projbuild | 22 + .../enc_adv_data_cent/main/ble_ead.c | 426 ++++++++++++++ .../enc_adv_data_cent/main/ble_ead.h | 95 ++++ .../main/enc_adv_data_cent.c | 519 ++++++++++++++++++ .../main/enc_adv_data_cent_no_connect.c | 239 ++++++++ .../enc_adv_data_cent/sdkconfig.defaults | 13 + .../enc_adv_data_prph/CMakeLists.txt | 8 + .../enc_adv_data_prph/README.md | 172 ++++++ .../enc_adv_data_prph/main/CMakeLists.txt | 2 + .../enc_adv_data_prph/main/Kconfig.projbuild | 14 + .../enc_adv_data_prph/main/ble_ead.c | 419 ++++++++++++++ .../enc_adv_data_prph/main/ble_ead.h | 95 ++++ .../main/enc_adv_data_prph.c | 353 ++++++++++++ .../enc_adv_data_prph/sdkconfig.defaults | 13 + 35 files changed, 2945 insertions(+) create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/README.md create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/Kconfig.projbuild create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.c create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.h create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/enc_adv_data_cent.c create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/enc_adv_data_cent_no_connect.c create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/sdkconfig.defaults create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/README.md create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/Kconfig.projbuild create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.c create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.h create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/enc_adv_data_prph.c create mode 100644 examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/sdkconfig.defaults diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 929e539919..e145613393 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -384,6 +384,16 @@ config BT_GATTS_SECURITY_LEVELS_CHAR help Enable LE GATT Security Levels Characteristic +config BT_GATTS_KEY_MATERIAL_CHAR + bool "Enable Encrypted Data Key Material Characteristic" + depends on BT_GATTS_ENABLE + default n + help + Enable the Encrypted Data Key Material characteristic in GAP service. + This characteristic allows advertising data to be decrypted and authenticated + using the key material (session key + IV) as defined in Bluetooth Core + Specification Version 5.4. The characteristic requires encrypted link to read. + menuconfig BT_GATTC_ENABLE bool "Include GATT client module(GATTC)" depends on BT_BLE_ENABLED 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 906e1280ba..8df0a9587f 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -440,6 +440,28 @@ esp_err_t esp_ble_gap_get_device_name(void) return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) +esp_err_t esp_ble_gap_set_key_material(const uint8_t session_key[16], const uint8_t iv[8]) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (session_key == NULL || iv == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_SET_KEY_MATERIAL; + memcpy(arg.set_key_material.session_key, session_key, 16); + memcpy(arg.set_key_material.iv, iv, 8); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) + esp_err_t esp_ble_gap_get_local_used_addr(esp_bd_addr_t local_used_addr, uint8_t * addr_type) { if(esp_bluedroid_get_status() != (ESP_BLUEDROID_STATUS_ENABLED)) { diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 102fdfd66b..704e2c1086 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -3120,6 +3120,25 @@ esp_err_t esp_ble_gap_set_device_name(const char *name); */ esp_err_t esp_ble_gap_get_device_name(void); +#if defined(CONFIG_BT_GATTS_KEY_MATERIAL_CHAR) && CONFIG_BT_GATTS_KEY_MATERIAL_CHAR +/** + * @brief Set the Encrypted Data Key Material in GAP service + * + * This function sets the session key and IV that will be exposed + * through the Key Material characteristic (UUID 0x2B88) in the GAP service. + * The Key Material allows central devices to decrypt encrypted advertising data. + * + * @param[in] session_key - 16-byte (128-bit) session key for AES-CCM encryption + * @param[in] iv - 8-byte (64-bit) initialization vector + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_set_key_material(const uint8_t session_key[16], const uint8_t iv[8]); +#endif // CONFIG_BT_GATTS_KEY_MATERIAL_CHAR + /** * @brief This function is called to get local used address and address type. * uint8_t *esp_bt_dev_get_address(void) get the public address diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 724ea7c67a..5f6e490b5b 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -5406,6 +5406,22 @@ void bta_dm_ble_config_local_icon (tBTA_DM_MSG *p_data) BTM_BleConfigLocalIcon (p_data->ble_local_icon.icon); } +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) +/******************************************************************************* +** +** Function bta_dm_ble_set_key_material +** +** Description This function sets the Encrypted Data Key Material. +** +** +*******************************************************************************/ +void bta_dm_ble_set_key_material (tBTA_DM_MSG *p_data) +{ + BTM_BleSetKeyMaterial (p_data->ble_key_material.session_key, + p_data->ble_key_material.iv); +} +#endif + #if (BLE_HOST_BLE_OBSERVE_EN == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index cd06eb4fd1..6dcce7beac 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -2223,6 +2223,41 @@ void BTA_DmBleConfigLocalIcon(uint16_t icon) } } +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) +/******************************************************************************* +** +** Function BTA_DmBleSetKeyMaterial +** +** Description Set the Encrypted Data Key Material in GAP service +** +** Parameters: session_key - 16-byte session key (must not be NULL) +** iv - 8-byte initialization vector (must not be NULL) +** +** Returns void +** +*******************************************************************************/ +void BTA_DmBleSetKeyMaterial(const uint8_t *session_key, const uint8_t *iv) +{ + tBTA_DM_API_KEY_MATERIAL *p_msg; + + if (session_key == NULL || iv == NULL) { + APPL_TRACE_ERROR("%s: NULL pointer parameter", __func__); + return; + } + + if ((p_msg = (tBTA_DM_API_KEY_MATERIAL *) osi_malloc(sizeof(tBTA_DM_API_KEY_MATERIAL))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_KEY_MATERIAL)); + + p_msg->hdr.event = BTA_DM_API_KEY_MATERIAL_EVT; + memcpy(p_msg->session_key, session_key, 16); + memcpy(p_msg->iv, iv, 8); + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s: failed to allocate memory", __func__); + } +} +#endif + #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 77bc60a7f2..1d69fb2434 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -170,6 +170,9 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_config_local_privacy, /* BTA_DM_API_LOCAL_PRIVACY_EVT */ #endif bta_dm_ble_config_local_icon, /* BTA_DM_API_LOCAL_ICON_EVT */ +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) + bta_dm_ble_set_key_material, /* BTA_DM_API_KEY_MATERIAL_EVT */ +#endif #if (BLE_42_ADV_EN == TRUE) bta_dm_ble_set_adv_params_all, /* BTA_DM_API_BLE_ADV_PARAM_All_EVT */ bta_dm_ble_set_adv_config, /* BTA_DM_API_BLE_SET_ADV_CONFIG_EVT */ diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 9ef189a26f..bc625d3df8 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -159,6 +159,9 @@ enum { BTA_DM_API_LOCAL_PRIVACY_EVT, #endif BTA_DM_API_LOCAL_ICON_EVT, +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) + BTA_DM_API_KEY_MATERIAL_EVT, +#endif /*******This event added by Yulong at 2016/10/20 to support setting the ble advertising param by the APP******/ @@ -853,6 +856,14 @@ typedef struct { uint16_t icon; } tBTA_DM_API_LOCAL_ICON; +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) +typedef struct { + BT_HDR hdr; + uint8_t session_key[16]; + uint8_t iv[8]; +} tBTA_DM_API_KEY_MATERIAL; +#endif + /* set scan parameter for BLE connections */ typedef struct { BT_HDR hdr; @@ -1900,6 +1911,9 @@ typedef union { tBTA_DM_API_ENABLE_PRIVACY ble_remote_privacy; tBTA_DM_API_LOCAL_PRIVACY ble_local_privacy; tBTA_DM_API_LOCAL_ICON ble_local_icon; +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) + tBTA_DM_API_KEY_MATERIAL ble_key_material; +#endif tBTA_DM_API_BLE_ADV_PARAMS_ALL ble_set_adv_params_all; tBTA_DM_API_SET_ADV_CONFIG ble_set_adv_data; tBTA_DM_API_SET_ADV_CONFIG_RAW ble_set_adv_data_raw; @@ -2504,6 +2518,9 @@ extern void bta_dm_ble_stop_advertising(tBTA_DM_MSG *p_data); #endif // #if (BLE_HOST_STOP_ADV_UNUSED == TRUE) extern void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data); extern void bta_dm_ble_config_local_icon (tBTA_DM_MSG *p_data); +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) +extern void bta_dm_ble_set_key_material (tBTA_DM_MSG *p_data); +#endif extern void bta_dm_ble_set_adv_params_all(tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_adv_config_raw (tBTA_DM_MSG *p_data); diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 23bf8915d9..a75e48943b 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -2939,6 +2939,22 @@ extern void BTA_DmBleConfigLocalPrivacy(BOOLEAN privacy_enable, tBTA_SET_LOCAL_P *******************************************************************************/ extern void BTA_DmBleConfigLocalIcon(uint16_t icon); +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) +/******************************************************************************* +** +** Function BTA_DmBleSetKeyMaterial +** +** Description Set the Encrypted Data Key Material in GAP service +** +** Parameters: session_key - 16-byte session key +** iv - 8-byte initialization vector +** +** Returns void +** +*******************************************************************************/ +extern void BTA_DmBleSetKeyMaterial(const uint8_t *session_key, const uint8_t *iv); +#endif + /******************************************************************************* ** ** Function BTA_DmBleEnableRemotePrivacy 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 ff1f63cba8..2ad52bf8bd 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 @@ -3187,6 +3187,11 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) BTA_DmBleGapCsProcEnable(arg_5->cs_procedure_enable_params.conn_handle, arg_5->cs_procedure_enable_params.config_id, arg_5->cs_procedure_enable_params.enable); break; #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) + case BTC_GAP_BLE_ACT_SET_KEY_MATERIAL: + BTA_DmBleSetKeyMaterial(arg->set_key_material.session_key, arg->set_key_material.iv); + break; +#endif default: break; } diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index 8f844a50b8..9784dbf126 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -160,6 +160,9 @@ typedef enum { BTC_GAP_BLE_CS_SET_PROCEDURE_PARAMS, BTC_GAP_BLE_CS_PROCEDURE_ENABLE, #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) + BTC_GAP_BLE_ACT_SET_KEY_MATERIAL, +#endif } btc_gap_ble_act_t; /* btc_ble_gap_args_t */ @@ -215,6 +218,13 @@ typedef union { struct cfg_local_icon_args { uint16_t icon; } cfg_local_icon; +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) + //BTC_GAP_BLE_ACT_SET_KEY_MATERIAL + struct set_key_material_args { + uint8_t session_key[16]; + uint8_t iv[8]; + } set_key_material; +#endif //BTC_GAP_BLE_ACT_UPDATE_WHITE_LIST struct update_white_list_args { bool add_remove; 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 52b82891e2..97bd25404f 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 @@ -610,6 +610,12 @@ #define UC_BT_GATTS_SECURITY_LEVELS_CHAR FALSE #endif +#ifdef CONFIG_BT_GATTS_KEY_MATERIAL_CHAR +#define UC_BT_GATTS_KEY_MATERIAL_CHAR CONFIG_BT_GATTS_KEY_MATERIAL_CHAR +#else +#define UC_BT_GATTS_KEY_MATERIAL_CHAR FALSE +#endif + #ifdef CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN #define UC_BT_BLE_ACT_SCAN_REP_ADV_SCAN CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN #else 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 36b596fb39..38b0003ee7 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -828,6 +828,12 @@ #define BT_GATTS_SECURITY_LEVELS_CHAR FALSE #endif +#if (UC_BT_GATTS_KEY_MATERIAL_CHAR == TRUE) +#define BT_GATTS_KEY_MATERIAL_CHAR TRUE +#else +#define BT_GATTS_KEY_MATERIAL_CHAR FALSE +#endif + #ifdef UC_BT_BLE_ACT_SCAN_REP_ADV_SCAN #define BTM_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY UC_BT_BLE_ACT_SCAN_REP_ADV_SCAN #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index e43185e72d..d06ed23f5a 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -1164,6 +1164,39 @@ void BTM_BleConfigLocalIcon(uint16_t icon) #endif } +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) +/******************************************************************************* +** +** Function BTM_BleSetKeyMaterial +** +** Description Set the Encrypted Data Key Material in GAP service +** +** Parameters session_key: 16-byte session key (must not be NULL) +** iv: 8-byte initialization vector (must not be NULL) +** +** Returns void +** +*******************************************************************************/ +void BTM_BleSetKeyMaterial(const uint8_t *session_key, const uint8_t *iv) +{ +#if (defined(GAP_INCLUDED) && GAP_INCLUDED == TRUE && GATTS_INCLUDED == TRUE) + tGAP_BLE_ATTR_VALUE p_value; + + if (session_key == NULL || iv == NULL) { + BTM_TRACE_ERROR("%s: NULL pointer parameter", __func__); + return; + } + + memset(&p_value, 0, sizeof(tGAP_BLE_ATTR_VALUE)); + memcpy(p_value.key_material.session_key, session_key, GAP_KEY_MATERIAL_SESSION_KEY_SIZE); + memcpy(p_value.key_material.iv, iv, GAP_KEY_MATERIAL_IV_SIZE); + GAP_BleAttrDBUpdate(GATT_UUID_GAP_KEY_MATERIAL, &p_value); +#else + BTM_TRACE_ERROR("%s\n", __func__); +#endif +} +#endif + /******************************************************************************* ** ** Function BTM_BleConfigConnParams diff --git a/components/bt/host/bluedroid/stack/gap/gap_ble.c b/components/bt/host/bluedroid/stack/gap/gap_ble.c index 7e4f453278..154fcca0b0 100644 --- a/components/bt/host/bluedroid/stack/gap/gap_ble.c +++ b/components/bt/host/bluedroid/stack/gap/gap_ble.c @@ -262,6 +262,13 @@ tGATT_STATUS gap_read_attr_value (UINT16 handle, tGATT_VALUE *p_value, BOOLEAN i p_value->len = 2; break; #endif // (BT_GATTS_SECURITY_LEVELS_CHAR == TRUE) +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) + case GATT_UUID_GAP_KEY_MATERIAL: + ARRAY_TO_STREAM(p, p_db_attr->attr_value.key_material.session_key, GAP_KEY_MATERIAL_SESSION_KEY_SIZE); + ARRAY_TO_STREAM(p, p_db_attr->attr_value.key_material.iv, GAP_KEY_MATERIAL_IV_SIZE); + p_value->len = GAP_KEY_MATERIAL_SIZE; + break; +#endif // (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) } return GATT_SUCCESS; } @@ -481,6 +488,20 @@ void gap_attr_db_init(void) p_db_attr++; #endif // (BT_GATTS_SECURITY_LEVELS_CHAR == TRUE) +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) + /* Add Encrypted Data Key Material Characteristic + * Per Bluetooth spec: readable only when authenticated and authorized, + * requires encrypted link to read. + */ + uuid.len = LEN_UUID_16; + uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_KEY_MATERIAL; + p_db_attr->handle = GATTS_AddCharacteristic(service_handle, &uuid, + GATT_PERM_READ_ENCRYPTED, GATT_CHAR_PROP_BIT_READ, + NULL, NULL); + memset(&p_db_attr->attr_value.key_material, 0, sizeof(tGAP_BLE_KEY_MATERIAL)); + p_db_attr++; +#endif // (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) + /* start service now */ memset (&app_uuid.uu.uuid128, 0x81, LEN_UUID_128); @@ -512,6 +533,11 @@ void GAP_BleAttrDBUpdate(UINT16 attr_uuid, tGAP_BLE_ATTR_VALUE *p_value) GAP_TRACE_EVENT("GAP_BleAttrDBUpdate attr_uuid=0x%04x\n", attr_uuid); + if (p_value == NULL) { + GAP_TRACE_ERROR("GAP_BleAttrDBUpdate: NULL pointer parameter"); + return; + } + for (i = 0; i < GAP_MAX_CHAR_NUM; i ++, p_db_attr ++) { if (p_db_attr->uuid == attr_uuid) { GAP_TRACE_EVENT("Found attr_uuid=0x%04x\n", attr_uuid); @@ -540,6 +566,13 @@ void GAP_BleAttrDBUpdate(UINT16 attr_uuid, tGAP_BLE_ATTR_VALUE *p_value) break; #endif // (BT_GATTS_SECURITY_LEVELS_CHAR == TRUE) +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) + case GATT_UUID_GAP_KEY_MATERIAL: + memcpy(&p_db_attr->attr_value.key_material, &p_value->key_material, + sizeof(tGAP_BLE_KEY_MATERIAL)); + break; +#endif // (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) + } break; } diff --git a/components/bt/host/bluedroid/stack/gap/include/gap_int.h b/components/bt/host/bluedroid/stack/gap/include/gap_int.h index 175a27e695..8f5472589c 100644 --- a/components/bt/host/bluedroid/stack/gap/include/gap_int.h +++ b/components/bt/host/bluedroid/stack/gap/include/gap_int.h @@ -93,7 +93,11 @@ typedef struct { #if BLE_INCLUDED == TRUE +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) +#define GAP_MAX_CHAR_NUM 6 +#else #define GAP_MAX_CHAR_NUM 5 +#endif typedef struct { UINT16 handle; 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 8961197865..33522b7aef 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 @@ -2948,6 +2948,22 @@ BOOLEAN BTM_BleConfigPrivacy(BOOLEAN enable, tBTM_SET_LOCAL_PRIVACY_CBACK *set_l *******************************************************************************/ void BTM_BleConfigLocalIcon(uint16_t icon); +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) +/******************************************************************************* +** +** Function BTM_BleSetKeyMaterial +** +** Description Set the Encrypted Data Key Material in GAP service +** +** Parameters session_key: 16-byte session key +** iv: 8-byte initialization vector +** +** Returns void +** +*******************************************************************************/ +void BTM_BleSetKeyMaterial(const uint8_t *session_key, const uint8_t *iv); +#endif + /******************************************************************************* ** ** Function BTM_BleConfigConnParams diff --git a/components/bt/host/bluedroid/stack/include/stack/gap_api.h b/components/bt/host/bluedroid/stack/include/stack/gap_api.h index a79d9748c8..81d353d022 100644 --- a/components/bt/host/bluedroid/stack/include/stack/gap_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/gap_api.h @@ -113,6 +113,17 @@ typedef struct { UINT16 sp_tout; } tGAP_BLE_PREF_PARAM; +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) +#define GAP_KEY_MATERIAL_SESSION_KEY_SIZE 16 /* 128-bit session key */ +#define GAP_KEY_MATERIAL_IV_SIZE 8 /* 64-bit IV */ +#define GAP_KEY_MATERIAL_SIZE (GAP_KEY_MATERIAL_SESSION_KEY_SIZE + GAP_KEY_MATERIAL_IV_SIZE) + +typedef struct { + UINT8 session_key[GAP_KEY_MATERIAL_SESSION_KEY_SIZE]; + UINT8 iv[GAP_KEY_MATERIAL_IV_SIZE]; +} tGAP_BLE_KEY_MATERIAL; +#endif // (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) + typedef union { tGAP_BLE_PREF_PARAM conn_param; BD_ADDR reconn_bda; @@ -122,6 +133,9 @@ typedef union { #if (BT_GATTS_SECURITY_LEVELS_CHAR == TRUE) UINT16 security_level; #endif // (BT_GATTS_SECURITY_LEVELS_CHAR == TRUE) +#if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) + tGAP_BLE_KEY_MATERIAL key_material; +#endif // (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) } tGAP_BLE_ATTR_VALUE; diff --git a/components/bt/host/bluedroid/stack/include/stack/gattdefs.h b/components/bt/host/bluedroid/stack/include/stack/gattdefs.h index 2ae8cef839..8da14f4cb7 100644 --- a/components/bt/host/bluedroid/stack/include/stack/gattdefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/gattdefs.h @@ -53,6 +53,7 @@ #define GATT_UUID_GAP_CENTRAL_ADDR_RESOL 0x2AA6 #define GATT_UUID_GAP_GATT_SECURITY_LEVELS 0x2BF5 +#define GATT_UUID_GAP_KEY_MATERIAL 0x2B88 /* Encrypted Data Key Material */ /* Attribute Profile Attribute UUID */ #define GATT_UUID_GATT_SRV_CHGD 0x2A05 diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/CMakeLists.txt b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/CMakeLists.txt new file mode 100644 index 0000000000..6daf7bc1f0 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/CMakeLists.txt @@ -0,0 +1,8 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five 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(enc_adv_data_cent) diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/README.md b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/README.md new file mode 100644 index 0000000000..7649b1e653 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/README.md @@ -0,0 +1,273 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | + +# BLE Encrypted Advertising Data Central Example (Bluedroid) + +This example demonstrates how to receive and decrypt BLE Encrypted Advertising Data (EAD) with Bluedroid stack. + +## Overview + +This central example works with the `enc_adv_data_prph` peripheral example to demonstrate: + +1. Scanning for devices that advertise encrypted data +2. Connecting to read the Key Material characteristic +3. Decrypting advertising data using the obtained key + +## Two Operation Modes + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ Mode Selection │ +├────────────────────────────────┬────────────────────────────────────────────┤ +│ Mode 1: With Connection │ Mode 2: No Connection │ +│ (Default) │ (Pre-shared Key) │ +├────────────────────────────────┼────────────────────────────────────────────┤ +│ │ │ +│ First scan: │ All scans: │ +│ ┌─────────┐ ┌─────────┐ │ ┌─────────┐ ┌─────────┐ │ +│ │ Central │══▶│ Periph │ │ │ Central │──▶│ Periph │ │ +│ └─────────┘ └─────────┘ │ └─────────┘ └─────────┘ │ +│ │ │ │ │ │ +│ │ Connect │ │ │ Scan only │ +│ │ Read Key │ │ ▼ │ +│ │ Disconnect │ │ Use pre-configured │ +│ ▼ │ │ key to decrypt │ +│ Store key │ │ │ │ +│ │ │ │ ▼ │ +│ ▼ │ │ ✅ Decrypt immediately │ +│ Later scans: │ │ │ +│ ┌─────────┐ ┌─────────┐ │ │ +│ │ Central │──▶│ Periph │ │ │ +│ └─────────┘ └─────────┘ │ │ +│ │ │ │ +│ │ No connection needed │ │ +│ ▼ │ │ +│ ✅ Decrypt using stored key │ │ +│ │ │ +├────────────────────────────────┼────────────────────────────────────────────┤ +│ ✓ Secure key exchange │ ✓ No connection latency │ +│ ✓ Dynamic key support │ ✓ Simpler implementation │ +│ ✗ First-time connection needed │ ✗ Key must be pre-provisioned │ +└────────────────────────────────┴────────────────────────────────────────────┘ +``` + +## System Flow Diagram + +### Mode 1: With Connection (Default) + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ Central Flow - With Connection Mode │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────┐ ┌─────────────┐ │ +│ │ Central │ │ Peripheral │ │ +│ └────┬────┘ └──────┬──────┘ │ +│ │ │ │ +│ │ ════════════════ First Encounter ════════════════ │ │ +│ │ │ │ +│ │ 1. Scan │ │ +│ │ ──────────────────────────────────────────────────▶ │ │ +│ │ │ │ +│ │ 2. Receive Adv (UUID=0x2C01, Encrypted Data) │ │ +│ │ ◀────────────────────────────────────────────────── │ │ +│ │ │ │ +│ │ [No key yet - cannot decrypt] │ │ +│ │ │ │ +│ │ 3. Connect │ │ +│ │ ═══════════════════════════════════════════════════▶│ │ +│ │ │ │ +│ │ 4. Establish Encrypted Link (Pairing) │ │ +│ │ ◀═══════════════════════════════════════════════════│ │ +│ │ │ │ +│ │ 5. Read Key Material Characteristic (0x2B88) │ │ +│ │ ═══════════════════════════════════════════════════▶│ │ +│ │ │ │ +│ │ 6. Response: [Session Key (16B)] [IV (8B)] │ │ +│ │ ◀═══════════════════════════════════════════════════│ │ +│ │ │ │ +│ │ 7. Store key in memory │ │ +│ │ 8. Disconnect │ │ +│ │ ═══════════════════════════════════════════════════▶│ │ +│ │ │ │ +│ │ ════════════════ Later Scans ════════════════════ │ │ +│ │ │ │ +│ │ 9. Scan │ │ +│ │ ──────────────────────────────────────────────────▶ │ │ +│ │ │ │ +│ │ 10. Receive Encrypted Adv Data │ │ +│ │ ◀────────────────────────────────────────────────── │ │ +│ │ │ │ +│ │ 11. Decrypt using stored key (NO CONNECTION!) │ │ +│ │ ┌────────────────────────────────────────┐ │ │ +│ │ │ ble_ead_decrypt(session_key, iv, ...) │ │ │ +│ │ │ Result: "prph" (decrypted name) │ │ │ +│ │ └────────────────────────────────────────┘ │ │ +│ │ │ │ +│ ▼ ▼ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +### Mode 2: No Connection (Pre-shared Key) + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ Central Flow - No Connection Mode │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────────────────────────────┐ │ +│ │ Pre-configured Key (same as Peripheral) │ │ +│ │ Session Key: 19 6a 0a d1 2a 61 20 1e │ │ +│ │ 13 6e 2e d1 12 da a9 57 │ │ +│ │ IV: 9E 7a 00 ef b1 7a e7 46 │ │ +│ └─────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────┐ ┌─────────────┐ │ +│ │ Central │ │ Peripheral │ │ +│ └────┬────┘ └──────┬──────┘ │ +│ │ │ │ +│ │ 1. Scan (passive) │ │ +│ │ ──────────────────────────────────────────────────▶ │ │ +│ │ │ │ +│ │ 2. Receive Encrypted Adv Data │ │ +│ │ ◀────────────────────────────────────────────────── │ │ +│ │ │ │ +│ │ 3. Immediately decrypt (NO CONNECTION!) │ │ +│ │ ┌────────────────────────────────────────┐ │ │ +│ │ │ ble_ead_decrypt(pre_shared_key, ...) │ │ │ +│ │ │ Result: "prph" (decrypted name) │ │ │ +│ │ └────────────────────────────────────────┘ │ │ +│ │ │ │ +│ ▼ ▼ │ +│ │ +│ ⚡ No connection overhead - instant decryption! │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +## Decryption Process + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ Decryption Process │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ Received Encrypted Advertising Data: │ +│ ┌───────────────────┬─────────────────────┬─────────────────┐ │ +│ │ Randomizer │ Ciphertext │ MIC │ │ +│ │ (5 bytes) │ (6 bytes) │ (4 bytes) │ │ +│ └─────────┬─────────┴──────────┬──────────┴────────┬────────┘ │ +│ │ │ │ │ +│ ▼ │ │ │ +│ 1. Extract Randomizer │ │ │ +│ ┌─────────────────────┐ │ │ │ +│ │ XX XX XX XX [D|XX] │ │ │ │ +│ └─────────────────────┘ │ │ │ +│ │ │ │ │ +│ ▼ │ │ │ +│ 2. Build Nonce │ │ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ Randomizer (5B) + IV from Key Material (8B) = Nonce (13B) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ │ │ +│ ▼ ▼ ▼ │ +│ 3. AES-CCM Decrypt + Verify │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ Input: Ciphertext, MIC, Nonce, Session Key, AAD (0xEA) │ │ +│ │ Algorithm: AES-CCM-128 Authenticated Decryption │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ 4. Output: Decrypted Plaintext │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ [05] [09] [70 72 70 68] │ │ +│ │ Len Type 'p' 'r' 'p' 'h' │ │ +│ │ │ │ +│ │ → Complete Local Name: "prph" │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +## How to Use Example + +### Hardware Required + +* Two development boards with ESP32/ESP32-C2/ESP32-C3/ESP32-C5/ESP32-C6/ESP32-C61/ESP32-H2/ESP32-S3 SoC +* USB cables for power supply and programming + +### Setup + +1. Flash `enc_adv_data_prph` on one board (peripheral) +2. Flash `enc_adv_data_cent` on another board (central) + +### Configure the project + +```bash +idf.py set-target +idf.py menuconfig +``` + +In menuconfig, navigate to: +- `Example Configuration` → `Central Mode` + - `With Connection` - Connect to read key (default) + - `No Connection` - Use pre-shared key + +### Build and Flash + +```bash +idf.py -p PORT flash monitor +``` + +(To exit the serial monitor, type `Ctrl-]`.) + +### Example Output + +**Mode 1 - With Connection (first scan):** +``` +I (XXX) ENC_ADV_CENT: Encrypted Advertising Data Central started +I (XXX) ENC_ADV_CENT: Scanning started +I (XXX) ENC_ADV_CENT: Found target device: xx:xx:xx:xx:xx:xx +I (XXX) ENC_ADV_CENT: Connecting to get key material... +I (XXX) ENC_ADV_CENT: Connected, conn_id 0 +I (XXX) ENC_ADV_CENT: Authentication success +I (XXX) ENC_ADV_CENT: Key material received: +I (XXX) ENC_ADV_CENT: 19 6a 0a d1 2a 61 20 1e 13 6e 2e d1 12 da a9 57 9e 7a 00 ef b1 7a e7 46 +I (XXX) ENC_ADV_CENT: Disconnected +``` + +**Mode 1 - With Connection (subsequent scans):** +``` +I (XXX) ENC_ADV_CENT: Found target device: xx:xx:xx:xx:xx:xx +I (XXX) ENC_ADV_CENT: Have key material, decrypting... +I (XXX) ENC_ADV_CENT: Decryption successful! +I (XXX) ENC_ADV_CENT: Decrypted data: +I (XXX) ENC_ADV_CENT: 05 09 70 72 70 68 +I (XXX) ENC_ADV_CENT: Decrypted device name: prph +``` + +**Mode 2 - No Connection:** +``` +I (XXX) ENC_ADV_CENT_SIMPLE: ======================================== +I (XXX) ENC_ADV_CENT_SIMPLE: EAD Central - No Connection Mode +I (XXX) ENC_ADV_CENT_SIMPLE: ======================================== +I (XXX) ENC_ADV_CENT_SIMPLE: ⚡ This example decrypts WITHOUT connecting! +I (XXX) ENC_ADV_CENT_SIMPLE: 🔍 Scanning started (no connection mode) +... +I (XXX) ENC_ADV_CENT_SIMPLE: ✅ Decryption successful (no connection needed!) +I (XXX) ENC_ADV_CENT_SIMPLE: 📛 Decrypted device name: "prph" +``` + +## Troubleshooting + +### Authentication Failed +- Ensure both devices have matching security parameters +- Try erasing NVS on both devices: `idf.py erase_flash` + +### Decryption Failed +- Verify the peripheral and central use matching session key and IV +- Check that the encrypted advertising data format is correct + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/CMakeLists.txt b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/CMakeLists.txt new file mode 100644 index 0000000000..6bf438be39 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/CMakeLists.txt @@ -0,0 +1,8 @@ +if(CONFIG_EXAMPLE_MODE_NO_CONNECTION) + set(MAIN_SRC "enc_adv_data_cent_no_connect.c") +else() + set(MAIN_SRC "enc_adv_data_cent.c") +endif() + +idf_component_register(SRCS ${MAIN_SRC} "ble_ead.c" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/Kconfig.projbuild new file mode 100644 index 0000000000..a4c00b02ea --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/Kconfig.projbuild @@ -0,0 +1,22 @@ +menu "Example Configuration" + + choice EXAMPLE_MODE + prompt "Central Mode" + default EXAMPLE_MODE_WITH_CONNECTION + help + Select the central operation mode. + + config EXAMPLE_MODE_WITH_CONNECTION + bool "With Connection (read key from peripheral)" + help + Connect to peripheral to read Key Material characteristic. + This is the standard way when key is not pre-shared. + + config EXAMPLE_MODE_NO_CONNECTION + bool "No Connection (use pre-shared key)" + help + Use pre-configured key to decrypt without connecting. + Key must match the peripheral's key. + endchoice + +endmenu diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.c b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.c new file mode 100644 index 0000000000..7303c027b2 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.c @@ -0,0 +1,426 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "ble_ead.h" +#include "esp_random.h" +#include "esp_log.h" +#include "sdkconfig.h" + +#define TAG "BLE_EAD" + +/* Select crypto library based on configuration */ +#if defined(CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT) +#include "tinycrypt/aes.h" +#include "tinycrypt/ccm_mode.h" +#include "tinycrypt/constants.h" +#elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) +#include "psa/crypto.h" +#else +#error "Please select either CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT or CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS" +#endif + +/* Additional Authenticated Data for EAD - EA (Encrypted Advertising) */ +static const uint8_t ble_ead_aad[BLE_EAD_AAD_SIZE] = { 0xEA }; + +/** + * @brief Generate randomizer with direction bit set + * + * Per Bluetooth Core Spec Supplement v11, Part A 1.23.3: + * The MSB of the Randomizer shall be set to indicate direction + */ +static int ble_ead_generate_randomizer(uint8_t randomizer[BLE_EAD_RANDOMIZER_SIZE]) +{ + /* Generate random bytes */ + esp_fill_random(randomizer, BLE_EAD_RANDOMIZER_SIZE); + + /* Set direction bit (MSB of last byte) - required by spec */ + randomizer[BLE_EAD_RANDOMIZER_SIZE - 1] |= (1 << BLE_EAD_RANDOMIZER_DIRECTION_BIT); + + return 0; +} + +/** + * @brief Generate nonce from IV and randomizer + * + * Nonce = Randomizer (5 bytes) || IV (8 bytes) = 13 bytes + */ +static int ble_ead_generate_nonce(const uint8_t iv[BLE_EAD_IV_SIZE], + const uint8_t randomizer[BLE_EAD_RANDOMIZER_SIZE], + uint8_t nonce[BLE_EAD_NONCE_SIZE]) +{ + if (iv == NULL || nonce == NULL) { + return -1; + } + + /* Randomizer in first 5 bytes */ + if (randomizer != NULL) { + memcpy(nonce, randomizer, BLE_EAD_RANDOMIZER_SIZE); + } else { + /* Generate new randomizer with direction bit */ + ble_ead_generate_randomizer(nonce); + } + + /* IV in last 8 bytes */ + memcpy(nonce + BLE_EAD_RANDOMIZER_SIZE, iv, BLE_EAD_IV_SIZE); + + return 0; +} + +/** + * @brief AES-CCM encryption using selected crypto library + */ +static int ble_aes_ccm_encrypt(const uint8_t *key, const uint8_t *nonce, + const uint8_t *plaintext, size_t plaintext_len, + const uint8_t *aad, size_t aad_len, + uint8_t *ciphertext, size_t tag_len) +{ +#if defined(CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT) + struct tc_aes_key_sched_struct sched; + struct tc_ccm_mode_struct ccm_state; + int ret; + + /* Validate inputs */ + if (key == NULL || nonce == NULL || ciphertext == NULL) { + ESP_LOGE(TAG, "Invalid input parameters"); + return -1; + } + + /* Set AES encryption key */ + ret = tc_aes128_set_encrypt_key(&sched, key); + if (ret != TC_CRYPTO_SUCCESS) { + ESP_LOGE(TAG, "tc_aes128_set_encrypt_key failed"); + memset(&sched, 0, sizeof(sched)); + return -1; + } + + /* Configure CCM mode */ + ccm_state.sched = &sched; + ccm_state.nonce = (uint8_t *)nonce; + ccm_state.mlen = tag_len; + + ret = tc_ccm_config(&ccm_state, &sched, (uint8_t *)nonce, BLE_EAD_NONCE_SIZE, tag_len); + if (ret != TC_CRYPTO_SUCCESS) { + ESP_LOGE(TAG, "tc_ccm_config failed"); + memset(&sched, 0, sizeof(sched)); + memset(&ccm_state, 0, sizeof(ccm_state)); + return -1; + } + + /* Encrypt and generate tag */ + /* TinyCrypt outputs: ciphertext || tag */ + ret = tc_ccm_generation_encryption(ciphertext, plaintext_len + tag_len, + aad, aad_len, + plaintext, plaintext_len, + &ccm_state); + if (ret != TC_CRYPTO_SUCCESS) { + ESP_LOGE(TAG, "tc_ccm_generation_encryption failed"); + memset(&sched, 0, sizeof(sched)); + memset(&ccm_state, 0, sizeof(ccm_state)); + return -1; + } + + /* Clear sensitive data from key schedule */ + memset(&sched, 0, sizeof(sched)); + memset(&ccm_state, 0, sizeof(ccm_state)); + return 0; + +#elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_len); + size_t output_length = 0; + + /* Validate inputs */ + if (key == NULL || nonce == NULL || ciphertext == NULL) { + ESP_LOGE(TAG, "Invalid input parameters"); + return -1; + } + + /* Set key attributes */ + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, BLE_EAD_KEY_SIZE * 8); + + /* Import key */ + status = psa_import_key(&attributes, key, BLE_EAD_KEY_SIZE, &key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_import_key failed: %d", status); + psa_reset_key_attributes(&attributes); + return -1; + } + psa_reset_key_attributes(&attributes); + + /* Encrypt and authenticate */ + /* PSA AEAD encrypt outputs: ciphertext || tag */ + status = psa_aead_encrypt(key_id, alg, + nonce, BLE_EAD_NONCE_SIZE, + aad, aad_len, + plaintext, plaintext_len, + ciphertext, plaintext_len + tag_len, + &output_length); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_aead_encrypt failed: %d", status); + psa_destroy_key(key_id); + return -1; + } + + if (output_length != plaintext_len + tag_len) { + ESP_LOGE(TAG, "psa_aead_encrypt output length mismatch: expected %zu, got %zu", + plaintext_len + tag_len, output_length); + psa_destroy_key(key_id); + return -1; + } + + psa_destroy_key(key_id); + return 0; +#else + #error "No crypto library selected" +#endif +} + +/** + * @brief AES-CCM decryption with authentication using selected crypto library + */ +static int ble_aes_ccm_decrypt(const uint8_t *key, const uint8_t *nonce, + const uint8_t *ciphertext, size_t ciphertext_len, + const uint8_t *aad, size_t aad_len, + uint8_t *plaintext, size_t tag_len) +{ +#if defined(CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT) + struct tc_aes_key_sched_struct sched; + struct tc_ccm_mode_struct ccm_state; + int ret; + /* ciphertext_len here includes both ciphertext and tag */ + size_t plaintext_len; + + /* Validate inputs */ + if (key == NULL || nonce == NULL || ciphertext == NULL || plaintext == NULL) { + ESP_LOGE(TAG, "Invalid input parameters"); + return -1; + } + + /* Check for integer underflow */ + if (ciphertext_len < tag_len) { + ESP_LOGE(TAG, "ciphertext_len (%zu) < tag_len (%zu)", ciphertext_len, tag_len); + return -1; + } + + plaintext_len = ciphertext_len - tag_len; + + /* Set AES encryption key */ + ret = tc_aes128_set_encrypt_key(&sched, key); + if (ret != TC_CRYPTO_SUCCESS) { + ESP_LOGE(TAG, "tc_aes128_set_encrypt_key failed"); + memset(&sched, 0, sizeof(sched)); + return -1; + } + + /* Configure CCM mode */ + ccm_state.sched = &sched; + ccm_state.nonce = (uint8_t *)nonce; + ccm_state.mlen = tag_len; + + ret = tc_ccm_config(&ccm_state, &sched, (uint8_t *)nonce, BLE_EAD_NONCE_SIZE, tag_len); + if (ret != TC_CRYPTO_SUCCESS) { + ESP_LOGE(TAG, "tc_ccm_config failed"); + memset(&sched, 0, sizeof(sched)); + memset(&ccm_state, 0, sizeof(ccm_state)); + return -1; + } + + /* Decrypt and verify tag */ + /* TinyCrypt expects: ciphertext || tag */ + ret = tc_ccm_decryption_verification(plaintext, plaintext_len, + aad, aad_len, + (uint8_t *)ciphertext, ciphertext_len, + &ccm_state); + if (ret != TC_CRYPTO_SUCCESS) { + ESP_LOGE(TAG, "tc_ccm_decryption_verification failed"); + memset(&sched, 0, sizeof(sched)); + memset(&ccm_state, 0, sizeof(ccm_state)); + return -1; + } + + /* Clear sensitive data from key schedule */ + memset(&sched, 0, sizeof(sched)); + memset(&ccm_state, 0, sizeof(ccm_state)); + return 0; + +#elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_len); + size_t output_length = 0; + /* ciphertext_len here includes both ciphertext and tag */ + size_t plaintext_len; + + /* Validate inputs */ + if (key == NULL || nonce == NULL || ciphertext == NULL || plaintext == NULL) { + ESP_LOGE(TAG, "Invalid input parameters"); + return -1; + } + + /* Check for integer underflow */ + if (ciphertext_len < tag_len) { + ESP_LOGE(TAG, "ciphertext_len (%zu) < tag_len (%zu)", ciphertext_len, tag_len); + return -1; + } + + plaintext_len = ciphertext_len - tag_len; + + /* Set key attributes */ + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, BLE_EAD_KEY_SIZE * 8); + + /* Import key */ + status = psa_import_key(&attributes, key, BLE_EAD_KEY_SIZE, &key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_import_key failed: %d", status); + psa_reset_key_attributes(&attributes); + return -1; + } + psa_reset_key_attributes(&attributes); + + /* Decrypt and verify */ + /* PSA AEAD decrypt expects: ciphertext || tag */ + /* ciphertext_len here already includes tag length */ + status = psa_aead_decrypt(key_id, alg, + nonce, BLE_EAD_NONCE_SIZE, + aad, aad_len, + ciphertext, ciphertext_len, + plaintext, plaintext_len, + &output_length); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_aead_decrypt failed: %d", status); + psa_destroy_key(key_id); + return -1; + } + + if (output_length != plaintext_len) { + ESP_LOGE(TAG, "psa_aead_decrypt output length mismatch: expected %zu, got %zu", + plaintext_len, output_length); + psa_destroy_key(key_id); + return -1; + } + + psa_destroy_key(key_id); + return 0; +#else + #error "No crypto library selected" +#endif +} + +int ble_ead_encrypt(const uint8_t session_key[BLE_EAD_KEY_SIZE], + const uint8_t iv[BLE_EAD_IV_SIZE], + const uint8_t *payload, size_t payload_size, + uint8_t *encrypted_payload) +{ + int ret; + uint8_t nonce[BLE_EAD_NONCE_SIZE]; + + if (session_key == NULL) { + ESP_LOGE(TAG, "session_key is NULL"); + return -1; + } + + if (iv == NULL) { + ESP_LOGE(TAG, "iv is NULL"); + return -1; + } + + if (payload == NULL && payload_size > 0) { + ESP_LOGE(TAG, "payload is NULL but payload_size > 0"); + return -1; + } + + if (encrypted_payload == NULL) { + ESP_LOGE(TAG, "encrypted_payload is NULL"); + return -1; + } + + /* Generate nonce with random randomizer */ + ret = ble_ead_generate_nonce(iv, NULL, nonce); + if (ret != 0) { + return ret; + } + + /* Copy randomizer to the start of encrypted payload */ + memcpy(encrypted_payload, nonce, BLE_EAD_RANDOMIZER_SIZE); + + /* Encrypt: output = ciphertext + MIC */ + ret = ble_aes_ccm_encrypt(session_key, nonce, + payload, payload_size, + ble_ead_aad, BLE_EAD_AAD_SIZE, + &encrypted_payload[BLE_EAD_RANDOMIZER_SIZE], + BLE_EAD_MIC_SIZE); + + return ret; +} + +int ble_ead_decrypt(const uint8_t session_key[BLE_EAD_KEY_SIZE], + const uint8_t iv[BLE_EAD_IV_SIZE], + const uint8_t *encrypted_payload, size_t encrypted_payload_size, + uint8_t *payload) +{ + int ret; + uint8_t nonce[BLE_EAD_NONCE_SIZE]; + const uint8_t *randomizer; + const uint8_t *ciphertext; + size_t ciphertext_len; + + if (session_key == NULL) { + ESP_LOGE(TAG, "session_key is NULL"); + return -1; + } + + if (iv == NULL) { + ESP_LOGE(TAG, "iv is NULL"); + return -1; + } + + if (encrypted_payload == NULL) { + ESP_LOGE(TAG, "encrypted_payload is NULL"); + return -1; + } + + if (payload == NULL) { + ESP_LOGE(TAG, "payload is NULL"); + return -1; + } + + if (encrypted_payload_size < BLE_EAD_RANDOMIZER_SIZE + BLE_EAD_MIC_SIZE) { + ESP_LOGE(TAG, "encrypted_payload_size too small"); + return -1; + } + + /* Extract randomizer from the start of encrypted payload */ + randomizer = encrypted_payload; + + /* Ciphertext + MIC follows the randomizer */ + ciphertext = &encrypted_payload[BLE_EAD_RANDOMIZER_SIZE]; + /* ciphertext_len includes both ciphertext and MIC (tag) for PSA API */ + ciphertext_len = encrypted_payload_size - BLE_EAD_RANDOMIZER_SIZE; + + /* Generate nonce from randomizer and IV */ + ret = ble_ead_generate_nonce(iv, randomizer, nonce); + if (ret != 0) { + return ret; + } + + /* Decrypt and verify */ + ret = ble_aes_ccm_decrypt(session_key, nonce, + ciphertext, ciphertext_len, + ble_ead_aad, BLE_EAD_AAD_SIZE, + payload, BLE_EAD_MIC_SIZE); + + return ret; +} diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.h b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.h new file mode 100644 index 0000000000..a9bf8954eb --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.h @@ -0,0 +1,95 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BLE_EAD_H +#define BLE_EAD_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief BLE Encrypted Advertising Data (EAD) definitions + * Based on Bluetooth Core Specification Version 5.4 + */ + +#define BLE_EAD_KEY_SIZE 16 /* 128-bit session key */ +#define BLE_EAD_IV_SIZE 8 /* 64-bit Initialization Vector */ +#define BLE_EAD_RANDOMIZER_SIZE 5 /* 40-bit Randomizer */ +#define BLE_EAD_MIC_SIZE 4 /* 32-bit Message Integrity Check */ +#define BLE_EAD_NONCE_SIZE 13 /* 104-bit Nonce (Randomizer + IV) */ +#define BLE_EAD_AAD_SIZE 1 /* Additional Authenticated Data size */ + +/* Direction bit position in Randomizer (MSB of last byte) + * Per Bluetooth Core Spec Supplement v11, Part A 1.23.3 + */ +#define BLE_EAD_RANDOMIZER_DIRECTION_BIT 7 + +/* AD Type for Encrypted Advertising Data (0x31) */ +#define ESP_BLE_AD_TYPE_ENC_ADV_DATA 0x31 + +/** + * @brief Calculate encrypted payload size from plaintext size + */ +#define BLE_EAD_ENCRYPTED_PAYLOAD_SIZE(payload_size) \ + (BLE_EAD_RANDOMIZER_SIZE + (payload_size) + BLE_EAD_MIC_SIZE) + +/** + * @brief Calculate decrypted payload size from encrypted payload size + */ +#define BLE_EAD_DECRYPTED_PAYLOAD_SIZE(encrypted_size) \ + ((encrypted_size) - BLE_EAD_RANDOMIZER_SIZE - BLE_EAD_MIC_SIZE) + +/** + * @brief Key material structure for EAD + */ +typedef struct { + uint8_t session_key[BLE_EAD_KEY_SIZE]; /* 128-bit session key */ + uint8_t iv[BLE_EAD_IV_SIZE]; /* 64-bit Initialization Vector */ +} ble_ead_key_material_t; + +/** + * @brief Encrypt advertising data using AES-CCM + * + * @param session_key 16-byte session key + * @param iv 8-byte Initialization Vector + * @param payload Plaintext advertising data to encrypt + * @param payload_size Size of plaintext data + * @param encrypted_payload Output buffer for encrypted data + * Size must be at least BLE_EAD_ENCRYPTED_PAYLOAD_SIZE(payload_size) + * + * @return 0 on success, negative error code on failure + */ +int ble_ead_encrypt(const uint8_t session_key[BLE_EAD_KEY_SIZE], + const uint8_t iv[BLE_EAD_IV_SIZE], + const uint8_t *payload, size_t payload_size, + uint8_t *encrypted_payload); + +/** + * @brief Decrypt advertising data using AES-CCM + * + * @param session_key 16-byte session key + * @param iv 8-byte Initialization Vector + * @param encrypted_payload Encrypted advertising data (includes randomizer and MIC) + * @param encrypted_payload_size Size of encrypted data + * @param payload Output buffer for decrypted data + * Size must be at least BLE_EAD_DECRYPTED_PAYLOAD_SIZE(encrypted_payload_size) + * + * @return 0 on success, negative error code on failure + */ +int ble_ead_decrypt(const uint8_t session_key[BLE_EAD_KEY_SIZE], + const uint8_t iv[BLE_EAD_IV_SIZE], + const uint8_t *encrypted_payload, size_t encrypted_payload_size, + uint8_t *payload); + +#ifdef __cplusplus +} +#endif + +#endif /* BLE_EAD_H */ diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/enc_adv_data_cent.c b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/enc_adv_data_cent.c new file mode 100644 index 0000000000..e03c3b86ad --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/enc_adv_data_cent.c @@ -0,0 +1,519 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +/** + * @brief BLE Encrypted Advertising Data Central Example + * + * This example demonstrates how to: + * 1. Scan for devices broadcasting encrypted advertising data + * 2. Connect to read Key Material characteristic + * 3. Decrypt the advertising data using the obtained key + * + * Based on Bluetooth Core Specification Version 5.4 - Encrypted Advertising Data + */ + +#include +#include +#include +#include +#include "nvs.h" +#include "nvs_flash.h" +#include "esp_bt.h" +#include "esp_gap_ble_api.h" +#include "esp_gattc_api.h" +#include "esp_gatt_defs.h" +#include "esp_bt_main.h" +#include "esp_gatt_common_api.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "ble_ead.h" + +#define TAG "ENC_ADV_CENT" + +/* Service and characteristic UUIDs */ +#define GAP_SERVICE_UUID 0x1800 /* GAP Service UUID */ +#define KEY_MATERIAL_CHAR_UUID 0x2B88 /* Key Material Characteristic UUID */ + +/* Profile configuration */ +#define PROFILE_NUM 1 +#define PROFILE_APP_ID 0 +#define INVALID_HANDLE 0 + +/* Maximum peers to track */ +#define MAX_PEERS 5 + +/* Peer information structure */ +typedef struct { + bool valid; + esp_bd_addr_t addr; + bool key_material_exist; + ble_ead_key_material_t key_material; +} peer_info_t; + +static peer_info_t peers[MAX_PEERS] = {0}; + +/* GATT client state */ +static bool is_connected = false; +static bool get_server = false; +static uint16_t conn_id_stored = 0; +static uint16_t service_start_handle = 0; +static uint16_t service_end_handle = 0; +static uint16_t key_material_char_handle = INVALID_HANDLE; +static esp_bd_addr_t current_peer_addr = {0}; + +/* GATT interface */ +static esp_gatt_if_t gattc_if_stored = ESP_GATT_IF_NONE; + +/* Scan parameters */ +static esp_ble_scan_params_t ble_scan_params = { + .scan_type = BLE_SCAN_TYPE_ACTIVE, + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, + .scan_interval = 0x50, + .scan_window = 0x30, + .scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE, +}; + +/* Forward declarations */ +static void start_scan(void); + +/** + * @brief Find peer by address + */ +static int find_peer(const esp_bd_addr_t addr) +{ + for (int i = 0; i < MAX_PEERS; i++) { + if (peers[i].valid && memcmp(peers[i].addr, addr, sizeof(esp_bd_addr_t)) == 0) { + return i; + } + } + return -1; +} + +/** + * @brief Add or update peer + */ +static int add_peer(const esp_bd_addr_t addr) +{ + int idx = find_peer(addr); + if (idx >= 0) { + return idx; /* Already exists */ + } + + /* Find empty slot */ + for (int i = 0; i < MAX_PEERS; i++) { + if (!peers[i].valid) { + peers[i].valid = true; + memcpy(peers[i].addr, addr, sizeof(esp_bd_addr_t)); + peers[i].key_material_exist = false; + return i; + } + } + return -1; /* No space */ +} + +/** + * @brief Decrypt encrypted advertising data + */ +static void decrypt_enc_adv_data(const uint8_t *adv_data, uint8_t adv_len, const esp_bd_addr_t addr) +{ + int peer_idx = find_peer(addr); + if (peer_idx < 0 || !peers[peer_idx].key_material_exist) { + ESP_LOGW(TAG, "No key material for peer, cannot decrypt"); + return; + } + + uint8_t offset = 0; + while (offset < adv_len) { + uint8_t len = adv_data[offset]; + if (len == 0 || offset + len >= adv_len) { + break; + } + + uint8_t type = adv_data[offset + 1]; + if (type == ESP_BLE_AD_TYPE_ENC_ADV_DATA) { + /* Found encrypted advertising data */ + const uint8_t *enc_data = &adv_data[offset + 2]; + uint8_t enc_data_len = len - 1; /* Exclude type byte */ + + if (enc_data_len < BLE_EAD_RANDOMIZER_SIZE + BLE_EAD_MIC_SIZE) { + ESP_LOGW(TAG, "Encrypted data too short"); + break; + } + + uint8_t dec_data[32]; /* Buffer for decrypted data */ + size_t dec_len = BLE_EAD_DECRYPTED_PAYLOAD_SIZE(enc_data_len); + + int rc = ble_ead_decrypt( + peers[peer_idx].key_material.session_key, + peers[peer_idx].key_material.iv, + enc_data, enc_data_len, + dec_data); + + if (rc == 0) { + ESP_LOGI(TAG, "Decryption successful!"); + ESP_LOGI(TAG, "Decrypted data:"); + ESP_LOG_BUFFER_HEX(TAG, dec_data, dec_len); + + /* Parse decrypted advertising structure */ + if (dec_len >= 2) { + uint8_t dec_type = dec_data[1]; + if (dec_type == ESP_BLE_AD_TYPE_NAME_CMPL || dec_type == ESP_BLE_AD_TYPE_NAME_SHORT) { + char name[32] = {0}; + size_t name_len = dec_data[0] - 1; + if (name_len < sizeof(name)) { + memcpy(name, &dec_data[2], name_len); + ESP_LOGI(TAG, "Decrypted device name: %s", name); + } + } + } + } else { + ESP_LOGE(TAG, "Decryption failed: %d", rc); + } + break; + } + offset += len + 1; + } +} + +/** + * @brief Check if device advertises GAP service UUID + */ +static bool should_connect(const uint8_t *adv_data, uint8_t adv_len) +{ + uint8_t offset = 0; + while (offset < adv_len) { + uint8_t len = adv_data[offset]; + if (len == 0 || offset + len >= adv_len) { + break; + } + + uint8_t type = adv_data[offset + 1]; + if (type == ESP_BLE_AD_TYPE_16SRV_CMPL || type == ESP_BLE_AD_TYPE_16SRV_PART) { + /* Check for GAP service UUID */ + for (int i = 0; i < len - 1; i += 2) { + uint16_t uuid = adv_data[offset + 2 + i] | (adv_data[offset + 3 + i] << 8); + if (uuid == GAP_SERVICE_UUID) { + return true; + } + } + } + offset += len + 1; + } + return false; +} + +/** + * @brief Start scanning + */ +static void start_scan(void) +{ + esp_ble_gap_start_scanning(30); /* Scan for 30 seconds */ +} + +/** + * @brief GAP event handler + */ +static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) +{ + switch (event) { + case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: + ESP_LOGI(TAG, "Scan parameters set"); + start_scan(); + break; + + case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: + if (param->scan_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { + ESP_LOGE(TAG, "Scan start failed: %d", param->scan_start_cmpl.status); + } else { + ESP_LOGI(TAG, "Scanning started"); + } + break; + + case ESP_GAP_BLE_SCAN_RESULT_EVT: { + esp_ble_gap_cb_param_t *scan_result = param; + if (scan_result->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) { + uint8_t *adv_data = scan_result->scan_rst.ble_adv; + uint8_t adv_len = scan_result->scan_rst.adv_data_len; + + if (should_connect(adv_data, adv_len)) { + ESP_LOGI(TAG, "Found target device: "ESP_BD_ADDR_STR"", + ESP_BD_ADDR_HEX(scan_result->scan_rst.bda)); + + int peer_idx = find_peer(scan_result->scan_rst.bda); + if (peer_idx >= 0 && peers[peer_idx].key_material_exist) { + /* Already have key, try to decrypt */ + ESP_LOGI(TAG, "Have key material, decrypting..."); + decrypt_enc_adv_data(adv_data, adv_len, scan_result->scan_rst.bda); + } else { + /* Need to connect and get key */ + if (!is_connected) { + ESP_LOGI(TAG, "Connecting to get key material..."); + add_peer(scan_result->scan_rst.bda); + memcpy(current_peer_addr, scan_result->scan_rst.bda, sizeof(esp_bd_addr_t)); + + esp_ble_gap_stop_scanning(); + + esp_ble_gatt_creat_conn_params_t conn_params = {0}; + memcpy(conn_params.remote_bda, scan_result->scan_rst.bda, ESP_BD_ADDR_LEN); + conn_params.remote_addr_type = scan_result->scan_rst.ble_addr_type; + conn_params.own_addr_type = BLE_ADDR_TYPE_PUBLIC; + conn_params.is_direct = true; + conn_params.is_aux = false; + esp_ble_gattc_enh_open(gattc_if_stored, &conn_params); + } + } + } + } else if (scan_result->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_CMPL_EVT) { + ESP_LOGI(TAG, "Scan complete"); + if (!is_connected) { + start_scan(); /* Restart scanning */ + } + } + break; + } + + case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: + ESP_LOGI(TAG, "Scan stopped"); + break; + + case ESP_GAP_BLE_SEC_REQ_EVT: + ESP_LOGI(TAG, "Security request"); + esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true); + break; + + case ESP_GAP_BLE_AUTH_CMPL_EVT: + if (param->ble_security.auth_cmpl.success) { + ESP_LOGI(TAG, "Authentication success"); + } else { + ESP_LOGW(TAG, "Authentication failed: 0x%x", param->ble_security.auth_cmpl.fail_reason); + } + break; + + default: + break; + } +} + +/** + * @brief GATTC event handler + */ +static void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, + esp_ble_gattc_cb_param_t *param) +{ + switch (event) { + case ESP_GATTC_REG_EVT: + ESP_LOGI(TAG, "GATT client registered, status %d, if %d", param->reg.status, gattc_if); + gattc_if_stored = gattc_if; + esp_ble_gap_set_scan_params(&ble_scan_params); + break; + + case ESP_GATTC_CONNECT_EVT: + ESP_LOGI(TAG, "Connected, conn_id %d", param->connect.conn_id); + conn_id_stored = param->connect.conn_id; + is_connected = true; + + /* Request MTU exchange */ + esp_ble_gattc_send_mtu_req(gattc_if, param->connect.conn_id); + break; + + case ESP_GATTC_OPEN_EVT: + if (param->open.status != ESP_GATT_OK) { + ESP_LOGE(TAG, "Open failed: %d", param->open.status); + is_connected = false; + start_scan(); + } + break; + + case ESP_GATTC_CFG_MTU_EVT: + ESP_LOGI(TAG, "MTU configured: %d", param->cfg_mtu.mtu); + break; + + case ESP_GATTC_DIS_SRVC_CMPL_EVT: + ESP_LOGI(TAG, "Service discovery complete"); + /* Search for GAP service that contains Key Material characteristic */ + ESP_LOGI(TAG, "Searching for GAP service UUID 0x%04X", GAP_SERVICE_UUID); + esp_bt_uuid_t gap_uuid = { + .len = ESP_UUID_LEN_16, + .uuid = {.uuid16 = GAP_SERVICE_UUID}, + }; + esp_ble_gattc_search_service(gattc_if, param->dis_srvc_cmpl.conn_id, &gap_uuid); + break; + + case ESP_GATTC_SEARCH_RES_EVT: + ESP_LOGI(TAG, "Service found, UUID 0x%04X, start_handle %d, end_handle %d", + param->search_res.srvc_id.uuid.uuid.uuid16, + param->search_res.start_handle, param->search_res.end_handle); + if (param->search_res.srvc_id.uuid.len == ESP_UUID_LEN_16 && + param->search_res.srvc_id.uuid.uuid.uuid16 == GAP_SERVICE_UUID) { + get_server = true; + service_start_handle = param->search_res.start_handle; + service_end_handle = param->search_res.end_handle; + } + break; + + case ESP_GATTC_SEARCH_CMPL_EVT: + ESP_LOGI(TAG, "Service search complete"); + if (get_server) { + /* Get characteristics */ + uint16_t count = 0; + esp_ble_gattc_get_attr_count(gattc_if, conn_id_stored, + ESP_GATT_DB_CHARACTERISTIC, + service_start_handle, + service_end_handle, + INVALID_HANDLE, &count); + + if (count > 0) { + esp_gattc_char_elem_t *char_elem = malloc(sizeof(esp_gattc_char_elem_t) * count); + if (char_elem) { + esp_bt_uuid_t km_uuid = { + .len = ESP_UUID_LEN_16, + .uuid = {.uuid16 = KEY_MATERIAL_CHAR_UUID}, + }; + esp_ble_gattc_get_char_by_uuid(gattc_if, conn_id_stored, + service_start_handle, + service_end_handle, + km_uuid, char_elem, &count); + + if (count > 0) { + key_material_char_handle = char_elem[0].char_handle; + ESP_LOGI(TAG, "Key Material characteristic found, handle %d", key_material_char_handle); + + /* Read characteristic with encryption requirement + * GATT layer will automatically trigger encryption if needed */ + ESP_LOGI(TAG, "Reading key material (will trigger encryption if needed)..."); + esp_ble_gattc_read_char(gattc_if, conn_id_stored, + key_material_char_handle, ESP_GATT_AUTH_REQ_NO_MITM); + } + free(char_elem); + } + } + } + break; + + case ESP_GATTC_READ_CHAR_EVT: + if (param->read.status == ESP_GATT_OK) { + ESP_LOGI(TAG, "Read characteristic success, handle %d, len %d", + param->read.handle, param->read.value_len); + + if (param->read.handle == key_material_char_handle && + param->read.value_len == sizeof(ble_ead_key_material_t)) { + /* Store key material */ + int peer_idx = find_peer(current_peer_addr); + if (peer_idx >= 0) { + memcpy(&peers[peer_idx].key_material, param->read.value, + sizeof(ble_ead_key_material_t)); + peers[peer_idx].key_material_exist = true; + + ESP_LOGI(TAG, "Key material received:"); + ESP_LOG_BUFFER_HEX(TAG, &peers[peer_idx].key_material, + sizeof(ble_ead_key_material_t)); + } + + /* Disconnect and resume scanning */ + esp_ble_gattc_close(gattc_if, conn_id_stored); + } + } else { + ESP_LOGE(TAG, "Read failed: %d", param->read.status); + } + break; + + case ESP_GATTC_DISCONNECT_EVT: + ESP_LOGI(TAG, "Disconnected, reason 0x%02x", param->disconnect.reason); + is_connected = false; + get_server = false; + key_material_char_handle = INVALID_HANDLE; + start_scan(); + break; + + default: + break; + } +} + + +void app_main(void) +{ + esp_err_t ret; + + /* Initialize NVS */ + 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); + + /* Release memory for Classic BT */ + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); + + /* Initialize BT controller */ + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(TAG, "initialize controller failed: %s", esp_err_to_name(ret)); + return; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (ret) { + ESP_LOGE(TAG, "enable controller failed: %s", esp_err_to_name(ret)); + return; + } + + /* Initialize Bluedroid */ + esp_bluedroid_config_t cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT(); + ret = esp_bluedroid_init_with_cfg(&cfg); + if (ret) { + ESP_LOGE(TAG, "init bluetooth failed: %s", esp_err_to_name(ret)); + return; + } + + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(TAG, "enable bluetooth failed: %s", esp_err_to_name(ret)); + return; + } + + /* Register callbacks */ + ret = esp_ble_gap_register_callback(gap_event_handler); + if (ret) { + ESP_LOGE(TAG, "gap register error: %x", ret); + return; + } + + ret = esp_ble_gattc_register_callback(gattc_event_handler); + if (ret) { + ESP_LOGE(TAG, "gattc register error: %x", ret); + return; + } + + ret = esp_ble_gattc_app_register(PROFILE_APP_ID); + if (ret) { + ESP_LOGE(TAG, "gattc app register error: %x", ret); + return; + } + + /* Set MTU */ + esp_ble_gatt_set_local_mtu(500); + + /* Configure security parameters + * Using SC (Secure Connections) with bonding, no MITM (since IO_CAP is NONE) + */ + esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_BOND; /* SC + Bond, no MITM */ + esp_ble_io_cap_t io_cap = ESP_IO_CAP_NONE; + uint8_t key_size = 16; + uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK; + uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK; + + esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(auth_req)); + esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &io_cap, sizeof(io_cap)); + esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(key_size)); + esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(init_key)); + esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(rsp_key)); + + ESP_LOGI(TAG, "Encrypted Advertising Data Central started"); +} diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/enc_adv_data_cent_no_connect.c b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/enc_adv_data_cent_no_connect.c new file mode 100644 index 0000000000..62416b1ecc --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/enc_adv_data_cent_no_connect.c @@ -0,0 +1,239 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +/** + * @brief BLE Encrypted Advertising Data Central Example - No Connection Version + * + * This simplified example demonstrates decrypting advertising data WITHOUT connecting. + * The key material is pre-configured (same as peripheral). + * + * Use case: When the key is pre-shared or provisioned out-of-band. + */ + +#include +#include +#include +#include +#include "nvs.h" +#include "nvs_flash.h" +#include "esp_bt.h" +#include "esp_gap_ble_api.h" +#include "esp_bt_main.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "ble_ead.h" + +#define TAG "ENC_ADV_CENT_SIMPLE" + +/* Custom service UUID to identify target device */ +#define CUSTOM_SERVICE_UUID 0x2C01 + +/* + * Pre-shared Key Material - MUST match the Peripheral! + * In real applications, this would be provisioned securely. + */ +static const ble_ead_key_material_t pre_shared_key = { + .session_key = { + 0x19, 0x6a, 0x0a, 0xd1, 0x2a, 0x61, 0x20, 0x1e, + 0x13, 0x6e, 0x2e, 0xd1, 0x12, 0xda, 0xa9, 0x57 + }, + .iv = {0x9E, 0x7a, 0x00, 0xef, 0xb1, 0x7a, 0xe7, 0x46}, +}; + +/* Scan parameters */ +static esp_ble_scan_params_t ble_scan_params = { + .scan_type = BLE_SCAN_TYPE_PASSIVE, /* Passive scan is enough */ + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, + .scan_interval = 0x50, + .scan_window = 0x30, + .scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE, +}; + +/** + * @brief Check if device advertises our target service UUID + */ +static bool is_target_device(const uint8_t *adv_data, uint8_t adv_len) +{ + uint8_t offset = 0; + while (offset < adv_len) { + uint8_t len = adv_data[offset]; + if (len == 0 || offset + len >= adv_len) { + break; + } + + uint8_t type = adv_data[offset + 1]; + if (type == ESP_BLE_AD_TYPE_16SRV_CMPL || type == ESP_BLE_AD_TYPE_16SRV_PART) { + for (int i = 0; i < len - 1; i += 2) { + uint16_t uuid = adv_data[offset + 2 + i] | (adv_data[offset + 3 + i] << 8); + if (uuid == CUSTOM_SERVICE_UUID) { + return true; + } + } + } + offset += len + 1; + } + return false; +} + +/** + * @brief Decrypt encrypted advertising data using pre-shared key + * + * No connection required! + */ +static void decrypt_adv_data_no_connect(const uint8_t *adv_data, uint8_t adv_len, + const esp_bd_addr_t addr) +{ + uint8_t offset = 0; + + ESP_LOGI(TAG, "Processing advertising data from "ESP_BD_ADDR_STR"", + ESP_BD_ADDR_HEX(addr)); + + while (offset < adv_len) { + uint8_t len = adv_data[offset]; + if (len == 0 || offset + len >= adv_len) { + break; + } + + uint8_t type = adv_data[offset + 1]; + + /* Look for Encrypted Advertising Data (AD Type 0x31) */ + if (type == ESP_BLE_AD_TYPE_ENC_ADV_DATA) { + const uint8_t *enc_data = &adv_data[offset + 2]; + uint8_t enc_data_len = len - 1; /* Exclude type byte */ + + ESP_LOGI(TAG, "Found encrypted advertising data (%d bytes)", enc_data_len); + ESP_LOG_BUFFER_HEX(TAG, enc_data, enc_data_len); + + if (enc_data_len < BLE_EAD_RANDOMIZER_SIZE + BLE_EAD_MIC_SIZE) { + ESP_LOGW(TAG, "Encrypted data too short"); + break; + } + + /* Decrypt using pre-shared key */ + uint8_t dec_data[32]; + size_t dec_len = BLE_EAD_DECRYPTED_PAYLOAD_SIZE(enc_data_len); + + int rc = ble_ead_decrypt( + pre_shared_key.session_key, + pre_shared_key.iv, + enc_data, enc_data_len, + dec_data); + + if (rc == 0) { + ESP_LOGI(TAG, "✅ Decryption successful (no connection needed!)"); + ESP_LOGI(TAG, "Decrypted data (%d bytes):", dec_len); + ESP_LOG_BUFFER_HEX(TAG, dec_data, dec_len); + + /* Parse the decrypted advertising structure */ + if (dec_len >= 2) { + uint8_t inner_len = dec_data[0]; + uint8_t inner_type = dec_data[1]; + + if (inner_type == ESP_BLE_AD_TYPE_NAME_CMPL || + inner_type == ESP_BLE_AD_TYPE_NAME_SHORT) { + char name[32] = {0}; + size_t name_len = inner_len - 1; + if (name_len < sizeof(name) && name_len <= dec_len - 2) { + memcpy(name, &dec_data[2], name_len); + ESP_LOGI(TAG, "📛 Decrypted device name: \"%s\"", name); + } + } + } + } else { + ESP_LOGE(TAG, "❌ Decryption failed (rc=%d) - wrong key?", rc); + } + return; /* Found and processed encrypted data */ + } + offset += len + 1; + } + + ESP_LOGW(TAG, "No encrypted advertising data found in this packet"); +} + +/** + * @brief GAP event handler + */ +static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) +{ + switch (event) { + case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: + ESP_LOGI(TAG, "Scan parameters set, starting scan..."); + esp_ble_gap_start_scanning(0); /* Scan indefinitely */ + break; + + case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: + if (param->scan_start_cmpl.status == ESP_BT_STATUS_SUCCESS) { + ESP_LOGI(TAG, "🔍 Scanning started (no connection mode)"); + ESP_LOGI(TAG, "Looking for devices with UUID 0x%04X...", CUSTOM_SERVICE_UUID); + } else { + ESP_LOGE(TAG, "Scan start failed: %d", param->scan_start_cmpl.status); + } + break; + + case ESP_GAP_BLE_SCAN_RESULT_EVT: { + esp_ble_gap_cb_param_t *scan_result = param; + + if (scan_result->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) { + uint8_t *adv_data = scan_result->scan_rst.ble_adv; + uint8_t adv_len = scan_result->scan_rst.adv_data_len; + + /* Check if this is our target device */ + if (is_target_device(adv_data, adv_len)) { + /* Decrypt without connecting! */ + decrypt_adv_data_no_connect(adv_data, adv_len, scan_result->scan_rst.bda); + } + } + break; + } + + default: + break; + } +} + +void app_main(void) +{ + esp_err_t ret; + + ESP_LOGI(TAG, "========================================"); + ESP_LOGI(TAG, " EAD Central - No Connection Mode"); + ESP_LOGI(TAG, "========================================"); + + /* Initialize NVS */ + 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); + + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg)); + ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BLE)); + + esp_bluedroid_config_t cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_bluedroid_init_with_cfg(&cfg)); + ESP_ERROR_CHECK(esp_bluedroid_enable()); + + ESP_ERROR_CHECK(esp_ble_gap_register_callback(gap_event_handler)); + + /* Display pre-shared key */ + ESP_LOGI(TAG, "Using pre-shared key material:"); + ESP_LOGI(TAG, " Session Key:"); + ESP_LOG_BUFFER_HEX(TAG, pre_shared_key.session_key, BLE_EAD_KEY_SIZE); + ESP_LOGI(TAG, " IV:"); + ESP_LOG_BUFFER_HEX(TAG, pre_shared_key.iv, BLE_EAD_IV_SIZE); + + /* Start scanning */ + ESP_ERROR_CHECK(esp_ble_gap_set_scan_params(&ble_scan_params)); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "⚡ This example decrypts WITHOUT connecting!"); + ESP_LOGI(TAG, " Key must be pre-shared with peripheral."); +} diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/sdkconfig.defaults b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/sdkconfig.defaults new file mode 100644 index 0000000000..ae0ee30898 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/sdkconfig.defaults @@ -0,0 +1,13 @@ +# Enable BLE +CONFIG_BT_ENABLED=y +CONFIG_BT_BLUEDROID_ENABLED=y +CONFIG_BT_BLE_ENABLED=y +CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y +# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set + +# Enable SMP for security +CONFIG_BT_BLE_SMP_ENABLE=y + +# Select crypto library for EAD (Encrypted Advertising Data) +# Options: CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT or CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS +CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT=y diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/CMakeLists.txt b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/CMakeLists.txt new file mode 100644 index 0000000000..b78df5cd06 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/CMakeLists.txt @@ -0,0 +1,8 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five 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(enc_adv_data_prph) diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/README.md b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/README.md new file mode 100644 index 0000000000..95e86da46b --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/README.md @@ -0,0 +1,172 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | + +# BLE Encrypted Advertising Data Peripheral Example (Bluedroid) + +This example demonstrates how to use BLE Encrypted Advertising Data (EAD) feature with Bluedroid stack. + +## Overview + +The Encrypted Advertising Data feature (introduced in Bluetooth Core Specification 5.4) allows devices to encrypt portions of their advertising data using AES-CCM. This enables: + +- Privacy protection for sensitive advertising data +- Selective disclosure of advertising data to authorized devices +- Enhanced security for BLE advertising + +## System Architecture + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ PERIPHERAL (This Example) │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────────┐ │ +│ │ Original Data │───▶│ AES-CCM Encrypt │───▶│ Encrypted Adv Data │ │ +│ │ "prph" (name) │ │ (Session Key+IV)│ │ (Randomizer+Cipher │ │ +│ └─────────────────┘ └──────────────────┘ │ +MIC) │ │ +│ └──────────┬──────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────────────────────────────────────────────────────────────────┐ │ +│ │ BLE Advertising Packet │ │ +│ ├──────────┬─────────────┬────────────────┬────────────────────────────┤ │ +│ │ Flags │ Name "key" │ UUID 0x2C01 │ Encrypted Data (AD 0x31) │ │ +│ │ (3B) │ (5B) │ (4B) │ (16B) │ │ +│ └──────────┴─────────────┴────────────────┴────────────────────────────┘ │ +│ │ +│ ┌──────────────────────────────────────────────────────────────────────┐ │ +│ │ GATT Server │ │ +│ ├──────────────────────────────────────────────────────────────────────┤ │ +│ │ GAP Service (0x1800) │ │ +│ │ └── Key Material Characteristic (0x2B88) │ │ +│ │ └── Value: [Session Key (16B)] [IV (8B)] │ │ +│ │ └── Permission: Read (Encrypted Link Required) │ │ +│ └──────────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +## Encryption Flow + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ Encryption Process │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. Generate Random Randomizer (5 bytes) │ +│ ┌─────────────────────────────────────────┐ │ +│ │ XX XX XX XX [D|XX] │ D = Direction Bit = 1 │ +│ └─────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ 2. Build Nonce (13 bytes) │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ Randomizer (5B) │ IV (8B) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ 3. AES-CCM Encryption │ +│ ┌─────────────────┐ │ +│ │ Plaintext │ + Session Key + Nonce + AAD (0xEA) │ +│ │ [05 09 p r p h]│ │ +│ └─────────────────┘ │ +│ │ │ +│ ▼ │ +│ 4. Output: Encrypted Payload │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ Randomizer (5B) │ Ciphertext (6B) │ MIC (4B) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +## Advertising Data Format + +``` +Complete Advertising Packet (29 bytes): + +Offset Length Type Data Description +────── ────── ──── ──── ─────────── +0 2 0x01 0x06 Flags: LE General Discoverable +3 4 0x09 'k' 'e' 'y' Complete Local Name +8 3 0x03 0x01 0x2C 16-bit Service UUID: 0x2C01 +12 16 0x31 [Encrypted Payload] Encrypted Advertising Data + +Encrypted Payload Detail: +┌───────────────────┬─────────────────────┬─────────────────┐ +│ Randomizer │ Ciphertext │ MIC │ +│ (5 bytes) │ (6 bytes) │ (4 bytes) │ +│ Random + Dir=1 │ AES-CCM output │ Auth Tag │ +└───────────────────┴─────────────────────┴─────────────────┘ +``` + +## How to Use Example + +### Hardware Required + +* A development board with ESP32/ESP32-C2/ESP32-C3/ESP32-C5/ESP32-C6/ESP32-C61/ESP32-H2/ESP32-S3 SoC +* A USB cable for power supply and programming + +### Configure the project + +```bash +idf.py set-target +idf.py menuconfig +``` + +### Build and Flash + +```bash +idf.py -p PORT flash monitor +``` + +(To exit the serial monitor, type `Ctrl-]`.) + +### Example Output + +``` +I (XXX) ENC_ADV_PRPH: Encrypted Advertising Data Peripheral started +I (XXX) ENC_ADV_PRPH: Key Material (Session Key + IV): +I (XXX) ENC_ADV_PRPH: 19 6a 0a d1 2a 61 20 1e 13 6e 2e d1 12 da a9 57 9e 7a 00 ef b1 7a e7 46 +I (XXX) ENC_ADV_PRPH: Data before encryption: +I (XXX) ENC_ADV_PRPH: 05 09 70 72 70 68 +I (XXX) ENC_ADV_PRPH: Encryption of adv data done successfully +I (XXX) ENC_ADV_PRPH: Raw advertising data set complete +I (XXX) ENC_ADV_PRPH: Advertising start successfully +``` + +## Testing with Central + +Use the `enc_adv_data_cent` example as the central device: + +``` +┌──────────────────┐ ┌──────────────────┐ +│ PERIPHERAL │ │ CENTRAL │ +│ (This Example) │ │ (enc_adv_data_ │ +│ │ │ cent) │ +└────────┬─────────┘ └────────┬─────────┘ + │ │ + │ 1. Broadcast Encrypted Adv │ + │ ─────────────────────────────────────▶│ + │ │ + │ 2. Connect (first time only) │ + │ ◀═══════════════════════════════════ │ + │ │ + │ 3. Read Key Material (0x2B88) │ + │ ═══════════════════════════════════▶ │ + │ │ + │ 4. Return Session Key + IV │ + │ ◀═══════════════════════════════════ │ + │ │ + │ 5. Disconnect │ + │ ◀═══════════════════════════════════ │ + │ │ + │ 6. Future: Decrypt without connect │ + │ ─────────────────────────────────────▶│ + │ │ + ▼ ▼ +``` + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/CMakeLists.txt b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/CMakeLists.txt new file mode 100644 index 0000000000..a9fa58c00e --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "enc_adv_data_prph.c" "ble_ead.c" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/Kconfig.projbuild new file mode 100644 index 0000000000..305d0bfab6 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/Kconfig.projbuild @@ -0,0 +1,14 @@ +menu "Example Configuration" + + config EXAMPLE_ENABLE_KEY_MATERIAL + bool "Enable Key Material characteristic in GAP Service" + default y + select BT_GATTS_KEY_MATERIAL_CHAR + help + Enable the Key Material characteristic in the built-in GAP service + (UUID 0x1800) using the Bluedroid stack's support for this feature. + + This is the standard-compliant approach as defined in Bluetooth + Core Specification Version 5.4. + +endmenu diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.c b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.c new file mode 100644 index 0000000000..b3e1dcc8f8 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.c @@ -0,0 +1,419 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "ble_ead.h" +#include "esp_random.h" +#include "esp_log.h" +#include "sdkconfig.h" + +#define TAG "BLE_EAD" + +/* Select crypto library based on configuration */ +#if defined(CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT) +#include "tinycrypt/aes.h" +#include "tinycrypt/ccm_mode.h" +#include "tinycrypt/constants.h" +#elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) +#include "psa/crypto.h" +#else +#error "Please select either CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT or CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS" +#endif + +/* Additional Authenticated Data for EAD - EA (Encrypted Advertising) */ +static const uint8_t ble_ead_aad[BLE_EAD_AAD_SIZE] = { 0xEA }; + +/** + * @brief Generate randomizer with direction bit set + * + * Per Bluetooth Core Spec Supplement v11, Part A 1.23.3: + * The MSB of the Randomizer shall be set to indicate direction + */ +static int ble_ead_generate_randomizer(uint8_t randomizer[BLE_EAD_RANDOMIZER_SIZE]) +{ + /* Generate random bytes */ + esp_fill_random(randomizer, BLE_EAD_RANDOMIZER_SIZE); + + /* Set direction bit (MSB of last byte) - required by spec */ + randomizer[BLE_EAD_RANDOMIZER_SIZE - 1] |= (1 << BLE_EAD_RANDOMIZER_DIRECTION_BIT); + + return 0; +} + +/** + * @brief Generate nonce from IV and randomizer + * + * Nonce = Randomizer (5 bytes) || IV (8 bytes) = 13 bytes + */ +static int ble_ead_generate_nonce(const uint8_t iv[BLE_EAD_IV_SIZE], + const uint8_t randomizer[BLE_EAD_RANDOMIZER_SIZE], + uint8_t nonce[BLE_EAD_NONCE_SIZE]) +{ + if (iv == NULL || nonce == NULL) { + return -1; + } + + /* Randomizer in first 5 bytes */ + if (randomizer != NULL) { + memcpy(nonce, randomizer, BLE_EAD_RANDOMIZER_SIZE); + } else { + /* Generate new randomizer with direction bit */ + ble_ead_generate_randomizer(nonce); + } + + /* IV in last 8 bytes */ + memcpy(nonce + BLE_EAD_RANDOMIZER_SIZE, iv, BLE_EAD_IV_SIZE); + + return 0; +} + +/** + * @brief AES-CCM encryption using selected crypto library + */ +static int ble_aes_ccm_encrypt(const uint8_t *key, const uint8_t *nonce, + const uint8_t *plaintext, size_t plaintext_len, + const uint8_t *aad, size_t aad_len, + uint8_t *ciphertext, size_t tag_len) +{ +#if defined(CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT) + struct tc_aes_key_sched_struct sched; + struct tc_ccm_mode_struct ccm_state; + int ret; + + /* Validate inputs */ + if (key == NULL || nonce == NULL || ciphertext == NULL) { + ESP_LOGE(TAG, "Invalid input parameters"); + return -1; + } + + /* Set AES encryption key */ + ret = tc_aes128_set_encrypt_key(&sched, key); + if (ret != TC_CRYPTO_SUCCESS) { + ESP_LOGE(TAG, "tc_aes128_set_encrypt_key failed"); + memset(&sched, 0, sizeof(sched)); + return -1; + } + + /* Configure CCM mode */ + ccm_state.sched = &sched; + ccm_state.nonce = (uint8_t *)nonce; + ccm_state.mlen = tag_len; + + ret = tc_ccm_config(&ccm_state, &sched, (uint8_t *)nonce, BLE_EAD_NONCE_SIZE, tag_len); + if (ret != TC_CRYPTO_SUCCESS) { + ESP_LOGE(TAG, "tc_ccm_config failed"); + memset(&sched, 0, sizeof(sched)); + memset(&ccm_state, 0, sizeof(ccm_state)); + return -1; + } + + /* Encrypt and generate tag */ + /* TinyCrypt outputs: ciphertext || tag */ + ret = tc_ccm_generation_encryption(ciphertext, plaintext_len + tag_len, + aad, aad_len, + plaintext, plaintext_len, + &ccm_state); + if (ret != TC_CRYPTO_SUCCESS) { + ESP_LOGE(TAG, "tc_ccm_generation_encryption failed"); + memset(&sched, 0, sizeof(sched)); + memset(&ccm_state, 0, sizeof(ccm_state)); + return -1; + } + + /* Clear sensitive data from key schedule */ + memset(&sched, 0, sizeof(sched)); + memset(&ccm_state, 0, sizeof(ccm_state)); + return 0; + +#elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_len); + size_t output_length = 0; + + /* Set key attributes */ + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, BLE_EAD_KEY_SIZE * 8); + + /* Import key */ + status = psa_import_key(&attributes, key, BLE_EAD_KEY_SIZE, &key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_import_key failed: %d", status); + psa_reset_key_attributes(&attributes); + return -1; + } + psa_reset_key_attributes(&attributes); + + /* Encrypt and authenticate */ + /* PSA AEAD encrypt outputs: ciphertext || tag */ + status = psa_aead_encrypt(key_id, alg, + nonce, BLE_EAD_NONCE_SIZE, + aad, aad_len, + plaintext, plaintext_len, + ciphertext, plaintext_len + tag_len, + &output_length); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_aead_encrypt failed: %d", status); + psa_destroy_key(key_id); + return -1; + } + + if (output_length != plaintext_len + tag_len) { + ESP_LOGE(TAG, "psa_aead_encrypt output length mismatch: expected %zu, got %zu", + plaintext_len + tag_len, output_length); + psa_destroy_key(key_id); + return -1; + } + + psa_destroy_key(key_id); + return 0; +#else + #error "No crypto library selected" +#endif +} + +/** + * @brief AES-CCM decryption with authentication using selected crypto library + */ +static int ble_aes_ccm_decrypt(const uint8_t *key, const uint8_t *nonce, + const uint8_t *ciphertext, size_t ciphertext_len, + const uint8_t *aad, size_t aad_len, + uint8_t *plaintext, size_t tag_len) +{ +#if defined(CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT) + struct tc_aes_key_sched_struct sched; + struct tc_ccm_mode_struct ccm_state; + int ret; + /* ciphertext_len here includes both ciphertext and tag */ + size_t plaintext_len; + + /* Validate inputs */ + if (key == NULL || nonce == NULL || ciphertext == NULL || plaintext == NULL) { + ESP_LOGE(TAG, "Invalid input parameters"); + return -1; + } + + /* Check for integer underflow */ + if (ciphertext_len < tag_len) { + ESP_LOGE(TAG, "ciphertext_len (%zu) < tag_len (%zu)", ciphertext_len, tag_len); + return -1; + } + + plaintext_len = ciphertext_len - tag_len; + + /* Set AES encryption key */ + ret = tc_aes128_set_encrypt_key(&sched, key); + if (ret != TC_CRYPTO_SUCCESS) { + ESP_LOGE(TAG, "tc_aes128_set_encrypt_key failed"); + memset(&sched, 0, sizeof(sched)); + return -1; + } + + /* Configure CCM mode */ + ccm_state.sched = &sched; + ccm_state.nonce = (uint8_t *)nonce; + ccm_state.mlen = tag_len; + + ret = tc_ccm_config(&ccm_state, &sched, (uint8_t *)nonce, BLE_EAD_NONCE_SIZE, tag_len); + if (ret != TC_CRYPTO_SUCCESS) { + ESP_LOGE(TAG, "tc_ccm_config failed"); + memset(&sched, 0, sizeof(sched)); + memset(&ccm_state, 0, sizeof(ccm_state)); + return -1; + } + + /* Decrypt and verify tag */ + /* TinyCrypt expects: ciphertext || tag */ + ret = tc_ccm_decryption_verification(plaintext, plaintext_len, + aad, aad_len, + (uint8_t *)ciphertext, ciphertext_len, + &ccm_state); + if (ret != TC_CRYPTO_SUCCESS) { + ESP_LOGE(TAG, "tc_ccm_decryption_verification failed"); + memset(&sched, 0, sizeof(sched)); + memset(&ccm_state, 0, sizeof(ccm_state)); + return -1; + } + + /* Clear sensitive data from key schedule */ + memset(&sched, 0, sizeof(sched)); + memset(&ccm_state, 0, sizeof(ccm_state)); + return 0; + +#elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_len); + size_t output_length = 0; + /* ciphertext_len here includes both ciphertext and tag */ + size_t plaintext_len; + + /* Validate inputs */ + if (key == NULL || nonce == NULL || ciphertext == NULL || plaintext == NULL) { + ESP_LOGE(TAG, "Invalid input parameters"); + return -1; + } + + /* Check for integer underflow */ + if (ciphertext_len < tag_len) { + ESP_LOGE(TAG, "ciphertext_len (%zu) < tag_len (%zu)", ciphertext_len, tag_len); + return -1; + } + + plaintext_len = ciphertext_len - tag_len; + + /* Set key attributes */ + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, BLE_EAD_KEY_SIZE * 8); + + /* Import key */ + status = psa_import_key(&attributes, key, BLE_EAD_KEY_SIZE, &key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_import_key failed: %d", status); + psa_reset_key_attributes(&attributes); + return -1; + } + psa_reset_key_attributes(&attributes); + + /* Decrypt and verify */ + /* PSA AEAD decrypt expects: ciphertext || tag */ + status = psa_aead_decrypt(key_id, alg, + nonce, BLE_EAD_NONCE_SIZE, + aad, aad_len, + ciphertext, ciphertext_len, + plaintext, plaintext_len, + &output_length); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_aead_decrypt failed: %d", status); + psa_destroy_key(key_id); + return -1; + } + + if (output_length != plaintext_len) { + ESP_LOGE(TAG, "psa_aead_decrypt output length mismatch: expected %zu, got %zu", + plaintext_len, output_length); + psa_destroy_key(key_id); + return -1; + } + + psa_destroy_key(key_id); + return 0; +#else + #error "No crypto library selected" +#endif +} + +int ble_ead_encrypt(const uint8_t session_key[BLE_EAD_KEY_SIZE], + const uint8_t iv[BLE_EAD_IV_SIZE], + const uint8_t *payload, size_t payload_size, + uint8_t *encrypted_payload) +{ + int ret; + uint8_t nonce[BLE_EAD_NONCE_SIZE]; + + if (session_key == NULL) { + ESP_LOGE(TAG, "session_key is NULL"); + return -1; + } + + if (iv == NULL) { + ESP_LOGE(TAG, "iv is NULL"); + return -1; + } + + if (payload == NULL && payload_size > 0) { + ESP_LOGE(TAG, "payload is NULL but payload_size > 0"); + return -1; + } + + if (encrypted_payload == NULL) { + ESP_LOGE(TAG, "encrypted_payload is NULL"); + return -1; + } + + /* Generate nonce with random randomizer */ + ret = ble_ead_generate_nonce(iv, NULL, nonce); + if (ret != 0) { + return ret; + } + + /* Copy randomizer to the start of encrypted payload */ + memcpy(encrypted_payload, nonce, BLE_EAD_RANDOMIZER_SIZE); + + /* Encrypt: output = ciphertext + MIC */ + ret = ble_aes_ccm_encrypt(session_key, nonce, + payload, payload_size, + ble_ead_aad, BLE_EAD_AAD_SIZE, + &encrypted_payload[BLE_EAD_RANDOMIZER_SIZE], + BLE_EAD_MIC_SIZE); + + return ret; +} + +int ble_ead_decrypt(const uint8_t session_key[BLE_EAD_KEY_SIZE], + const uint8_t iv[BLE_EAD_IV_SIZE], + const uint8_t *encrypted_payload, size_t encrypted_payload_size, + uint8_t *payload) +{ + int ret; + uint8_t nonce[BLE_EAD_NONCE_SIZE]; + const uint8_t *randomizer; + const uint8_t *ciphertext; + size_t ciphertext_len; + + if (session_key == NULL) { + ESP_LOGE(TAG, "session_key is NULL"); + return -1; + } + + if (iv == NULL) { + ESP_LOGE(TAG, "iv is NULL"); + return -1; + } + + if (encrypted_payload == NULL) { + ESP_LOGE(TAG, "encrypted_payload is NULL"); + return -1; + } + + if (payload == NULL) { + ESP_LOGE(TAG, "payload is NULL"); + return -1; + } + + if (encrypted_payload_size < BLE_EAD_RANDOMIZER_SIZE + BLE_EAD_MIC_SIZE) { + ESP_LOGE(TAG, "encrypted_payload_size too small"); + return -1; + } + + /* Extract randomizer from the start of encrypted payload */ + randomizer = encrypted_payload; + + /* Ciphertext + MIC follows the randomizer */ + ciphertext = &encrypted_payload[BLE_EAD_RANDOMIZER_SIZE]; + /* ciphertext_len includes both ciphertext and MIC (tag) for PSA API */ + ciphertext_len = encrypted_payload_size - BLE_EAD_RANDOMIZER_SIZE; + + /* Generate nonce from randomizer and IV */ + ret = ble_ead_generate_nonce(iv, randomizer, nonce); + if (ret != 0) { + return ret; + } + + /* Decrypt and verify */ + ret = ble_aes_ccm_decrypt(session_key, nonce, + ciphertext, ciphertext_len, + ble_ead_aad, BLE_EAD_AAD_SIZE, + payload, BLE_EAD_MIC_SIZE); + + return ret; +} diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.h b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.h new file mode 100644 index 0000000000..a9bf8954eb --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.h @@ -0,0 +1,95 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BLE_EAD_H +#define BLE_EAD_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief BLE Encrypted Advertising Data (EAD) definitions + * Based on Bluetooth Core Specification Version 5.4 + */ + +#define BLE_EAD_KEY_SIZE 16 /* 128-bit session key */ +#define BLE_EAD_IV_SIZE 8 /* 64-bit Initialization Vector */ +#define BLE_EAD_RANDOMIZER_SIZE 5 /* 40-bit Randomizer */ +#define BLE_EAD_MIC_SIZE 4 /* 32-bit Message Integrity Check */ +#define BLE_EAD_NONCE_SIZE 13 /* 104-bit Nonce (Randomizer + IV) */ +#define BLE_EAD_AAD_SIZE 1 /* Additional Authenticated Data size */ + +/* Direction bit position in Randomizer (MSB of last byte) + * Per Bluetooth Core Spec Supplement v11, Part A 1.23.3 + */ +#define BLE_EAD_RANDOMIZER_DIRECTION_BIT 7 + +/* AD Type for Encrypted Advertising Data (0x31) */ +#define ESP_BLE_AD_TYPE_ENC_ADV_DATA 0x31 + +/** + * @brief Calculate encrypted payload size from plaintext size + */ +#define BLE_EAD_ENCRYPTED_PAYLOAD_SIZE(payload_size) \ + (BLE_EAD_RANDOMIZER_SIZE + (payload_size) + BLE_EAD_MIC_SIZE) + +/** + * @brief Calculate decrypted payload size from encrypted payload size + */ +#define BLE_EAD_DECRYPTED_PAYLOAD_SIZE(encrypted_size) \ + ((encrypted_size) - BLE_EAD_RANDOMIZER_SIZE - BLE_EAD_MIC_SIZE) + +/** + * @brief Key material structure for EAD + */ +typedef struct { + uint8_t session_key[BLE_EAD_KEY_SIZE]; /* 128-bit session key */ + uint8_t iv[BLE_EAD_IV_SIZE]; /* 64-bit Initialization Vector */ +} ble_ead_key_material_t; + +/** + * @brief Encrypt advertising data using AES-CCM + * + * @param session_key 16-byte session key + * @param iv 8-byte Initialization Vector + * @param payload Plaintext advertising data to encrypt + * @param payload_size Size of plaintext data + * @param encrypted_payload Output buffer for encrypted data + * Size must be at least BLE_EAD_ENCRYPTED_PAYLOAD_SIZE(payload_size) + * + * @return 0 on success, negative error code on failure + */ +int ble_ead_encrypt(const uint8_t session_key[BLE_EAD_KEY_SIZE], + const uint8_t iv[BLE_EAD_IV_SIZE], + const uint8_t *payload, size_t payload_size, + uint8_t *encrypted_payload); + +/** + * @brief Decrypt advertising data using AES-CCM + * + * @param session_key 16-byte session key + * @param iv 8-byte Initialization Vector + * @param encrypted_payload Encrypted advertising data (includes randomizer and MIC) + * @param encrypted_payload_size Size of encrypted data + * @param payload Output buffer for decrypted data + * Size must be at least BLE_EAD_DECRYPTED_PAYLOAD_SIZE(encrypted_payload_size) + * + * @return 0 on success, negative error code on failure + */ +int ble_ead_decrypt(const uint8_t session_key[BLE_EAD_KEY_SIZE], + const uint8_t iv[BLE_EAD_IV_SIZE], + const uint8_t *encrypted_payload, size_t encrypted_payload_size, + uint8_t *payload); + +#ifdef __cplusplus +} +#endif + +#endif /* BLE_EAD_H */ diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/enc_adv_data_prph.c b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/enc_adv_data_prph.c new file mode 100644 index 0000000000..7520bbc9d8 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/enc_adv_data_prph.c @@ -0,0 +1,353 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +/** + * @brief BLE Encrypted Advertising Data Peripheral Example + * + * This example demonstrates how to: + * 1. Encrypt advertising data using AES-CCM + * 2. Broadcast encrypted advertising data + * 3. Provide Key Material characteristic for central devices to read + * + * Based on Bluetooth Core Specification Version 5.4 - Encrypted Advertising Data + */ + +#include +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "esp_bt.h" +#include "esp_gap_ble_api.h" +#include "esp_gatts_api.h" +#include "esp_bt_defs.h" +#include "esp_bt_main.h" +#include "esp_gatt_common_api.h" +#include "ble_ead.h" + +#define TAG "ENC_ADV_PRPH" + +/* Device name */ +#define DEVICE_NAME "ENC_ADV_PRPH" +#define GAP_SERVICE_UUID 0x1800 /* GAP Service UUID */ + +/* Profile configuration */ +#define PROFILE_NUM 1 +#define PROFILE_APP_ID 0 + +/* Unencrypted advertising pattern to be encrypted */ +static uint8_t unencrypted_adv_pattern[] = { + 0x05, 0x09, 'p', 'r', 'p', 'h' /* Complete Local Name: "prph" */ +}; + +/* Session key and IV for encryption - in real application, generate securely! */ +static ble_ead_key_material_t key_material = { + .session_key = { + 0x19, 0x6a, 0x0a, 0xd1, 0x2a, 0x61, 0x20, 0x1e, + 0x13, 0x6e, 0x2e, 0xd1, 0x12, 0xda, 0xa9, 0x57 + }, + .iv = {0x9E, 0x7a, 0x00, 0xef, 0xb1, 0x7a, 0xe7, 0x46}, +}; + +/* GATT state */ +static esp_gatt_if_t gatts_if_stored = ESP_GATT_IF_NONE; +static uint16_t conn_id_stored = 0; +static bool is_connected = false; + +/* Advertising parameters */ +static esp_ble_adv_params_t adv_params = { + .adv_int_min = 0x20, + .adv_int_max = 0x40, + .adv_type = ADV_TYPE_IND, + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .channel_map = ADV_CHNL_ALL, + .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, +}; + +/* Calculate encrypted payload size */ +#define ENCRYPTED_ADV_DATA_LEN BLE_EAD_ENCRYPTED_PAYLOAD_SIZE(sizeof(unencrypted_adv_pattern)) + +/** + * @brief Encrypt advertising data and set raw advertising data + */ +static void set_encrypted_adv_data(void) +{ + esp_err_t ret; + uint8_t encrypted_adv_data[ENCRYPTED_ADV_DATA_LEN]; + int rc; + + ESP_LOGI(TAG, "Data before encryption:"); + ESP_LOG_BUFFER_HEX(TAG, unencrypted_adv_pattern, sizeof(unencrypted_adv_pattern)); + + /* Encrypt the advertising data */ + rc = ble_ead_encrypt(key_material.session_key, key_material.iv, + unencrypted_adv_pattern, sizeof(unencrypted_adv_pattern), + encrypted_adv_data); + if (rc != 0) { + ESP_LOGE(TAG, "Encryption of adv data failed: %d", rc); + return; + } + + ESP_LOGI(TAG, "Encryption of adv data done successfully"); + ESP_LOGI(TAG, "Data after encryption:"); + ESP_LOG_BUFFER_HEX(TAG, encrypted_adv_data, sizeof(encrypted_adv_data)); + + /* + * Build raw advertising data: + * - Flags (3 bytes) + * - Complete Local Name (device name) + * - Complete 16-bit Service UUIDs (for central to recognize) + * - Encrypted Advertising Data + */ + uint8_t raw_adv_data[31]; + uint8_t pos = 0; + + /* Flags */ + raw_adv_data[pos++] = 0x02; /* Length */ + raw_adv_data[pos++] = ESP_BLE_AD_TYPE_FLAG; + raw_adv_data[pos++] = ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT; + + /* Complete Local Name - "key" (short name for recognition) */ + raw_adv_data[pos++] = 0x04; /* Length */ + raw_adv_data[pos++] = ESP_BLE_AD_TYPE_NAME_CMPL; + raw_adv_data[pos++] = 'k'; + raw_adv_data[pos++] = 'e'; + raw_adv_data[pos++] = 'y'; + + /* Complete 16-bit Service UUIDs - GAP Service (0x1800) */ + raw_adv_data[pos++] = 0x03; /* Length */ + raw_adv_data[pos++] = ESP_BLE_AD_TYPE_16SRV_CMPL; + raw_adv_data[pos++] = GAP_SERVICE_UUID & 0xFF; + raw_adv_data[pos++] = (GAP_SERVICE_UUID >> 8) & 0xFF; + + /* Encrypted Advertising Data */ + raw_adv_data[pos++] = ENCRYPTED_ADV_DATA_LEN + 1; /* Length */ + raw_adv_data[pos++] = ESP_BLE_AD_TYPE_ENC_ADV_DATA; + memcpy(&raw_adv_data[pos], encrypted_adv_data, ENCRYPTED_ADV_DATA_LEN); + pos += ENCRYPTED_ADV_DATA_LEN; + + /* Set raw advertising data */ + ret = esp_ble_gap_config_adv_data_raw(raw_adv_data, pos); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "config raw adv data failed: %s", esp_err_to_name(ret)); + } +} + +/** + * @brief Start advertising + */ +static void start_advertising(void) +{ + esp_err_t ret = esp_ble_gap_start_advertising(&adv_params); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "start advertising failed: %s", esp_err_to_name(ret)); + } +} + +/** + * @brief GAP event handler + */ +static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) +{ + switch (event) { + case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: + ESP_LOGI(TAG, "Raw advertising data set complete"); + start_advertising(); + break; + + case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: + if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { + ESP_LOGE(TAG, "Advertising start failed: %d", param->adv_start_cmpl.status); + } else { + ESP_LOGI(TAG, "Advertising start successfully"); + } + break; + + case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: + if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) { + ESP_LOGE(TAG, "Advertising stop failed: %d", param->adv_stop_cmpl.status); + } else { + ESP_LOGI(TAG, "Advertising stop successfully"); + } + break; + + case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: + ESP_LOGI(TAG, "Connection params update, status %d, conn_int %d, latency %d, timeout %d", + param->update_conn_params.status, + param->update_conn_params.conn_int, + param->update_conn_params.latency, + param->update_conn_params.timeout); + break; + + case ESP_GAP_BLE_SEC_REQ_EVT: + ESP_LOGI(TAG, "Security request received"); + esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true); + break; + + case ESP_GAP_BLE_AUTH_CMPL_EVT: + ESP_LOGI(TAG, "Authentication complete, addr_type %d, addr "ESP_BD_ADDR_STR"", + param->ble_security.auth_cmpl.addr_type, + ESP_BD_ADDR_HEX(param->ble_security.auth_cmpl.bd_addr)); + if (param->ble_security.auth_cmpl.success) { + ESP_LOGI(TAG, "Authentication success, auth_mode %d", param->ble_security.auth_cmpl.auth_mode); + } else { + ESP_LOGW(TAG, "Authentication failed, reason 0x%x", param->ble_security.auth_cmpl.fail_reason); + } + break; + + default: + break; + } +} + +/** + * @brief GATTS profile event handler + */ +static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, + esp_ble_gatts_cb_param_t *param) +{ + switch (event) { + case ESP_GATTS_REG_EVT: + ESP_LOGI(TAG, "GATT server register, status %d, app_id %d, gatts_if %d", + param->reg.status, param->reg.app_id, gatts_if); + gatts_if_stored = gatts_if; + + /* Set device name */ + esp_ble_gap_set_device_name(DEVICE_NAME); + + /* Set encrypted advertising data */ + set_encrypted_adv_data(); + + /* Set Key Material in GAP service + * The Key Material characteristic is part of the built-in GAP service + */ + ESP_LOGI(TAG, "Setting Key Material in GAP service"); + esp_ble_gap_set_key_material(key_material.session_key, key_material.iv); + break; + + case ESP_GATTS_CONNECT_EVT: + ESP_LOGI(TAG, "Connected, conn_id %d, remote "ESP_BD_ADDR_STR"", + param->connect.conn_id, ESP_BD_ADDR_HEX(param->connect.remote_bda)); + conn_id_stored = param->connect.conn_id; + is_connected = true; + + /* Update connection parameters */ + esp_ble_conn_update_params_t conn_params = {0}; + memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t)); + conn_params.latency = 0; + conn_params.max_int = 0x20; + conn_params.min_int = 0x10; + conn_params.timeout = 400; + esp_ble_gap_update_conn_params(&conn_params); + break; + + case ESP_GATTS_DISCONNECT_EVT: + ESP_LOGI(TAG, "Disconnected, remote "ESP_BD_ADDR_STR", reason 0x%02x", + ESP_BD_ADDR_HEX(param->disconnect.remote_bda), param->disconnect.reason); + is_connected = false; + + /* Re-encrypt and restart advertising with new randomizer */ + set_encrypted_adv_data(); + break; + + case ESP_GATTS_MTU_EVT: + ESP_LOGI(TAG, "MTU exchange, MTU %d", param->mtu.mtu); + break; + + default: + break; + } +} + +void app_main(void) +{ + esp_err_t ret; + + /* Initialize NVS */ + 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); + + /* Release memory for Classic BT */ + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); + + /* Initialize BT controller */ + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(TAG, "initialize controller failed: %s", esp_err_to_name(ret)); + return; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (ret) { + ESP_LOGE(TAG, "enable controller failed: %s", esp_err_to_name(ret)); + return; + } + + /* Initialize Bluedroid */ + esp_bluedroid_config_t cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT(); + ret = esp_bluedroid_init_with_cfg(&cfg); + if (ret) { + ESP_LOGE(TAG, "init bluetooth failed: %s", esp_err_to_name(ret)); + return; + } + + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(TAG, "enable bluetooth failed: %s", esp_err_to_name(ret)); + return; + } + + /* Register callbacks */ + ret = esp_ble_gatts_register_callback(gatts_event_handler); + if (ret) { + ESP_LOGE(TAG, "gatts register error: %x", ret); + return; + } + + ret = esp_ble_gap_register_callback(gap_event_handler); + if (ret) { + ESP_LOGE(TAG, "gap register error: %x", ret); + return; + } + + /* Register GATT application */ + ret = esp_ble_gatts_app_register(PROFILE_APP_ID); + if (ret) { + ESP_LOGE(TAG, "gatts app register error: %x", ret); + return; + } + + /* Set MTU */ + esp_ble_gatt_set_local_mtu(500); + + /* Configure security parameters for Key Material characteristic access + * Using SC (Secure Connections) with bonding, no MITM (since IO_CAP is NONE) + */ + esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_BOND; /* SC + Bond, no MITM */ + esp_ble_io_cap_t io_cap = ESP_IO_CAP_NONE; + uint8_t key_size = 16; + uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK; + uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK; + + esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(auth_req)); + esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &io_cap, sizeof(io_cap)); + esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(key_size)); + esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(init_key)); + esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(rsp_key)); + + ESP_LOGI(TAG, "Encrypted Advertising Data Peripheral started"); + ESP_LOGI(TAG, "Key Material (Session Key + IV):"); + ESP_LOG_BUFFER_HEX(TAG, &key_material, sizeof(key_material)); +} diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/sdkconfig.defaults b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/sdkconfig.defaults new file mode 100644 index 0000000000..ae0ee30898 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/sdkconfig.defaults @@ -0,0 +1,13 @@ +# Enable BLE +CONFIG_BT_ENABLED=y +CONFIG_BT_BLUEDROID_ENABLED=y +CONFIG_BT_BLE_ENABLED=y +CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y +# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set + +# Enable SMP for security +CONFIG_BT_BLE_SMP_ENABLE=y + +# Select crypto library for EAD (Encrypted Advertising Data) +# Options: CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT or CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS +CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT=y From a48590a9f45d17d8a8199c485352ae02b17dcac1 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Mon, 5 Jan 2026 11:23:31 +0800 Subject: [PATCH 087/226] fix(ble/bluedroid): Replaced the psa_ api with the mbedtls_ api --- .../bt/host/bluedroid/stack/smp/smp_act.c | 54 +++-- .../bt/host/bluedroid/stack/smp/smp_cmac.c | 114 ++++------ .../bt/host/bluedroid/stack/smp/smp_keys.c | 200 +++++++++++------- .../enc_adv_data_cent/main/ble_ead.c | 110 ++++------ .../enc_adv_data_prph/main/ble_ead.c | 110 ++++------ 5 files changed, 281 insertions(+), 307 deletions(-) diff --git a/components/bt/host/bluedroid/stack/smp/smp_act.c b/components/bt/host/bluedroid/stack/smp/smp_act.c index e6cbc9c02b..3580dde427 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_act.c +++ b/components/bt/host/bluedroid/stack/smp/smp_act.c @@ -23,7 +23,7 @@ #include "stack/l2c_api.h" #include "smp_int.h" #if (SMP_CRYPTO_MBEDTLS == TRUE) -#include "psa/crypto.h" +#include "mbedtls/ecp.h" #elif (SMP_CRYPTO_TINYCRYPT == TRUE) #include "tinycrypt/ecc_dh.h" #include "tinycrypt/ecc.h" @@ -786,15 +786,27 @@ void smp_process_pairing_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) #if (SMP_CRYPTO_MBEDTLS == TRUE) { /* - * PSA Crypto validates the public key when importing. - * We try to import the peer's public key as a ECC public key. - * If import fails, the key is invalid. + * mbedTLS validates the public key using mbedtls_ecp_check_pubkey. */ - psa_status_t status; - psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; + mbedtls_ecp_group grp = {0}; + mbedtls_ecp_point pt = {0}; + int rc; UINT8 pub_be[BT_OCTET32_LEN + BT_OCTET32_LEN + 1]; /* 0x04 || X (32 bytes) || Y (32 bytes) */ + mbedtls_ecp_group_init(&grp); + mbedtls_ecp_point_init(&pt); + + /* Load the group */ + rc = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1); + if (rc != 0) { + SMP_TRACE_ERROR("%s, Invalid Public key. mbedtls_ecp_group_load failed: %d\n", __func__, rc); + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); + reason = SMP_INVALID_PARAMETERS; + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + return; + } + /* Construct peer public key in uncompressed format (0x04 || X || Y) */ pub_be[0] = 0x04; for (int i = 0; i < BT_OCTET32_LEN; i++) { @@ -802,23 +814,31 @@ void smp_process_pairing_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) pub_be[33 + i] = p_cb->peer_publ_key.y[BT_OCTET32_LEN - 1 - i]; } - /* Try to import as public key - PSA will validate it's on the curve */ - psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)); - psa_set_key_bits(&key_attributes, 256); - psa_set_key_usage_flags(&key_attributes, 0); /* No usage needed, just validating */ + /* Read public key */ + rc = mbedtls_ecp_point_read_binary(&grp, &pt, pub_be, sizeof(pub_be)); + if (rc != 0) { + SMP_TRACE_ERROR("%s, Invalid Public key. mbedtls_ecp_point_read_binary failed: %d\n", __func__, rc); + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); + reason = SMP_INVALID_PARAMETERS; + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + return; + } - status = psa_import_key(&key_attributes, pub_be, sizeof(pub_be), &key_id); - psa_reset_key_attributes(&key_attributes); - - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("%s, Invalid Public key. psa_import_key failed: %d\n", __func__, status); + /* Validate public key - check if it's on the curve */ + rc = mbedtls_ecp_check_pubkey(&grp, &pt); + if (rc != 0) { + SMP_TRACE_ERROR("%s, Invalid Public key. mbedtls_ecp_check_pubkey failed: %d\n", __func__, rc); + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); reason = SMP_INVALID_PARAMETERS; smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); return; } /* Key is valid, clean up */ - psa_destroy_key(key_id); + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); } #elif (SMP_CRYPTO_TINYCRYPT == TRUE) { diff --git a/components/bt/host/bluedroid/stack/smp/smp_cmac.c b/components/bt/host/bluedroid/stack/smp/smp_cmac.c index fd10e50760..b097a05d23 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_cmac.c +++ b/components/bt/host/bluedroid/stack/smp/smp_cmac.c @@ -33,7 +33,8 @@ #include "smp_int.h" #include "stack/hcimsgs.h" #if (SMP_CRYPTO_MBEDTLS == TRUE) -#include "psa/crypto.h" +#include "mbedtls/cipher.h" +#include "mbedtls/cmac.h" #elif (SMP_CRYPTO_TINYCRYPT == TRUE) #include "tinycrypt/aes.h" #include "tinycrypt/cmac_mode.h" @@ -307,92 +308,65 @@ BOOLEAN aes_cipher_msg_auth_code(BT_OCTET16 key, UINT8 *input, UINT16 length, #if (SMP_CRYPTO_MBEDTLS == TRUE) { /* - * PSA Crypto CMAC implementation. - * Bluedroid uses little-endian, PSA uses big-endian. - * We reverse the key and input, then reverse the output. + * mbedTLS CMAC implementation. + * Bluedroid and mbedTLS both use little-endian, so no byte order conversion needed. */ - psa_status_t status; - psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; - UINT8 key_be[BT_OCTET16_LEN]; - UINT8 *input_be = NULL; - UINT8 mac_be[BT_OCTET16_LEN]; - size_t mac_len = 0; + mbedtls_cipher_context_t ctx = {0}; + const mbedtls_cipher_info_t *cipher_info; + int rc; - SMP_TRACE_DEBUG("AES128_CMAC (PSA) started, length = %d", length); + SMP_TRACE_DEBUG("AES128_CMAC (mbedTLS) started, length = %d", length); - /* Convert key from little-endian to big-endian */ - for (int i = 0; i < BT_OCTET16_LEN; i++) { - key_be[i] = key[BT_OCTET16_LEN - 1 - i]; + mbedtls_cipher_init(&ctx); + + cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); + if (cipher_info == NULL) { + SMP_TRACE_ERROR("mbedtls_cipher_info_from_type failed"); + mbedtls_cipher_free(&ctx); + return FALSE; } - /* Allocate and convert input from little-endian to big-endian */ - if (length > 0) { - input_be = (UINT8 *)osi_malloc(length); - if (input_be == NULL) { - SMP_TRACE_ERROR("No resources for input_be"); + rc = mbedtls_cipher_setup(&ctx, cipher_info); + if (rc != 0) { + SMP_TRACE_ERROR("mbedtls_cipher_setup failed: %d", rc); + mbedtls_cipher_free(&ctx); + return FALSE; + } + + rc = mbedtls_cipher_cmac_starts(&ctx, key, 128); + if (rc != 0) { + SMP_TRACE_ERROR("mbedtls_cipher_cmac_starts failed: %d", rc); + mbedtls_cipher_free(&ctx); + return FALSE; + } + + if (length > 0 && input != NULL) { + rc = mbedtls_cipher_cmac_update(&ctx, input, length); + if (rc != 0) { + SMP_TRACE_ERROR("mbedtls_cipher_cmac_update failed: %d", rc); + mbedtls_cipher_free(&ctx); return FALSE; } - for (UINT16 i = 0; i < length; i++) { - input_be[i] = input[length - 1 - i]; - } } - /* Import the key */ - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_MESSAGE); - psa_set_key_algorithm(&key_attributes, PSA_ALG_CMAC); - psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); - psa_set_key_bits(&key_attributes, 128); + UINT8 mac[BT_OCTET16_LEN]; + rc = mbedtls_cipher_cmac_finish(&ctx, mac); + mbedtls_cipher_free(&ctx); - status = psa_import_key(&key_attributes, key_be, BT_OCTET16_LEN, &key_id); - psa_reset_key_attributes(&key_attributes); - - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("psa_import_key failed: %d", status); - if (input_be) osi_free(input_be); + if (rc != 0) { + SMP_TRACE_ERROR("mbedtls_cipher_cmac_finish failed: %d", rc); + /* Clear sensitive data from stack */ + memset(mac, 0, sizeof(mac)); return FALSE; } - /* Setup MAC operation */ - status = psa_mac_sign_setup(&operation, key_id, PSA_ALG_CMAC); - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("psa_mac_sign_setup failed: %d", status); - psa_destroy_key(key_id); - if (input_be) osi_free(input_be); - return FALSE; - } - - /* Update with input data */ - if (length > 0 && input_be != NULL) { - status = psa_mac_update(&operation, input_be, length); - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("psa_mac_update failed: %d", status); - psa_mac_abort(&operation); - psa_destroy_key(key_id); - osi_free(input_be); - return FALSE; - } - osi_free(input_be); - } - - /* Finish and get MAC */ - status = psa_mac_sign_finish(&operation, mac_be, sizeof(mac_be), &mac_len); - psa_destroy_key(key_id); - - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("psa_mac_sign_finish failed: %d", status); - psa_mac_abort(&operation); - return FALSE; - } - - /* Convert MAC from big-endian to little-endian and truncate to tlen bytes */ + /* Truncate to tlen bytes */ for (UINT16 i = 0; i < tlen && i < BT_OCTET16_LEN; i++) { - p_signature[i] = mac_be[BT_OCTET16_LEN - 1 - i]; + p_signature[i] = mac[i]; } /* Clear sensitive data from stack */ - memset(key_be, 0, sizeof(key_be)); + memset(mac, 0, sizeof(mac)); ret = TRUE; } diff --git a/components/bt/host/bluedroid/stack/smp/smp_keys.c b/components/bt/host/bluedroid/stack/smp/smp_keys.c index ee57dcad62..9c0fcfd52a 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_keys.c +++ b/components/bt/host/bluedroid/stack/smp/smp_keys.c @@ -35,7 +35,18 @@ #include "btm_ble_int.h" #include "stack/hcimsgs.h" #if (SMP_CRYPTO_MBEDTLS == TRUE) -#include "psa/crypto.h" +#include "mbedtls/aes.h" +#include "mbedtls/ecdh.h" +#include "mbedtls/ecp.h" +#include "esp_random.h" + +/* Random number generator function for mbedTLS ECP operations */ +static int smp_mbedtls_rng(void *ctx, unsigned char *output, size_t len) +{ + (void)ctx; /* Unused parameter */ + esp_fill_random(output, len); + return 0; +} #elif (SMP_CRYPTO_TINYCRYPT == TRUE) #include "tinycrypt/aes.h" #include "tinycrypt/cmac_mode.h" @@ -206,31 +217,28 @@ BOOLEAN smp_encrypt_data (UINT8 *key, UINT8 key_len, #if (SMP_CRYPTO_MBEDTLS == TRUE) { - psa_status_t status; - psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - size_t output_len = 0; + mbedtls_aes_context ctx = {0}; + int rc; - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT); - psa_set_key_algorithm(&key_attributes, PSA_ALG_ECB_NO_PADDING); - psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); - psa_set_key_bits(&key_attributes, 128); + mbedtls_aes_init(&ctx); - status = psa_import_key(&key_attributes, p_rev_key, SMP_ENCRYT_KEY_SIZE, &key_id); - psa_reset_key_attributes(&key_attributes); - - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("%s psa_import_key failed: %d\n", __func__, status); + rc = mbedtls_aes_setkey_enc(&ctx, p_rev_key, 128); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_aes_setkey_enc failed: %d\n", __func__, rc); + mbedtls_aes_free(&ctx); + /* Clear sensitive data before freeing */ + memset(p_start, 0, SMP_ENCRYT_DATA_SIZE * 4); osi_free(p_start); return FALSE; } - status = psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING, p_rev_data, - SMP_ENCRYT_DATA_SIZE, p_rev_output, SMP_ENCRYT_DATA_SIZE, &output_len); - psa_destroy_key(key_id); + rc = mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, p_rev_data, p_rev_output); + mbedtls_aes_free(&ctx); - if (status != PSA_SUCCESS || output_len != SMP_ENCRYT_DATA_SIZE) { - SMP_TRACE_ERROR("%s psa_cipher_encrypt failed: %d\n", __func__, status); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_aes_crypt_ecb failed: %d\n", __func__, rc); + /* Clear sensitive data before freeing */ + memset(p_start, 0, SMP_ENCRYT_DATA_SIZE * 4); osi_free(p_start); return FALSE; } @@ -1200,37 +1208,48 @@ void smp_process_private_key(tSMP_CB *p_cb) memcpy(p_cb->local_random, p_loc_oob->randomizer, BT_OCTET16_LEN); } else { #if (SMP_CRYPTO_MBEDTLS == TRUE) - psa_status_t status; - psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - UINT8 priv_be[BT_OCTET32_LEN]; - UINT8 pub_be[BT_OCTET32_LEN + BT_OCTET32_LEN + 1]; /* 0x04 || X (32 bytes) || Y (32 bytes) */ - size_t pub_len = 0; + mbedtls_ecp_keypair keypair = {0}; + int rc; + size_t olen; - /* Convert private key from little-endian to big-endian */ - for (int i = 0; i < BT_OCTET32_LEN; i++) { - priv_be[i] = p_cb->private_key[BT_OCTET32_LEN - 1 - i]; + mbedtls_ecp_keypair_init(&keypair); + + /* Load the group */ + rc = mbedtls_ecp_group_load(&keypair.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_ecp_group_load failed: %d\n", __FUNCTION__, rc); + goto mbedtls_pubkey_cleanup; } - /* Import the private key */ - psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); - psa_set_key_bits(&key_attributes, 256); - psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT); - - status = psa_import_key(&key_attributes, priv_be, BT_OCTET32_LEN, &key_id); - psa_reset_key_attributes(&key_attributes); - - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("%s psa_import_key failed: %d\n", __FUNCTION__, status); - goto psa_pubkey_cleanup; + /* Import private key (little-endian) */ + rc = mbedtls_mpi_read_binary(&keypair.MBEDTLS_PRIVATE(d), p_cb->private_key, BT_OCTET32_LEN); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_mpi_read_binary failed: %d\n", __FUNCTION__, rc); + goto mbedtls_pubkey_cleanup; } - /* Export public key */ - status = psa_export_public_key(key_id, pub_be, sizeof(pub_be), &pub_len); - if (status != PSA_SUCCESS || pub_len != (BT_OCTET32_LEN + BT_OCTET32_LEN + 1)) { - SMP_TRACE_ERROR("%s psa_export_public_key failed: %d\n", __FUNCTION__, status); - goto psa_pubkey_cleanup; + /* Validate private key */ + rc = mbedtls_ecp_check_privkey(&keypair.MBEDTLS_PRIVATE(grp), &keypair.MBEDTLS_PRIVATE(d)); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_ecp_check_privkey failed: %d\n", __FUNCTION__, rc); + goto mbedtls_pubkey_cleanup; + } + + /* Compute public key from private key */ + /* mbedtls_ecp_keypair_calc_public requires a non-NULL RNG function for side-channel protection */ + rc = mbedtls_ecp_keypair_calc_public(&keypair, smp_mbedtls_rng, NULL); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_ecp_keypair_calc_public failed: %d\n", __FUNCTION__, rc); + goto mbedtls_pubkey_cleanup; + } + + /* Export public key in uncompressed format: 0x04 || X || Y */ + UINT8 pub_be[BT_OCTET32_LEN + BT_OCTET32_LEN + 1]; + rc = mbedtls_ecp_point_write_binary(&keypair.MBEDTLS_PRIVATE(grp), &keypair.MBEDTLS_PRIVATE(Q), + MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, pub_be, sizeof(pub_be)); + if (rc != 0 || olen != sizeof(pub_be)) { + SMP_TRACE_ERROR("%s mbedtls_ecp_point_write_binary failed: %d\n", __FUNCTION__, rc); + goto mbedtls_pubkey_cleanup; } /* Convert X and Y from big-endian to little-endian */ @@ -1240,10 +1259,10 @@ void smp_process_private_key(tSMP_CB *p_cb) p_cb->loc_publ_key.y[i] = pub_be[33 + BT_OCTET32_LEN - 1 - i]; } -psa_pubkey_cleanup: - psa_destroy_key(key_id); - /* Clear sensitive data from stack */ - memset(priv_be, 0, sizeof(priv_be)); +mbedtls_pubkey_cleanup: + /* Clear sensitive data - mbedtls_ecp_keypair_free will zero the private key */ + mbedtls_ecp_keypair_free(&keypair); + /* Note: pub_be contains public key data, no need to clear */ #elif (SMP_CRYPTO_TINYCRYPT == TRUE) { UINT8 pub_key[64]; /* TinyCrypt format: X (32 bytes) || Y (32 bytes), no prefix */ @@ -1312,31 +1331,30 @@ void smp_compute_dhkey (tSMP_CB *p_cb) SMP_TRACE_DEBUG ("%s\n", __FUNCTION__); #if (SMP_CRYPTO_MBEDTLS == TRUE) - psa_status_t status; - psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - UINT8 priv_be[BT_OCTET32_LEN]; + mbedtls_ecp_group grp = {0}; + mbedtls_ecp_point Q = {0}; + mbedtls_mpi d = {0}; + mbedtls_mpi z = {0}; + int rc; UINT8 peer_pub_be[BT_OCTET32_LEN + BT_OCTET32_LEN + 1]; /* 0x04 || X (32 bytes) || Y (32 bytes) */ - UINT8 shared_secret[BT_OCTET32_LEN]; - size_t output_len = 0; - /* Convert private key from little-endian to big-endian */ - for (int i = 0; i < BT_OCTET32_LEN; i++) { - priv_be[i] = p_cb->private_key[BT_OCTET32_LEN - 1 - i]; + mbedtls_ecp_group_init(&grp); + mbedtls_ecp_point_init(&Q); + mbedtls_mpi_init(&d); + mbedtls_mpi_init(&z); + + /* Load the group */ + rc = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_ecp_group_load failed: %d\n", __FUNCTION__, rc); + goto mbedtls_dhkey_cleanup; } - /* Import the private key */ - psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); - psa_set_key_bits(&key_attributes, 256); - psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); - - status = psa_import_key(&key_attributes, priv_be, BT_OCTET32_LEN, &key_id); - psa_reset_key_attributes(&key_attributes); - - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("%s psa_import_key failed: %d\n", __FUNCTION__, status); - goto psa_dhkey_cleanup; + /* Import private key (little-endian) */ + rc = mbedtls_mpi_read_binary(&d, p_cb->private_key, BT_OCTET32_LEN); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_mpi_read_binary failed: %d\n", __FUNCTION__, rc); + goto mbedtls_dhkey_cleanup; } /* Construct peer public key in uncompressed format: 0x04 || X || Y */ @@ -1346,12 +1364,34 @@ void smp_compute_dhkey (tSMP_CB *p_cb) peer_pub_be[33 + i] = p_cb->peer_publ_key.y[BT_OCTET32_LEN - 1 - i]; } + /* Read peer public key */ + rc = mbedtls_ecp_point_read_binary(&grp, &Q, peer_pub_be, sizeof(peer_pub_be)); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_ecp_point_read_binary failed: %d\n", __FUNCTION__, rc); + goto mbedtls_dhkey_cleanup; + } + + /* Validate peer public key */ + rc = mbedtls_ecp_check_pubkey(&grp, &Q); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_ecp_check_pubkey failed: %d\n", __FUNCTION__, rc); + goto mbedtls_dhkey_cleanup; + } + /* Compute ECDH shared secret */ - status = psa_raw_key_agreement(PSA_ALG_ECDH, key_id, peer_pub_be, sizeof(peer_pub_be), - shared_secret, sizeof(shared_secret), &output_len); - if (status != PSA_SUCCESS || output_len != BT_OCTET32_LEN) { - SMP_TRACE_ERROR("%s psa_raw_key_agreement failed: %d\n", __FUNCTION__, status); - goto psa_dhkey_cleanup; + /* mbedtls_ecdh_compute_shared requires a non-NULL RNG function for side-channel protection */ + rc = mbedtls_ecdh_compute_shared(&grp, &z, &Q, &d, smp_mbedtls_rng, NULL); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_ecdh_compute_shared failed: %d\n", __FUNCTION__, rc); + goto mbedtls_dhkey_cleanup; + } + + /* Export shared secret (big-endian) and convert to little-endian for DHKey */ + UINT8 shared_secret[BT_OCTET32_LEN]; + rc = mbedtls_mpi_write_binary(&z, shared_secret, BT_OCTET32_LEN); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_mpi_write_binary failed: %d\n", __FUNCTION__, rc); + goto mbedtls_dhkey_cleanup; } /* Convert shared secret from big-endian to little-endian for DHKey */ @@ -1359,11 +1399,15 @@ void smp_compute_dhkey (tSMP_CB *p_cb) p_cb->dhkey[i] = shared_secret[BT_OCTET32_LEN - 1 - i]; } -psa_dhkey_cleanup: - psa_destroy_key(key_id); +mbedtls_dhkey_cleanup: + /* Clear sensitive data - mbedtls_mpi_free will zero the memory */ + mbedtls_mpi_free(&z); + mbedtls_mpi_free(&d); + mbedtls_ecp_point_free(&Q); + mbedtls_ecp_group_free(&grp); /* Clear sensitive data from stack */ - memset(priv_be, 0, sizeof(priv_be)); memset(shared_secret, 0, sizeof(shared_secret)); + /* Note: peer_pub_be contains public key data, no need to clear */ #elif (SMP_CRYPTO_TINYCRYPT == TRUE) { UINT8 priv_be[BT_OCTET32_LEN]; diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.c b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.c index 7303c027b2..92420dd406 100644 --- a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.c +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,7 +18,7 @@ #include "tinycrypt/ccm_mode.h" #include "tinycrypt/constants.h" #elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) -#include "psa/crypto.h" +#include "mbedtls/ccm.h" #else #error "Please select either CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT or CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS" #endif @@ -129,11 +129,8 @@ static int ble_aes_ccm_encrypt(const uint8_t *key, const uint8_t *nonce, return 0; #elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) - psa_status_t status; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_len); - size_t output_length = 0; + mbedtls_ccm_context ctx = {0}; + int ret; /* Validate inputs */ if (key == NULL || nonce == NULL || ciphertext == NULL) { @@ -141,43 +138,30 @@ static int ble_aes_ccm_encrypt(const uint8_t *key, const uint8_t *nonce, return -1; } - /* Set key attributes */ - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); - psa_set_key_algorithm(&attributes, alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); - psa_set_key_bits(&attributes, BLE_EAD_KEY_SIZE * 8); + mbedtls_ccm_init(&ctx); - /* Import key */ - status = psa_import_key(&attributes, key, BLE_EAD_KEY_SIZE, &key_id); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_import_key failed: %d", status); - psa_reset_key_attributes(&attributes); + /* Set encryption key */ + ret = mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, BLE_EAD_KEY_SIZE * 8); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_setkey failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - psa_reset_key_attributes(&attributes); /* Encrypt and authenticate */ - /* PSA AEAD encrypt outputs: ciphertext || tag */ - status = psa_aead_encrypt(key_id, alg, - nonce, BLE_EAD_NONCE_SIZE, - aad, aad_len, - plaintext, plaintext_len, - ciphertext, plaintext_len + tag_len, - &output_length); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_aead_encrypt failed: %d", status); - psa_destroy_key(key_id); + /* mbedtls_ccm_encrypt_and_tag outputs: ciphertext || tag */ + ret = mbedtls_ccm_encrypt_and_tag(&ctx, plaintext_len, + nonce, BLE_EAD_NONCE_SIZE, + aad, aad_len, + plaintext, ciphertext, + ciphertext + plaintext_len, tag_len); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_encrypt_and_tag failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - if (output_length != plaintext_len + tag_len) { - ESP_LOGE(TAG, "psa_aead_encrypt output length mismatch: expected %zu, got %zu", - plaintext_len + tag_len, output_length); - psa_destroy_key(key_id); - return -1; - } - - psa_destroy_key(key_id); + mbedtls_ccm_free(&ctx); return 0; #else #error "No crypto library selected" @@ -253,11 +237,8 @@ static int ble_aes_ccm_decrypt(const uint8_t *key, const uint8_t *nonce, return 0; #elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) - psa_status_t status; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_len); - size_t output_length = 0; + mbedtls_ccm_context ctx = {0}; + int ret; /* ciphertext_len here includes both ciphertext and tag */ size_t plaintext_len; @@ -275,44 +256,31 @@ static int ble_aes_ccm_decrypt(const uint8_t *key, const uint8_t *nonce, plaintext_len = ciphertext_len - tag_len; - /* Set key attributes */ - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); - psa_set_key_algorithm(&attributes, alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); - psa_set_key_bits(&attributes, BLE_EAD_KEY_SIZE * 8); + mbedtls_ccm_init(&ctx); - /* Import key */ - status = psa_import_key(&attributes, key, BLE_EAD_KEY_SIZE, &key_id); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_import_key failed: %d", status); - psa_reset_key_attributes(&attributes); + /* Set decryption key */ + ret = mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, BLE_EAD_KEY_SIZE * 8); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_setkey failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - psa_reset_key_attributes(&attributes); /* Decrypt and verify */ - /* PSA AEAD decrypt expects: ciphertext || tag */ + /* mbedtls_ccm_auth_decrypt expects: ciphertext || tag */ /* ciphertext_len here already includes tag length */ - status = psa_aead_decrypt(key_id, alg, - nonce, BLE_EAD_NONCE_SIZE, - aad, aad_len, - ciphertext, ciphertext_len, - plaintext, plaintext_len, - &output_length); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_aead_decrypt failed: %d", status); - psa_destroy_key(key_id); + ret = mbedtls_ccm_auth_decrypt(&ctx, plaintext_len, + nonce, BLE_EAD_NONCE_SIZE, + aad, aad_len, + ciphertext, plaintext, + ciphertext + plaintext_len, tag_len); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_auth_decrypt failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - if (output_length != plaintext_len) { - ESP_LOGE(TAG, "psa_aead_decrypt output length mismatch: expected %zu, got %zu", - plaintext_len, output_length); - psa_destroy_key(key_id); - return -1; - } - - psa_destroy_key(key_id); + mbedtls_ccm_free(&ctx); return 0; #else #error "No crypto library selected" @@ -407,7 +375,7 @@ int ble_ead_decrypt(const uint8_t session_key[BLE_EAD_KEY_SIZE], /* Ciphertext + MIC follows the randomizer */ ciphertext = &encrypted_payload[BLE_EAD_RANDOMIZER_SIZE]; - /* ciphertext_len includes both ciphertext and MIC (tag) for PSA API */ + /* ciphertext_len includes both ciphertext and MIC (tag) for mbedTLS API */ ciphertext_len = encrypted_payload_size - BLE_EAD_RANDOMIZER_SIZE; /* Generate nonce from randomizer and IV */ diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.c b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.c index b3e1dcc8f8..cc0abeca1d 100644 --- a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.c +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,7 +18,7 @@ #include "tinycrypt/ccm_mode.h" #include "tinycrypt/constants.h" #elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) -#include "psa/crypto.h" +#include "mbedtls/ccm.h" #else #error "Please select either CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT or CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS" #endif @@ -129,49 +129,33 @@ static int ble_aes_ccm_encrypt(const uint8_t *key, const uint8_t *nonce, return 0; #elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) - psa_status_t status; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_len); - size_t output_length = 0; + mbedtls_ccm_context ctx = {0}; + int ret; - /* Set key attributes */ - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); - psa_set_key_algorithm(&attributes, alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); - psa_set_key_bits(&attributes, BLE_EAD_KEY_SIZE * 8); + mbedtls_ccm_init(&ctx); - /* Import key */ - status = psa_import_key(&attributes, key, BLE_EAD_KEY_SIZE, &key_id); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_import_key failed: %d", status); - psa_reset_key_attributes(&attributes); + /* Set encryption key */ + ret = mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, BLE_EAD_KEY_SIZE * 8); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_setkey failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - psa_reset_key_attributes(&attributes); /* Encrypt and authenticate */ - /* PSA AEAD encrypt outputs: ciphertext || tag */ - status = psa_aead_encrypt(key_id, alg, - nonce, BLE_EAD_NONCE_SIZE, - aad, aad_len, - plaintext, plaintext_len, - ciphertext, plaintext_len + tag_len, - &output_length); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_aead_encrypt failed: %d", status); - psa_destroy_key(key_id); + /* mbedtls_ccm_encrypt_and_tag outputs: ciphertext || tag */ + ret = mbedtls_ccm_encrypt_and_tag(&ctx, plaintext_len, + nonce, BLE_EAD_NONCE_SIZE, + aad, aad_len, + plaintext, ciphertext, + ciphertext + plaintext_len, tag_len); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_encrypt_and_tag failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - if (output_length != plaintext_len + tag_len) { - ESP_LOGE(TAG, "psa_aead_encrypt output length mismatch: expected %zu, got %zu", - plaintext_len + tag_len, output_length); - psa_destroy_key(key_id); - return -1; - } - - psa_destroy_key(key_id); + mbedtls_ccm_free(&ctx); return 0; #else #error "No crypto library selected" @@ -247,11 +231,8 @@ static int ble_aes_ccm_decrypt(const uint8_t *key, const uint8_t *nonce, return 0; #elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) - psa_status_t status; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_len); - size_t output_length = 0; + mbedtls_ccm_context ctx = {0}; + int ret; /* ciphertext_len here includes both ciphertext and tag */ size_t plaintext_len; @@ -269,43 +250,30 @@ static int ble_aes_ccm_decrypt(const uint8_t *key, const uint8_t *nonce, plaintext_len = ciphertext_len - tag_len; - /* Set key attributes */ - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); - psa_set_key_algorithm(&attributes, alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); - psa_set_key_bits(&attributes, BLE_EAD_KEY_SIZE * 8); + mbedtls_ccm_init(&ctx); - /* Import key */ - status = psa_import_key(&attributes, key, BLE_EAD_KEY_SIZE, &key_id); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_import_key failed: %d", status); - psa_reset_key_attributes(&attributes); + /* Set decryption key */ + ret = mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, BLE_EAD_KEY_SIZE * 8); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_setkey failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - psa_reset_key_attributes(&attributes); /* Decrypt and verify */ - /* PSA AEAD decrypt expects: ciphertext || tag */ - status = psa_aead_decrypt(key_id, alg, - nonce, BLE_EAD_NONCE_SIZE, - aad, aad_len, - ciphertext, ciphertext_len, - plaintext, plaintext_len, - &output_length); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_aead_decrypt failed: %d", status); - psa_destroy_key(key_id); + /* mbedtls_ccm_auth_decrypt expects: ciphertext || tag */ + ret = mbedtls_ccm_auth_decrypt(&ctx, plaintext_len, + nonce, BLE_EAD_NONCE_SIZE, + aad, aad_len, + ciphertext, plaintext, + ciphertext + plaintext_len, tag_len); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_auth_decrypt failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - if (output_length != plaintext_len) { - ESP_LOGE(TAG, "psa_aead_decrypt output length mismatch: expected %zu, got %zu", - plaintext_len, output_length); - psa_destroy_key(key_id); - return -1; - } - - psa_destroy_key(key_id); + mbedtls_ccm_free(&ctx); return 0; #else #error "No crypto library selected" @@ -400,7 +368,7 @@ int ble_ead_decrypt(const uint8_t session_key[BLE_EAD_KEY_SIZE], /* Ciphertext + MIC follows the randomizer */ ciphertext = &encrypted_payload[BLE_EAD_RANDOMIZER_SIZE]; - /* ciphertext_len includes both ciphertext and MIC (tag) for PSA API */ + /* ciphertext_len includes both ciphertext and MIC (tag) for mbedTLS API */ ciphertext_len = encrypted_payload_size - BLE_EAD_RANDOMIZER_SIZE; /* Generate nonce from randomizer and IV */ From a82ca85558a187b34fa4b5127d389d40cd0eda3c Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Tue, 30 Dec 2025 17:13:42 +0800 Subject: [PATCH 088/226] fix(ble): add esp timer trigger back for timestamp synchronization (cherry picked from commit d1a5804de9c1fa2f27ee01b68180fa25b2a29005) Co-authored-by: Zhou Xiao --- components/bt/common/ble_log/Kconfig.in | 38 ++++++++++-- components/bt/common/ble_log/src/ble_log_rt.c | 61 ++++++++++++++++--- .../ble_log/src/internal_include/ble_log_rt.h | 5 ++ 3 files changed, 88 insertions(+), 16 deletions(-) diff --git a/components/bt/common/ble_log/Kconfig.in b/components/bt/common/ble_log/Kconfig.in index edf459311d..6eca6ad4e5 100644 --- a/components/bt/common/ble_log/Kconfig.in +++ b/components/bt/common/ble_log/Kconfig.in @@ -110,12 +110,38 @@ if BLE_LOG_ENABLED help Enable BLE Log TS with external logging module - config BLE_LOG_SYNC_IO_NUM - int "GPIO number for Timestamp Synchronization (TS) toggle output" - depends on BLE_LOG_TS_ENABLED - default 0 - help - GPIO number for TS toggle output + if BLE_LOG_TS_ENABLED + config BLE_LOG_SYNC_IO_NUM + int "GPIO number for Timestamp Synchronization (TS) toggle output" + depends on BLE_LOG_TS_ENABLED + default 0 + help + GPIO number for TS toggle output + + config BLE_LOG_TS_TRIGGER_TIMEOUT_MS + int "Timeout (ms) for Timestamp Synchronization toggle" + default 1000 + help + Timeout (ms) for Timestamp Synchronization toggle + + choice BLE_LOG_TS_TRIGGER_CHOICE + prompt "BLE Log Timestamp Synchronization trigger choice" + default BLE_LOG_TS_TRIGGER_TASK_EVENT + help + Choose BLE Log Timestamp Synchronization trigger + + config BLE_LOG_TS_TRIGGER_ESP_TIMER + bool "BLE Log Timestamp Synchronization trigger - ESP Timer" + select ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD + help + ESP Timer based periodic TS trigger + + config BLE_LOG_TS_TRIGGER_TASK_EVENT + bool "BLE Log Timestamp Synchronization trigger - Task Event" + help + Task Event based TS trigger (Light Sleep Test Compatibility) + endchoice + endif choice BLE_LOG_PRPH_CHOICE prompt "BLE Log peripheral choice" diff --git a/components/bt/common/ble_log/src/ble_log_rt.c b/components/bt/common/ble_log/src/ble_log_rt.c index 7268797e36..1c9c829f11 100644 --- a/components/bt/common/ble_log/src/ble_log_rt.c +++ b/components/bt/common/ble_log/src/ble_log_rt.c @@ -19,6 +19,15 @@ BLE_LOG_STATIC TaskHandle_t rt_task_handle = NULL; BLE_LOG_STATIC QueueHandle_t rt_queue_handle = NULL; #if CONFIG_BLE_LOG_TS_ENABLED BLE_LOG_STATIC bool rt_ts_enabled = false; +#if CONFIG_BLE_LOG_TS_TRIGGER_ESP_TIMER +BLE_LOG_STATIC esp_timer_handle_t rt_ts_timer = NULL; +#endif /* CONFIG_BLE_LOG_TS_TRIGGER_ESP_TIMER */ +#endif /* CONFIG_BLE_LOG_TS_ENABLED */ + +/* PRIVATE FUNCTION DECLARATION */ +#if CONFIG_BLE_LOG_TS_ENABLED +BLE_LOG_STATIC void ble_log_rt_task(void *pvParameters); +BLE_LOG_STATIC void ble_log_rt_ts_trigger(void *arg); #endif /* CONFIG_BLE_LOG_TS_ENABLED */ /* PRIVATE FUNCTION */ @@ -56,15 +65,9 @@ BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void ble_log_rt_task(void *pvParameters) }; ble_log_write_hex(BLE_LOG_SRC_INTERNAL, (const uint8_t *)&ble_log_info, sizeof(ble_log_info_t)); -#if CONFIG_BLE_LOG_TS_ENABLED - if (rt_ts_enabled) { - ble_log_ts_info_t *ts_info = NULL; - ble_log_ts_info_update(&ts_info); - if (ts_info) { - ble_log_write_hex(BLE_LOG_SRC_INTERNAL, (const uint8_t *)ts_info, sizeof(ble_log_ts_info_t)); - } - } -#endif /* CONFIG_BLE_LOG_TS_ENABLED */ +#if CONFIG_BLE_LOG_TS_TRIGGER_TASK_EVENT + ble_log_rt_ts_trigger(NULL); +#endif /* CONFIG_BLE_LOG_TS_TRIGGER_TASK_EVENT */ #if CONFIG_BLE_LOG_ENH_STAT_ENABLED ble_log_write_enh_stat(); @@ -72,6 +75,21 @@ BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void ble_log_rt_task(void *pvParameters) } } +#if CONFIG_BLE_LOG_TS_ENABLED +BLE_LOG_STATIC void ble_log_rt_ts_trigger(void *arg) +{ + (void)arg; + if (!rt_inited || !rt_ts_enabled) { + return; + } + ble_log_ts_info_t *ts_info = NULL; + ble_log_ts_info_update(&ts_info); + if (ts_info) { + ble_log_write_hex(BLE_LOG_SRC_INTERNAL, (const uint8_t *)ts_info, sizeof(ble_log_ts_info_t)); + } +} +#endif /* CONFIG_BLE_LOG_TS_ENABLED */ + /* INTERFACE */ bool ble_log_rt_init(void) { @@ -92,10 +110,26 @@ bool ble_log_rt_init(void) goto exit; } - rt_inited = true; #if CONFIG_BLE_LOG_TS_ENABLED rt_ts_enabled = false; +#if CONFIG_BLE_LOG_TS_TRIGGER_ESP_TIMER + /* Initialize ESP Timer Trigger */ + esp_timer_create_args_t ts_timer_args = { + .callback = ble_log_rt_ts_trigger, + .arg = NULL, + .dispatch_method = ESP_TIMER_ISR, + .name = "ble_log_ts_timer", + }; + if (esp_timer_create(&ts_timer_args, &rt_ts_timer) != ESP_OK) { + goto exit; + } + if (esp_timer_start_periodic(rt_ts_timer, BLE_LOG_TS_TRIGGER_TIMEOUT_US) != ESP_OK) { + goto exit; + } +#endif /* CONFIG_BLE_LOG_TS_TRIGGER_ESP_TIMER */ #endif /* CONFIG_BLE_LOG_TS_ENABLED */ + + rt_inited = true; return true; exit: @@ -108,6 +142,13 @@ void ble_log_rt_deinit(void) rt_inited = false; #if CONFIG_BLE_LOG_TS_ENABLED rt_ts_enabled = false; +#if CONFIG_BLE_LOG_TS_TRIGGER_ESP_TIMER + if (rt_ts_timer) { + esp_timer_stop(rt_ts_timer); + esp_timer_delete(rt_ts_timer); + rt_ts_timer = NULL; + } +#endif /* CONFIG_BLE_LOG_TS_TRIGGER_ESP_TIMER */ #endif /* CONFIG_BLE_LOG_TS_ENABLED */ /* CRITICAL: diff --git a/components/bt/common/ble_log/src/internal_include/ble_log_rt.h b/components/bt/common/ble_log/src/internal_include/ble_log_rt.h index ae8b4b05a3..7becb1202b 100644 --- a/components/bt/common/ble_log/src/internal_include/ble_log_rt.h +++ b/components/bt/common/ble_log/src/internal_include/ble_log_rt.h @@ -22,7 +22,12 @@ /* MACRO */ #define BLE_LOG_TASK_PRIO (ESP_TASK_PRIO_MAX - 1) #define BLE_LOG_TASK_STACK_SIZE CONFIG_BLE_LOG_TASK_STACK_SIZE +#if CONFIG_BLE_LOG_TS_ENABLED +#define BLE_LOG_TS_TRIGGER_TIMEOUT_US (CONFIG_BLE_LOG_TS_TRIGGER_TIMEOUT_MS * 1000) +#define BLE_LOG_TASK_HOOK_TIMEOUT_MS CONFIG_BLE_LOG_TS_TRIGGER_TIMEOUT_MS +#else /* !CONFIG_BLE_LOG_TS_ENABLED */ #define BLE_LOG_TASK_HOOK_TIMEOUT_MS (1000) +#endif /* CONFIG_BLE_LOG_TS_ENABLED */ /* INTERFACE */ bool ble_log_rt_init(); From df013bae453d1ff58d1f505fcd6b52b7d1372fac Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Tue, 30 Dec 2025 17:28:58 +0800 Subject: [PATCH 089/226] feat(ble): provide isr dispatch method option for ble log ts --- components/bt/common/ble_log/Kconfig.in | 10 +++++++++- components/bt/common/ble_log/src/ble_log_rt.c | 5 +++++ components/bt/common/ble_log/src/ble_log_ts.c | 3 +++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/components/bt/common/ble_log/Kconfig.in b/components/bt/common/ble_log/Kconfig.in index 6eca6ad4e5..35405367e2 100644 --- a/components/bt/common/ble_log/Kconfig.in +++ b/components/bt/common/ble_log/Kconfig.in @@ -132,7 +132,6 @@ if BLE_LOG_ENABLED config BLE_LOG_TS_TRIGGER_ESP_TIMER bool "BLE Log Timestamp Synchronization trigger - ESP Timer" - select ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD help ESP Timer based periodic TS trigger @@ -141,6 +140,15 @@ if BLE_LOG_ENABLED help Task Event based TS trigger (Light Sleep Test Compatibility) endchoice + + config BLE_LOG_TS_TRIGGER_ESP_TIMER_ISR_DISPATCH_METHOD + bool "Utilize ISR dispatch method for ESP Timer as Timestamp Synchronization trigger" + default n + select ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD + select GPIO_CTRL_FUNC_IN_IRAM + depends on BLE_LOG_TS_TRIGGER_ESP_TIMER + help + Utilize ISR dispatch method for ESP Timer as Timestamp Synchronization trigger endif choice BLE_LOG_PRPH_CHOICE diff --git a/components/bt/common/ble_log/src/ble_log_rt.c b/components/bt/common/ble_log/src/ble_log_rt.c index 1c9c829f11..951d4d2a45 100644 --- a/components/bt/common/ble_log/src/ble_log_rt.c +++ b/components/bt/common/ble_log/src/ble_log_rt.c @@ -76,6 +76,9 @@ BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void ble_log_rt_task(void *pvParameters) } #if CONFIG_BLE_LOG_TS_ENABLED +#if CONFIG_BLE_LOG_TS_TRIGGER_ESP_TIMER_ISR_DISPATCH_METHOD +BLE_LOG_IRAM_ATTR +#endif /* CONFIG_BLE_LOG_TS_TRIGGER_ESP_TIMER_ISR_DISPATCH_METHOD */ BLE_LOG_STATIC void ble_log_rt_ts_trigger(void *arg) { (void)arg; @@ -117,7 +120,9 @@ bool ble_log_rt_init(void) esp_timer_create_args_t ts_timer_args = { .callback = ble_log_rt_ts_trigger, .arg = NULL, +#if CONFIG_BLE_LOG_TS_TRIGGER_ESP_TIMER_ISR_DISPATCH_METHOD .dispatch_method = ESP_TIMER_ISR, +#endif /* CONFIG_BLE_LOG_TS_TRIGGER_ESP_TIMER_ISR_DISPATCH_METHOD */ .name = "ble_log_ts_timer", }; if (esp_timer_create(&ts_timer_args, &rt_ts_timer) != ESP_OK) { diff --git a/components/bt/common/ble_log/src/ble_log_ts.c b/components/bt/common/ble_log/src/ble_log_ts.c index e01611da10..db719b3dc5 100644 --- a/components/bt/common/ble_log/src/ble_log_ts.c +++ b/components/bt/common/ble_log/src/ble_log_ts.c @@ -61,6 +61,9 @@ void ble_log_ts_deinit(void) gpio_reset_pin(CONFIG_BLE_LOG_SYNC_IO_NUM); } +#if CONFIG_BLE_LOG_TS_TRIGGER_ESP_TIMER_ISR_DISPATCH_METHOD +BLE_LOG_IRAM_ATTR +#endif /* CONFIG_BLE_LOG_TS_TRIGGER_ESP_TIMER_ISR_DISPATCH_METHOD */ void ble_log_ts_info_update(ble_log_ts_info_t **info) { if (!ts_inited) { From 0394fe266c198391184cbdd45833a66f310c647c Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Sun, 4 Jan 2026 10:17:34 +0800 Subject: [PATCH 090/226] fix(ble): fixed cache error risk in ble log module --- components/bt/common/ble_log/src/ble_log_lbm.c | 3 ++- components/bt/common/ble_log/src/ble_log_util.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/components/bt/common/ble_log/src/ble_log_lbm.c b/components/bt/common/ble_log/src/ble_log_lbm.c index 0cc996c721..4504663c5f 100644 --- a/components/bt/common/ble_log/src/ble_log_lbm.c +++ b/components/bt/common/ble_log/src/ble_log_lbm.c @@ -107,7 +107,8 @@ void ble_log_lbm_write_trans(ble_log_prph_trans_t **trans, ble_log_src_t src_cod } if (len_append) { #if CONFIG_SOC_ESP_NIMBLE_CONTROLLER - if (omdata) { + if (omdata && !BLE_LOG_IN_ISR()) { + /* os_mbuf_copydata is in flash and not safe to call from ISR */ os_mbuf_copydata((struct os_mbuf *)addr_append, 0, len_append, buf + BLE_LOG_FRAME_HEAD_LEN + len); } diff --git a/components/bt/common/ble_log/src/ble_log_util.c b/components/bt/common/ble_log/src/ble_log_util.c index c084d6d249..aac709e4e1 100644 --- a/components/bt/common/ble_log/src/ble_log_util.c +++ b/components/bt/common/ble_log/src/ble_log_util.c @@ -20,7 +20,8 @@ portMUX_TYPE ble_log_spin_lock = portMUX_INITIALIZER_UNLOCKED; #if CONFIG_BLE_LOG_XOR_CHECKSUM_ENABLED #include "esp_compiler.h" -static inline uint32_t ror32(uint32_t word, uint32_t shift) +BLE_LOG_IRAM_ATTR BLE_LOG_STATIC BLE_LOG_INLINE +uint32_t ror32(uint32_t word, uint32_t shift) { if (unlikely(shift == 0)) { return word; From 2ee0f153465f2b13109c96f474fcd3a3d63eb14e Mon Sep 17 00:00:00 2001 From: Roland Dobai Date: Thu, 18 Dec 2025 11:04:44 +0100 Subject: [PATCH 091/226] change(readme): Add auto-generated chip support table into the README --- README.md | 20 ++------------------ README_CN.md | 21 ++------------------- 2 files changed, 4 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 5031fd4645..5cd3a1528d 100644 --- a/README.md +++ b/README.md @@ -13,25 +13,9 @@ ESP-IDF is the development framework for Espressif SoCs supported on Windows, Li # ESP-IDF Release and SoC Compatibility -The following table shows ESP-IDF support of Espressif SoCs where ![alt text][preview] and ![alt text][supported] denote preview status and support, respectively. The preview support is usually limited in time and intended for beta versions of chips. Please use an ESP-IDF release where the desired SoC is already supported. +![Chip support](https://dl.espressif.com/dl/esp-idf/chip-support.svg?v=1) -|Chip | v5.1 | v5.2 | v5.3 | v5.4 | v5.5 | | -|:----------- |:--------------------: | :--------------------: | :--------------------: | :--------------------: | :--------------------: |:------------------------------------------------------------------- | -|ESP32 | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | | -|ESP32-S2 |![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | | -|ESP32-C3 | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | | -|ESP32-S3 | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] |[Announcement](https://www.espressif.com/en/news/ESP32_S3) | -|ESP32-C2 | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] |[Announcement](https://www.espressif.com/en/news/ESP32-C2) | -|ESP32-C6 | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] |[Announcement](https://www.espressif.com/en/news/ESP32_C6) | -|ESP32-H2 |![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] |[Announcement](https://www.espressif.com/en/news/ESP32_H2) | -|ESP32-P4 | | | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] |[Announcement](https://www.espressif.com/en/news/ESP32-P4) | -|ESP32-C5 | | | | |![alt text][supported] |since v5.5.1, [Announcement](https://www.espressif.com/en/news/ESP32-C5) | -|ESP32-C61 | | | | |![alt text][supported] |since v5.5.1, [Announcement](https://www.espressif.com/en/products/socs/esp32-c61) | - -[supported]: https://img.shields.io/badge/-supported-green "supported" -[preview]: https://img.shields.io/badge/-preview-orange "preview" - -There are variants of revisions for a series of chips. See [Compatibility Between ESP-IDF Releases and Revisions of Espressif SoCs](https://github.com/espressif/esp-idf/blob/master/COMPATIBILITY.md) for the details of the compatibility between ESP-IDF and chip revisions. +See [Compatibility Between ESP-IDF Releases and Revisions of Espressif SoCs](https://github.com/espressif/esp-idf/blob/master/COMPATIBILITY.md) for the details of the compatibility between ESP-IDF and chip revisions. Espressif SoCs released before 2016 (ESP8266 and ESP8285) are supported by [RTOS SDK](https://github.com/espressif/ESP8266_RTOS_SDK) instead. diff --git a/README_CN.md b/README_CN.md index 168dd74b97..631d289fd9 100644 --- a/README_CN.md +++ b/README_CN.md @@ -13,26 +13,9 @@ ESP-IDF 是乐鑫官方推出的物联网开发框架,支持 Windows、Linux # ESP-IDF 与乐鑫芯片 -下表总结了乐鑫芯片在 ESP-IDF 各版本中的支持状态,其中 ![alt text][supported] 代表已支持,![alt text][preview] 代表目前处于预览支持状态。预览支持状态通常有时间限制,而且仅适用于测试版芯片。请确保使用与芯片相匹配的 ESP-IDF 版本。 +![芯片支持](https://dl.espressif.com/dl/esp-idf/chip-support.svg?v=1) -芯片 | v5.1 | v5.2 | v5.3 | v5.4 | v5.5 | | -|:----------- | :--------------------: | :--------------------: | :--------------------: | :--------------------: | :--------------------: |:------------------------------------------------------------------------ | -|ESP32 |![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] |![alt text][supported] | | -|ESP32-S2 |![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | | -|ESP32-C3 |![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | | -|ESP32-S3 |![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] |![alt text][supported] | [芯片发布公告](https://www.espressif.com/zh-hans/news/ESP32_S3) | -|ESP32-C2 |![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] |![alt text][supported] | [芯片发布公告](https://www.espressif.com/zh-hans/news/ESP32-C2) | -|ESP32-C6 |![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] |![alt text][supported] | [芯片发布公告](https://www.espressif.com/zh-hans/news/ESP32_C6) | -|ESP32-H2 |![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] |![alt text][supported] | [芯片发布公告](https://www.espressif.com/zh-hans/news/ESP32_H2) | -|ESP32-P4 | | | ![alt text][supported] | ![alt text][supported] |![alt text][supported] | [芯片发布公告](https://www.espressif.com/zh-hans/news/ESP32-P4) | -|ESP32-C5 | | | | |![alt text][supported] | 自 v5.5.1 开始,[芯片发布公告](https://www.espressif.com/zh-hans/news/ESP32-C5) | -|ESP32-C61 | | | | |![alt text][supported] | 自 v5.5.1 开始,[芯片发布公告](https://www.espressif.com/zh-hans/products/socs/esp32-c61) | - - -[supported]: https://img.shields.io/badge/-%E6%94%AF%E6%8C%81-green "supported" -[preview]: https://img.shields.io/badge/-%E9%A2%84%E8%A7%88-orange "preview" - -每款乐鑫芯片都可能有不同版本。建议参考 [ESP-IDF 版本与乐鑫芯片版本兼容性](https://github.com/espressif/esp-idf/blob/master/COMPATIBILITY_CN.md),了解 ESP-IDF 版本与各芯片版本之间的兼容性。 +请参考 [ESP-IDF 版本与乐鑫芯片版本兼容性](https://github.com/espressif/esp-idf/blob/master/COMPATIBILITY_CN.md) 了解 ESP-IDF 版本与芯片版本之间的兼容性详情。 对于 2016 年之前发布的乐鑫芯片(包括 ESP8266 和 ESP8285),请参考 [RTOS SDK](https://github.com/espressif/ESP8266_RTOS_SDK)。 From 3924afbf28ee0283a369984ec363d0662ab06dd5 Mon Sep 17 00:00:00 2001 From: Wan Lei Date: Tue, 8 Jul 2025 19:22:54 +0800 Subject: [PATCH 092/226] feat(spi_master): support dma transfer with psram directly --- components/esp_driver_spi/CMakeLists.txt | 2 +- components/esp_driver_spi/Kconfig | 2 +- .../include/driver/spi_master.h | 8 +- .../esp_driver_spi/src/gpspi/spi_master.c | 159 ++++++++++++------ .../test_apps/master/main/CMakeLists.txt | 2 +- .../test_apps/master/main/test_spi_master.c | 110 +++++++++++- .../master/sdkconfig.ci.release.esp32c5 | 1 + .../master/sdkconfig.ci.release.esp32c61 | 1 + .../master/sdkconfig.ci.release.esp32p4 | 1 + .../master/sdkconfig.ci.release.esp32s3 | 1 + components/hal/esp32c5/include/hal/spi_ll.h | 24 +-- components/hal/esp32c61/include/hal/spi_ll.h | 24 +-- components/hal/esp32p4/include/hal/spi_ll.h | 24 +-- components/hal/esp32s3/include/hal/spi_ll.h | 4 + components/hal/include/hal/spi_hal.h | 27 +-- components/hal/spi_hal_iram.c | 20 ++- .../api-reference/peripherals/spi_master.rst | 9 + .../api-reference/peripherals/spi_master.rst | 9 + 18 files changed, 316 insertions(+), 112 deletions(-) create mode 100644 components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32c5 create mode 100644 components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32c61 create mode 100644 components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32p4 create mode 100644 components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32s3 diff --git a/components/esp_driver_spi/CMakeLists.txt b/components/esp_driver_spi/CMakeLists.txt index cb1efc7488..945d920b5f 100644 --- a/components/esp_driver_spi/CMakeLists.txt +++ b/components/esp_driver_spi/CMakeLists.txt @@ -27,6 +27,6 @@ idf_component_register( SRCS ${srcs} INCLUDE_DIRS ${public_include} REQUIRES esp_pm - PRIV_REQUIRES esp_timer esp_mm esp_driver_gpio + PRIV_REQUIRES esp_timer esp_mm esp_driver_gpio spi_flash esp_psram #For CONFIG_SPIRAM_SPEED LDFRAGMENTS "linker.lf" ) diff --git a/components/esp_driver_spi/Kconfig b/components/esp_driver_spi/Kconfig index ee180564da..a50a321872 100644 --- a/components/esp_driver_spi/Kconfig +++ b/components/esp_driver_spi/Kconfig @@ -44,7 +44,7 @@ menu "ESP-Driver:SPI Configurations" help Normally only the ISR of SPI slave is placed in the IRAM, so that it can work without the flash when interrupt is triggered. - For other functions, there's some possibility that the flash cache + For other functions, there is some possibility that the flash cache miss when running inside and out of SPI functions, which may increase the interval of SPI transactions. Enable this to put ``queue_trans``, ``get_trans_result`` and diff --git a/components/esp_driver_spi/include/driver/spi_master.h b/components/esp_driver_spi/include/driver/spi_master.h index a432e62334..3567c45e9a 100644 --- a/components/esp_driver_spi/include/driver/spi_master.h +++ b/components/esp_driver_spi/include/driver/spi_master.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -104,6 +104,7 @@ typedef struct { */ } spi_device_interface_config_t; +// Input flags #define SPI_TRANS_MODE_DIO (1<<0) ///< Transmit/receive data in 2-bit mode #define SPI_TRANS_MODE_QIO (1<<1) ///< Transmit/receive data in 4-bit mode #define SPI_TRANS_USE_RXDATA (1<<2) ///< Receive into rx_data member of spi_transaction_t instead into memory at rx_buffer. @@ -117,6 +118,11 @@ typedef struct { #define SPI_TRANS_MODE_OCT (1<<10) ///< Transmit/receive data in 8-bit mode #define SPI_TRANS_MULTILINE_ADDR SPI_TRANS_MODE_DIOQIO_ADDR ///< The data lines used at address phase is the same as data phase (otherwise, only one data line is used at address phase) #define SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL (1<<11) ///< By default driver will automatically re-alloc dma buffer if it doesn't meet hardware alignment or dma_capable requirements, this flag is for you to disable this feature, you will need to take care of the alignment otherwise driver will return you error ESP_ERR_INVALID_ARG +#define SPI_TRANS_DMA_USE_PSRAM (1<<12) ///< Use PSRAM for DMA buffer directly, has speed limit, but no temp buffer and save memory + +// Output flags +#define SPI_TRANS_DMA_RX_FAIL (1<<30) ///< RX transaction data lose flag, indicate DMA RX overflow +#define SPI_TRANS_DMA_TX_FAIL (1<<31) ///< TX transaction data lose flag, indicate DMA TX underflow /** * This structure describes one SPI transaction. The descriptor should not be modified until the transaction finishes. diff --git a/components/esp_driver_spi/src/gpspi/spi_master.c b/components/esp_driver_spi/src/gpspi/spi_master.c index 62f06ae604..1493dd5e98 100644 --- a/components/esp_driver_spi/src/gpspi/spi_master.c +++ b/components/esp_driver_spi/src/gpspi/spi_master.c @@ -116,11 +116,14 @@ We have two bits to control the interrupt: #include "esp_private/spi_common_internal.h" #include "esp_private/spi_master_internal.h" #include "esp_private/esp_clk_tree_common.h" +#include "esp_private/cache_utils.h" #include "driver/spi_master.h" #include "clk_ctrl_os.h" #include "esp_log.h" #include "esp_check.h" #include "esp_ipc.h" +#include "esp_cache.h" +#include "esp_heap_caps.h" #include "freertos/task.h" #include "freertos/queue.h" #include "soc/soc_memory_layout.h" @@ -128,10 +131,6 @@ We have two bits to control the interrupt: #include "hal/spi_hal.h" #include "hal/spi_ll.h" #include "hal/hal_utils.h" -#include "esp_heap_caps.h" -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE -#include "esp_cache.h" -#endif #ifdef CONFIG_SPI_MASTER_ISR_IN_IRAM #define SPI_MASTER_ISR_ATTR IRAM_ATTR @@ -159,7 +158,25 @@ We have two bits to control the interrupt: #define SPI_PERIPH_SRC_FREQ_MAX (80*1000*1000) //peripheral hardware limitation for clock source into peripheral -static const char *SPI_TAG = "spi_master"; +/** + * The approx time for dma setup and pop data into peripheral + * This time is theoretically inverse proportion to the PSRAM speed(bandwidth), and direct proportion to the SPI speed, but hard to accurately calculated + * Below is an engineering value based on experience test result, e.g. delay 5us for 20MHz PSRAM speed, 1us for 80M + * Then the formula is: Delay_time = K * (SPI_SPEED / PSRAM_SPEED) + B + * delay + * ▲ + * │ x + * │ x + * │ x + * │ x x + * ─┼─────────────────► + * │ psram speed + */ +#define K_EDMA_SETUP_RATIO 1 / 50000 +#define B_EDMA_SETUP_TIME_US 1 +#define SPI_EDMA_SETUP_TIME_US(spi_speed) ((spi_speed) * K_EDMA_SETUP_RATIO / CONFIG_SPIRAM_SPEED + B_EDMA_SETUP_TIME_US) + +ESP_LOG_ATTR_TAG_DRAM(SPI_TAG, "spi_master"); #define SPI_CHECK(a, str, ret_val, ...) ESP_RETURN_ON_FALSE_ISR(a, ret_val, SPI_TAG, str, ##__VA_ARGS__) typedef struct spi_device_t spi_device_t; @@ -834,6 +851,13 @@ static void SPI_MASTER_ISR_ATTR spi_new_trans(spi_device_t *dev, spi_trans_priv_ if (dev->cfg.pre_cb) { dev->cfg.pre_cb(trans); } +#if CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE + spi_hal_clear_intr_mask(hal, SPI_LL_INTR_IN_FULL | SPI_LL_INTR_OUT_EMPTY); + if (esp_ptr_dma_ext_capable(hal_trans.send_buffer)) { + // ! Delay here is required for EDMA to pass data from PSRAM to GPSPI + esp_rom_delay_us(SPI_EDMA_SETUP_TIME_US(hal_dev->timing_conf.real_freq)); + } +#endif //Kick off transfer spi_hal_user_start(hal); } @@ -931,6 +955,26 @@ static void SPI_MASTER_ISR_ATTR spi_post_sct_trans(spi_host_t *host) } #endif //#if SOC_SPI_SCT_SUPPORTED +static void SPI_MASTER_ISR_ATTR spi_trans_dma_error_check(spi_host_t *host) +{ +#if SOC_PSRAM_DMA_CAPABLE && CONFIG_SPIRAM //error checks only for psram dma + if (!host->sct_mode_enabled) { + if (esp_ptr_external_ram(host->cur_trans_buf.buffer_to_rcv) && spi_hal_get_intr_mask(&host->hal, SPI_LL_INTR_IN_FULL)) { + host->cur_trans_buf.trans->flags |= SPI_TRANS_DMA_RX_FAIL; + ESP_DRAM_LOGE(SPI_TAG, "DMA RX overflow detected"); + } else { + host->cur_trans_buf.trans->flags &= ~SPI_TRANS_DMA_RX_FAIL; + } + if (esp_ptr_external_ram(host->cur_trans_buf.buffer_to_send) && spi_hal_get_intr_mask(&host->hal, SPI_LL_INTR_OUT_EMPTY)) { + host->cur_trans_buf.trans->flags |= SPI_TRANS_DMA_TX_FAIL; + ESP_DRAM_LOGE(SPI_TAG, "DMA TX underflow detected"); + } else { + host->cur_trans_buf.trans->flags &= ~SPI_TRANS_DMA_TX_FAIL; + } + } +#endif +} + // This is run in interrupt context. static void SPI_MASTER_ISR_ATTR spi_intr(void *arg) { @@ -979,6 +1023,7 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg) assert(ret == ESP_OK); } #endif + spi_trans_dma_error_check(host); } #if SOC_SPI_SCT_SUPPORTED @@ -1130,7 +1175,9 @@ static SPI_MASTER_ISR_ATTR esp_err_t check_trans_valid(spi_device_handle_t handl SPI_CHECK(trans_desc->length <= SPI_LL_CPU_MAX_BIT_LEN, "txdata transfer > hardware max supported len", ESP_ERR_INVALID_ARG); SPI_CHECK(trans_desc->rxlength <= SPI_LL_CPU_MAX_BIT_LEN, "rxdata transfer > hardware max supported len", ESP_ERR_INVALID_ARG); } - + if (esp_ptr_external_ram(trans_desc->tx_buffer) || esp_ptr_external_ram(trans_desc->rx_buffer)){ + SPI_CHECK(spi_flash_cache_enabled(), "Using PSRAM must when cache is enabled", ESP_ERR_INVALID_STATE); + } return ESP_OK; } @@ -1152,6 +1199,45 @@ static SPI_MASTER_ISR_ATTR void uninstall_priv_desc(spi_trans_priv_t* trans_buf) } } +static SPI_MASTER_ISR_ATTR esp_err_t setup_dma_priv_buffer(uint32_t *buffer, uint32_t len, uint32_t alignment, bool is_tx, uint32_t flags, uint32_t **ret_buffer) +{ + bool unaligned = ((((uint32_t)buffer) | len) & (alignment - 1)); +#if !SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + if (!((flags & SPI_TRANS_DMA_USE_PSRAM) && esp_ptr_dma_ext_capable(buffer))) { + // tx don't need align on addr or length on those chips + unaligned = is_tx ? false : (((uint32_t)buffer) & (alignment - 1)); + } +#endif + +#if SOC_PSRAM_DMA_CAPABLE + if ((flags & SPI_TRANS_DMA_USE_PSRAM) && esp_ptr_dma_ext_capable(buffer)) { + // dma psram don't do additional copy, check only + ESP_RETURN_ON_FALSE_ISR(!unaligned, ESP_ERR_INVALID_ARG, SPI_TAG, "%s buffer addr and length should align to %ld Byte to use PSRAM, use heap_caps_aligned_calloc() may helpful", is_tx ? "TX" : "RX", alignment); + ESP_RETURN_ON_ERROR_ISR(esp_cache_msync((void *)buffer, len, is_tx ? ESP_CACHE_MSYNC_FLAG_DIR_C2M : ESP_CACHE_MSYNC_FLAG_DIR_M2C), SPI_TAG, "sync failed for %s buffer", is_tx ? "TX" : "RX"); + *ret_buffer = buffer; + return ESP_OK; + } +#endif + if ((!esp_ptr_dma_capable(buffer) || unaligned)) { + ESP_RETURN_ON_FALSE_ISR(!(flags & SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL), ESP_ERR_INVALID_ARG, SPI_TAG, "Set flag SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL but %s addr&len not align to %d, or not dma_capable", is_tx ? "TX" : "RX", alignment); + //if buf in the desc not DMA-capable, or not bytes aligned to alignment, malloc a new one + ESP_EARLY_LOGD(SPI_TAG, "Allocate %s buffer for DMA", is_tx ? "TX" : "RX"); + len = (len + alignment - 1) & (~(alignment - 1)); // up align alignment + uint32_t *temp = heap_caps_aligned_alloc(alignment, len, MALLOC_CAP_DMA); + ESP_RETURN_ON_FALSE_ISR(temp != NULL, ESP_ERR_NO_MEM, SPI_TAG, "Failed to allocate priv %s buffer", is_tx ? "TX" : "RX"); + + if (is_tx) { + memcpy(temp, buffer, len); + } + buffer = temp; + } +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + ESP_RETURN_ON_ERROR_ISR(esp_cache_msync((void *)buffer, len, is_tx ? ESP_CACHE_MSYNC_FLAG_DIR_C2M : ESP_CACHE_MSYNC_FLAG_DIR_M2C), SPI_TAG, "sync failed for %s buffer", is_tx ? "TX" : "RX"); +#endif + *ret_buffer = buffer; + return ESP_OK; +} + static SPI_MASTER_ISR_ATTR esp_err_t setup_priv_desc(spi_host_t *host, spi_trans_priv_t* priv_desc) { spi_transaction_t *trans_desc = priv_desc->trans; @@ -1168,68 +1254,36 @@ static SPI_MASTER_ISR_ATTR esp_err_t setup_priv_desc(spi_host_t *host, spi_trans } // tx memory assign - const uint32_t *send_ptr; + uint32_t *send_ptr; if (trans_desc->flags & SPI_TRANS_USE_TXDATA) { send_ptr = (uint32_t *)&trans_desc->tx_data[0]; } else { //if not use TXDATA neither tx_buffer, tx data assigned to NULL - send_ptr = trans_desc->tx_buffer ; + send_ptr = (uint32_t *)trans_desc->tx_buffer ; } - uint32_t tx_byte_len = (trans_desc->length + 7) / 8; - uint32_t rx_byte_len = (trans_desc->rxlength + 7) / 8; -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - bool tx_unaligned = ((((uint32_t)send_ptr) | tx_byte_len) & (alignment - 1)); - bool rx_unaligned = ((((uint32_t)rcv_ptr) | rx_byte_len) & (alignment - 1)); -#else - bool tx_unaligned = false; //tx don't need align on addr or length, for other chips - bool rx_unaligned = (((uint32_t)rcv_ptr) & (alignment - 1)); -#endif - + esp_err_t ret = ESP_OK; if (send_ptr && bus_attr->dma_enabled) { - if ((!esp_ptr_dma_capable(send_ptr) || tx_unaligned)) { - ESP_RETURN_ON_FALSE(!(trans_desc->flags & SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL), ESP_ERR_INVALID_ARG, SPI_TAG, "Set flag SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL but TX buffer addr&len not align to %d byte, or not dma_capable", alignment); - //if txbuf in the desc not DMA-capable, or not bytes aligned to alignment, malloc a new one - ESP_EARLY_LOGD(SPI_TAG, "Allocate TX buffer for DMA"); - tx_byte_len = (tx_byte_len + alignment - 1) & (~(alignment - 1)); // up align alignment - uint32_t *temp = heap_caps_aligned_alloc(alignment, tx_byte_len, MALLOC_CAP_DMA); - if (temp == NULL) { - goto clean_up; - } - - memcpy(temp, send_ptr, (trans_desc->length + 7) / 8); - send_ptr = temp; + ret = setup_dma_priv_buffer(send_ptr, (trans_desc->length + 7) / 8, alignment, true, trans_desc->flags, &send_ptr); + if (ret != ESP_OK) { + goto clean_up; } -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - esp_err_t ret = esp_cache_msync((void *)send_ptr, tx_byte_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); - assert(ret == ESP_OK); -#endif } if (rcv_ptr && bus_attr->dma_enabled) { - if ((!esp_ptr_dma_capable(rcv_ptr) || rx_unaligned)) { - ESP_RETURN_ON_FALSE(!(trans_desc->flags & SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL), ESP_ERR_INVALID_ARG, SPI_TAG, "Set flag SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL but RX buffer addr&len not align to %d byte, or not dma_capable", alignment); - //if rxbuf in the desc not DMA-capable, or not aligned to alignment, malloc a new one - ESP_EARLY_LOGD(SPI_TAG, "Allocate RX buffer for DMA"); - rx_byte_len = (rx_byte_len + alignment - 1) & (~(alignment - 1)); // up align alignment - rcv_ptr = heap_caps_aligned_alloc(alignment, rx_byte_len, MALLOC_CAP_DMA); - if (rcv_ptr == NULL) { - goto clean_up; - } + ret = setup_dma_priv_buffer(rcv_ptr, (trans_desc->rxlength + 7) / 8, alignment, false, trans_desc->flags, &rcv_ptr); + if (ret != ESP_OK) { + goto clean_up; } -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - // do invalid here to hold on cache status to avoid hardware auto write back during dma transaction - esp_err_t ret = esp_cache_msync((void *)rcv_ptr, rx_byte_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); - assert(ret == ESP_OK); -#endif } + priv_desc->buffer_to_send = send_ptr; priv_desc->buffer_to_rcv = rcv_ptr; return ESP_OK; clean_up: uninstall_priv_desc(priv_desc); - return ESP_ERR_NO_MEM; + return ret; } esp_err_t SPI_MASTER_ATTR spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *trans_desc, TickType_t ticks_to_wait) @@ -1308,7 +1362,7 @@ esp_err_t SPI_MASTER_ATTR spi_device_get_trans_result(spi_device_handle_t handle } (*trans_desc) = trans_buf.trans; - return ESP_OK; + return (trans_buf.trans->flags & (SPI_TRANS_DMA_RX_FAIL | SPI_TRANS_DMA_TX_FAIL)) ? ESP_ERR_INVALID_STATE : ESP_OK; } //Porcelain to do one blocking transmission. @@ -1457,6 +1511,8 @@ esp_err_t SPI_MASTER_ISR_ATTR spi_device_polling_end(spi_device_handle_t handle, return ESP_ERR_TIMEOUT; } } + spi_trans_dma_error_check(host); + uint32_t trans_flags = host->cur_trans_buf.trans->flags; // save the flags before bus_lock release #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE //invalidate here to let user access rx data in post_cb if possible const spi_bus_attr_t *bus_attr = host->bus_attr; @@ -1470,7 +1526,6 @@ esp_err_t SPI_MASTER_ISR_ATTR spi_device_polling_end(spi_device_handle_t handle, } } #endif - ESP_LOGV(SPI_TAG, "polling trans done"); //deal with the in-flight transaction spi_post_trans(host); @@ -1486,7 +1541,7 @@ esp_err_t SPI_MASTER_ISR_ATTR spi_device_polling_end(spi_device_handle_t handle, spi_bus_lock_acquire_end(handle->dev_lock); } - return ESP_OK; + return (trans_flags & (SPI_TRANS_DMA_RX_FAIL | SPI_TRANS_DMA_TX_FAIL)) ? ESP_ERR_INVALID_STATE : ESP_OK; } esp_err_t SPI_MASTER_ISR_ATTR spi_device_polling_transmit(spi_device_handle_t handle, spi_transaction_t* trans_desc) diff --git a/components/esp_driver_spi/test_apps/master/main/CMakeLists.txt b/components/esp_driver_spi/test_apps/master/main/CMakeLists.txt index cc99e1467a..91e5f4d0fc 100644 --- a/components/esp_driver_spi/test_apps/master/main/CMakeLists.txt +++ b/components/esp_driver_spi/test_apps/master/main/CMakeLists.txt @@ -16,6 +16,6 @@ endif() # the component can be registered as WHOLE_ARCHIVE idf_component_register( SRCS ${srcs} - PRIV_REQUIRES esp_driver_spi spi_flash esp_timer + PRIV_REQUIRES esp_driver_spi spi_flash esp_timer esp_driver_gpio esp_mm WHOLE_ARCHIVE ) diff --git a/components/esp_driver_spi/test_apps/master/main/test_spi_master.c b/components/esp_driver_spi/test_apps/master/main/test_spi_master.c index 66942bf579..775c2e8af5 100644 --- a/components/esp_driver_spi/test_apps/master/main/test_spi_master.c +++ b/components/esp_driver_spi/test_apps/master/main/test_spi_master.c @@ -26,6 +26,7 @@ #include "esp_clk_tree.h" #include "esp_timer.h" #include "esp_log.h" +#include "esp_cache.h" #include "test_utils.h" #include "test_spi_utils.h" #include "spi_performance.h" @@ -775,24 +776,27 @@ TEST_CASE("SPI Master DMA test, TX and RX in different regions", "[spi]") //connect MOSI to two devices breaks the output, fix it. spitest_gpio_output_sel(buscfg.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out); -#define TEST_REGION_SIZE 2 +#define TEST_REGION_SIZE 3 static spi_transaction_t trans[TEST_REGION_SIZE]; - int x; memset(trans, 0, sizeof(trans)); - trans[0].length = 320 * 8, - trans[0].tx_buffer = data_malloc + 2; + trans[0].length = 320 * 8; + trans[0].tx_buffer = data_malloc + 2; trans[0].rx_buffer = data_dram; - trans[1].length = 4 * 8, - trans[1].flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA; + trans[1].length = 4 * 8; + trans[1].flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA; uint32_t *ptr = (uint32_t *)trans[1].rx_data; *ptr = 0x54545454; ptr = (uint32_t *)trans[1].tx_data; *ptr = 0xbc124960; + trans[2].length = 64 * 8; + trans[2].tx_buffer = data_drom; + trans[2].rx_buffer = data_malloc; + //Queue all transactions. - for (x = 0; x < TEST_REGION_SIZE; x++) { + for (int x = 0; x < TEST_REGION_SIZE; x++) { ESP_LOGI(TAG, "transmitting %d...", x); ret = spi_device_transmit(spi, &trans[x]); TEST_ASSERT(ret == ESP_OK); @@ -1969,3 +1973,95 @@ TEST_CASE("test_spi_master_auto_sleep_retention", "[spi]") } #endif //CONFIG_PM_ENABLE #endif //SOC_LIGHT_SLEEP_SUPPORTED + +#if CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE +#define TEST_EDMA_PSRAM_TRANS_NUM 5 +#define TEST_EDMA_TRANS_LEN 20480 //Use PSRAM need a 16/32/64 aligned buffer len +#define TEST_EDMA_BUFFER_SZ (TEST_EDMA_PSRAM_TRANS_NUM * TEST_EDMA_TRANS_LEN) + +void test_spi_psram_trans(spi_device_handle_t dev_handle, void *tx, void *rx) +{ + spi_transaction_t trans_cfg = { + .length = TEST_EDMA_TRANS_LEN * 8, + .flags = SPI_TRANS_DMA_USE_PSRAM, + }; + + for (uint8_t cnt = 0; cnt < TEST_EDMA_PSRAM_TRANS_NUM; cnt ++) { + trans_cfg.tx_buffer = tx + TEST_EDMA_TRANS_LEN * cnt; + trans_cfg.rx_buffer = rx + TEST_EDMA_TRANS_LEN * cnt; + + // To use psram, hardware will pass data through MSPI and GDMA to GPSPI, which need some time + // GPSPI bandwidth(speed * line_num) should always no more than PSRAM bandwidth + trans_cfg.override_freq_hz = (CONFIG_SPIRAM_SPEED / 4) * 1000 * 1000; + printf("%d TX %p RX %p len %d @%ld kHz\n", cnt, trans_cfg.tx_buffer, trans_cfg.rx_buffer, TEST_EDMA_TRANS_LEN, trans_cfg.override_freq_hz / 1000); + TEST_ESP_OK(spi_device_transmit(dev_handle, &trans_cfg)); + TEST_ASSERT(!(trans_cfg.flags & (SPI_TRANS_DMA_RX_FAIL | SPI_TRANS_DMA_TX_FAIL))); + spitest_cmp_or_dump(trans_cfg.tx_buffer, trans_cfg.rx_buffer, TEST_EDMA_TRANS_LEN); + } +} + +TEST_CASE("SPI_Master: PSRAM buffer transaction via EDMA", "[spi]") +{ + spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG(); + buscfg.miso_io_num = buscfg.mosi_io_num; // set spi "self-loopback" + buscfg.max_transfer_sz = TEST_EDMA_BUFFER_SZ; + TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO)); + + spi_device_handle_t dev_handle; + spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG(); + devcfg.clock_speed_hz = 80 * 1000 * 1000; // Test error case on highest freq first + TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &dev_handle)); + int real_freq_khz; + spi_device_get_actual_freq(dev_handle, &real_freq_khz); + + uint32_t cache_width = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA); + uint8_t *internal_1 = heap_caps_aligned_calloc(cache_width, 1, TEST_EDMA_BUFFER_SZ, MALLOC_CAP_INTERNAL); + uint8_t *external_1 = heap_caps_aligned_calloc(cache_width, 1, TEST_EDMA_BUFFER_SZ, MALLOC_CAP_SPIRAM); + uint8_t *external_2 = heap_caps_aligned_calloc(cache_width, 1, TEST_EDMA_BUFFER_SZ, MALLOC_CAP_SPIRAM); + test_fill_random_to_buffers_dualboard(1001, internal_1, external_2, TEST_EDMA_BUFFER_SZ); + + printf("Test error case: High freq @%d kHz\n", real_freq_khz); + spi_transaction_t trans_cfg = { + .length = TEST_EDMA_TRANS_LEN * 8, + .tx_buffer = external_2, + .rx_buffer = external_1, + }; + + for (uint8_t i = 0; i < 2; i++) { + trans_cfg.flags = i ? SPI_TRANS_DMA_USE_PSRAM : 0; + uint32_t before = esp_get_free_heap_size(); + spi_device_polling_start(dev_handle, &trans_cfg, portMAX_DELAY); + uint32_t after = esp_get_free_heap_size(); + printf("\n==== %s ====\n", i ? "EDMA" : "Auto Malloc"); + printf("before: %ld, after: %ld, diff: %ld\n", before, after, after - before); + spi_device_polling_end(dev_handle, portMAX_DELAY); + printf("RX fail: %d, TX fail: %d\n", !!(trans_cfg.flags & SPI_TRANS_DMA_RX_FAIL), !!(trans_cfg.flags & SPI_TRANS_DMA_TX_FAIL)); + TEST_ASSERT(i ? (before - after) < TEST_EDMA_TRANS_LEN : (before - after) > 2 * TEST_EDMA_TRANS_LEN); + TEST_ASSERT((!!i) == !!(trans_cfg.flags & (SPI_TRANS_DMA_RX_FAIL | SPI_TRANS_DMA_TX_FAIL))); + } + + printf("\nTest unaligned tx psram buffer\n"); + trans_cfg.tx_buffer ++; + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, spi_device_transmit(dev_handle, &trans_cfg)); + + printf("\nTest trans: internal -> psram\n"); + memset(external_1, 0, TEST_EDMA_BUFFER_SZ); + TEST_ESP_OK(esp_cache_msync((void *)external_1, TEST_EDMA_BUFFER_SZ, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); + test_spi_psram_trans(dev_handle, internal_1, external_1); + + printf("\nTest trans: psram -> psram\n"); + memset(external_2, 0, TEST_EDMA_BUFFER_SZ); + TEST_ESP_OK(esp_cache_msync((void *)external_2, TEST_EDMA_BUFFER_SZ, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); + test_spi_psram_trans(dev_handle, external_1, external_2); + + printf("\nTest trans: psram -> internal\n"); + memset(internal_1, 0, TEST_EDMA_BUFFER_SZ); + test_spi_psram_trans(dev_handle, external_2, internal_1); + + free(internal_1); + free(external_1); + free(external_2); + spi_bus_remove_device(dev_handle); + spi_bus_free(TEST_SPI_HOST); +} +#endif diff --git a/components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32c5 b/components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32c5 new file mode 100644 index 0000000000..cc641ea603 --- /dev/null +++ b/components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32c5 @@ -0,0 +1 @@ +CONFIG_SPIRAM=y diff --git a/components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32c61 b/components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32c61 new file mode 100644 index 0000000000..cc641ea603 --- /dev/null +++ b/components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32c61 @@ -0,0 +1 @@ +CONFIG_SPIRAM=y diff --git a/components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32p4 b/components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32p4 new file mode 100644 index 0000000000..cc641ea603 --- /dev/null +++ b/components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32p4 @@ -0,0 +1 @@ +CONFIG_SPIRAM=y diff --git a/components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32s3 b/components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32s3 new file mode 100644 index 0000000000..cc641ea603 --- /dev/null +++ b/components/esp_driver_spi/test_apps/master/sdkconfig.ci.release.esp32s3 @@ -0,0 +1 @@ +CONFIG_SPIRAM=y diff --git a/components/hal/esp32c5/include/hal/spi_ll.h b/components/hal/esp32c5/include/hal/spi_ll.h index 538ea77ac0..897e979494 100644 --- a/components/hal/esp32c5/include/hal/spi_ll.h +++ b/components/hal/esp32c5/include/hal/spi_ll.h @@ -54,6 +54,8 @@ typedef spi_dev_t spi_dma_dev_t; // Type definition of all supported interrupts typedef enum { SPI_LL_INTR_TRANS_DONE = BIT(0), ///< A transaction has done + SPI_LL_INTR_IN_FULL = BIT(4), ///< DMA in_full error happened + SPI_LL_INTR_OUT_EMPTY = BIT(5), ///< DMA out_empty error happened SPI_LL_INTR_RDBUF = BIT(6), ///< Has received RDBUF command. Only available in slave HD. SPI_LL_INTR_WRBUF = BIT(7), ///< Has received WRBUF command. Only available in slave HD. SPI_LL_INTR_RDDMA = BIT(8), ///< Has received RDDMA command. Only available in slave HD. @@ -1097,16 +1099,18 @@ static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw) //helper macros to generate code for each interrupts #define FOR_EACH_ITEM(op, list) do { list(op) } while(0) #define INTR_LIST(item) \ - item(SPI_LL_INTR_TRANS_DONE, dma_int_ena.trans_done_int_ena, dma_int_raw.trans_done_int_raw, dma_int_clr.trans_done_int_clr, dma_int_set.trans_done_int_set) \ - item(SPI_LL_INTR_RDBUF, dma_int_ena.slv_rd_buf_done_int_ena, dma_int_raw.slv_rd_buf_done_int_raw, dma_int_clr.slv_rd_buf_done_int_clr, dma_int_set.slv_rd_buf_done_int_set) \ - item(SPI_LL_INTR_WRBUF, dma_int_ena.slv_wr_buf_done_int_ena, dma_int_raw.slv_wr_buf_done_int_raw, dma_int_clr.slv_wr_buf_done_int_clr, dma_int_set.slv_wr_buf_done_int_set) \ - item(SPI_LL_INTR_RDDMA, dma_int_ena.slv_rd_dma_done_int_ena, dma_int_raw.slv_rd_dma_done_int_raw, dma_int_clr.slv_rd_dma_done_int_clr, dma_int_set.slv_rd_dma_done_int_set) \ - item(SPI_LL_INTR_WRDMA, dma_int_ena.slv_wr_dma_done_int_ena, dma_int_raw.slv_wr_dma_done_int_raw, dma_int_clr.slv_wr_dma_done_int_clr, dma_int_set.slv_wr_dma_done_int_set) \ - item(SPI_LL_INTR_SEG_DONE, dma_int_ena.dma_seg_trans_done_int_ena, dma_int_raw.dma_seg_trans_done_int_raw, dma_int_clr.dma_seg_trans_done_int_clr, dma_int_set.dma_seg_trans_done_int_set) \ - item(SPI_LL_INTR_CMD7, dma_int_ena.slv_cmd7_int_ena, dma_int_raw.slv_cmd7_int_raw, dma_int_clr.slv_cmd7_int_clr, dma_int_set.slv_cmd7_int_set) \ - item(SPI_LL_INTR_CMD8, dma_int_ena.slv_cmd8_int_ena, dma_int_raw.slv_cmd8_int_raw, dma_int_clr.slv_cmd8_int_clr, dma_int_set.slv_cmd8_int_set) \ - item(SPI_LL_INTR_CMD9, dma_int_ena.slv_cmd9_int_ena, dma_int_raw.slv_cmd9_int_raw, dma_int_clr.slv_cmd9_int_clr, dma_int_set.slv_cmd9_int_set) \ - item(SPI_LL_INTR_CMDA, dma_int_ena.slv_cmda_int_ena, dma_int_raw.slv_cmda_int_raw, dma_int_clr.slv_cmda_int_clr, dma_int_set.slv_cmda_int_set) + item(SPI_LL_INTR_TRANS_DONE, dma_int_ena.trans_done_int_ena, dma_int_raw.trans_done_int_raw, dma_int_clr.trans_done_int_clr, dma_int_set.trans_done_int_set) \ + item(SPI_LL_INTR_IN_FULL, dma_int_ena.dma_infifo_full_err_int_ena, dma_int_raw.dma_infifo_full_err_int_raw, dma_int_clr.dma_infifo_full_err_int_clr, dma_int_set.dma_infifo_full_err_int_set) \ + item(SPI_LL_INTR_OUT_EMPTY, dma_int_ena.dma_outfifo_empty_err_int_ena, dma_int_raw.dma_outfifo_empty_err_int_raw, dma_int_clr.dma_outfifo_empty_err_int_clr, dma_int_set.dma_outfifo_empty_err_int_set) \ + item(SPI_LL_INTR_RDBUF, dma_int_ena.slv_rd_buf_done_int_ena, dma_int_raw.slv_rd_buf_done_int_raw, dma_int_clr.slv_rd_buf_done_int_clr, dma_int_set.slv_rd_buf_done_int_set) \ + item(SPI_LL_INTR_WRBUF, dma_int_ena.slv_wr_buf_done_int_ena, dma_int_raw.slv_wr_buf_done_int_raw, dma_int_clr.slv_wr_buf_done_int_clr, dma_int_set.slv_wr_buf_done_int_set) \ + item(SPI_LL_INTR_RDDMA, dma_int_ena.slv_rd_dma_done_int_ena, dma_int_raw.slv_rd_dma_done_int_raw, dma_int_clr.slv_rd_dma_done_int_clr, dma_int_set.slv_rd_dma_done_int_set) \ + item(SPI_LL_INTR_WRDMA, dma_int_ena.slv_wr_dma_done_int_ena, dma_int_raw.slv_wr_dma_done_int_raw, dma_int_clr.slv_wr_dma_done_int_clr, dma_int_set.slv_wr_dma_done_int_set) \ + item(SPI_LL_INTR_SEG_DONE, dma_int_ena.dma_seg_trans_done_int_ena, dma_int_raw.dma_seg_trans_done_int_raw, dma_int_clr.dma_seg_trans_done_int_clr, dma_int_set.dma_seg_trans_done_int_set) \ + item(SPI_LL_INTR_CMD7, dma_int_ena.slv_cmd7_int_ena, dma_int_raw.slv_cmd7_int_raw, dma_int_clr.slv_cmd7_int_clr, dma_int_set.slv_cmd7_int_set) \ + item(SPI_LL_INTR_CMD8, dma_int_ena.slv_cmd8_int_ena, dma_int_raw.slv_cmd8_int_raw, dma_int_clr.slv_cmd8_int_clr, dma_int_set.slv_cmd8_int_set) \ + item(SPI_LL_INTR_CMD9, dma_int_ena.slv_cmd9_int_ena, dma_int_raw.slv_cmd9_int_raw, dma_int_clr.slv_cmd9_int_clr, dma_int_set.slv_cmd9_int_set) \ + item(SPI_LL_INTR_CMDA, dma_int_ena.slv_cmda_int_ena, dma_int_raw.slv_cmda_int_raw, dma_int_clr.slv_cmda_int_clr, dma_int_set.slv_cmda_int_set) static inline void spi_ll_enable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask) diff --git a/components/hal/esp32c61/include/hal/spi_ll.h b/components/hal/esp32c61/include/hal/spi_ll.h index 4c8bf5edb2..6a6918a63f 100644 --- a/components/hal/esp32c61/include/hal/spi_ll.h +++ b/components/hal/esp32c61/include/hal/spi_ll.h @@ -54,6 +54,8 @@ typedef spi_dev_t spi_dma_dev_t; // Type definition of all supported interrupts typedef enum { SPI_LL_INTR_TRANS_DONE = BIT(0), ///< A transaction has done + SPI_LL_INTR_IN_FULL = BIT(4), ///< DMA in_full error happened + SPI_LL_INTR_OUT_EMPTY = BIT(5), ///< DMA out_empty error happened SPI_LL_INTR_RDBUF = BIT(6), ///< Has received RDBUF command. Only available in slave HD. SPI_LL_INTR_WRBUF = BIT(7), ///< Has received WRBUF command. Only available in slave HD. SPI_LL_INTR_RDDMA = BIT(8), ///< Has received RDDMA command. Only available in slave HD. @@ -1099,16 +1101,18 @@ static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw) //helper macros to generate code for each interrupts #define FOR_EACH_ITEM(op, list) do { list(op) } while(0) #define INTR_LIST(item) \ - item(SPI_LL_INTR_TRANS_DONE, dma_int_ena.trans_done, dma_int_raw.trans_done, dma_int_clr.trans_done, dma_int_set.trans_done) \ - item(SPI_LL_INTR_RDBUF, dma_int_ena.slv_rd_buf_done, dma_int_raw.slv_rd_buf_done, dma_int_clr.slv_rd_buf_done, dma_int_set.slv_rd_buf_done) \ - item(SPI_LL_INTR_WRBUF, dma_int_ena.slv_wr_buf_done, dma_int_raw.slv_wr_buf_done, dma_int_clr.slv_wr_buf_done, dma_int_set.slv_wr_buf_done) \ - item(SPI_LL_INTR_RDDMA, dma_int_ena.slv_rd_dma_done, dma_int_raw.slv_rd_dma_done, dma_int_clr.slv_rd_dma_done, dma_int_set.slv_rd_dma_done) \ - item(SPI_LL_INTR_WRDMA, dma_int_ena.slv_wr_dma_done, dma_int_raw.slv_wr_dma_done, dma_int_clr.slv_wr_dma_done, dma_int_set.slv_wr_dma_done) \ - item(SPI_LL_INTR_SEG_DONE, dma_int_ena.dma_seg_trans_done, dma_int_raw.dma_seg_trans_done, dma_int_clr.dma_seg_trans_done, dma_int_set.dma_seg_trans_done) \ - item(SPI_LL_INTR_CMD7, dma_int_ena.slv_cmd7, dma_int_raw.slv_cmd7, dma_int_clr.slv_cmd7, dma_int_set.slv_cmd7) \ - item(SPI_LL_INTR_CMD8, dma_int_ena.slv_cmd8, dma_int_raw.slv_cmd8, dma_int_clr.slv_cmd8, dma_int_set.slv_cmd8) \ - item(SPI_LL_INTR_CMD9, dma_int_ena.slv_cmd9, dma_int_raw.slv_cmd9, dma_int_clr.slv_cmd9, dma_int_set.slv_cmd9) \ - item(SPI_LL_INTR_CMDA, dma_int_ena.slv_cmda, dma_int_raw.slv_cmda, dma_int_clr.slv_cmda, dma_int_set.slv_cmda) + item(SPI_LL_INTR_TRANS_DONE, dma_int_ena.trans_done, dma_int_raw.trans_done, dma_int_clr.trans_done, dma_int_set.trans_done) \ + item(SPI_LL_INTR_IN_FULL, dma_int_ena.dma_infifo_full_err, dma_int_raw.dma_infifo_full_err, dma_int_clr.dma_infifo_full_err, dma_int_set.dma_infifo_full_err) \ + item(SPI_LL_INTR_OUT_EMPTY, dma_int_ena.dma_outfifo_empty_err, dma_int_raw.dma_outfifo_empty_err, dma_int_clr.dma_outfifo_empty_err, dma_int_set.dma_outfifo_empty_err) \ + item(SPI_LL_INTR_RDBUF, dma_int_ena.slv_rd_buf_done, dma_int_raw.slv_rd_buf_done, dma_int_clr.slv_rd_buf_done, dma_int_set.slv_rd_buf_done) \ + item(SPI_LL_INTR_WRBUF, dma_int_ena.slv_wr_buf_done, dma_int_raw.slv_wr_buf_done, dma_int_clr.slv_wr_buf_done, dma_int_set.slv_wr_buf_done) \ + item(SPI_LL_INTR_RDDMA, dma_int_ena.slv_rd_dma_done, dma_int_raw.slv_rd_dma_done, dma_int_clr.slv_rd_dma_done, dma_int_set.slv_rd_dma_done) \ + item(SPI_LL_INTR_WRDMA, dma_int_ena.slv_wr_dma_done, dma_int_raw.slv_wr_dma_done, dma_int_clr.slv_wr_dma_done, dma_int_set.slv_wr_dma_done) \ + item(SPI_LL_INTR_SEG_DONE, dma_int_ena.dma_seg_trans_done, dma_int_raw.dma_seg_trans_done, dma_int_clr.dma_seg_trans_done, dma_int_set.dma_seg_trans_done) \ + item(SPI_LL_INTR_CMD7, dma_int_ena.slv_cmd7, dma_int_raw.slv_cmd7, dma_int_clr.slv_cmd7, dma_int_set.slv_cmd7) \ + item(SPI_LL_INTR_CMD8, dma_int_ena.slv_cmd8, dma_int_raw.slv_cmd8, dma_int_clr.slv_cmd8, dma_int_set.slv_cmd8) \ + item(SPI_LL_INTR_CMD9, dma_int_ena.slv_cmd9, dma_int_raw.slv_cmd9, dma_int_clr.slv_cmd9, dma_int_set.slv_cmd9) \ + item(SPI_LL_INTR_CMDA, dma_int_ena.slv_cmda, dma_int_raw.slv_cmda, dma_int_clr.slv_cmda, dma_int_set.slv_cmda) static inline void spi_ll_enable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask) diff --git a/components/hal/esp32p4/include/hal/spi_ll.h b/components/hal/esp32p4/include/hal/spi_ll.h index 04a895d421..d5f335087e 100644 --- a/components/hal/esp32p4/include/hal/spi_ll.h +++ b/components/hal/esp32p4/include/hal/spi_ll.h @@ -56,6 +56,8 @@ typedef spi_dev_t spi_dma_dev_t; // Type definition of all supported interrupts typedef enum { SPI_LL_INTR_TRANS_DONE = BIT(0), ///< A transaction has done + SPI_LL_INTR_IN_FULL = BIT(4), ///< DMA in_full error happened + SPI_LL_INTR_OUT_EMPTY = BIT(5), ///< DMA out_empty error happened SPI_LL_INTR_RDBUF = BIT(6), ///< Has received RDBUF command. Only available in slave HD. SPI_LL_INTR_WRBUF = BIT(7), ///< Has received WRBUF command. Only available in slave HD. SPI_LL_INTR_RDDMA = BIT(8), ///< Has received RDDMA command. Only available in slave HD. @@ -1155,16 +1157,18 @@ static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw) //helper macros to generate code for each interrupts #define FOR_EACH_ITEM(op, list) do { list(op) } while(0) #define INTR_LIST(item) \ - item(SPI_LL_INTR_TRANS_DONE, dma_int_ena.trans_done_int, dma_int_raw.trans_done_int, dma_int_clr.trans_done_int, dma_int_set.trans_done_int) \ - item(SPI_LL_INTR_RDBUF, dma_int_ena.slv_rd_buf_done_int, dma_int_raw.slv_rd_buf_done_int, dma_int_clr.slv_rd_buf_done_int, dma_int_set.slv_rd_buf_done_int) \ - item(SPI_LL_INTR_WRBUF, dma_int_ena.slv_wr_buf_done_int, dma_int_raw.slv_wr_buf_done_int, dma_int_clr.slv_wr_buf_done_int, dma_int_set.slv_wr_buf_done_int) \ - item(SPI_LL_INTR_RDDMA, dma_int_ena.slv_rd_dma_done_int, dma_int_raw.slv_rd_dma_done_int, dma_int_clr.slv_rd_dma_done_int, dma_int_set.slv_rd_dma_done_int) \ - item(SPI_LL_INTR_WRDMA, dma_int_ena.slv_wr_dma_done_int, dma_int_raw.slv_wr_dma_done_int, dma_int_clr.slv_wr_dma_done_int, dma_int_set.slv_wr_dma_done_int) \ - item(SPI_LL_INTR_SEG_DONE, dma_int_ena.dma_seg_trans_done_int, dma_int_raw.dma_seg_trans_done_int, dma_int_clr.dma_seg_trans_done_int, dma_int_set.dma_seg_trans_done_int) \ - item(SPI_LL_INTR_CMD7, dma_int_ena.slv_cmd7_int, dma_int_raw.slv_cmd7_int, dma_int_clr.slv_cmd7_int, dma_int_set.slv_cmd7_int) \ - item(SPI_LL_INTR_CMD8, dma_int_ena.slv_cmd8_int, dma_int_raw.slv_cmd8_int, dma_int_clr.slv_cmd8_int, dma_int_set.slv_cmd8_int) \ - item(SPI_LL_INTR_CMD9, dma_int_ena.slv_cmd9_int, dma_int_raw.slv_cmd9_int, dma_int_clr.slv_cmd9_int, dma_int_set.slv_cmd9_int) \ - item(SPI_LL_INTR_CMDA, dma_int_ena.slv_cmda_int, dma_int_raw.slv_cmda_int, dma_int_clr.slv_cmda_int, dma_int_set.slv_cmda_int) + item(SPI_LL_INTR_TRANS_DONE, dma_int_ena.trans_done_int, dma_int_raw.trans_done_int, dma_int_clr.trans_done_int, dma_int_set.trans_done_int) \ + item(SPI_LL_INTR_IN_FULL, dma_int_ena.dma_infifo_full_err_int, dma_int_raw.dma_infifo_full_err_int, dma_int_clr.dma_infifo_full_err_int, dma_int_set.dma_infifo_full_err_int) \ + item(SPI_LL_INTR_OUT_EMPTY, dma_int_ena.dma_outfifo_empty_err_int, dma_int_raw.dma_outfifo_empty_err_int, dma_int_clr.dma_outfifo_empty_err_int, dma_int_set.dma_outfifo_empty_err_int) \ + item(SPI_LL_INTR_RDBUF, dma_int_ena.slv_rd_buf_done_int, dma_int_raw.slv_rd_buf_done_int, dma_int_clr.slv_rd_buf_done_int, dma_int_set.slv_rd_buf_done_int) \ + item(SPI_LL_INTR_WRBUF, dma_int_ena.slv_wr_buf_done_int, dma_int_raw.slv_wr_buf_done_int, dma_int_clr.slv_wr_buf_done_int, dma_int_set.slv_wr_buf_done_int) \ + item(SPI_LL_INTR_RDDMA, dma_int_ena.slv_rd_dma_done_int, dma_int_raw.slv_rd_dma_done_int, dma_int_clr.slv_rd_dma_done_int, dma_int_set.slv_rd_dma_done_int) \ + item(SPI_LL_INTR_WRDMA, dma_int_ena.slv_wr_dma_done_int, dma_int_raw.slv_wr_dma_done_int, dma_int_clr.slv_wr_dma_done_int, dma_int_set.slv_wr_dma_done_int) \ + item(SPI_LL_INTR_SEG_DONE, dma_int_ena.dma_seg_trans_done_int, dma_int_raw.dma_seg_trans_done_int, dma_int_clr.dma_seg_trans_done_int, dma_int_set.dma_seg_trans_done_int) \ + item(SPI_LL_INTR_CMD7, dma_int_ena.slv_cmd7_int, dma_int_raw.slv_cmd7_int, dma_int_clr.slv_cmd7_int, dma_int_set.slv_cmd7_int) \ + item(SPI_LL_INTR_CMD8, dma_int_ena.slv_cmd8_int, dma_int_raw.slv_cmd8_int, dma_int_clr.slv_cmd8_int, dma_int_set.slv_cmd8_int) \ + item(SPI_LL_INTR_CMD9, dma_int_ena.slv_cmd9_int, dma_int_raw.slv_cmd9_int, dma_int_clr.slv_cmd9_int, dma_int_set.slv_cmd9_int) \ + item(SPI_LL_INTR_CMDA, dma_int_ena.slv_cmda_int, dma_int_raw.slv_cmda_int, dma_int_clr.slv_cmda_int, dma_int_set.slv_cmda_int) static inline void spi_ll_enable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask) diff --git a/components/hal/esp32s3/include/hal/spi_ll.h b/components/hal/esp32s3/include/hal/spi_ll.h index c3db5cbd26..a318f40a86 100644 --- a/components/hal/esp32s3/include/hal/spi_ll.h +++ b/components/hal/esp32s3/include/hal/spi_ll.h @@ -56,6 +56,8 @@ typedef spi_dev_t spi_dma_dev_t; // Type definition of all supported interrupts typedef enum { SPI_LL_INTR_TRANS_DONE = BIT(0), ///< A transaction has done + SPI_LL_INTR_IN_FULL = BIT(4), ///< DMA in_full error happened + SPI_LL_INTR_OUT_EMPTY = BIT(5), ///< DMA out_empty error happened SPI_LL_INTR_RDBUF = BIT(6), ///< Has received RDBUF command. Only available in slave HD. SPI_LL_INTR_WRBUF = BIT(7), ///< Has received WRBUF command. Only available in slave HD. SPI_LL_INTR_RDDMA = BIT(8), ///< Has received RDDMA command. Only available in slave HD. @@ -1107,6 +1109,8 @@ static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw) #define FOR_EACH_ITEM(op, list) do { list(op) } while(0) #define INTR_LIST(item) \ item(SPI_LL_INTR_TRANS_DONE, dma_int_ena.trans_done, dma_int_raw.trans_done, dma_int_clr.trans_done, dma_int_set.trans_done_int_set) \ + item(SPI_LL_INTR_IN_FULL, dma_int_ena.infifo_full_err, dma_int_raw.infifo_full_err, dma_int_clr.infifo_full_err, dma_int_set.infifo_full_err_int_set) \ + item(SPI_LL_INTR_OUT_EMPTY, dma_int_ena.outfifo_empty_err, dma_int_raw.outfifo_empty_err, dma_int_clr.outfifo_empty_err, dma_int_set.outfifo_empty_err_int_set) \ item(SPI_LL_INTR_RDBUF, dma_int_ena.rd_buf_done, dma_int_raw.rd_buf_done, dma_int_clr.rd_buf_done, dma_int_set.rd_buf_done_int_set) \ item(SPI_LL_INTR_WRBUF, dma_int_ena.wr_buf_done, dma_int_raw.wr_buf_done, dma_int_clr.wr_buf_done, dma_int_set.wr_buf_done_int_set) \ item(SPI_LL_INTR_RDDMA, dma_int_ena.rd_dma_done, dma_int_raw.rd_dma_done, dma_int_clr.rd_dma_done, dma_int_set.rd_dma_done_int_set) \ diff --git a/components/hal/include/hal/spi_hal.h b/components/hal/include/hal/spi_hal.h index c9d2e136e8..3dacc434c8 100644 --- a/components/hal/include/hal/spi_hal.h +++ b/components/hal/include/hal/spi_hal.h @@ -240,6 +240,23 @@ void spi_hal_user_start(const spi_hal_context_t *hal); */ bool spi_hal_usr_is_done(const spi_hal_context_t *hal); +/** + * Get SPI interrupt bits status by mask + * + * @param hal Context of the HAL layer. + * @param mask Mask of the interrupt bits to check. + * @return True if the masked interrupts are set, false otherwise. + */ +bool spi_hal_get_intr_mask(spi_hal_context_t *hal, uint32_t mask); + +/** + * Clear SPI interrupt bits by mask + * + * @param hal Context of the HAL layer. + * @param mask Mask of the interrupt bits to clear. + */ +void spi_hal_clear_intr_mask(spi_hal_context_t *hal, uint32_t mask); + /** * Setup transaction operations, write tx buffer to HW registers * @@ -342,16 +359,6 @@ void spi_hal_sct_deinit(spi_hal_context_t *hal); */ void spi_hal_sct_set_conf_bits_len(spi_hal_context_t *hal, uint32_t conf_len); -/** - * Clear SPI interrupt bits by mask - */ -void spi_hal_clear_intr_mask(spi_hal_context_t *hal, uint32_t mask); - -/** - * Get SPI interrupt bits status by mask - */ -bool spi_hal_get_intr_mask(spi_hal_context_t *hal, uint32_t mask); - /** * Set conf_bitslen base to HW for sct, only supported on s2. */ diff --git a/components/hal/spi_hal_iram.c b/components/hal/spi_hal_iram.c index 1b38660a58..35d6ecd4f9 100644 --- a/components/hal/spi_hal_iram.c +++ b/components/hal/spi_hal_iram.c @@ -235,6 +235,16 @@ bool spi_hal_usr_is_done(const spi_hal_context_t *hal) return spi_ll_usr_is_done(hal->hw); } +#if SOC_SPI_SUPPORT_SLAVE_HD_VER2 +bool spi_hal_get_intr_mask(spi_hal_context_t *hal, uint32_t mask) { + return spi_ll_get_intr(hal->hw, mask); +} + +void spi_hal_clear_intr_mask(spi_hal_context_t *hal, uint32_t mask) { + spi_ll_clear_intr(hal->hw, mask); +} +#endif + void spi_hal_push_tx_buffer(const spi_hal_context_t *hal, const spi_hal_trans_config_t *hal_trans) { if (hal_trans->send_buffer) { @@ -256,15 +266,7 @@ void spi_hal_fetch_result(const spi_hal_context_t *hal) #if SOC_SPI_SCT_SUPPORTED /*------------------------------------------------------------------------------ * Segmented-Configure-Transfer - *----------------------------------------------------------------------------*/ -void spi_hal_clear_intr_mask(spi_hal_context_t *hal, uint32_t mask) { - spi_ll_clear_intr(hal->hw, mask); -} - -bool spi_hal_get_intr_mask(spi_hal_context_t *hal, uint32_t mask) { - return spi_ll_get_intr(hal->hw, mask); -} - +*----------------------------------------------------------------------------*/ void spi_hal_sct_set_conf_bits_len(spi_hal_context_t *hal, uint32_t conf_len) { spi_ll_set_conf_phase_bits_len(hal->hw, conf_len); } diff --git a/docs/en/api-reference/peripherals/spi_master.rst b/docs/en/api-reference/peripherals/spi_master.rst index 6c002fa84f..92c7eda4c7 100644 --- a/docs/en/api-reference/peripherals/spi_master.rst +++ b/docs/en/api-reference/peripherals/spi_master.rst @@ -353,6 +353,15 @@ Driver Usage The example code for the SPI Master driver can be found in the :example:`peripherals/spi_master` directory of ESP-IDF examples. +.. only:: SOC_PSRAM_DMA_CAPABLE + + Transactions with Data on PSRAM + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + {IDF_TARGET_NAME} supports GPSPI Master with DMA transferring data from/to PSRAM directly without extra internal copy process, by adding :c:macro:`SPI_TRANS_DMA_USE_PSRAM` flag to the transaction. Some requirements for PSRAM transactions are: + + 1. The data memory **address** and **transaction length** must both be aligned to cache length, usually the cache length is 16/32/64 bytes. + 2. This feature shares bandwidth with MSPI bus, so GPSPI transfer bandwidth should be less than PSRAM bandwidth, **otherwise transmission data may be lost**. You can check the :c:macro:`SPI_TRANS_DMA_RX_FAIL` and :c:macro:`SPI_TRANS_DMA_TX_FAIL` flags after the transaction is finished to check if error occurs during the transmission. Transactions with Data Not Exceeding 32 Bits ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/zh_CN/api-reference/peripherals/spi_master.rst b/docs/zh_CN/api-reference/peripherals/spi_master.rst index beb77711c6..a67bb05ed4 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_master.rst +++ b/docs/zh_CN/api-reference/peripherals/spi_master.rst @@ -353,6 +353,15 @@ SPI 总线传输事务由五个阶段构成,详见下表(任意阶段均可 SPI 主机驱动程序的示例代码存放在 ESP-IDF 示例项目的 :example:`peripherals/spi_master` 目录下。 +.. only:: SOC_PSRAM_DMA_CAPABLE + + 使用 PSRAM 的传输事务 + ^^^^^^^^^^^^^^^^^^^^^^ + + {IDF_TARGET_NAME} 支持 GPSPI Master 通过 DMA 直接传输 PSRAM 存储的数据而不用内部额外的拷贝过程,在传输配置中添加 :c:macro:`SPI_TRANS_DMA_USE_PSRAM` 标志信号即可使用。使用 PSRAM 传输事务时,请注意以下几点: + + 1. 数据内存 **地址** 和 **传输长度** 都需要与 Cache 长度对齐,通常 Cache 长度为 16/32/64 字节。 + 2. 因为该功能与 MSPI 总线共享带宽,因此 GPSPI 传输带宽应小于 PSRAM 带宽,否则 **可能会丢失传输数据**。可通过在传输结束时检查 :c:macro:`SPI_TRANS_DMA_RX_FAIL` 和 :c:macro:`SPI_TRANS_DMA_TX_FAIL` 标志信号来判断传输是否发生了错误。 传输数据小于 32 位的传输事务 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 32895539f2f961673094de4c92812fe0571fb142 Mon Sep 17 00:00:00 2001 From: wanckl Date: Mon, 18 Aug 2025 22:12:43 +0800 Subject: [PATCH 093/226] fix(driver_spi): support un-aligned dma transaction and psram transaction --- .../include/esp_private/spi_common_internal.h | 13 +- .../include/esp_private/spi_dma.h | 10 ++ .../esp_driver_spi/src/gpspi/spi_common.c | 47 ++--- components/esp_driver_spi/src/gpspi/spi_dma.c | 12 ++ .../esp_driver_spi/src/gpspi/spi_master.c | 165 ++++++------------ .../test_apps/master/main/test_spi_master.c | 52 +++--- .../test_apps/slave/main/test_spi_slave.c | 1 + components/hal/esp32/include/hal/spi_ll.h | 13 ++ components/hal/esp32s2/include/hal/spi_ll.h | 14 ++ .../api-reference/peripherals/spi_master.rst | 5 +- .../api-reference/peripherals/spi_master.rst | 5 +- .../spi_master/lcd/main/Kconfig.projbuild | 9 + .../spi_master/lcd/main/pretty_effect.c | 6 +- .../lcd/main/spi_master_example_main.c | 14 +- 14 files changed, 202 insertions(+), 164 deletions(-) diff --git a/components/esp_driver_spi/include/esp_private/spi_common_internal.h b/components/esp_driver_spi/include/esp_private/spi_common_internal.h index 9e374c991d..ba0a11a692 100644 --- a/components/esp_driver_spi/include/esp_private/spi_common_internal.h +++ b/components/esp_driver_spi/include/esp_private/spi_common_internal.h @@ -56,7 +56,8 @@ typedef struct { uint32_t flags; ///< Flags (attributes) of the bus int max_transfer_sz; ///< Maximum length of bytes available to send bool dma_enabled; ///< To enable DMA or not - size_t internal_mem_align_size; ///< Buffer align byte requirement for internal memory + size_t cache_align_int; ///< Internal memory align byte requirement + size_t cache_align_ext; ///< External memory align byte requirement spi_bus_lock_handle_t lock; #ifdef CONFIG_PM_ENABLE esp_pm_lock_handle_t pm_lock; ///< Power management lock @@ -71,9 +72,13 @@ typedef struct { spi_dma_chan_handle_t tx_dma_chan; ///< TX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same spi_dma_chan_handle_t rx_dma_chan; ///< RX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same #endif - int dma_desc_num; ///< DMA descriptor number of dmadesc_tx or dmadesc_rx. - spi_dma_desc_t *dmadesc_tx; ///< DMA descriptor array for TX - spi_dma_desc_t *dmadesc_rx; ///< DMA descriptor array for RX + size_t dma_align_tx_int; ///< Internal memory align byte requirement for TX + size_t dma_align_tx_ext; ///< External memory align byte requirement for TX + size_t dma_align_rx_int; ///< Internal memory align byte requirement for RX + size_t dma_align_rx_ext; ///< External memory align byte requirement for RX + int dma_desc_num; ///< DMA descriptor number of dmadesc_tx or dmadesc_rx. + spi_dma_desc_t *dmadesc_tx; ///< DMA descriptor array for TX + spi_dma_desc_t *dmadesc_rx; ///< DMA descriptor array for RX } spi_dma_ctx_t; /// Destructor called when a bus is deinitialized. diff --git a/components/esp_driver_spi/include/esp_private/spi_dma.h b/components/esp_driver_spi/include/esp_private/spi_dma.h index 32c4c9e94b..38cf08020d 100644 --- a/components/esp_driver_spi/include/esp_private/spi_dma.h +++ b/components/esp_driver_spi/include/esp_private/spi_dma.h @@ -5,6 +5,7 @@ */ #pragma once +#include #include "stdbool.h" #include "hal/spi_types.h" @@ -36,6 +37,15 @@ typedef struct { */ void spi_dma_enable_burst(spi_dma_chan_handle_t chan_handle, bool data_burst, bool desc_burst); +/** + * Get the alignment constraints for DMA + * + * @param chan_handle Context of the spi_dma channel. + * @param internal_size The alignment size for internal memory. + * @param external_size The alignment size for external memory. + */ +void spi_dma_get_alignment_constraints(spi_dma_chan_handle_t chan_handle, size_t *internal_size, size_t *external_size); + /** * Re-trigger a HW pre-load to pick up appended linked descriptor * diff --git a/components/esp_driver_spi/src/gpspi/spi_common.c b/components/esp_driver_spi/src/gpspi/spi_common.c index 98da337c77..1558541b99 100644 --- a/components/esp_driver_spi/src/gpspi/spi_common.c +++ b/components/esp_driver_spi/src/gpspi/spi_common.c @@ -6,6 +6,7 @@ #include #include +#include #include "sdkconfig.h" #include "esp_types.h" #include "esp_attr.h" @@ -214,6 +215,10 @@ static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_ch spi_dma_enable_burst(dma_ctx->tx_dma_chan, true, true); spi_dma_enable_burst(dma_ctx->rx_dma_chan, true, true); + + // Get DMA alignment constraints + spi_dma_get_alignment_constraints(dma_ctx->tx_dma_chan, &dma_ctx->dma_align_tx_int, &dma_ctx->dma_align_tx_ext); + spi_dma_get_alignment_constraints(dma_ctx->rx_dma_chan, &dma_ctx->dma_align_rx_int, &dma_ctx->dma_align_rx_ext); return ret; } @@ -254,13 +259,16 @@ static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_ch gdma_connect(dma_ctx->rx_dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 3)); } #endif - // TODO: add support to allow SPI transfer PSRAM buffer gdma_transfer_config_t trans_cfg = { .max_data_burst_size = 32, - .access_ext_mem = false, + .access_ext_mem = true, // allow to transfer data from/to external memory directly by DMA }; ESP_RETURN_ON_ERROR(gdma_config_transfer(dma_ctx->tx_dma_chan, &trans_cfg), SPI_TAG, "config gdma tx transfer failed"); ESP_RETURN_ON_ERROR(gdma_config_transfer(dma_ctx->rx_dma_chan, &trans_cfg), SPI_TAG, "config gdma rx transfer failed"); + + // Get DMA alignment constraints + gdma_get_alignment_constraints(dma_ctx->tx_dma_chan, &dma_ctx->dma_align_tx_int, &dma_ctx->dma_align_tx_ext); + gdma_get_alignment_constraints(dma_ctx->rx_dma_chan, &dma_ctx->dma_align_rx_int, &dma_ctx->dma_align_rx_ext); } return ret; } @@ -646,7 +654,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT_OUTPUT); esp_rom_gpio_connect_out_signal(bus_config->mosi_io_num, spi_periph_signal[host].spid_out, false, false); } else { - gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT); + gpio_input_enable(bus_config->mosi_io_num); } esp_rom_gpio_connect_in_signal(bus_config->mosi_io_num, spi_periph_signal[host].spid_in, false); #if CONFIG_IDF_TARGET_ESP32S2 @@ -659,7 +667,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT_OUTPUT); esp_rom_gpio_connect_out_signal(bus_config->miso_io_num, spi_periph_signal[host].spiq_out, false, false); } else { - gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT); + gpio_input_enable(bus_config->miso_io_num); } esp_rom_gpio_connect_in_signal(bus_config->miso_io_num, spi_periph_signal[host].spiq_in, false); #if CONFIG_IDF_TARGET_ESP32S2 @@ -837,9 +845,9 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t * bus_attr = &ctx->bus_attr; bus_attr->bus_cfg = *bus_config; - if (dma_chan != SPI_DMA_DISABLED) { - bus_attr->dma_enabled = 1; - + bus_attr->dma_enabled = (dma_chan != SPI_DMA_DISABLED); + bus_attr->max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE; + if (bus_attr->dma_enabled) { err = spicommon_dma_chan_alloc(host_id, dma_chan, &ctx->dma_ctx); if (err != ESP_OK) { goto cleanup; @@ -848,14 +856,10 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t * if (err != ESP_OK) { goto cleanup; } -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - esp_cache_get_alignment(MALLOC_CAP_DMA, (size_t *)&bus_attr->internal_mem_align_size); -#else - bus_attr->internal_mem_align_size = 4; -#endif - } else { - bus_attr->dma_enabled = 0; - bus_attr->max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE; + + // Get cache alignment constraints + esp_cache_get_alignment(MALLOC_CAP_DMA, &bus_attr->cache_align_int); + esp_cache_get_alignment(MALLOC_CAP_SPIRAM, &bus_attr->cache_align_ext); } spi_bus_lock_config_t lock_config = { @@ -939,11 +943,14 @@ cleanup: void *spi_bus_dma_memory_alloc(spi_host_device_t host_id, size_t size, uint32_t extra_heap_caps) { - (void) host_id; //remain for extendability - ESP_RETURN_ON_FALSE((extra_heap_caps & MALLOC_CAP_SPIRAM) == 0, NULL, SPI_TAG, "external memory is not supported now"); - - size_t dma_requir = 16; //TODO: IDF-10111, using max alignment temp, refactor to "gdma_get_alignment_constraints" instead - return heap_caps_aligned_calloc(dma_requir, 1, size, extra_heap_caps | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + size_t alignment = 16; + // As don't know the buffer will used for TX or RX, so use the max alignment requirement + if (bus_ctx[host_id] && bus_ctx[host_id]->dma_ctx) { + alignment = (extra_heap_caps & MALLOC_CAP_SPIRAM) ? \ + MAX(bus_ctx[host_id]->dma_ctx->dma_align_tx_ext, bus_ctx[host_id]->dma_ctx->dma_align_rx_ext) : \ + MAX(bus_ctx[host_id]->dma_ctx->dma_align_tx_int, bus_ctx[host_id]->dma_ctx->dma_align_rx_int); + } + return heap_caps_aligned_calloc(alignment, 1, size, extra_heap_caps | MALLOC_CAP_DMA); } const spi_bus_attr_t* spi_bus_get_attr(spi_host_device_t host_id) diff --git a/components/esp_driver_spi/src/gpspi/spi_dma.c b/components/esp_driver_spi/src/gpspi/spi_dma.c index a02bf43df8..84c913a13c 100644 --- a/components/esp_driver_spi/src/gpspi/spi_dma.c +++ b/components/esp_driver_spi/src/gpspi/spi_dma.c @@ -27,6 +27,18 @@ void spi_dma_enable_burst(spi_dma_chan_handle_t chan_handle, bool data_burst, bo } } +void spi_dma_get_alignment_constraints(spi_dma_chan_handle_t chan_handle, size_t *internal_size, size_t *external_size) +{ + spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id); + + if (chan_handle.dir == DMA_CHANNEL_DIRECTION_TX) { + *internal_size = 1; // TX don't need to follow dma alignment in driver design + *external_size = 1; + } else { + spi_dma_ll_get_rx_alignment_require(spi_dma, (uint32_t *)internal_size, (uint32_t *)external_size); + } +} + #if SOC_SPI_SUPPORT_SLAVE_HD_VER2 void spi_dma_append(spi_dma_chan_handle_t chan_handle) { diff --git a/components/esp_driver_spi/src/gpspi/spi_master.c b/components/esp_driver_spi/src/gpspi/spi_master.c index 1493dd5e98..cf85c00b9b 100644 --- a/components/esp_driver_spi/src/gpspi/spi_master.c +++ b/components/esp_driver_spi/src/gpspi/spi_master.c @@ -176,7 +176,7 @@ We have two bits to control the interrupt: #define B_EDMA_SETUP_TIME_US 1 #define SPI_EDMA_SETUP_TIME_US(spi_speed) ((spi_speed) * K_EDMA_SETUP_RATIO / CONFIG_SPIRAM_SPEED + B_EDMA_SETUP_TIME_US) -ESP_LOG_ATTR_TAG_DRAM(SPI_TAG, "spi_master"); +static const char *SPI_TAG = "spi_master"; #define SPI_CHECK(a, str, ret_val, ...) ESP_RETURN_ON_FALSE_ISR(a, ret_val, SPI_TAG, str, ##__VA_ARGS__) typedef struct spi_device_t spi_device_t; @@ -772,31 +772,13 @@ static void SPI_MASTER_ISR_ATTR s_spi_dma_prepare_data(spi_host_t *host, spi_hal } } -static void SPI_MASTER_ISR_ATTR s_spi_prepare_data(spi_device_t *dev, const spi_hal_trans_config_t *hal_trans) -{ - spi_host_t *host = dev->host; - spi_hal_dev_config_t *hal_dev = &(dev->hal_dev); - spi_hal_context_t *hal = &(host->hal); - - if (host->bus_attr->dma_enabled) { - s_spi_dma_prepare_data(host, hal, hal_dev, hal_trans); - } else { - //Need to copy data to registers manually - spi_hal_push_tx_buffer(hal, hal_trans); - } - - //in ESP32 these registers should be configured after the DMA is set - spi_hal_enable_data_line(hal->hw, (!hal_dev->half_duplex && hal_trans->rcv_buffer) || hal_trans->send_buffer, !!hal_trans->rcv_buffer); -} - static void SPI_MASTER_ISR_ATTR spi_format_hal_trans_struct(spi_device_t *dev, spi_trans_priv_t *trans_buf, spi_hal_trans_config_t *hal_trans) { - spi_host_t *host = dev->host; spi_transaction_t *trans = trans_buf->trans; hal_trans->tx_bitlen = trans->length; hal_trans->rx_bitlen = trans->rxlength; - hal_trans->rcv_buffer = (uint8_t*)host->cur_trans_buf.buffer_to_rcv; - hal_trans->send_buffer = (uint8_t*)host->cur_trans_buf.buffer_to_send; + hal_trans->rcv_buffer = (uint8_t *)trans_buf->buffer_to_rcv; + hal_trans->send_buffer = (uint8_t *)trans_buf->buffer_to_send; hal_trans->cmd = trans->cmd; hal_trans->addr = trans->addr; @@ -832,6 +814,7 @@ static void SPI_MASTER_ISR_ATTR spi_format_hal_trans_struct(spi_device_t *dev, s // Setup the transaction-specified registers and linked-list used by the DMA (or FIFO if DMA is not used) static void SPI_MASTER_ISR_ATTR spi_new_trans(spi_device_t *dev, spi_trans_priv_t *trans_buf) { + spi_host_t *host = dev->host; spi_transaction_t *trans = trans_buf->trans; spi_hal_context_t *hal = &(dev->host->hal); spi_hal_dev_config_t *hal_dev = &(dev->hal_dev); @@ -845,7 +828,15 @@ static void SPI_MASTER_ISR_ATTR spi_new_trans(spi_device_t *dev, spi_trans_priv_ spi_hal_trans_config_t hal_trans = {}; spi_format_hal_trans_struct(dev, trans_buf, &hal_trans); spi_hal_setup_trans(hal, hal_dev, &hal_trans); - s_spi_prepare_data(dev, &hal_trans); + + if (host->bus_attr->dma_enabled) { + s_spi_dma_prepare_data(host, hal, hal_dev, &hal_trans); + } else { + //Need to copy data to registers manually + spi_hal_push_tx_buffer(hal, &hal_trans); + } + //these registers should be configured after the DMA is set + spi_hal_enable_data_line(hal->hw, (!hal_dev->half_duplex && hal_trans.rcv_buffer) || hal_trans.send_buffer, !!hal_trans.rcv_buffer); //Call pre-transmission callback, if any if (dev->cfg.pre_cb) { @@ -1012,17 +1003,6 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg) //This workaround is only for esp32, where tx_dma_chan and rx_dma_chan are always same spicommon_dmaworkaround_idle(dma_ctx->tx_dma_chan.chan_id); #endif //#if CONFIG_IDF_TARGET_ESP32 - -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE //invalidate here to let user access rx data in post_cb if possible - if (host->cur_trans_buf.buffer_to_rcv) { - uint16_t alignment = bus_attr->internal_mem_align_size; - uint32_t buffer_byte_len = (host->cur_trans_buf.trans->rxlength + 7) / 8; - buffer_byte_len = (buffer_byte_len + alignment - 1) & (~(alignment - 1)); - // invalidate priv_trans.buffer_to_rcv anyway, only user provide aligned buffer can rcv correct data in post_cb - esp_err_t ret = esp_cache_msync((void *)host->cur_trans_buf.buffer_to_rcv, buffer_byte_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); - assert(ret == ESP_OK); - } -#endif spi_trans_dma_error_check(host); } @@ -1175,7 +1155,7 @@ static SPI_MASTER_ISR_ATTR esp_err_t check_trans_valid(spi_device_handle_t handl SPI_CHECK(trans_desc->length <= SPI_LL_CPU_MAX_BIT_LEN, "txdata transfer > hardware max supported len", ESP_ERR_INVALID_ARG); SPI_CHECK(trans_desc->rxlength <= SPI_LL_CPU_MAX_BIT_LEN, "rxdata transfer > hardware max supported len", ESP_ERR_INVALID_ARG); } - if (esp_ptr_external_ram(trans_desc->tx_buffer) || esp_ptr_external_ram(trans_desc->rx_buffer)){ + if (esp_ptr_external_ram(trans_desc->tx_buffer) || esp_ptr_external_ram(trans_desc->rx_buffer)) { SPI_CHECK(spi_flash_cache_enabled(), "Using PSRAM must when cache is enabled", ESP_ERR_INVALID_STATE); } return ESP_OK; @@ -1184,46 +1164,45 @@ static SPI_MASTER_ISR_ATTR esp_err_t check_trans_valid(spi_device_handle_t handl static SPI_MASTER_ISR_ATTR void uninstall_priv_desc(spi_trans_priv_t* trans_buf) { spi_transaction_t *trans_desc = trans_buf->trans; - if ((void *)trans_buf->buffer_to_send != &trans_desc->tx_data[0] && - trans_buf->buffer_to_send != trans_desc->tx_buffer) { + if ((void *)trans_buf->buffer_to_send != trans_desc->tx_data && trans_buf->buffer_to_send != trans_desc->tx_buffer) { free((void *)trans_buf->buffer_to_send); //force free, ignore const } - // copy data from temporary DMA-capable buffer back to IRAM buffer and free the temporary one. - if (trans_buf->buffer_to_rcv && (void *)trans_buf->buffer_to_rcv != &trans_desc->rx_data[0] && trans_buf->buffer_to_rcv != trans_desc->rx_buffer) { // NOLINT(clang-analyzer-unix.Malloc) - if (trans_desc->flags & SPI_TRANS_USE_RXDATA) { - memcpy((uint8_t *) & trans_desc->rx_data[0], trans_buf->buffer_to_rcv, (trans_desc->rxlength + 7) / 8); - } else { - memcpy(trans_desc->rx_buffer, trans_buf->buffer_to_rcv, (trans_desc->rxlength + 7) / 8); - } + + // copy data from temporary DMA-capable buffer back to trans_desc buffer and free the temporary one. + void *orig_rx_buffer = (trans_desc->flags & SPI_TRANS_USE_RXDATA) ? trans_desc->rx_data : trans_desc->rx_buffer; + if (trans_buf->buffer_to_rcv != orig_rx_buffer) { + memcpy(orig_rx_buffer, trans_buf->buffer_to_rcv, (trans_desc->rxlength + 7) / 8); free(trans_buf->buffer_to_rcv); } } -static SPI_MASTER_ISR_ATTR esp_err_t setup_dma_priv_buffer(uint32_t *buffer, uint32_t len, uint32_t alignment, bool is_tx, uint32_t flags, uint32_t **ret_buffer) +static SPI_MASTER_ISR_ATTR esp_err_t setup_dma_priv_buffer(spi_host_t *host, uint32_t *buffer, uint32_t len, bool is_tx, uint32_t flags, uint32_t **ret_buffer) { - bool unaligned = ((((uint32_t)buffer) | len) & (alignment - 1)); -#if !SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - if (!((flags & SPI_TRANS_DMA_USE_PSRAM) && esp_ptr_dma_ext_capable(buffer))) { - // tx don't need align on addr or length on those chips - unaligned = is_tx ? false : (((uint32_t)buffer) & (alignment - 1)); - } +#if CONFIG_IDF_TARGET_ESP32S2 + ESP_RETURN_ON_FALSE_ISR((host->id != SPI3_HOST) || !(flags & SPI_TRANS_DMA_USE_PSRAM), ESP_ERR_NOT_SUPPORTED, SPI_TAG, "SPI3 does not support external memory"); #endif - -#if SOC_PSRAM_DMA_CAPABLE - if ((flags & SPI_TRANS_DMA_USE_PSRAM) && esp_ptr_dma_ext_capable(buffer)) { - // dma psram don't do additional copy, check only - ESP_RETURN_ON_FALSE_ISR(!unaligned, ESP_ERR_INVALID_ARG, SPI_TAG, "%s buffer addr and length should align to %ld Byte to use PSRAM, use heap_caps_aligned_calloc() may helpful", is_tx ? "TX" : "RX", alignment); - ESP_RETURN_ON_ERROR_ISR(esp_cache_msync((void *)buffer, len, is_tx ? ESP_CACHE_MSYNC_FLAG_DIR_C2M : ESP_CACHE_MSYNC_FLAG_DIR_M2C), SPI_TAG, "sync failed for %s buffer", is_tx ? "TX" : "RX"); - *ret_buffer = buffer; - return ESP_OK; + bool is_ptr_ext = esp_ptr_external_ram(buffer); + bool use_psram = is_ptr_ext && (flags & SPI_TRANS_DMA_USE_PSRAM); + bool need_malloc = is_ptr_ext ? (!use_psram || !esp_ptr_dma_ext_capable(buffer)) : !esp_ptr_dma_capable(buffer); + uint16_t alignment = 0; + // If psram is wanted, re-malloc also from psram. + uint32_t mem_cap = MALLOC_CAP_DMA | (use_psram ? MALLOC_CAP_SPIRAM : MALLOC_CAP_INTERNAL); + if (is_tx) { + alignment = use_psram ? host->dma_ctx->dma_align_tx_ext : host->dma_ctx->dma_align_tx_int; + } else { + // RX cache sync still need consider the cache alignment requirement + if (use_psram) { + alignment = MAX(host->dma_ctx->dma_align_rx_ext, host->bus_attr->cache_align_ext); + } else { + alignment = MAX(host->dma_ctx->dma_align_rx_int, host->bus_attr->cache_align_int); + } } -#endif - if ((!esp_ptr_dma_capable(buffer) || unaligned)) { + need_malloc |= (((uint32_t)buffer | len) & (alignment - 1)); + ESP_EARLY_LOGD(SPI_TAG, "%s %p, len %d, is_ptr_ext %d, use_psram: %d, alignment: %d, need_malloc: %d from %s", is_tx ? "TX" : "RX", buffer, len, is_ptr_ext, use_psram, alignment, need_malloc, (mem_cap & MALLOC_CAP_SPIRAM) ? "psram" : "internal"); + if (need_malloc) { ESP_RETURN_ON_FALSE_ISR(!(flags & SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL), ESP_ERR_INVALID_ARG, SPI_TAG, "Set flag SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL but %s addr&len not align to %d, or not dma_capable", is_tx ? "TX" : "RX", alignment); - //if buf in the desc not DMA-capable, or not bytes aligned to alignment, malloc a new one - ESP_EARLY_LOGD(SPI_TAG, "Allocate %s buffer for DMA", is_tx ? "TX" : "RX"); len = (len + alignment - 1) & (~(alignment - 1)); // up align alignment - uint32_t *temp = heap_caps_aligned_alloc(alignment, len, MALLOC_CAP_DMA); + uint32_t *temp = heap_caps_aligned_alloc(alignment, len, mem_cap); ESP_RETURN_ON_FALSE_ISR(temp != NULL, ESP_ERR_NO_MEM, SPI_TAG, "Failed to allocate priv %s buffer", is_tx ? "TX" : "RX"); if (is_tx) { @@ -1231,9 +1210,10 @@ static SPI_MASTER_ISR_ATTR esp_err_t setup_dma_priv_buffer(uint32_t *buffer, uin } buffer = temp; } -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - ESP_RETURN_ON_ERROR_ISR(esp_cache_msync((void *)buffer, len, is_tx ? ESP_CACHE_MSYNC_FLAG_DIR_C2M : ESP_CACHE_MSYNC_FLAG_DIR_M2C), SPI_TAG, "sync failed for %s buffer", is_tx ? "TX" : "RX"); -#endif + if (use_psram) { + esp_err_t ret = esp_cache_msync((void *)buffer, len, is_tx ? (ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED) : ESP_CACHE_MSYNC_FLAG_DIR_M2C); + ESP_RETURN_ON_FALSE_ISR(ret == ESP_OK, ESP_ERR_INVALID_ARG, SPI_TAG, "sync failed for %s buffer", is_tx ? "TX" : "RX"); + } *ret_buffer = buffer; return ESP_OK; } @@ -1242,36 +1222,22 @@ static SPI_MASTER_ISR_ATTR esp_err_t setup_priv_desc(spi_host_t *host, spi_trans { spi_transaction_t *trans_desc = priv_desc->trans; const spi_bus_attr_t *bus_attr = host->bus_attr; - uint16_t alignment = bus_attr->internal_mem_align_size; // rx memory assign - uint32_t* rcv_ptr; - if (trans_desc->flags & SPI_TRANS_USE_RXDATA) { - rcv_ptr = (uint32_t *)&trans_desc->rx_data[0]; - } else { - //if not use RXDATA neither rx_buffer, buffer_to_rcv assigned to NULL - rcv_ptr = trans_desc->rx_buffer; - } - + uint32_t* rcv_ptr = (trans_desc->flags & SPI_TRANS_USE_RXDATA) ? (uint32_t *)trans_desc->rx_data : (uint32_t *)trans_desc->rx_buffer; // tx memory assign - uint32_t *send_ptr; - if (trans_desc->flags & SPI_TRANS_USE_TXDATA) { - send_ptr = (uint32_t *)&trans_desc->tx_data[0]; - } else { - //if not use TXDATA neither tx_buffer, tx data assigned to NULL - send_ptr = (uint32_t *)trans_desc->tx_buffer ; - } + uint32_t *send_ptr = (trans_desc->flags & SPI_TRANS_USE_TXDATA) ? (uint32_t *)trans_desc->tx_data : (uint32_t *)trans_desc->tx_buffer; esp_err_t ret = ESP_OK; if (send_ptr && bus_attr->dma_enabled) { - ret = setup_dma_priv_buffer(send_ptr, (trans_desc->length + 7) / 8, alignment, true, trans_desc->flags, &send_ptr); + ret = setup_dma_priv_buffer(host, send_ptr, (trans_desc->length + 7) / 8, true, trans_desc->flags, &send_ptr); if (ret != ESP_OK) { goto clean_up; } } if (rcv_ptr && bus_attr->dma_enabled) { - ret = setup_dma_priv_buffer(rcv_ptr, (trans_desc->rxlength + 7) / 8, alignment, false, trans_desc->flags, &rcv_ptr); + ret = setup_dma_priv_buffer(host, rcv_ptr, (trans_desc->rxlength + 7) / 8, false, trans_desc->flags, &rcv_ptr); if (ret != ESP_OK) { goto clean_up; } @@ -1343,7 +1309,6 @@ esp_err_t SPI_MASTER_ATTR spi_device_get_trans_result(spi_device_handle_t handle BaseType_t r; spi_trans_priv_t trans_buf; SPI_CHECK(handle != NULL, "invalid dev handle", ESP_ERR_INVALID_ARG); - bool use_dma = handle->host->bus_attr->dma_enabled; //if SPI_DEVICE_NO_RETURN_RESULT is set, ret_queue will always be empty SPI_CHECK(!(handle->cfg.flags & SPI_DEVICE_NO_RETURN_RESULT), "API not Supported!", ESP_ERR_NOT_SUPPORTED); @@ -1357,9 +1322,7 @@ esp_err_t SPI_MASTER_ATTR spi_device_get_trans_result(spi_device_handle_t handle return ESP_ERR_TIMEOUT; } //release temporary buffers used by dma - if (use_dma) { - uninstall_priv_desc(&trans_buf); - } + uninstall_priv_desc(&trans_buf); (*trans_desc) = trans_buf.trans; return (trans_buf.trans->flags & (SPI_TRANS_DMA_RX_FAIL | SPI_TRANS_DMA_TX_FAIL)) ? ESP_ERR_INVALID_STATE : ESP_OK; @@ -1514,18 +1477,6 @@ esp_err_t SPI_MASTER_ISR_ATTR spi_device_polling_end(spi_device_handle_t handle, spi_trans_dma_error_check(host); uint32_t trans_flags = host->cur_trans_buf.trans->flags; // save the flags before bus_lock release -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE //invalidate here to let user access rx data in post_cb if possible - const spi_bus_attr_t *bus_attr = host->bus_attr; - if (bus_attr->dma_enabled && host->cur_trans_buf.buffer_to_rcv) { - uint16_t alignment = bus_attr->internal_mem_align_size; - uint32_t buffer_byte_len = (host->cur_trans_buf.trans->rxlength + 7) / 8; - buffer_byte_len = (buffer_byte_len + alignment - 1) & (~(alignment - 1)); - esp_err_t ret = esp_cache_msync((void *)host->cur_trans_buf.buffer_to_rcv, buffer_byte_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); - if (ret != ESP_OK) { - return ret; - } - } -#endif ESP_LOGV(SPI_TAG, "polling trans done"); //deal with the in-flight transaction spi_post_trans(host); @@ -1880,20 +1831,16 @@ esp_err_t SPI_MASTER_ATTR spi_device_queue_multi_trans(spi_device_handle_t handl SPI_CHECK(handle, "Invalid arguments.", ESP_ERR_INVALID_ARG); SPI_CHECK(SOC_SPI_SCT_SUPPORTED_PERIPH(handle->host->id), "Invalid arguments", ESP_ERR_INVALID_ARG); SPI_CHECK(handle->host->sct_mode_enabled == 1, "SCT mode isn't enabled", ESP_ERR_INVALID_STATE); + esp_err_t ret = ESP_OK; - - uint16_t alignment = handle->host->bus_attr->internal_mem_align_size; - uint32_t *conf_buffer = heap_caps_aligned_alloc(alignment, (trans_num * SOC_SPI_SCT_BUFFER_NUM_MAX * sizeof(uint32_t)), MALLOC_CAP_DMA); - SPI_CHECK(conf_buffer, "No enough memory", ESP_ERR_NO_MEM); - for (int i = 0; i < trans_num; i++) { - ret = check_trans_valid(handle, (spi_transaction_t *)&seg_trans_desc[i]); - if (ret != ESP_OK) { - return ret; - } + ESP_RETURN_ON_ERROR(check_trans_valid(handle, (spi_transaction_t *)&seg_trans_desc[i]), SPI_TAG, "Invalid transaction"); } SPI_CHECK(!spi_bus_device_is_polling(handle), "Cannot queue new transaction while previous polling transaction is not terminated.", ESP_ERR_INVALID_STATE); + uint32_t *conf_buffer = heap_caps_malloc(trans_num * SOC_SPI_SCT_BUFFER_NUM_MAX * sizeof(uint32_t), MALLOC_CAP_DMA); + SPI_CHECK(conf_buffer, "No enough memory", ESP_ERR_NO_MEM); + spi_hal_context_t *hal = &handle->host->hal; s_sct_init_conf_buffer(hal, conf_buffer, trans_num); diff --git a/components/esp_driver_spi/test_apps/master/main/test_spi_master.c b/components/esp_driver_spi/test_apps/master/main/test_spi_master.c index 775c2e8af5..1fac410229 100644 --- a/components/esp_driver_spi/test_apps/master/main/test_spi_master.c +++ b/components/esp_driver_spi/test_apps/master/main/test_spi_master.c @@ -1727,6 +1727,7 @@ static IRAM_ATTR void test_master_iram(void) spi_device_handle_t dev_handle = {0}; spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG(); + devcfg.cs_ena_pretrans = 1; devcfg.post_cb = test_master_iram_post_trans_cbk; TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &dev_handle)); @@ -1976,27 +1977,32 @@ TEST_CASE("test_spi_master_auto_sleep_retention", "[spi]") #if CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE #define TEST_EDMA_PSRAM_TRANS_NUM 5 -#define TEST_EDMA_TRANS_LEN 20480 //Use PSRAM need a 16/32/64 aligned buffer len +#define TEST_EDMA_TRANS_LEN 20000 #define TEST_EDMA_BUFFER_SZ (TEST_EDMA_PSRAM_TRANS_NUM * TEST_EDMA_TRANS_LEN) void test_spi_psram_trans(spi_device_handle_t dev_handle, void *tx, void *rx) { spi_transaction_t trans_cfg = { - .length = TEST_EDMA_TRANS_LEN * 8, - .flags = SPI_TRANS_DMA_USE_PSRAM, + .tx_buffer = tx, + .rx_buffer = rx, }; + int trans_len = TEST_EDMA_TRANS_LEN - TEST_EDMA_PSRAM_TRANS_NUM / 2; for (uint8_t cnt = 0; cnt < TEST_EDMA_PSRAM_TRANS_NUM; cnt ++) { - trans_cfg.tx_buffer = tx + TEST_EDMA_TRANS_LEN * cnt; - trans_cfg.rx_buffer = rx + TEST_EDMA_TRANS_LEN * cnt; + trans_cfg.length = trans_len * 8; + trans_cfg.rxlength = trans_len * 8; + trans_cfg.flags = (cnt % 2) ? 0 : SPI_TRANS_DMA_USE_PSRAM; // To use psram, hardware will pass data through MSPI and GDMA to GPSPI, which need some time // GPSPI bandwidth(speed * line_num) should always no more than PSRAM bandwidth trans_cfg.override_freq_hz = (CONFIG_SPIRAM_SPEED / 4) * 1000 * 1000; - printf("%d TX %p RX %p len %d @%ld kHz\n", cnt, trans_cfg.tx_buffer, trans_cfg.rx_buffer, TEST_EDMA_TRANS_LEN, trans_cfg.override_freq_hz / 1000); + printf("%d TX %p RX %p len %d @%ld kHz\n", cnt, trans_cfg.tx_buffer, trans_cfg.rx_buffer, trans_len, trans_cfg.override_freq_hz / 1000); TEST_ESP_OK(spi_device_transmit(dev_handle, &trans_cfg)); TEST_ASSERT(!(trans_cfg.flags & (SPI_TRANS_DMA_RX_FAIL | SPI_TRANS_DMA_TX_FAIL))); - spitest_cmp_or_dump(trans_cfg.tx_buffer, trans_cfg.rx_buffer, TEST_EDMA_TRANS_LEN); + spitest_cmp_or_dump(trans_cfg.tx_buffer, trans_cfg.rx_buffer, trans_len); + trans_cfg.tx_buffer += trans_len; + trans_cfg.rx_buffer += trans_len; + trans_len ++; } } @@ -2007,17 +2013,16 @@ TEST_CASE("SPI_Master: PSRAM buffer transaction via EDMA", "[spi]") buscfg.max_transfer_sz = TEST_EDMA_BUFFER_SZ; TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO)); - spi_device_handle_t dev_handle; + spi_device_handle_t dev_handle = NULL; spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG(); devcfg.clock_speed_hz = 80 * 1000 * 1000; // Test error case on highest freq first TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &dev_handle)); int real_freq_khz; spi_device_get_actual_freq(dev_handle, &real_freq_khz); - uint32_t cache_width = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA); - uint8_t *internal_1 = heap_caps_aligned_calloc(cache_width, 1, TEST_EDMA_BUFFER_SZ, MALLOC_CAP_INTERNAL); - uint8_t *external_1 = heap_caps_aligned_calloc(cache_width, 1, TEST_EDMA_BUFFER_SZ, MALLOC_CAP_SPIRAM); - uint8_t *external_2 = heap_caps_aligned_calloc(cache_width, 1, TEST_EDMA_BUFFER_SZ, MALLOC_CAP_SPIRAM); + uint8_t *internal_1 = heap_caps_calloc(1, TEST_EDMA_BUFFER_SZ, MALLOC_CAP_INTERNAL); + uint8_t *external_1 = heap_caps_calloc(1, TEST_EDMA_BUFFER_SZ, MALLOC_CAP_SPIRAM); + uint8_t *external_2 = heap_caps_calloc(1, TEST_EDMA_BUFFER_SZ, MALLOC_CAP_SPIRAM); test_fill_random_to_buffers_dualboard(1001, internal_1, external_2, TEST_EDMA_BUFFER_SZ); printf("Test error case: High freq @%d kHz\n", real_freq_khz); @@ -2027,31 +2032,32 @@ TEST_CASE("SPI_Master: PSRAM buffer transaction via EDMA", "[spi]") .rx_buffer = external_1, }; + // also test on polling API, and automalloc mechanism for (uint8_t i = 0; i < 2; i++) { + printf("\n==== %s ====\n", i ? "EDMA" : "Auto Malloc"); trans_cfg.flags = i ? SPI_TRANS_DMA_USE_PSRAM : 0; uint32_t before = esp_get_free_heap_size(); spi_device_polling_start(dev_handle, &trans_cfg, portMAX_DELAY); uint32_t after = esp_get_free_heap_size(); - printf("\n==== %s ====\n", i ? "EDMA" : "Auto Malloc"); - printf("before: %ld, after: %ld, diff: %ld\n", before, after, after - before); + printf("mem_diff: %ld, trans_len: %d\n", after - before, TEST_EDMA_TRANS_LEN); + // rx buffer still potential re-malloc from psram even if SPI_TRANS_DMA_USE_PSRAM is set + TEST_ASSERT(i ? (before - after) < 2 * TEST_EDMA_TRANS_LEN : (before - after) > 2 * TEST_EDMA_TRANS_LEN); spi_device_polling_end(dev_handle, portMAX_DELAY); - printf("RX fail: %d, TX fail: %d\n", !!(trans_cfg.flags & SPI_TRANS_DMA_RX_FAIL), !!(trans_cfg.flags & SPI_TRANS_DMA_TX_FAIL)); - TEST_ASSERT(i ? (before - after) < TEST_EDMA_TRANS_LEN : (before - after) > 2 * TEST_EDMA_TRANS_LEN); - TEST_ASSERT((!!i) == !!(trans_cfg.flags & (SPI_TRANS_DMA_RX_FAIL | SPI_TRANS_DMA_TX_FAIL))); + printf("TX fail: %d, RX fail: %d\n", !!(trans_cfg.flags & SPI_TRANS_DMA_TX_FAIL), !!(trans_cfg.flags & SPI_TRANS_DMA_RX_FAIL)); + TEST_ASSERT((!!i) == !!(trans_cfg.flags & (SPI_TRANS_DMA_TX_FAIL | SPI_TRANS_DMA_RX_FAIL))); + if (!i) { // data should be correct if using auto malloc + spitest_cmp_or_dump(trans_cfg.tx_buffer, trans_cfg.rx_buffer, TEST_EDMA_TRANS_LEN); + } } - printf("\nTest unaligned tx psram buffer\n"); - trans_cfg.tx_buffer ++; - TEST_ESP_ERR(ESP_ERR_INVALID_ARG, spi_device_transmit(dev_handle, &trans_cfg)); - printf("\nTest trans: internal -> psram\n"); memset(external_1, 0, TEST_EDMA_BUFFER_SZ); - TEST_ESP_OK(esp_cache_msync((void *)external_1, TEST_EDMA_BUFFER_SZ, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); + TEST_ESP_OK(esp_cache_msync((void *)external_1, TEST_EDMA_BUFFER_SZ, (ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED))); test_spi_psram_trans(dev_handle, internal_1, external_1); printf("\nTest trans: psram -> psram\n"); memset(external_2, 0, TEST_EDMA_BUFFER_SZ); - TEST_ESP_OK(esp_cache_msync((void *)external_2, TEST_EDMA_BUFFER_SZ, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); + TEST_ESP_OK(esp_cache_msync((void *)external_2, TEST_EDMA_BUFFER_SZ, (ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED))); test_spi_psram_trans(dev_handle, external_1, external_2); printf("\nTest trans: psram -> internal\n"); diff --git a/components/esp_driver_spi/test_apps/slave/main/test_spi_slave.c b/components/esp_driver_spi/test_apps/slave/main/test_spi_slave.c index 34c9e0a09a..33ddd18c82 100644 --- a/components/esp_driver_spi/test_apps/slave/main/test_spi_slave.c +++ b/components/esp_driver_spi/test_apps/slave/main/test_spi_slave.c @@ -312,6 +312,7 @@ static void test_slave_iram_master_normal(void) spi_device_handle_t dev_handle = {0}; spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG(); + devcfg.cs_ena_pretrans = 1; TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &dev_handle)); uint8_t *master_send = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DMA); diff --git a/components/hal/esp32/include/hal/spi_ll.h b/components/hal/esp32/include/hal/spi_ll.h index b685cf11a7..5e7b137612 100644 --- a/components/hal/esp32/include/hal/spi_ll.h +++ b/components/hal/esp32/include/hal/spi_ll.h @@ -1172,6 +1172,19 @@ static inline void spi_dma_ll_rx_enable_burst_desc(spi_dma_dev_t *dma_in, uint32 dma_in->dma_conf.indscr_burst_en = enable; } +/** + * Get the DMA RX alignment requirements + * + * @param dma_dev Beginning address of the DMA peripheral registers. + * @param internal_size The internal memory alignment requirements. + * @param external_size The external memory alignment requirements. + */ +static inline void spi_dma_ll_get_rx_alignment_require(spi_dma_dev_t *dma_dev, uint32_t *internal_size, uint32_t *external_size) +{ + *internal_size = 4; // esp32 needs 4 bytes alignment on hardware design + *external_size = UINT32_MAX; // dma of esp32 spi don't support external memory +} + /** * Reset TX DMA which transmits the data from RAM to a peripheral. * diff --git a/components/hal/esp32s2/include/hal/spi_ll.h b/components/hal/esp32s2/include/hal/spi_ll.h index 68f0834f79..b55bb8c046 100644 --- a/components/hal/esp32s2/include/hal/spi_ll.h +++ b/components/hal/esp32s2/include/hal/spi_ll.h @@ -1364,6 +1364,20 @@ static inline uint32_t spi_dma_ll_get_in_suc_eof_desc_addr(spi_dma_dev_t *dma_in return dma_in->dma_in_suc_eof_des_addr; } +/** + * Get the DMA RX alignment requirements + * + * @param dma_dev Beginning address of the DMA peripheral registers. + * @param internal_size The internal memory alignment requirements. + * @param external_size The external memory alignment requirements. + */ +static inline void spi_dma_ll_get_rx_alignment_require(spi_dma_dev_t *dma_dev, uint32_t *internal_size, uint32_t *external_size) +{ + *internal_size = 4; + // SPI2 supports external memory, SPI3 does not + *external_size = (dma_dev == &GPSPI2) ? 16 << dma_dev->dma_conf.ext_mem_bk_size : UINT32_MAX; +} + //---------------------------------------------------TX-------------------------------------------------// /** * Reset TX DMA which transmits the data from RAM to a peripheral. diff --git a/docs/en/api-reference/peripherals/spi_master.rst b/docs/en/api-reference/peripherals/spi_master.rst index 92c7eda4c7..fb797cb968 100644 --- a/docs/en/api-reference/peripherals/spi_master.rst +++ b/docs/en/api-reference/peripherals/spi_master.rst @@ -358,10 +358,9 @@ The example code for the SPI Master driver can be found in the :example:`periphe Transactions with Data on PSRAM ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - {IDF_TARGET_NAME} supports GPSPI Master with DMA transferring data from/to PSRAM directly without extra internal copy process, by adding :c:macro:`SPI_TRANS_DMA_USE_PSRAM` flag to the transaction. Some requirements for PSRAM transactions are: + {IDF_TARGET_NAME} supports GPSPI Master with DMA transferring data from/to PSRAM directly without extra internal copy process, which saves memory, by adding :c:macro:`SPI_TRANS_DMA_USE_PSRAM` flag to the transaction. - 1. The data memory **address** and **transaction length** must both be aligned to cache length, usually the cache length is 16/32/64 bytes. - 2. This feature shares bandwidth with MSPI bus, so GPSPI transfer bandwidth should be less than PSRAM bandwidth, **otherwise transmission data may be lost**. You can check the :c:macro:`SPI_TRANS_DMA_RX_FAIL` and :c:macro:`SPI_TRANS_DMA_TX_FAIL` flags after the transaction is finished to check if error occurs during the transmission. + Note that this feature shares bandwidth (bus frequency * bus bits width) with MSPI bus, so GPSPI transfer bandwidth should be less than PSRAM bandwidth, **otherwise transmission data may be lost**. You can check the return value or :c:macro:`SPI_TRANS_DMA_RX_FAIL` and :c:macro:`SPI_TRANS_DMA_TX_FAIL` flags after the transaction is finished to check if error occurs during the transmission. If the transaction returns :c:macro:`ESP_ERR_INVALID_STATE` error, the transaction fails. Transactions with Data Not Exceeding 32 Bits ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/zh_CN/api-reference/peripherals/spi_master.rst b/docs/zh_CN/api-reference/peripherals/spi_master.rst index a67bb05ed4..c53ac3aea7 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_master.rst +++ b/docs/zh_CN/api-reference/peripherals/spi_master.rst @@ -358,10 +358,9 @@ SPI 主机驱动程序的示例代码存放在 ESP-IDF 示例项目的 :example: 使用 PSRAM 的传输事务 ^^^^^^^^^^^^^^^^^^^^^^ - {IDF_TARGET_NAME} 支持 GPSPI Master 通过 DMA 直接传输 PSRAM 存储的数据而不用内部额外的拷贝过程,在传输配置中添加 :c:macro:`SPI_TRANS_DMA_USE_PSRAM` 标志信号即可使用。使用 PSRAM 传输事务时,请注意以下几点: + {IDF_TARGET_NAME} 支持 GPSPI Master 通过 DMA 直接传输 PSRAM 存储的数据而不用内部额外的零时拷贝,应此可以节省内存,在传输配置中添加 :c:macro:`SPI_TRANS_DMA_USE_PSRAM` 标志信号即可使用。 - 1. 数据内存 **地址** 和 **传输长度** 都需要与 Cache 长度对齐,通常 Cache 长度为 16/32/64 字节。 - 2. 因为该功能与 MSPI 总线共享带宽,因此 GPSPI 传输带宽应小于 PSRAM 带宽,否则 **可能会丢失传输数据**。可通过在传输结束时检查 :c:macro:`SPI_TRANS_DMA_RX_FAIL` 和 :c:macro:`SPI_TRANS_DMA_TX_FAIL` 标志信号来判断传输是否发生了错误。 + 请注意该功能共享 MSPI 总线带宽(总线频率 * 总线位宽),因此 GPSPI 传输带宽应小于 PSRAM 带宽,否则 **可能会丢失传输数据**。可通过在传输结束时检查返回值或 :c:macro:`SPI_TRANS_DMA_RX_FAIL` 和 :c:macro:`SPI_TRANS_DMA_TX_FAIL` 标志信号来判断传输是否发生了错误。若传输事务返回 :c:macro:`ESP_ERR_INVALID_STATE` 错误,则传输事务失败。 传输数据小于 32 位的传输事务 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/peripherals/spi_master/lcd/main/Kconfig.projbuild b/examples/peripherals/spi_master/lcd/main/Kconfig.projbuild index bab78fc6bf..6a341da771 100644 --- a/examples/peripherals/spi_master/lcd/main/Kconfig.projbuild +++ b/examples/peripherals/spi_master/lcd/main/Kconfig.projbuild @@ -23,4 +23,13 @@ menu "Example Configuration" in practice the driver chips work fine with a higher clock rate, and using that gives a better framerate. Select this to try using the out-of-spec clock rate. + config LCD_BUFFER_IN_PSRAM + bool + prompt "Malloc LCD buffer from PSRAM, it can save internal RAM" + depends on SPIRAM && SOC_PSRAM_DMA_CAPABLE + default "y" + help + Driver is now support using PSRAM memory as LCD buffer directly + without additional internal copy, using it is able to save internal + memory space, and without CPU cost. endmenu diff --git a/examples/peripherals/spi_master/lcd/main/pretty_effect.c b/examples/peripherals/spi_master/lcd/main/pretty_effect.c index 9ccd6fd020..bce1d1c8a3 100644 --- a/examples/peripherals/spi_master/lcd/main/pretty_effect.c +++ b/examples/peripherals/spi_master/lcd/main/pretty_effect.c @@ -19,6 +19,10 @@ uint16_t *pixels; //Grab a rgb16 pixel from the esp32_tiles image static inline uint16_t get_bgnd_pixel(int x, int y) { + // Clamp coordinates to valid image bounds + x = (x < 0) ? 0 : (x >= IMAGE_W) ? IMAGE_W - 1 : x; + y = (y < 0) ? 0 : (y >= IMAGE_H) ? IMAGE_H - 1 : y; + //Get color of the pixel on x,y coords return (uint16_t) * (pixels + (y * IMAGE_W) + x); } @@ -26,7 +30,7 @@ static inline uint16_t get_bgnd_pixel(int x, int y) //This variable is used to detect the next frame. static int prev_frame = -1; -//Instead of calculating the offsets for each pixel we grab, we pre-calculate the valueswhenever a frame changes, then re-use +//Instead of calculating the offsets for each pixel we grab, we pre-calculate the valueswhenever a frame changes, then reuse //these as we go through all the pixels in the frame. This is much, much faster. static int8_t xofs[320], yofs[240]; static int8_t xcomp[320], ycomp[240]; diff --git a/examples/peripherals/spi_master/lcd/main/spi_master_example_main.c b/examples/peripherals/spi_master/lcd/main/spi_master_example_main.c index 498a83e1a1..f0e33bf428 100644 --- a/examples/peripherals/spi_master/lcd/main/spi_master_example_main.c +++ b/examples/peripherals/spi_master/lcd/main/spi_master_example_main.c @@ -343,7 +343,11 @@ static void send_lines(spi_device_handle_t spi, int ypos, uint16_t *linedata) trans[4].tx_data[0] = 0x2C; //memory write trans[5].tx_buffer = linedata; //finally send the line data trans[5].length = 320 * 2 * 8 * PARALLEL_LINES; //Data length, in bits +#if CONFIG_LCD_BUFFER_IN_PSRAM + trans[5].flags = SPI_TRANS_DMA_USE_PSRAM; //using PSRAM +#else trans[5].flags = 0; //undo SPI_TRANS_USE_TXDATA flag +#endif //Queue all transactions. for (x = 0; x < 6; x++) { @@ -375,9 +379,17 @@ static void send_line_finish(spi_device_handle_t spi) static void display_pretty_colors(spi_device_handle_t spi) { uint16_t *lines[2]; +#if CONFIG_LCD_BUFFER_IN_PSRAM + uint32_t mem_cap = MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA; + printf("Get LCD buffer from PSRAM\n"); +#else + uint32_t mem_cap = MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA; + printf("Get LCD buffer from internal\n"); +#endif + //Allocate memory for the pixel buffers for (int i = 0; i < 2; i++) { - lines[i] = spi_bus_dma_memory_alloc(LCD_HOST, 320 * PARALLEL_LINES * sizeof(uint16_t), 0); + lines[i] = spi_bus_dma_memory_alloc(LCD_HOST, 320 * PARALLEL_LINES * sizeof(uint16_t), mem_cap); assert(lines[i] != NULL); } int frame = 0; From c55a188d4cc12c6dc1d38f8bb31f0d11c764e04b Mon Sep 17 00:00:00 2001 From: nvmd Date: Tue, 9 Dec 2025 21:05:28 -0300 Subject: [PATCH 094/226] change: declutter SPI DMA debug logs SPI component is overly verbose about its handling of pre-DMA cache<->memory synchronization. This commit moves the logs to verbose level. --- components/esp_driver_spi/src/gpspi/spi_master.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_driver_spi/src/gpspi/spi_master.c b/components/esp_driver_spi/src/gpspi/spi_master.c index cf85c00b9b..e59f8bb8b4 100644 --- a/components/esp_driver_spi/src/gpspi/spi_master.c +++ b/components/esp_driver_spi/src/gpspi/spi_master.c @@ -1198,7 +1198,7 @@ static SPI_MASTER_ISR_ATTR esp_err_t setup_dma_priv_buffer(spi_host_t *host, uin } } need_malloc |= (((uint32_t)buffer | len) & (alignment - 1)); - ESP_EARLY_LOGD(SPI_TAG, "%s %p, len %d, is_ptr_ext %d, use_psram: %d, alignment: %d, need_malloc: %d from %s", is_tx ? "TX" : "RX", buffer, len, is_ptr_ext, use_psram, alignment, need_malloc, (mem_cap & MALLOC_CAP_SPIRAM) ? "psram" : "internal"); + ESP_EARLY_LOGV(SPI_TAG, "%s %p, len %d, is_ptr_ext %d, use_psram: %d, alignment: %d, need_malloc: %d from %s", is_tx ? "TX" : "RX", buffer, len, is_ptr_ext, use_psram, alignment, need_malloc, (mem_cap & MALLOC_CAP_SPIRAM) ? "psram" : "internal"); if (need_malloc) { ESP_RETURN_ON_FALSE_ISR(!(flags & SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL), ESP_ERR_INVALID_ARG, SPI_TAG, "Set flag SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL but %s addr&len not align to %d, or not dma_capable", is_tx ? "TX" : "RX", alignment); len = (len + alignment - 1) & (~(alignment - 1)); // up align alignment From 613e2aefce6886f9c704b111425e218914a6b45b Mon Sep 17 00:00:00 2001 From: wanckl Date: Mon, 15 Dec 2025 14:50:06 +0800 Subject: [PATCH 095/226] fix(driver_spi): docs currect gpio config performs --- docs/en/api-reference/peripherals/spi_master.rst | 2 +- docs/zh_CN/api-reference/peripherals/spi_master.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/api-reference/peripherals/spi_master.rst b/docs/en/api-reference/peripherals/spi_master.rst index fb797cb968..cb54d44d92 100644 --- a/docs/en/api-reference/peripherals/spi_master.rst +++ b/docs/en/api-reference/peripherals/spi_master.rst @@ -498,7 +498,7 @@ GPIO Matrix and IO_MUX Most of the chip's peripheral signals have a direct connection to their dedicated IO_MUX pins. However, the signals can also be routed to any other available pins using the less direct GPIO matrix. If at least one signal is routed through the GPIO matrix, then all signals will be routed through it. - When an SPI Host is set to 80 MHz or lower frequencies, routing SPI pins via the GPIO matrix will behave the same compared to routing them via IOMUX. + When an SPI Host is set to 40 MHz or lower frequencies, routing SPI pins via the GPIO matrix will behave the same compared to routing them via IOMUX. The IO_MUX pins for SPI buses are given below. diff --git a/docs/zh_CN/api-reference/peripherals/spi_master.rst b/docs/zh_CN/api-reference/peripherals/spi_master.rst index c53ac3aea7..71f28f4645 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_master.rst +++ b/docs/zh_CN/api-reference/peripherals/spi_master.rst @@ -498,7 +498,7 @@ GPIO 矩阵与 IO_MUX 管脚 芯片的大多数外围信号都与之专用的 IO_MUX 管脚连接,但这些信号也可以通过较不直接的 GPIO 矩阵路由到任何其他可用的管脚。只要有一个信号是通过 GPIO 矩阵路由的,那么所有的信号都将通过它路由。 - 当 SPI 主机被设置为 80 MHz 或更低的频率时,通过 GPIO 矩阵路由 SPI 管脚的行为将与通过 IOMUX 路由相同。 + 当 SPI 主机被设置为 40 MHz 或更低的频率时,通过 GPIO 矩阵路由 SPI 管脚的行为将与通过 IOMUX 路由相同。 SPI 总线的 IO_MUX 管脚如下表所示。 From 6be402c1774076fc7a26baa42e306ca82ef9df64 Mon Sep 17 00:00:00 2001 From: wanckl Date: Mon, 15 Dec 2025 16:58:10 +0800 Subject: [PATCH 096/226] fix(driver_spi): fix some master test apps --- .../esp_driver_spi/test_apps/master/main/test_spi_master.c | 2 +- .../esp_driver_spi/test_apps/master/main/test_spi_sio.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/components/esp_driver_spi/test_apps/master/main/test_spi_master.c b/components/esp_driver_spi/test_apps/master/main/test_spi_master.c index 1fac410229..5ba2d040ab 100644 --- a/components/esp_driver_spi/test_apps/master/main/test_spi_master.c +++ b/components/esp_driver_spi/test_apps/master/main/test_spi_master.c @@ -124,7 +124,7 @@ TEST_CASE("SPI Master clockdiv calculation routines", "[spi]") // Test All clock source #define TEST_CLK_BYTE_LEN 10000 -#define TEST_TRANS_TIME_BIAS_RATIO (float)5.0/100 // think 5% transfer time bias as acceptable +#define TEST_TRANS_TIME_BIAS_RATIO (float)8.0/100 // think 8% transfer time bias as acceptable TEST_CASE("SPI Master clk_source and divider accuracy", "[spi]") { int64_t start = 0, end = 0; diff --git a/components/esp_driver_spi/test_apps/master/main/test_spi_sio.c b/components/esp_driver_spi/test_apps/master/main/test_spi_sio.c index 8df60daa13..c8d9c9cff3 100644 --- a/components/esp_driver_spi/test_apps/master/main/test_spi_sio.c +++ b/components/esp_driver_spi/test_apps/master/main/test_spi_sio.c @@ -140,7 +140,6 @@ TEST_CASE("SPI Single Board Test SIO", "[spi]") } #endif //#if (TEST_SPI_PERIPH_NUM >= 2) -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //IDF-7503 slave support /******************************************************************************** * Test SIO Master * SIO Slave is not supported, and one unit test is limited to one feature, so,,, @@ -271,7 +270,7 @@ void test_sio_slave_emulate(bool sio_master_in) unity_wait_for_signal("Master ready"); for (int i = 0; i < TEST_NUM; i++) { - spi_slave_transaction_t trans = {}; + spi_slave_transaction_t trans = { .flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, }; if (sio_master_in) { // slave output only section trans.length = (i + 1) * 8 * 8; @@ -324,4 +323,3 @@ void test_slave_run(void) } TEST_CASE_MULTIPLE_DEVICES("SPI_Master:Test_SIO_Mode_Multi_Board", "[spi_ms][test_env=generic_multi_device]", test_master_run, test_slave_run); -#endif //p4 slave support From 2b199da3359a7a8e273f12ca14c54cb1f5367969 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Wed, 24 Dec 2025 17:09:50 +0800 Subject: [PATCH 097/226] fix(esp_driver_isp): Fix AWB subwindown compatibility for ESP32-P4 ECO4 --- components/esp_driver_isp/src/isp_awb.c | 57 +++++++++++++------------ 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/components/esp_driver_isp/src/isp_awb.c b/components/esp_driver_isp/src/isp_awb.c index d596d3ee19..61f0df71df 100644 --- a/components/esp_driver_isp/src/isp_awb.c +++ b/components/esp_driver_isp/src/isp_awb.c @@ -83,38 +83,39 @@ static esp_err_t s_esp_isp_awb_config_hardware(isp_proc_handle_t isp_proc, const if (!subwindow_is_zero) { ESP_LOGW(TAG, "Subwindow feature is not supported on REV < 3.0, subwindow will not be configured"); } - } + } else { + // Subwindow is just checked and configured on REV >= 3.0 + isp_window_t subwindow = awb_cfg->subwindow; + ESP_RETURN_ON_FALSE( + (subwindow.top_left.x >= awb_cfg->window.top_left.x) && + (subwindow.top_left.y >= awb_cfg->window.top_left.y) && + (subwindow.btm_right.x <= awb_cfg->window.btm_right.x) && + (subwindow.btm_right.y <= awb_cfg->window.btm_right.y), + ESP_ERR_INVALID_ARG, TAG, "subwindow exceeds window range" + ); - isp_window_t subwindow = awb_cfg->subwindow; - ESP_RETURN_ON_FALSE( - (subwindow.top_left.x >= awb_cfg->window.top_left.x) && - (subwindow.top_left.y >= awb_cfg->window.top_left.y) && - (subwindow.btm_right.x <= awb_cfg->window.btm_right.x) && - (subwindow.btm_right.y <= awb_cfg->window.btm_right.y), - ESP_ERR_INVALID_ARG, TAG, "subwindow exceeds window range" - ); + if ((subwindow.btm_right.x - subwindow.top_left.x + 1) / ISP_AWB_WINDOW_X_NUM < 4 || + (subwindow.btm_right.y - subwindow.top_left.y + 1) / ISP_AWB_WINDOW_Y_NUM < 4) { + ESP_LOGE(TAG, "subwindow block size is too small: width and height must be at least 4 (got %d x %d)", + (subwindow.btm_right.x - subwindow.top_left.x + 1) / ISP_AWB_WINDOW_X_NUM, + (subwindow.btm_right.y - subwindow.top_left.y + 1) / ISP_AWB_WINDOW_Y_NUM); + return ESP_ERR_INVALID_ARG; + } - if ((subwindow.btm_right.x - subwindow.top_left.x + 1) / ISP_AWB_WINDOW_X_NUM < 4 || - (subwindow.btm_right.y - subwindow.top_left.y + 1) / ISP_AWB_WINDOW_Y_NUM < 4) { - ESP_LOGE(TAG, "subwindow block size is too small: width and height must be at least 4 (got %"PRIu32" x %"PRIu32")", - (subwindow.btm_right.x - subwindow.top_left.x + 1) / ISP_AWB_WINDOW_X_NUM, - (subwindow.btm_right.y - subwindow.top_left.y + 1) / ISP_AWB_WINDOW_Y_NUM); - return ESP_ERR_INVALID_ARG; + int size_x = subwindow.btm_right.x - subwindow.top_left.x + 1; + int size_y = subwindow.btm_right.y - subwindow.top_left.y + 1; + if ((size_x % ISP_AWB_WINDOW_X_NUM != 0) || (size_y % ISP_AWB_WINDOW_Y_NUM != 0)) { + ESP_LOGW(TAG, "subwindow size (%d x %d) is not divisible by AWB subwindow blocks grid (%d x %d). \ + Resolution will be floored to the nearest divisible value.", + size_x, size_y, ISP_AWB_WINDOW_X_NUM, ISP_AWB_WINDOW_Y_NUM); + // floor to the nearest divisible value + subwindow.btm_right.x -= size_x % ISP_AWB_WINDOW_X_NUM; + subwindow.btm_right.y -= size_y % ISP_AWB_WINDOW_Y_NUM; + } + ESP_RETURN_ON_FALSE(isp_hal_awb_set_subwindow_range(&isp_proc->hal, &subwindow), + ESP_ERR_INVALID_ARG, TAG, "invalid subwindow range"); } - int size_x = subwindow.btm_right.x - subwindow.top_left.x + 1; - int size_y = subwindow.btm_right.y - subwindow.top_left.y + 1; - if ((size_x % ISP_AWB_WINDOW_X_NUM != 0) || (size_y % ISP_AWB_WINDOW_Y_NUM != 0)) { - ESP_LOGW(TAG, "subwindow size (%d x %d) is not divisible by AWB subwindow blocks grid (%d x %d). \ - Resolution will be floored to the nearest divisible value.", - size_x, size_y, ISP_AWB_WINDOW_X_NUM, ISP_AWB_WINDOW_Y_NUM); - // floor to the nearest divisible value - subwindow.btm_right.x -= size_x % ISP_AWB_WINDOW_X_NUM; - subwindow.btm_right.y -= size_y % ISP_AWB_WINDOW_Y_NUM; - } - ESP_RETURN_ON_FALSE(isp_hal_awb_set_subwindow_range(&isp_proc->hal, &subwindow), - ESP_ERR_INVALID_ARG, TAG, "invalid subwindow range"); - isp_u32_range_t lum_range = awb_cfg->white_patch.luminance; ESP_RETURN_ON_FALSE(isp_hal_awb_set_luminance_range(&isp_proc->hal, lum_range.min, lum_range.max), ESP_ERR_INVALID_ARG, TAG, "invalid luminance range"); From c34a8f9c888ee8374b5cb0ceb89ecaef321b1ce9 Mon Sep 17 00:00:00 2001 From: Marek Fiala Date: Tue, 6 Jan 2026 11:33:08 +0100 Subject: [PATCH 098/226] change(tools): Updated argument files with quotations in README.md --- examples/build_system/cmake/multi_config/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/build_system/cmake/multi_config/README.md b/examples/build_system/cmake/multi_config/README.md index ddf11e894e..1e036f01de 100644 --- a/examples/build_system/cmake/multi_config/README.md +++ b/examples/build_system/cmake/multi_config/README.md @@ -89,14 +89,14 @@ You can further enhance your build process by using configuration profile files. You can use these profile files to quickly set up the build environment with specific configurations. -- To build with the production profile: `idf.py @profiles/prod build` -- To build with the debug profile: `idf.py @profiles/debug build` +- To build with the production profile: `idf.py "@profiles/prod" build` +- To build with the debug profile: `idf.py "@profiles/debug" build` This approach simplifies the process of specifying complex command-line arguments and allows for greater flexibility in managing different build scenarios. Moreover, you can combine arguments from a profile file with additional command line arguments. Anywhere on the idf.py command line, you can specify a file as @filename.txt to read one or more arguments from the text file. Arguments in the file can be separated by newlines or spaces and are expanded exactly as if they had appeared in that order on the idf.py command line. -For example using [cutom_flash.txt](custom_flash.txt), you can expand the command: `idf.py -B build_production @custom_flash.txt monitor` +For example using [cutom_flash.txt](custom_flash.txt), you can expand the command: `idf.py -B build_production "@custom_flash.txt" monitor` ### Generated `sdkconfig` file From 980e8289a184e69ce7bde1182f730b2b004daed7 Mon Sep 17 00:00:00 2001 From: morris Date: Fri, 2 Jan 2026 23:41:41 +0800 Subject: [PATCH 099/226] refactor(tests): add missing sdkconfig files in the driver test --- .../esp_driver_i2s/test_apps/lp_i2s/pytest_lp_i2s.py | 7 +++++++ .../{sdkconfig.ci.defaults => sdkconfig.ci.default} | 0 components/esp_driver_sdio/src/sdio_slave.c | 2 +- .../temperature_sensor/pytest_temperature_sensor.py | 9 ++++++++- .../spi_flash/test_apps/esp_flash/pytest_esp_flash.py | 4 ++-- .../test_apps/flash_suspend/pytest_flash_auto_suspend.py | 1 - .../touch_sens_sleep/main/touch_sens_sleep.c | 4 ++-- .../touch_sens_sleep/pytest_touch_sens_sleep.py | 8 ++++++++ 8 files changed, 28 insertions(+), 7 deletions(-) rename components/esp_driver_i2s/test_apps/lp_i2s/{sdkconfig.ci.defaults => sdkconfig.ci.default} (100%) diff --git a/components/esp_driver_i2s/test_apps/lp_i2s/pytest_lp_i2s.py b/components/esp_driver_i2s/test_apps/lp_i2s/pytest_lp_i2s.py index db2527a9ec..8045374fbb 100644 --- a/components/esp_driver_i2s/test_apps/lp_i2s/pytest_lp_i2s.py +++ b/components/esp_driver_i2s/test_apps/lp_i2s/pytest_lp_i2s.py @@ -6,6 +6,13 @@ from pytest_embedded_idf.utils import idf_parametrize @pytest.mark.lp_i2s +@pytest.mark.parametrize( + 'config', + [ + 'default', + ], + indirect=True, +) @idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_lp_i2s(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=200) diff --git a/components/esp_driver_i2s/test_apps/lp_i2s/sdkconfig.ci.defaults b/components/esp_driver_i2s/test_apps/lp_i2s/sdkconfig.ci.default similarity index 100% rename from components/esp_driver_i2s/test_apps/lp_i2s/sdkconfig.ci.defaults rename to components/esp_driver_i2s/test_apps/lp_i2s/sdkconfig.ci.default diff --git a/components/esp_driver_sdio/src/sdio_slave.c b/components/esp_driver_sdio/src/sdio_slave.c index b5cbc62649..2398018add 100644 --- a/components/esp_driver_sdio/src/sdio_slave.c +++ b/components/esp_driver_sdio/src/sdio_slave.c @@ -611,7 +611,7 @@ static void sdio_intr_send(void *arg) esp_err_t sdio_slave_send_queue(uint8_t *addr, size_t len, void *arg, TickType_t wait) { - SDIO_SLAVE_CHECK(len > 0, "len <= 0", ESP_ERR_INVALID_ARG); + SDIO_SLAVE_CHECK(len > 0 && len <= 4092, "length out of range: (0, 4092]", ESP_ERR_INVALID_ARG); SDIO_SLAVE_CHECK(esp_ptr_dma_capable(addr) && (uint32_t)addr % 4 == 0, "buffer to send should be DMA capable and 32-bit aligned", ESP_ERR_INVALID_ARG); diff --git a/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py b/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py index 236a1076ca..f79a884efe 100644 --- a/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py +++ b/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py @@ -51,8 +51,15 @@ def test_temperature_sensor_cbs_esp32c5(dut: Dut) -> None: @pytest.mark.two_duts @pytest.mark.parametrize('count', [2], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) @idf_parametrize('target', ['esp32s2', 'esp32c3', 'esp32s3', 'esp32c2', 'esp32c6', 'esp32c61'], indirect=['target']) def test_temperature_phy_cases(case_tester: CaseTester) -> None: # type: ignore for case in case_tester.test_menu: if case.attributes.get('test_env', 'two_duts') == 'two_duts': - case_tester.run_all_multi_dev_cases(case=case, reset=True) + case_tester.run_multi_dev_case(case=case, reset=True) diff --git a/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py b/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py index 423e01c440..bd4087e03c 100644 --- a/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py +++ b/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py @@ -54,8 +54,8 @@ def test_esp_flash_multi(dut: Dut) -> None: @pytest.mark.parametrize( 'config, baud', [ - ('esp32c2_xtal26m', '74880'), - ('esp32c2_xtal26m_rom', '74880'), + ('c2_xtal26m', '74880'), + ('c2_xtal26m_rom', '74880'), ], indirect=True, ) diff --git a/components/spi_flash/test_apps/flash_suspend/pytest_flash_auto_suspend.py b/components/spi_flash/test_apps/flash_suspend/pytest_flash_auto_suspend.py index 09d1bda04d..624898ccae 100644 --- a/components/spi_flash/test_apps/flash_suspend/pytest_flash_auto_suspend.py +++ b/components/spi_flash/test_apps/flash_suspend/pytest_flash_auto_suspend.py @@ -10,7 +10,6 @@ from pytest_embedded_idf.utils import idf_parametrize 'config', [ 'release', - 'i2c_isr_flash', 'text_in_flash_when_suspend', ], indirect=True, diff --git a/examples/peripherals/touch_sensor/touch_sens_sleep/main/touch_sens_sleep.c b/examples/peripherals/touch_sensor/touch_sens_sleep/main/touch_sens_sleep.c index 7b2c3aa293..d363a932cf 100644 --- a/examples/peripherals/touch_sensor/touch_sens_sleep/main/touch_sens_sleep.c +++ b/examples/peripherals/touch_sensor/touch_sens_sleep/main/touch_sens_sleep.c @@ -13,11 +13,11 @@ static const char *TAG = "touch_wakeup"; #define EXAMPLE_TOUCH_SAMPLE_CFG_NUM 1 -#define EXAMPLE_TOUCH_CHANNEL_NUM 3 +#define EXAMPLE_TOUCH_CHANNEL_NUM 2 #define EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES 3 // If you want to change the wake-up channels, please make sure the channel GPIOs won't conflict to the EXT wakeup GPIOs -static int s_channel_id[EXAMPLE_TOUCH_CHANNEL_NUM] = {7, 8, 9}; +static int s_channel_id[EXAMPLE_TOUCH_CHANNEL_NUM] = {8, 9}; // Active threshold to benchmark ratio. (i.e., touch will be activated when data >= benchmark * (1 + ratio)) static float s_thresh2bm_ratio[EXAMPLE_TOUCH_CHANNEL_NUM] = { diff --git a/examples/peripherals/touch_sensor/touch_sens_sleep/pytest_touch_sens_sleep.py b/examples/peripherals/touch_sensor/touch_sens_sleep/pytest_touch_sens_sleep.py index 6228462e5e..21c40d7ef6 100644 --- a/examples/peripherals/touch_sensor/touch_sens_sleep/pytest_touch_sens_sleep.py +++ b/examples/peripherals/touch_sensor/touch_sens_sleep/pytest_touch_sens_sleep.py @@ -7,6 +7,14 @@ from pytest_embedded_idf.utils import soc_filtered_targets @pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'deep_sleep', + 'light_sleep', + ], + indirect=True, +) @idf_parametrize( 'target', soc_filtered_targets('SOC_TOUCH_SENSOR_SUPPORTED == 1 and SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP == 1'), From 613b878df33199eeccaefa1f3f384f558b34333e Mon Sep 17 00:00:00 2001 From: Ashish Sharma Date: Tue, 6 Jan 2026 16:19:31 +0800 Subject: [PATCH 100/226] fix(esp_http_client): fix incorrect digest calculation for SHA256 auth digest According to RFC 7616, nonce-prime and cnonce-prime is used for SHA-256-sess only and not for SHA-256. This commit updates the check and uses nonce only for "-sess" algorithms. Regression from 66995965e783df909096ce56a0ac93778116a504 --- components/esp_http_client/lib/http_auth.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/esp_http_client/lib/http_auth.c b/components/esp_http_client/lib/http_auth.c index 862bc25665..8de6f0c173 100644 --- a/components/esp_http_client/lib/http_auth.c +++ b/components/esp_http_client/lib/http_auth.c @@ -150,8 +150,7 @@ char *http_auth_digest(const char *username, const char *password, esp_http_auth ESP_LOGD(TAG, "%s %s %s %s", "Digest", username, auth_data->realm, password); if ((strcasecmp(auth_data->algorithm, "md5-sess") == 0) || - (strcasecmp(auth_data->algorithm, "SHA256") == 0) || - (strcasecmp(auth_data->algorithm, "SHA-256") == 0)) { + (strcasecmp(auth_data->algorithm, "SHA-256-sess") == 0)) { if (digest_func(ha1, "%s:%s:%016llx", ha1, auth_data->nonce, auth_data->cnonce) <= 0) { goto _digest_exit; } From 799d65ab19312fb69ce62f5d16d77a64d716dac9 Mon Sep 17 00:00:00 2001 From: xiongweichao Date: Wed, 24 Dec 2025 19:07:49 +0800 Subject: [PATCH 101/226] fix(bt): fix l2cap malloc fail in throughput test --- .../bluedroid/btc/profile/std/l2cap/btc_l2cap.c | 13 +++++++------ .../bluedroid/common/include/common/bt_target.h | 2 +- components/bt/host/bluedroid/stack/gap/gap_conn.c | 7 ++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c index 9155784fb8..88de12856b 100644 --- a/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c +++ b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c @@ -42,6 +42,7 @@ #define VFS_CLOSE_TIMEOUT (20 * 1000) #define BTC_L2CAP_ROLE_MASTER 0 #define BTC_L2CAP_ROLE_SLAVE 1 +#define BTC_L2CAP_RX_MTU (990) typedef struct { bool peer_fc; /* true if flow control is set based on peer's request */ @@ -101,10 +102,10 @@ static const tL2CAP_ERTM_INFO obex_l2c_etm_opt = { L2CAP_FCR_ERTM_MODE, /* Mandatory for OBEX over l2cap */ L2CAP_FCR_CHAN_OPT_ERTM, /* Mandatory for OBEX over l2cap */ - OBX_USER_RX_POOL_ID, - OBX_USER_TX_POOL_ID, - OBX_FCR_RX_POOL_ID, - OBX_FCR_TX_POOL_ID + L2CAP_USER_RX_BUF_SIZE, + L2CAP_USER_TX_BUF_SIZE, + L2CAP_FCR_RX_BUF_SIZE, + L2CAP_FCR_TX_BUF_SIZE }; #if L2CAP_DYNAMIC_MEMORY == FALSE @@ -553,7 +554,7 @@ static void btc_l2cap_start_srv(btc_l2cap_args_t *arg) cfg.fcr_present = TRUE; cfg.fcr = obex_l2c_fcr_opts_def; BTA_JvL2capStartServer(slot->security, slot->role, &obex_l2c_etm_opt, slot->psm, - L2CAP_MAX_SDU_LENGTH, &cfg, (tBTA_JV_L2CAP_CBACK *)btc_l2cap_inter_cb, (void *)slot->id); + BTC_L2CAP_RX_MTU, &cfg, (tBTA_JV_L2CAP_CBACK *)btc_l2cap_inter_cb, (void *)slot->id); osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex); } while(0); @@ -694,7 +695,7 @@ static void btc_l2cap_connect(btc_l2cap_args_t *arg) cfg.fcr = obex_l2c_fcr_opts_def; BTA_JvL2capConnect(slot->security, slot->role, &obex_l2c_etm_opt, slot->psm, - L2CAP_MAX_SDU_LENGTH, &cfg, slot->addr, (tBTA_JV_L2CAP_CBACK *)btc_l2cap_inter_cb, (void *)slot->id); + BTC_L2CAP_RX_MTU, &cfg, slot->addr, (tBTA_JV_L2CAP_CBACK *)btc_l2cap_inter_cb, (void *)slot->id); osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex); } while (0); 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 23fca3f3d0..8d0ce74594 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -2112,7 +2112,7 @@ * in basic and streaming modes. Range: 1 - 63 */ #ifndef OBX_FCR_OPT_TX_WINDOW_SIZE_BR_EDR -#define OBX_FCR_OPT_TX_WINDOW_SIZE_BR_EDR 20 +#define OBX_FCR_OPT_TX_WINDOW_SIZE_BR_EDR 10 #endif /* diff --git a/components/bt/host/bluedroid/stack/gap/gap_conn.c b/components/bt/host/bluedroid/stack/gap/gap_conn.c index db9065de81..f6eda25bd2 100644 --- a/components/bt/host/bluedroid/stack/gap/gap_conn.c +++ b/components/bt/host/bluedroid/stack/gap/gap_conn.c @@ -510,18 +510,19 @@ UINT16 GAP_ConnWriteData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT } while (max_len) { + UINT16 length = (p_ccb->rem_mtu_size < max_len) ? p_ccb->rem_mtu_size : max_len; if (p_ccb->cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) { - if ((p_buf = (BT_HDR *)osi_malloc(L2CAP_FCR_ERTM_BUF_SIZE)) == NULL) { + if ((p_buf = (BT_HDR *)osi_malloc(BT_HDR_SIZE + length + L2CAP_MIN_OFFSET + L2CAP_FCS_LEN)) == NULL) { return (GAP_ERR_CONGESTED); } } else { - if ((p_buf = (BT_HDR *)osi_malloc(GAP_DATA_BUF_SIZE)) == NULL) { + if ((p_buf = (BT_HDR *)osi_malloc(BT_HDR_SIZE + length + L2CAP_MIN_OFFSET)) == NULL) { return (GAP_ERR_CONGESTED); } } p_buf->offset = L2CAP_MIN_OFFSET; - p_buf->len = (p_ccb->rem_mtu_size < max_len) ? p_ccb->rem_mtu_size : max_len; + p_buf->len = length; p_buf->event = BT_EVT_TO_BTU_SP_DATA; memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, p_buf->len); From bc5190981d0bb76efe959a5cb08c52474802a018 Mon Sep 17 00:00:00 2001 From: xiongweichao Date: Wed, 24 Dec 2025 19:21:54 +0800 Subject: [PATCH 102/226] fix(bt): retry when L2CAP write fails --- .../host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c index 88de12856b..29bf3105bd 100644 --- a/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c +++ b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c @@ -1022,6 +1022,15 @@ void btc_l2cap_cb_handler(btc_msg_t *msg) p_buf->event++; BTA_JvL2capWrite(p_data->l2c_write.handle, slot->id, p_buf->data + p_buf->offset, p_buf->len, (void *)slot->id); } + } else { + if (!p_data->l2c_write.cong && slot->connected) { + // retry + BTA_JvL2capWrite(p_data->l2c_write.handle, slot->id, p_buf->data + p_buf->offset, p_buf->len, (void *)slot->id); + } else { + p_buf->event--; + // Reset layer-specific flag to 0, marking packet as ready for transmission + p_buf->layer_specific = 0; + } } } osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex); @@ -1082,7 +1091,7 @@ static ssize_t l2cap_vfs_write(int fd, const void * data, size_t size) } p_buf->offset = 0; p_buf->len = write_size; - p_buf->event = 0; // indicate the p_buf be sent count + p_buf->event = 0; // Indicate the count of successful sends of p_buf p_buf->layer_specific = 0; // indicate the p_buf whether to be sent, 0 - ready to send; 1 - have sent memcpy((UINT8 *)(p_buf + 1), data + sent, write_size); } From 321e86bc1a493febb0799a56c182d36b86dae662 Mon Sep 17 00:00:00 2001 From: armando Date: Mon, 5 Jan 2026 14:47:21 +0800 Subject: [PATCH 103/226] feat(isp): allow to bypass shadow register --- .../esp_driver_isp/include/driver/isp_bf.h | 3 + .../esp_driver_isp/include/driver/isp_blc.h | 13 +- .../esp_driver_isp/include/driver/isp_color.h | 3 + .../include/driver/isp_sharpen.h | 3 + .../esp_driver_isp/include/driver/isp_wbg.h | 4 +- components/esp_driver_isp/src/isp_bf.c | 2 +- components/esp_driver_isp/src/isp_blc.c | 2 +- components/esp_driver_isp/src/isp_color.c | 2 +- components/esp_driver_isp/src/isp_sharpen.c | 2 +- components/esp_driver_isp/src/isp_wbg.c | 10 +- components/hal/esp32p4/include/hal/isp_ll.h | 132 +++++++++++------- 11 files changed, 113 insertions(+), 63 deletions(-) diff --git a/components/esp_driver_isp/include/driver/isp_bf.h b/components/esp_driver_isp/include/driver/isp_bf.h index b1301301a9..2669ae3d03 100644 --- a/components/esp_driver_isp/include/driver/isp_bf.h +++ b/components/esp_driver_isp/include/driver/isp_bf.h @@ -24,6 +24,9 @@ typedef struct { uint8_t denoising_level; ///< BF denoising level, from 2 to 20, the bigger the better denoising performance, but the worse detailed uint8_t padding_line_tail_valid_start_pixel; ///< BF edge padding line tail valid start pixel, padding data will only be valid between the valid start pixel and the valid end pixel. Set both the start and end pixel to 0 to make all padding pixel valid uint8_t padding_line_tail_valid_end_pixel; ///< BF edge padding line tail valid end pixel, padding data will only be valid between the valid start pixel and the valid end pixel. Set both the start and end pixel to 0 to make all padding pixel valid + struct { + uint32_t update_once_configured : 1; ///< If set, apply configuration to hardware immediately; otherwise defer to frame boundary + } flags; ///< Driver behaviour flags } esp_isp_bf_config_t; /** diff --git a/components/esp_driver_isp/include/driver/isp_blc.h b/components/esp_driver_isp/include/driver/isp_blc.h index d4a9bd8120..3954e5cfb1 100644 --- a/components/esp_driver_isp/include/driver/isp_blc.h +++ b/components/esp_driver_isp/include/driver/isp_blc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -43,10 +43,13 @@ typedef struct { * @brief ISP BLC configurations */ typedef struct { - isp_window_t window; ///< The sampling windows of BLC, only pixels within the window will be sampled - esp_isp_blc_thresh_t filter_threshold; ///< Black level threshold for each channel of the raw Bayer image - bool filter_enable; ///< Enable filter for BLC, if enabled, only pixels within the threshold will be sampled - esp_isp_blc_stretch_t stretch; ///< Stretch configurations for each channel of the raw Bayer image + isp_window_t window; ///< The sampling windows of BLC, only pixels within the window will be sampled + esp_isp_blc_thresh_t filter_threshold; ///< Black level threshold for each channel of the raw Bayer image + bool filter_enable; ///< Enable filter for BLC, if enabled, only pixels within the threshold will be sampled + esp_isp_blc_stretch_t stretch; ///< Stretch configurations for each channel of the raw Bayer image + struct { + uint32_t update_once_configured : 1; ///< If set, apply configuration to hardware immediately; otherwise defer to frame boundary + } flags; ///< Driver behaviour flags } esp_isp_blc_config_t; /** diff --git a/components/esp_driver_isp/include/driver/isp_color.h b/components/esp_driver_isp/include/driver/isp_color.h index 5549fdeab3..aaf2906eae 100644 --- a/components/esp_driver_isp/include/driver/isp_color.h +++ b/components/esp_driver_isp/include/driver/isp_color.h @@ -36,6 +36,9 @@ typedef struct { * Zero (0): Maintains the original brightness, without adjusting the image's brightness. * Positive range (1 to 127): Increases brightness, the larger the value, the brighter the image. */ + struct { + uint32_t update_once_configured : 1; ///< If set, apply configuration to hardware immediately; otherwise defer to frame boundary + } flags; ///< Driver behaviour flags } esp_isp_color_config_t; /** diff --git a/components/esp_driver_isp/include/driver/isp_sharpen.h b/components/esp_driver_isp/include/driver/isp_sharpen.h index 636454affb..01dc51873c 100644 --- a/components/esp_driver_isp/include/driver/isp_sharpen.h +++ b/components/esp_driver_isp/include/driver/isp_sharpen.h @@ -27,6 +27,9 @@ typedef struct { uint8_t sharpen_template[ISP_SHARPEN_TEMPLATE_X_NUMS][ISP_SHARPEN_TEMPLATE_Y_NUMS]; ///< Sharpen template data uint8_t padding_line_tail_valid_start_pixel; ///< Sharpen edge padding line tail valid start pixel, padding data will only be valid between the valid start pixel and the valid end pixel. Set both the start and end pixel to 0 to make all padding pixel valid uint8_t padding_line_tail_valid_end_pixel; ///< Sharpen edge padding line tail valid end pixel, padding data will only be valid between the valid start pixel and the valid end pixel. Set both the start and end pixel to 0 to make all padding pixel valid + struct { + uint32_t update_once_configured : 1; ///< If set, apply configuration to hardware immediately; otherwise defer to frame boundary + } flags; ///< Driver behaviour flags } esp_isp_sharpen_config_t; /** diff --git a/components/esp_driver_isp/include/driver/isp_wbg.h b/components/esp_driver_isp/include/driver/isp_wbg.h index b8add5cd50..c4545aed18 100644 --- a/components/esp_driver_isp/include/driver/isp_wbg.h +++ b/components/esp_driver_isp/include/driver/isp_wbg.h @@ -21,7 +21,9 @@ extern "C" { * @brief ISP BLC configurations */ typedef struct { - //for future proof + struct { + uint32_t update_once_configured : 1; ///< If set, apply configuration to hardware immediately; otherwise defer to frame boundary + } flags; ///< Driver behaviour flags } esp_isp_wbg_config_t; /** diff --git a/components/esp_driver_isp/src/isp_bf.c b/components/esp_driver_isp/src/isp_bf.c index 1c71d0eefd..23fd164428 100644 --- a/components/esp_driver_isp/src/isp_bf.c +++ b/components/esp_driver_isp/src/isp_bf.c @@ -43,7 +43,7 @@ esp_err_t esp_isp_bf_configure(isp_proc_handle_t proc, const esp_isp_bf_config_t isp_hal_bf_config(&(proc->hal), NULL); } - bool valid = isp_ll_shadow_update_bf(proc->hal.hw); + bool valid = isp_ll_shadow_update_bf(proc->hal.hw, config->flags.update_once_configured); ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update bf shadow register"); return ESP_OK; diff --git a/components/esp_driver_isp/src/isp_blc.c b/components/esp_driver_isp/src/isp_blc.c index f8faa2774b..9a9ca10445 100644 --- a/components/esp_driver_isp/src/isp_blc.c +++ b/components/esp_driver_isp/src/isp_blc.c @@ -58,7 +58,7 @@ esp_err_t esp_isp_blc_configure(isp_proc_handle_t isp_proc, const esp_isp_blc_co // Configure stretch enable for each channel isp_ll_blc_enable_stretch(isp_proc->hal.hw, config->stretch.top_left_chan_stretch_en, config->stretch.top_right_chan_stretch_en, config->stretch.bottom_left_chan_stretch_en, config->stretch.bottom_right_chan_stretch_en); - bool valid = isp_ll_shadow_update_blc(isp_proc->hal.hw); + bool valid = isp_ll_shadow_update_blc(isp_proc->hal.hw, config->flags.update_once_configured); ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update blc shadow register"); return ESP_OK; diff --git a/components/esp_driver_isp/src/isp_color.c b/components/esp_driver_isp/src/isp_color.c index c3da6d5cdc..cea2d7945f 100644 --- a/components/esp_driver_isp/src/isp_color.c +++ b/components/esp_driver_isp/src/isp_color.c @@ -43,7 +43,7 @@ esp_err_t esp_isp_color_configure(isp_proc_handle_t proc, const esp_isp_color_co isp_hal_color_config(&(proc->hal), NULL); } - bool valid = isp_ll_shadow_update_color(proc->hal.hw); + bool valid = isp_ll_shadow_update_color(proc->hal.hw, config->flags.update_once_configured); ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update color shadow register"); return ESP_OK; diff --git a/components/esp_driver_isp/src/isp_sharpen.c b/components/esp_driver_isp/src/isp_sharpen.c index c0dd2fc258..e0746946d0 100644 --- a/components/esp_driver_isp/src/isp_sharpen.c +++ b/components/esp_driver_isp/src/isp_sharpen.c @@ -45,7 +45,7 @@ esp_err_t esp_isp_sharpen_configure(isp_proc_handle_t proc, const esp_isp_sharpe isp_hal_sharpen_config(&(proc->hal), NULL); } - bool valid = isp_ll_shadow_update_sharpen(proc->hal.hw); + bool valid = isp_ll_shadow_update_sharpen(proc->hal.hw, config->flags.update_once_configured); ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update sharp shadow register"); return ESP_OK; diff --git a/components/esp_driver_isp/src/isp_wbg.c b/components/esp_driver_isp/src/isp_wbg.c index 96b809840c..b17d7d9ecc 100644 --- a/components/esp_driver_isp/src/isp_wbg.c +++ b/components/esp_driver_isp/src/isp_wbg.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -32,11 +32,14 @@ esp_err_t esp_isp_wbg_configure(isp_proc_handle_t isp_proc, const esp_isp_wbg_co } #endif - ESP_RETURN_ON_FALSE(isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE(isp_proc && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); // Configure clock control mode isp_ll_awb_set_wb_gain_clk_ctrl_mode(isp_proc->hal.hw, ISP_LL_PIPELINE_CLK_CTRL_AUTO); + bool valid = isp_ll_shadow_update_wbg(isp_proc->hal.hw, config->flags.update_once_configured); + ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update wbg shadow register"); + return ESP_OK; } @@ -61,9 +64,6 @@ esp_err_t esp_isp_wbg_set_wb_gain(isp_proc_handle_t isp_proc, isp_wbg_gain_t gai // Set WBG gain isp_ll_awb_set_wb_gain(isp_proc->hal.hw, gain); - bool valid = isp_ll_shadow_update_wbg(isp_proc->hal.hw); - ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update wbg shadow register"); - return ESP_OK; } diff --git a/components/hal/esp32p4/include/hal/isp_ll.h b/components/hal/esp32p4/include/hal/isp_ll.h index 79aead92d0..aa21ed0ebc 100644 --- a/components/hal/esp32p4/include/hal/isp_ll.h +++ b/components/hal/esp32p4/include/hal/isp_ll.h @@ -1899,21 +1899,27 @@ static inline void isp_ll_shadow_set_mode(isp_dev_t *hw, isp_ll_shadow_mode_t mo /** * @brief Update BLC shadow register * - * @param[in] hw Hardware instance address + * @param[in] hw Hardware instance address + * @param[in] force_update Force update * @return * - True if update is successful, False otherwise */ -static inline bool isp_ll_shadow_update_blc(isp_dev_t *hw) +static inline bool isp_ll_shadow_update_blc(isp_dev_t *hw, bool force_update) { //only valid when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC HAL_ASSERT(hw->shadow_reg_ctrl.shadow_update_sel == ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC); - if (hw->shadow_reg_ctrl.blc_update == 1) { - return false; - } + if (force_update) { + //don't care shadow register + hw->shadow_reg_ctrl.blc_update = 1; + } else { + if (hw->shadow_reg_ctrl.blc_update == 1) { + return false; + } - //self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC - hw->shadow_reg_ctrl.blc_update = 1; + //self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC + hw->shadow_reg_ctrl.blc_update = 1; + } return true; } @@ -1921,21 +1927,27 @@ static inline bool isp_ll_shadow_update_blc(isp_dev_t *hw) /** * @brief Update DPC shadow register * - * @param[in] hw Hardware instance address + * @param[in] hw Hardware instance address + * @param[in] force_update Force update * @return * - True if update is successful, False otherwise */ -static inline bool isp_ll_shadow_update_dpc(isp_dev_t *hw) +static inline bool isp_ll_shadow_update_dpc(isp_dev_t *hw, bool force_update) { //only valid when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC HAL_ASSERT(hw->shadow_reg_ctrl.shadow_update_sel == ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC); - if (hw->shadow_reg_ctrl.dpc_update == 1) { - return false; - } + if (force_update) { + //don't care shadow register + hw->shadow_reg_ctrl.dpc_update = 1; + } else { + if (hw->shadow_reg_ctrl.dpc_update == 1) { + return false; + } - //self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC - hw->shadow_reg_ctrl.dpc_update = 1; + //self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC + hw->shadow_reg_ctrl.dpc_update = 1; + } return true; } @@ -1943,21 +1955,27 @@ static inline bool isp_ll_shadow_update_dpc(isp_dev_t *hw) /** * @brief Update BF shadow register * - * @param[in] hw Hardware instance address + * @param[in] hw Hardware instance address + * @param[in] force_update Force update * @return * - True if update is successful, False otherwise */ -static inline bool isp_ll_shadow_update_bf(isp_dev_t *hw) +static inline bool isp_ll_shadow_update_bf(isp_dev_t *hw, bool force_update) { //only valid when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC HAL_ASSERT(hw->shadow_reg_ctrl.shadow_update_sel == ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC); - if (hw->shadow_reg_ctrl.bf_update == 1) { - return false; - } + if (force_update) { + //don't care shadow register + hw->shadow_reg_ctrl.bf_update = 1; + } else { + if (hw->shadow_reg_ctrl.bf_update == 1) { + return false; + } - //self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC - hw->shadow_reg_ctrl.bf_update = 1; + //self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC + hw->shadow_reg_ctrl.bf_update = 1; + } return true; } @@ -1965,21 +1983,27 @@ static inline bool isp_ll_shadow_update_bf(isp_dev_t *hw) /** * @brief Update WBG shadow register * - * @param[in] hw Hardware instance address + * @param[in] hw Hardware instance address + * @param[in] force_update Force update * @return * - True if update is successful, False otherwise */ -static inline bool isp_ll_shadow_update_wbg(isp_dev_t *hw) +static inline bool isp_ll_shadow_update_wbg(isp_dev_t *hw, bool force_update) { //only valid when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC HAL_ASSERT(hw->shadow_reg_ctrl.shadow_update_sel == ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC); - if (hw->shadow_reg_ctrl.wbg_update == 1) { - return false; - } + if (force_update) { + //don't care shadow register + hw->shadow_reg_ctrl.wbg_update = 1; + } else { + if (hw->shadow_reg_ctrl.wbg_update == 1) { + return false; + } - //self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC - hw->shadow_reg_ctrl.wbg_update = 1; + //self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC + hw->shadow_reg_ctrl.wbg_update = 1; + } return true; } @@ -2015,21 +2039,27 @@ static inline bool isp_ll_shadow_update_ccm(isp_dev_t *hw, bool force_update) /** * @brief Update Sharpen shadow register * - * @param[in] hw Hardware instance address + * @param[in] hw Hardware instance address + * @param[in] force_update Force update * @return * - True if update is successful, False otherwise */ -static inline bool isp_ll_shadow_update_sharpen(isp_dev_t *hw) +static inline bool isp_ll_shadow_update_sharpen(isp_dev_t *hw, bool force_update) { //only valid when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC HAL_ASSERT(hw->shadow_reg_ctrl.shadow_update_sel == ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC); - if (hw->shadow_reg_ctrl.sharp_update == 1) { - return false; - } + if (force_update) { + //don't care shadow register + hw->shadow_reg_ctrl.sharp_update = 1; + } else { + if (hw->shadow_reg_ctrl.sharp_update == 1) { + return false; + } - //self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC - hw->shadow_reg_ctrl.sharp_update = 1; + //self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC + hw->shadow_reg_ctrl.sharp_update = 1; + } return true; } @@ -2037,21 +2067,27 @@ static inline bool isp_ll_shadow_update_sharpen(isp_dev_t *hw) /** * @brief Update Color shadow register * - * @param[in] hw Hardware instance address + * @param[in] hw Hardware instance address + * @param[in] force_update Force update * @return * - True if update is successful, False otherwise */ -static inline bool isp_ll_shadow_update_color(isp_dev_t *hw) +static inline bool isp_ll_shadow_update_color(isp_dev_t *hw, bool force_update) { //only valid when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC HAL_ASSERT(hw->shadow_reg_ctrl.shadow_update_sel == ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC); - if (hw->shadow_reg_ctrl.color_update == 1) { - return false; - } + if (force_update) { + //don't care shadow register + hw->shadow_reg_ctrl.color_update = 1; + } else { + if (hw->shadow_reg_ctrl.color_update == 1) { + return false; + } - //self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC - hw->shadow_reg_ctrl.color_update = 1; + //self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC + hw->shadow_reg_ctrl.color_update = 1; + } return true; } @@ -2062,25 +2098,25 @@ static inline void isp_ll_shadow_set_mode(isp_dev_t *hw, isp_ll_shadow_mode_t mo //for compatibility } -static inline bool isp_ll_shadow_update_blc(isp_dev_t *hw) +static inline bool isp_ll_shadow_update_blc(isp_dev_t *hw, bool force_update) { //for compatibility return true; } -static inline bool isp_ll_shadow_update_dpc(isp_dev_t *hw) +static inline bool isp_ll_shadow_update_dpc(isp_dev_t *hw, bool force_update) { //for compatibility return true; } -static inline bool isp_ll_shadow_update_bf(isp_dev_t *hw) +static inline bool isp_ll_shadow_update_bf(isp_dev_t *hw, bool force_update) { //for compatibility return true; } -static inline bool isp_ll_shadow_update_wbg(isp_dev_t *hw) +static inline bool isp_ll_shadow_update_wbg(isp_dev_t *hw, bool force_update) { //for compatibility return true; @@ -2092,13 +2128,13 @@ static inline bool isp_ll_shadow_update_ccm(isp_dev_t *hw, bool force_update) return true; } -static inline bool isp_ll_shadow_update_sharpen(isp_dev_t *hw) +static inline bool isp_ll_shadow_update_sharpen(isp_dev_t *hw, bool force_update) { //for compatibility return true; } -static inline bool isp_ll_shadow_update_color(isp_dev_t *hw) +static inline bool isp_ll_shadow_update_color(isp_dev_t *hw, bool force_update) { //for compatibility return true; From dc7b41a3654f8963964a1586a02429d16379da4e Mon Sep 17 00:00:00 2001 From: armando Date: Mon, 5 Jan 2026 15:58:08 +0800 Subject: [PATCH 104/226] fix(isp): fixed awb subwindow always need to be set issue --- components/esp_driver_isp/src/isp_awb.c | 66 +++++++++++++------------ 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/components/esp_driver_isp/src/isp_awb.c b/components/esp_driver_isp/src/isp_awb.c index 61f0df71df..b9f25de790 100644 --- a/components/esp_driver_isp/src/isp_awb.c +++ b/components/esp_driver_isp/src/isp_awb.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -74,46 +74,48 @@ static esp_err_t s_esp_isp_awb_config_hardware(isp_proc_handle_t isp_proc, const ESP_RETURN_ON_FALSE(isp_hal_awb_set_window_range(&isp_proc->hal, &awb_cfg->window), ESP_ERR_INVALID_ARG, TAG, "invalid window range"); + bool subwindow_is_zero = awb_cfg->subwindow.top_left.x == 0 && + awb_cfg->subwindow.top_left.y == 0 && + awb_cfg->subwindow.btm_right.x == 0 && + awb_cfg->subwindow.btm_right.y == 0; // Subwindow feature is only supported on REV >= 3.0 if (efuse_hal_chip_revision() < 300) { - bool subwindow_is_zero = awb_cfg->subwindow.top_left.x == 0 && - awb_cfg->subwindow.top_left.y == 0 && - awb_cfg->subwindow.btm_right.x == 0 && - awb_cfg->subwindow.btm_right.y == 0; if (!subwindow_is_zero) { ESP_LOGW(TAG, "Subwindow feature is not supported on REV < 3.0, subwindow will not be configured"); } } else { - // Subwindow is just checked and configured on REV >= 3.0 - isp_window_t subwindow = awb_cfg->subwindow; - ESP_RETURN_ON_FALSE( - (subwindow.top_left.x >= awb_cfg->window.top_left.x) && - (subwindow.top_left.y >= awb_cfg->window.top_left.y) && - (subwindow.btm_right.x <= awb_cfg->window.btm_right.x) && - (subwindow.btm_right.y <= awb_cfg->window.btm_right.y), - ESP_ERR_INVALID_ARG, TAG, "subwindow exceeds window range" - ); + if (!subwindow_is_zero) { + // Subwindow is just checked and configured on REV >= 3.0 + isp_window_t subwindow = awb_cfg->subwindow; + ESP_RETURN_ON_FALSE( + (subwindow.top_left.x >= awb_cfg->window.top_left.x) && + (subwindow.top_left.y >= awb_cfg->window.top_left.y) && + (subwindow.btm_right.x <= awb_cfg->window.btm_right.x) && + (subwindow.btm_right.y <= awb_cfg->window.btm_right.y), + ESP_ERR_INVALID_ARG, TAG, "subwindow exceeds window range" + ); - if ((subwindow.btm_right.x - subwindow.top_left.x + 1) / ISP_AWB_WINDOW_X_NUM < 4 || - (subwindow.btm_right.y - subwindow.top_left.y + 1) / ISP_AWB_WINDOW_Y_NUM < 4) { - ESP_LOGE(TAG, "subwindow block size is too small: width and height must be at least 4 (got %d x %d)", - (subwindow.btm_right.x - subwindow.top_left.x + 1) / ISP_AWB_WINDOW_X_NUM, - (subwindow.btm_right.y - subwindow.top_left.y + 1) / ISP_AWB_WINDOW_Y_NUM); - return ESP_ERR_INVALID_ARG; - } + if ((subwindow.btm_right.x - subwindow.top_left.x + 1) / ISP_AWB_WINDOW_X_NUM < 4 || + (subwindow.btm_right.y - subwindow.top_left.y + 1) / ISP_AWB_WINDOW_Y_NUM < 4) { + ESP_LOGE(TAG, "subwindow block size is too small: width and height must be at least 4 (got %d x %d)", + (subwindow.btm_right.x - subwindow.top_left.x + 1) / ISP_AWB_WINDOW_X_NUM, + (subwindow.btm_right.y - subwindow.top_left.y + 1) / ISP_AWB_WINDOW_Y_NUM); + return ESP_ERR_INVALID_ARG; + } - int size_x = subwindow.btm_right.x - subwindow.top_left.x + 1; - int size_y = subwindow.btm_right.y - subwindow.top_left.y + 1; - if ((size_x % ISP_AWB_WINDOW_X_NUM != 0) || (size_y % ISP_AWB_WINDOW_Y_NUM != 0)) { - ESP_LOGW(TAG, "subwindow size (%d x %d) is not divisible by AWB subwindow blocks grid (%d x %d). \ - Resolution will be floored to the nearest divisible value.", - size_x, size_y, ISP_AWB_WINDOW_X_NUM, ISP_AWB_WINDOW_Y_NUM); - // floor to the nearest divisible value - subwindow.btm_right.x -= size_x % ISP_AWB_WINDOW_X_NUM; - subwindow.btm_right.y -= size_y % ISP_AWB_WINDOW_Y_NUM; + int size_x = subwindow.btm_right.x - subwindow.top_left.x + 1; + int size_y = subwindow.btm_right.y - subwindow.top_left.y + 1; + if ((size_x % ISP_AWB_WINDOW_X_NUM != 0) || (size_y % ISP_AWB_WINDOW_Y_NUM != 0)) { + ESP_LOGW(TAG, "subwindow size (%d x %d) is not divisible by AWB subwindow blocks grid (%d x %d). \ + Resolution will be floored to the nearest divisible value.", + size_x, size_y, ISP_AWB_WINDOW_X_NUM, ISP_AWB_WINDOW_Y_NUM); + // floor to the nearest divisible value + subwindow.btm_right.x -= size_x % ISP_AWB_WINDOW_X_NUM; + subwindow.btm_right.y -= size_y % ISP_AWB_WINDOW_Y_NUM; + } + ESP_RETURN_ON_FALSE(isp_hal_awb_set_subwindow_range(&isp_proc->hal, &subwindow), + ESP_ERR_INVALID_ARG, TAG, "invalid subwindow range"); } - ESP_RETURN_ON_FALSE(isp_hal_awb_set_subwindow_range(&isp_proc->hal, &subwindow), - ESP_ERR_INVALID_ARG, TAG, "invalid subwindow range"); } isp_u32_range_t lum_range = awb_cfg->white_patch.luminance; From b40f1d049c38becea08590a49079a1592f142793 Mon Sep 17 00:00:00 2001 From: Chen Jian Hua Date: Wed, 7 Jan 2026 16:47:09 +0800 Subject: [PATCH 105/226] feat(bt/bluedroid): Support get allocated heap size (cherry picked from commit b85771d57722a842eb0a895f1a55e0df4b6db2dd) Co-authored-by: chenjianhua --- components/bt/common/include/bt_common.h | 6 ++ components/bt/common/include/bt_user_config.h | 6 ++ components/bt/common/osi/allocator.c | 74 ++++++++++++++++++- .../bt/common/osi/include/osi/allocator.h | 6 +- components/bt/common/osi/pkt_queue.c | 2 +- components/bt/host/bluedroid/Kconfig.in | 8 ++ .../bt/host/bluedroid/api/esp_bt_main.c | 11 +++ components/bt/host/bluedroid/hci/hci_hal_h4.c | 2 +- 8 files changed, 111 insertions(+), 4 deletions(-) diff --git a/components/bt/common/include/bt_common.h b/components/bt/common/include/bt_common.h index 098082f647..372ea68e7e 100644 --- a/components/bt/common/include/bt_common.h +++ b/components/bt/common/include/bt_common.h @@ -61,6 +61,12 @@ #define HEAP_MEMORY_DEBUG FALSE #endif +#if UC_BT_BLUEDROID_MEM_STATS +#define HEAP_MEMORY_STATS TRUE +#else +#define HEAP_MEMORY_STATS FALSE +#endif + #if UC_BT_BLUEDROID_THREAD_DEBUG #define OSI_THREAD_DEBUG TRUE #else diff --git a/components/bt/common/include/bt_user_config.h b/components/bt/common/include/bt_user_config.h index 2d695fa1c3..3ddc188f13 100644 --- a/components/bt/common/include/bt_user_config.h +++ b/components/bt/common/include/bt_user_config.h @@ -107,6 +107,12 @@ #define UC_BT_BLUEDROID_MEM_DEBUG FALSE #endif +#ifdef CONFIG_BT_BLUEDROID_MEM_STATS +#define UC_BT_BLUEDROID_MEM_STATS TRUE +#else +#define UC_BT_BLUEDROID_MEM_STATS FALSE +#endif + #ifdef CONFIG_BT_BLUEDROID_THREAD_DEBUG #define UC_BT_BLUEDROID_THREAD_DEBUG TRUE #else diff --git a/components/bt/common/osi/allocator.c b/components/bt/common/osi/allocator.c index 91ec942eb5..68a5bdb3a4 100644 --- a/components/bt/common/osi/allocator.c +++ b/components/bt/common/osi/allocator.c @@ -20,6 +20,12 @@ #include "bt_common.h" #include "osi/allocator.h" +#if HEAP_MEMORY_STATS +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#endif extern void *pvPortZalloc(size_t size); extern void vPortFree(void *pv); @@ -198,6 +204,28 @@ uint32_t osi_mem_dbg_get_max_size_section(uint8_t index) } #endif +#if HEAP_MEMORY_STATS +static size_t s_mem_used_size = 0; +static SemaphoreHandle_t s_mem_mutex = NULL; + +int osi_mem_init(void) +{ + s_mem_mutex = xSemaphoreCreateMutex(); + if (s_mem_mutex == NULL) { + return -1; + } + return 0; +} + +void osi_mem_deinit(void) +{ + if (s_mem_mutex) { + vSemaphoreDelete(s_mem_mutex); + s_mem_mutex = NULL; + } +} +#endif + char *osi_strdup(const char *str) { size_t size = strlen(str) + 1; // + 1 for the null terminator @@ -224,6 +252,15 @@ void *osi_malloc_func(size_t size) #endif } +#if HEAP_MEMORY_STATS + if (s_mem_mutex != NULL && p != NULL) { + size_t alloc_size = heap_caps_get_allocated_size(p); + xSemaphoreTake(s_mem_mutex, portMAX_DELAY); + s_mem_used_size += alloc_size; + xSemaphoreGive(s_mem_mutex); + } +#endif + return p; } @@ -240,10 +277,45 @@ void *osi_calloc_func(size_t size) #endif } +#if HEAP_MEMORY_STATS + if (s_mem_mutex != NULL && p != NULL) { + size_t alloc_size = heap_caps_get_allocated_size(p); + xSemaphoreTake(s_mem_mutex, portMAX_DELAY); + s_mem_used_size += alloc_size; + xSemaphoreGive(s_mem_mutex); + } +#endif + return p; } void osi_free_func(void *ptr) { - osi_free(ptr); +#if HEAP_MEMORY_DEBUG + osi_mem_dbg_clean(ptr, __func__, __LINE__); +#endif + +#if HEAP_MEMORY_STATS + if (s_mem_mutex != NULL && ptr != NULL) { + size_t free_size = heap_caps_get_allocated_size(ptr); + xSemaphoreTake(s_mem_mutex, portMAX_DELAY); + if (s_mem_used_size >= free_size) { + s_mem_used_size -= free_size; + } else { + OSI_TRACE_ERROR("The size of malloc and free not match: alloc_size=%u free_size=%u", + s_mem_used_size, free_size); + } + xSemaphoreGive(s_mem_mutex); + } +#endif + + free(ptr); } + +#if HEAP_MEMORY_STATS +// Get the size of memory allocated by Bluedroid but not yet freed +uint32_t esp_host_used_heap_size_get(void) +{ + return s_mem_used_size; +} +#endif diff --git a/components/bt/common/osi/include/osi/allocator.h b/components/bt/common/osi/include/osi/allocator.h index 071892ffaf..caba42f3ea 100644 --- a/components/bt/common/osi/include/osi/allocator.h +++ b/components/bt/common/osi/include/osi/allocator.h @@ -24,6 +24,10 @@ #include "bt_common.h" #include "esp_heap_caps.h" +#if HEAP_MEMORY_STATS +int osi_mem_init(void); +void osi_mem_deinit(void); +#endif char *osi_strdup(const char *str); void *osi_malloc_func(size_t size); @@ -109,7 +113,7 @@ do { \ // Memory alloc function with print and assertion when fails #define osi_malloc(size) osi_malloc_func((size)) #define osi_calloc(size) osi_calloc_func((size)) -#define osi_free(p) free((p)) +#define osi_free(p) osi_free_func((p)) #endif /* HEAP_MEMORY_DEBUG */ diff --git a/components/bt/common/osi/pkt_queue.c b/components/bt/common/osi/pkt_queue.c index 4c149be2c6..50720de0c5 100644 --- a/components/bt/common/osi/pkt_queue.c +++ b/components/bt/common/osi/pkt_queue.c @@ -19,7 +19,7 @@ struct pkt_queue { struct pkt_queue *pkt_queue_create(void) { - struct pkt_queue *queue = calloc(1, sizeof(struct pkt_queue)); + struct pkt_queue *queue = osi_calloc(sizeof(struct pkt_queue)); if (queue == NULL) { return NULL; } diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 892ac18306..46de142fea 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -492,6 +492,14 @@ menu "Bluedroid debug option" help Bluedroid memory debug + config BT_BLUEDROID_MEM_STATS + bool "Bluedroid memory statistics" + depends on BT_BLUEDROID_ENABLED + depends on !BT_BLUEDROID_MEM_DEBUG + default n + help + Enable Bluedroid memory usage statistics + config BT_BLUEDROID_THREAD_DEBUG bool "Bluedroid thread debug" depends on BT_BLUEDROID_ENABLED diff --git a/components/bt/host/bluedroid/api/esp_bt_main.c b/components/bt/host/bluedroid/api/esp_bt_main.c index fb7d59f02f..a728e81c35 100644 --- a/components/bt/host/bluedroid/api/esp_bt_main.c +++ b/components/bt/host/bluedroid/api/esp_bt_main.c @@ -153,6 +153,13 @@ esp_err_t esp_bluedroid_init_with_cfg(esp_bluedroid_config_t *cfg) osi_mem_dbg_init(); #endif +#if HEAP_MEMORY_STATS + if (osi_mem_init() != 0) { + LOG_ERROR("Bluedroid Initialize Fail"); + return ESP_FAIL; + } +#endif + ret = bluedroid_config_init(cfg); if (ret != BT_STATUS_SUCCESS) { LOG_ERROR("Bluedroid stack initialize fail, ret:%d", ret); @@ -243,6 +250,10 @@ esp_err_t esp_bluedroid_deinit(void) bt_hci_log_deinit(); #endif // (BT_HCI_LOG_INCLUDED == TRUE) +#if HEAP_MEMORY_STATS + osi_mem_deinit(); +#endif + s_bt_host_state = ESP_BLUEDROID_STATUS_UNINITIALIZED; return ESP_OK; } diff --git a/components/bt/host/bluedroid/hci/hci_hal_h4.c b/components/bt/host/bluedroid/hci/hci_hal_h4.c index 0baa265f2a..90cb2a1177 100644 --- a/components/bt/host/bluedroid/hci/hci_hal_h4.c +++ b/components/bt/host/bluedroid/hci/hci_hal_h4.c @@ -660,7 +660,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) } #endif pkt_size = BT_PKT_LINKED_HDR_SIZE + BT_HDR_SIZE + len; - #if HEAP_MEMORY_DEBUG + #if (HEAP_MEMORY_DEBUG || HEAP_MEMORY_STATS) linked_pkt = (pkt_linked_item_t *) osi_calloc(pkt_size); #else linked_pkt = (pkt_linked_item_t *) osi_calloc_base(pkt_size); From a310a0f3556dc1e59b0c7b2b7793c849f7814dc9 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:16 +0800 Subject: [PATCH 106/226] feat(ble/bluedroid): reduce bluedroid host heap used for BLE (cherry picked from commit 438590a1f5cf02edfe659770e1e86e342b8c88f7) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 41 +++++++++++++++---- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 10 ++++- .../bluedroid/bta/dm/include/bta_dm_int.h | 9 ++-- .../bt/host/bluedroid/btc/core/btc_main.c | 4 +- .../common/include/common/bt_target.h | 4 +- components/bt/host/bluedroid/main/bte_init.c | 6 +++ .../bt/host/bluedroid/stack/btm/btm_acl.c | 17 +++++++- .../bt/host/bluedroid/stack/btm/btm_devctl.c | 7 ++-- .../bt/host/bluedroid/stack/btm/btm_main.c | 4 ++ .../bt/host/bluedroid/stack/btm/btm_pm.c | 12 ++++-- .../bt/host/bluedroid/stack/btm/btm_sec.c | 5 ++- .../bluedroid/stack/btm/include/btm_int.h | 4 ++ .../bt/host/bluedroid/stack/gatt/gatt_api.c | 10 ++++- .../bt/host/bluedroid/stack/gatt/gatt_auth.c | 11 ++++- .../bt/host/bluedroid/stack/gatt/gatt_main.c | 31 ++++++++------ .../bt/host/bluedroid/stack/gatt/gatt_utils.c | 35 +++++++++++----- .../bluedroid/stack/gatt/include/gatt_int.h | 18 +++++--- 17 files changed, 172 insertions(+), 56 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 5f6e490b5b..77cbd7af18 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -49,9 +49,10 @@ #if (BT_CONTROLLER_INCLUDED == TRUE) #include "esp_bt.h" #endif - +#if (CLASSIC_BT_INCLUDED == TRUE) 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); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc, BD_NAME bd_name); static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name); #if (SDP_INCLUDED == TRUE) @@ -70,7 +71,9 @@ static UINT8 bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class, BD_ static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, int result); #endif ///SMP_INCLUDED == TRUE static void bta_dm_local_name_cback(const BD_ADDR bd_addr); +#if (CLASSIC_BT_INCLUDED == TRUE) static BOOLEAN bta_dm_check_av(UINT16 event); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data); @@ -91,7 +94,9 @@ static void bta_dm_eir_search_services( tBTM_INQ_RESULTS *p_result, static void bta_dm_search_timer_cback (TIMER_LIST_ENT *p_tle); static void bta_dm_disable_conn_down_timer_cback (TIMER_LIST_ENT *p_tle); static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr); +#if (CLASSIC_BT_INCLUDED == TRUE) static void bta_dm_adjust_roles(BOOLEAN delay_role_switch); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #if (SDP_INCLUDED == TRUE || SMP_INCLUDED == TRUE) static char *bta_dm_get_remname(void); #endif ///SDP_INCLUDED == TRUE || SMP_INCLUDED == TRUE @@ -137,7 +142,10 @@ static void bta_dm_observe_cmpl_cb(void *p_result); static void bta_dm_observe_discard_cb (uint32_t num_dis); #endif ///BLE_INCLUDED == TRUE +#if (CLASSIC_BT_INCLUDED == TRUE) static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) + extern void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8 *p_uuid128); static void bta_dm_disable_timer_cback(TIMER_LIST_ENT *p_tle); @@ -481,7 +489,9 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status ) /* hw is ready, go on with BTA DM initialization */ memset(&bta_dm_search_cb, 0x00, sizeof(bta_dm_search_cb)); memset(&bta_dm_conn_srvcs, 0x00, sizeof(bta_dm_conn_srvcs)); +#if (CLASSIC_BT_INCLUDED == TRUE) memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB)); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) memcpy(dev_class, p_bta_dm_cfg->dev_class, sizeof(dev_class)); #if CLASSIC_BT_INCLUDED BTM_SetDeviceClass (dev_class); @@ -1673,7 +1683,9 @@ void bta_dm_ci_rmt_oob_act(tBTA_DM_MSG *p_data) *******************************************************************************/ void bta_dm_search_start (tBTA_DM_MSG *p_data) { +#if (CLASSIC_BT_INCLUDED == TRUE) tBTM_INQUIRY_CMPL result; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE) UINT16 len = (UINT16)(sizeof(tBT_UUID) * p_data->search.num_uuid); @@ -1682,12 +1694,13 @@ void bta_dm_search_start (tBTA_DM_MSG *p_data) APPL_TRACE_DEBUG("%s avoid_scatter=%d", __func__, p_bta_dm_cfg->avoid_scatter); +#if (CLASSIC_BT_INCLUDED == TRUE) if (p_bta_dm_cfg->avoid_scatter && (p_data->search.rs_res == BTA_DM_RS_NONE) && bta_dm_check_av(BTA_DM_API_SEARCH_EVT)) { memcpy(&bta_dm_cb.search_msg, &p_data->search, sizeof(tBTA_DM_API_SEARCH)); return; } - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) BTM_ClearInqDb(NULL); /* save search params */ bta_dm_search_cb.p_search_cback = p_data->search.p_cback; @@ -1710,6 +1723,7 @@ void bta_dm_search_start (tBTA_DM_MSG *p_data) memcpy(bta_dm_search_cb.p_srvc_uuid, p_data->search.p_uuid, len); } #endif +#if (CLASSIC_BT_INCLUDED == TRUE) result.status = BTM_StartInquiry( (tBTM_INQ_PARMS *)&p_data->search.inq_params, bta_dm_inq_results_cb, (tBTM_CMPL_CB *) bta_dm_inq_cmpl_cb); @@ -1719,6 +1733,7 @@ void bta_dm_search_start (tBTA_DM_MSG *p_data) result.num_resp = 0; bta_dm_inq_cmpl_cb ((void *)&result); } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } /******************************************************************************* @@ -2869,6 +2884,7 @@ static void bta_dm_sdp_callback (UINT16 sdp_status) } } #endif ///SDP_INCLUDED == TRUE +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function bta_dm_inq_results_cb @@ -2957,6 +2973,7 @@ static void bta_dm_inq_cmpl_cb (void *p_result) } } } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** @@ -3583,6 +3600,7 @@ static void bta_dm_acl_link_stat_cback(tBTM_ACL_LINK_STAT_EVENT_DATA *p_data) } } +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function bta_dm_rs_cback @@ -3651,6 +3669,7 @@ static BOOLEAN bta_dm_check_av(UINT16 event) } return switching; } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** @@ -3670,10 +3689,11 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data) tBTA_DM_SEC conn; BOOLEAN is_new = p_data->acl_change.is_new; BD_ADDR_PTR p_bda = p_data->acl_change.bd_addr; - BOOLEAN need_policy_change = FALSE; BOOLEAN issue_unpair_cb = FALSE; - +#if (CLASSIC_BT_INCLUDED == TRUE) + BOOLEAN need_policy_change = FALSE; tBTA_DM_PEER_DEVICE *p_dev; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) memset(&conn, 0, sizeof(tBTA_DM_SEC)); switch (p_data->acl_change.event) { @@ -3684,7 +3704,7 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data) bta_dm_cb.p_sec_cback(BTA_DM_BUSY_LEVEL_EVT, &conn); } return; - +#if (CLASSIC_BT_INCLUDED == TRUE) case BTM_BL_ROLE_CHG_EVT: /* role change event */ p_dev = bta_dm_find_peer_device(p_bda); if (p_dev) { @@ -3720,6 +3740,7 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data) } } return; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } /* Collision report from Stack: Notify profiles */ @@ -3857,7 +3878,9 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data) } } +#if (CLASSIC_BT_INCLUDED == TRUE) bta_dm_adjust_roles(TRUE); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } /******************************************************************************* @@ -3934,7 +3957,7 @@ static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, } } } - +#if (CLASSIC_BT_INCLUDED == TRUE) if ((BTA_ID_AV == id) || (BTA_ID_AVK == id)) { if ( status == BTA_SYS_CONN_BUSY) { if (p_dev) { @@ -3963,8 +3986,10 @@ static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, if ((status != BTA_SYS_CONN_BUSY) && (status != BTA_SYS_CONN_IDLE)) { bta_dm_adjust_roles(FALSE); } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function bta_dm_delay_role_switch_cback @@ -3980,6 +4005,7 @@ static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle) APPL_TRACE_EVENT("bta_dm_delay_role_switch_cback: initiating Delayed RS"); bta_dm_adjust_roles (FALSE); } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** @@ -4023,7 +4049,7 @@ static BOOLEAN bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr) } #endif ///SMP_INCLUDED == TRUE - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function bta_dm_adjust_roles @@ -4107,6 +4133,7 @@ static void bta_dm_adjust_roles(BOOLEAN delay_role_switch) } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 1d69fb2434..8ac39f6a06 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -42,11 +42,15 @@ #if BTA_DYNAMIC_MEMORY == FALSE tBTA_DM_CB bta_dm_cb; tBTA_DM_SEARCH_CB bta_dm_search_cb; +#if (CLASSIC_BT_INCLUDED == TRUE) tBTA_DM_DI_CB bta_dm_di_cb; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #else tBTA_DM_CB *bta_dm_cb_ptr; tBTA_DM_SEARCH_CB *bta_dm_search_cb_ptr; -tBTA_DM_DI_CB *bta_dm_di_cb_ptr; +#if (CLASSIC_BT_INCLUDED == TRUE) + tBTA_DM_DI_CB *bta_dm_di_cb_ptr; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) SemaphoreHandle_t deinit_semaphore; #endif @@ -572,11 +576,15 @@ void bta_dm_sm_deinit(void) { memset(&bta_dm_cb, 0, sizeof(tBTA_DM_CB)); memset(&bta_dm_search_cb, 0, sizeof(tBTA_DM_SEARCH_CB)); +#if (CLASSIC_BT_INCLUDED == TRUE) memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB)); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #if BTA_DYNAMIC_MEMORY FREE_AND_RESET(bta_dm_cb_ptr); FREE_AND_RESET(bta_dm_search_cb_ptr); +#if (CLASSIC_BT_INCLUDED == TRUE) FREE_AND_RESET(bta_dm_di_cb_ptr); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #endif /* #if BTA_DYNAMIC_MEMORY */ } diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index bc625d3df8..4646267ff7 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -2212,9 +2212,6 @@ typedef struct { UINT16 state; BOOLEAN disabling; TIMER_LIST_ENT disable_timer; - UINT32 wbt_sdp_handle; /* WIDCOMM Extensions SDP record handle */ - UINT8 wbt_scn; /* WIDCOMM Extensions SCN */ - UINT8 num_master_only; #if (BTA_DM_PM_INCLUDED == TRUE) UINT8 pm_id; tBTA_PM_TIMER pm_timer[BTA_DM_NUM_PM_TIMER]; @@ -2222,7 +2219,9 @@ typedef struct { UINT32 role_policy_mask; /* the bits set indicates the modules that wants to remove role switch from the default link policy */ UINT16 cur_policy; /* current default link policy */ UINT16 rs_event; /* the event waiting for role switch */ +#if (CLASSIC_BT_INCLUDED == TRUE) UINT8 cur_av_count; /* current AV connections */ +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) BOOLEAN disable_pair_mode; /* disable pair mode or not */ BOOLEAN conn_paired_only; /* allow connectable to paired device only or not */ tBTA_DM_API_SEARCH search_msg; @@ -2253,7 +2252,9 @@ typedef struct { tBTA_DM_ENCRYPT_CBACK *p_encrypt_cback; +#if (CLASSIC_BT_INCLUDED == TRUE) TIMER_LIST_ENT switch_delay_timer[BTA_DM_NUM_PEER_DEVICE]; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } tBTA_DM_CB; @@ -2423,8 +2424,10 @@ extern tBTA_DM_SEARCH_CB *bta_dm_search_cb_ptr; #if BTA_DYNAMIC_MEMORY == FALSE extern tBTA_DM_DI_CB bta_dm_di_cb; #else +#if (CLASSIC_BT_INCLUDED == TRUE) extern tBTA_DM_DI_CB *bta_dm_di_cb_ptr; #define bta_dm_di_cb (*bta_dm_di_cb_ptr) +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) extern SemaphoreHandle_t deinit_semaphore; #endif diff --git a/components/bt/host/bluedroid/btc/core/btc_main.c b/components/bt/host/bluedroid/btc/core/btc_main.c index 593bb99e07..e05e7db020 100644 --- a/components/bt/host/bluedroid/btc/core/btc_main.c +++ b/components/bt/host/bluedroid/btc/core/btc_main.c @@ -79,9 +79,9 @@ static void btc_deinit_bluetooth(void) #if (GATTC_INCLUDED) bta_gattc_deinit(); #endif /* #if (GATTC_INCLUDED) */ -#if (GATTS_INCLUDED) +#if (GATTS_INCLUDED == TRUE) bta_gatts_deinit(); -#endif /* #if (GATTS_INCLUDED) */ +#endif /* #if (GATTS_INCLUDED == TRUE) */ bte_main_shutdown(); #if (SMP_INCLUDED) btc_config_clean_up(); 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 9ef207ebef..7674298d4c 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -451,13 +451,13 @@ #define CONTROLLER_RPA_LIST_ENABLE FALSE #endif -#if (UC_BT_GATTS_ENABLE) +#if (UC_BT_GATTS_ENABLE == TRUE) #define GATTS_INCLUDED TRUE #else #define GATTS_INCLUDED FALSE #endif /* UC_BT_GATTS_ENABLE */ -#if (UC_BT_GATTC_ENABLE) +#if (UC_BT_GATTC_ENABLE == TRUE) #define GATTC_INCLUDED TRUE #else #define GATTC_INCLUDED FALSE diff --git a/components/bt/host/bluedroid/main/bte_init.c b/components/bt/host/bluedroid/main/bte_init.c index c60f6f7bd1..f556cd6a0c 100644 --- a/components/bt/host/bluedroid/main/bte_init.c +++ b/components/bt/host/bluedroid/main/bte_init.c @@ -268,10 +268,12 @@ void BTE_DeinitStack(void) osi_free(bta_dm_conn_srvcs_ptr); bta_dm_conn_srvcs_ptr = NULL; } +#if (CLASSIC_BT_INCLUDED == TRUE) if (bta_dm_di_cb_ptr){ osi_free(bta_dm_di_cb_ptr); bta_dm_di_cb_ptr = NULL; } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) if (bta_dm_search_cb_ptr){ osi_free(bta_dm_search_cb_ptr); bta_dm_search_cb_ptr = NULL; @@ -438,16 +440,20 @@ bt_status_t BTE_InitStack(void) if ((bta_dm_search_cb_ptr = (tBTA_DM_SEARCH_CB *)osi_malloc(sizeof(tBTA_DM_SEARCH_CB))) == NULL) { goto error_exit; } +#if (CLASSIC_BT_INCLUDED == TRUE) if ((bta_dm_di_cb_ptr = (tBTA_DM_DI_CB *)osi_malloc(sizeof(tBTA_DM_DI_CB))) == NULL) { goto error_exit; } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) if ((bta_dm_conn_srvcs_ptr = (tBTA_DM_CONNECTED_SRVCS *)osi_malloc(sizeof(tBTA_DM_CONNECTED_SRVCS))) == NULL) { goto error_exit; } memset((void *)bta_sys_cb_ptr, 0, sizeof(tBTA_SYS_CB)); memset((void *)bta_dm_cb_ptr, 0, sizeof(tBTA_DM_CB)); memset((void *)bta_dm_search_cb_ptr, 0, sizeof(tBTA_DM_SEARCH_CB)); +#if (CLASSIC_BT_INCLUDED == TRUE) memset((void *)bta_dm_di_cb_ptr, 0, sizeof(tBTA_DM_DI_CB)); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) memset((void *)bta_dm_conn_srvcs_ptr, 0, sizeof(tBTA_DM_CONNECTED_SRVCS)); //memset((void *)bta_prm_cb_ptr, 0, sizeof(tBTA_PRM_CB)); diff --git a/components/bt/host/bluedroid/stack/btm/btm_acl.c b/components/bt/host/bluedroid/stack/btm/btm_acl.c index fc4b44a277..6bd991c1f9 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_acl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_acl.c @@ -532,7 +532,9 @@ void btm_acl_device_down (void) void btm_acl_update_busy_level (tBTM_BLI_EVENT event) { UINT8 busy_level_flags = 0; +#if (CLASSIC_BT_INCLUDED == TRUE) BOOLEAN old_inquiry_state = btm_cb.is_inquiry; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) BTM_TRACE_DEBUG ("btm_acl_update_busy_level\n"); @@ -543,6 +545,7 @@ void btm_acl_update_busy_level (tBTM_BLI_EVENT event) case BTM_BLI_ACL_DOWN_EVT: BTM_TRACE_DEBUG ("BTM_BLI_ACL_DOWN_EVT\n"); break; +#if (CLASSIC_BT_INCLUDED == TRUE) case BTM_BLI_PAGE_EVT: BTM_TRACE_DEBUG ("BTM_BLI_PAGE_EVT\n"); btm_cb.is_paging = TRUE; @@ -568,16 +571,24 @@ void btm_acl_update_busy_level (tBTM_BLI_EVENT event) btm_cb.is_inquiry = FALSE; busy_level_flags = BTM_BL_INQUIRY_COMPLETE; break; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } UINT8 busy_level; +#if (CLASSIC_BT_INCLUDED == TRUE) if (btm_cb.is_paging || btm_cb.is_inquiry) { busy_level = 10; - } else { + } else +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) + { busy_level = BTM_GetNumAclLinks(); } - if ((busy_level != btm_cb.busy_level) || (old_inquiry_state != btm_cb.is_inquiry)) { + if ((busy_level != btm_cb.busy_level) +#if (CLASSIC_BT_INCLUDED == TRUE) + || (old_inquiry_state != btm_cb.is_inquiry) +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) + ) { tBTM_BL_UPDATE_DATA evt = { .event = BTM_BL_UPDATE_EVT, .busy_level = busy_level, @@ -2640,6 +2651,7 @@ void btm_cont_rswitch (tACL_CONN *p, tBTM_SEC_DEV_REC *p_dev_rec, } } +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btm_acl_resubmit_page @@ -2693,6 +2705,7 @@ void btm_acl_reset_paging (void) btm_cb.paging = FALSE; } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/btm/btm_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index 63c26e881e..bc076e8692 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -93,13 +93,14 @@ void btm_dev_init (void) btm_cb.btm_acl_pkt_types_supported = BTM_ACL_PKT_TYPES_MASK_DH1 + BTM_ACL_PKT_TYPES_MASK_DM1 + BTM_ACL_PKT_TYPES_MASK_DH3 + BTM_ACL_PKT_TYPES_MASK_DM3 + BTM_ACL_PKT_TYPES_MASK_DH5 + BTM_ACL_PKT_TYPES_MASK_DM5; - +#if (CLASSIC_BT_INCLUDED == TRUE) btm_cb.btm_sco_pkt_types_supported = BTM_SCO_PKT_TYPES_MASK_HV1 + BTM_SCO_PKT_TYPES_MASK_HV2 + BTM_SCO_PKT_TYPES_MASK_HV3 + BTM_SCO_PKT_TYPES_MASK_EV3 + BTM_SCO_PKT_TYPES_MASK_EV4 + BTM_SCO_PKT_TYPES_MASK_EV5; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } @@ -330,7 +331,7 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p BTM_TRACE_DEBUG("Local supported ACL packet types: 0x%04x", btm_cb.btm_acl_pkt_types_supported); - +#if (CLASSIC_BT_INCLUDED == TRUE) /* Create (e)SCO supported packet types mask */ btm_cb.btm_sco_pkt_types_supported = 0; #if BTM_SCO_INCLUDED == TRUE @@ -386,7 +387,7 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p BTM_TRACE_DEBUG("Local supported SCO packet types: 0x%04x", btm_cb.btm_sco_pkt_types_supported); - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /* Create Default Policy Settings */ if (HCI_SWITCH_SUPPORTED(p_features)) { btm_cb.btm_def_link_policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH; diff --git a/components/bt/host/bluedroid/stack/btm/btm_main.c b/components/bt/host/bluedroid/stack/btm/btm_main.c index b109e5395b..49447f00f6 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_main.c +++ b/components/bt/host/bluedroid/stack/btm/btm_main.c @@ -64,7 +64,9 @@ void btm_init (void) #endif /* #if BTM_DYNAMIC_MEMORY */ /* All fields are cleared; nonzero fields are reinitialized in appropriate function */ memset(&btm_cb, 0, sizeof(tBTM_CB)); +#if (CLASSIC_BT_INCLUDED == TRUE) btm_cb.page_queue = fixed_queue_new(QUEUE_SIZE_MAX); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) btm_cb.sec_pending_q = fixed_queue_new(QUEUE_SIZE_MAX); #if defined(BTM_INITIAL_TRACE_LEVEL) @@ -110,8 +112,10 @@ void btm_init (void) *******************************************************************************/ void btm_free(void) { +#if (CLASSIC_BT_INCLUDED == TRUE) fixed_queue_free(btm_cb.page_queue, osi_free_func); fixed_queue_free(btm_cb.sec_pending_q, osi_free_func); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) btm_acl_free(); btm_sec_dev_free(); #if BTM_SCO_INCLUDED == TRUE diff --git a/components/bt/host/bluedroid/stack/btm/btm_pm.c b/components/bt/host/bluedroid/stack/btm/btm_pm.c index de48a2dad6..915cd43d55 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_pm.c +++ b/components/bt/host/bluedroid/stack/btm/btm_pm.c @@ -901,7 +901,7 @@ BOOLEAN btm_pm_device_in_active_or_sniff_mode(void) return FALSE; } - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btm_pm_device_in_scan_state @@ -930,7 +930,7 @@ BOOLEAN btm_pm_device_in_scan_state(void) return FALSE; } - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function BTM_PM_ReadControllerState @@ -944,9 +944,13 @@ tBTM_CONTRL_STATE BTM_PM_ReadControllerState(void) { if (TRUE == btm_pm_device_in_active_or_sniff_mode()) { return BTM_CONTRL_ACTIVE; - } else if (TRUE == btm_pm_device_in_scan_state()) { + } +#if (CLASSIC_BT_INCLUDED == TRUE) + else if (TRUE == btm_pm_device_in_scan_state()) { return BTM_CONTRL_SCAN; - } else { + } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) + else { return BTM_CONTRL_IDLE; } } diff --git a/components/bt/host/bluedroid/stack/btm/btm_sec.c b/components/bt/host/bluedroid/stack/btm/btm_sec.c index 35337e40a3..94f05ff98f 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_sec.c +++ b/components/bt/host/bluedroid/stack/btm/btm_sec.c @@ -3007,7 +3007,9 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT BTM_TRACE_EVENT ("btm_sec_rmt_name_request_complete\n"); if (((p_bd_addr == NULL) && !BTM_ACL_IS_CONNECTED(btm_cb.connecting_bda)) || ((p_bd_addr != NULL) && !BTM_ACL_IS_CONNECTED(p_bd_addr))) { +#if (CLASSIC_BT_INCLUDED == TRUE) btm_acl_resubmit_page(); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } /* If remote name request failed, p_bd_addr is null and we need to search */ @@ -4303,8 +4305,9 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) BOOLEAN is_pairing_device = FALSE; tACL_CONN *p_acl_cb; UINT8 bit_shift = 0; - +#if (CLASSIC_BT_INCLUDED == TRUE) btm_acl_resubmit_page(); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bda); diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index d4d96c81a9..4adea06b06 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -901,7 +901,9 @@ typedef struct { /* Packet types supported by the local device */ UINT16 btm_acl_pkt_types_supported; +#if (CLASSIC_BT_INCLUDED == TRUE) UINT16 btm_sco_pkt_types_supported; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /***************************************************** @@ -971,10 +973,12 @@ typedef struct { UINT8 acl_disc_reason; UINT8 trace_level; UINT8 busy_level; /* the current busy level */ +#if (CLASSIC_BT_INCLUDED == TRUE) BOOLEAN is_paging; /* TRUE, if paging is in progress */ BOOLEAN is_inquiry; /* TRUE, if inquiry is in progress */ fixed_queue_t *page_queue; BOOLEAN paging; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) BOOLEAN discing; fixed_queue_t *sec_pending_q; /* pending sequrity requests in tBTM_SEC_QUEUE_ENTRY format */ #if (!defined(BT_TRACE_VERBOSE) || (BT_TRACE_VERBOSE == FALSE)) diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_api.c b/components/bt/host/bluedroid/stack/gatt/gatt_api.c index db7952e95a..e48d9d2289 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_api.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_api.c @@ -1044,11 +1044,13 @@ tGATT_STATUS GATTC_Read (UINT16 conn_id, tGATT_READ_TYPE type, tGATT_READ_PARAM default: break; } +#if (SMP_INCLUDED == TRUE) /* start security check */ if (gatt_security_check_start(p_clcb) == FALSE) { status = GATT_NO_RESOURCES; gatt_clcb_dealloc(p_clcb); } +#endif // (SMP_INCLUDED == TRUE) } else { status = GATT_NO_RESOURCES; } @@ -1108,10 +1110,11 @@ tGATT_STATUS GATTC_Write (UINT16 conn_id, tGATT_WRITE_TYPE type, tGATT_VALUE *p_ p_clcb->start_offset = p_write->offset; p->offset = 0; } - +#if (SMP_INCLUDED == TRUE) if (gatt_security_check_start(p_clcb) == FALSE) { status = GATT_NO_RESOURCES; } +#endif // (SMP_INCLUDED == TRUE) } else { status = GATT_NO_RESOURCES; } @@ -1584,6 +1587,7 @@ tGATT_STATUS GATT_Disconnect (UINT16 conn_id) return ret; } +#if (GATTS_INCLUDED == TRUE) /******************************************************************************* ** ** Function GATT_SendServiceChangeIndication @@ -1630,6 +1634,7 @@ tGATT_STATUS GATT_SendServiceChangeIndication (BD_ADDR bd_addr) return status; } +#endif // (GATTS_INCLUDED == TRUE) /******************************************************************************* ** @@ -1737,6 +1742,7 @@ BOOLEAN GATT_Listen (tGATT_IF gatt_if, BOOLEAN start, BD_ADDR_PTR bd_addr) return gatt_update_listen_mode(); } +#if (GATTS_INCLUDED == TRUE) tGATT_STATUS GATTS_SetServiceChangeMode(UINT8 mode) { if (mode > GATTS_SEND_SERVICE_CHANGE_MANUAL) { @@ -1748,6 +1754,8 @@ tGATT_STATUS GATTS_SetServiceChangeMode(UINT8 mode) return GATT_SUCCESS; } +#endif // (GATTS_INCLUDED == TRUE) + tGATT_STATUS GATTS_HandleMultiValueNotification (UINT16 conn_id, tGATT_HLV *tuples, UINT16 num_tuples) { tGATT_STATUS cmd_sent = GATT_ILLEGAL_PARAMETER; diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_auth.c b/components/bt/host/bluedroid/stack/gatt/gatt_auth.c index 4db0a554d5..a5769a83d7 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_auth.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_auth.c @@ -129,6 +129,8 @@ void gatt_verify_signature(tGATT_TCB *p_tcb, BT_HDR *p_buf) } #endif ///SMP_INCLUDED == TRUE +#if (SMP_INCLUDED == TRUE) + /******************************************************************************* ** ** Function gatt_sec_check_complete @@ -155,6 +157,7 @@ void gatt_sec_check_complete(BOOLEAN sec_check_ok, tGATT_CLCB *p_clcb, UINT8 s #endif ///GATTC_INCLUDED == TRUE } } + /******************************************************************************* ** ** Function gatt_enc_cmpl_cback @@ -253,6 +256,7 @@ void gatt_notify_enc_cmpl(BD_ADDR bd_addr) } return; } + /******************************************************************************* ** ** Function gatt_set_sec_act @@ -268,6 +272,7 @@ void gatt_set_sec_act(tGATT_TCB *p_tcb, tGATT_SEC_ACTION sec_act) p_tcb->sec_act = sec_act; } } + /******************************************************************************* ** ** Function gatt_get_sec_act @@ -285,6 +290,7 @@ tGATT_SEC_ACTION gatt_get_sec_act(tGATT_TCB *p_tcb) } return sec_act; } +#endif // (SMP_INCLUDED == TRUE) /******************************************************************************* ** ** Function gatt_determine_sec_act @@ -420,7 +426,7 @@ tGATT_STATUS gatt_get_link_encrypt_status(tGATT_TCB *p_tcb) return encrypt_status ; } - +#if (SMP_INCLUDED == TRUE) /******************************************************************************* ** ** Function gatt_convert_sec_action @@ -450,6 +456,7 @@ static BOOLEAN gatt_convert_sec_action(tGATT_SEC_ACTION gatt_sec_act, tBTM_BLE_S return status; } + /******************************************************************************* ** ** Function gatt_check_enc_req @@ -517,6 +524,6 @@ BOOLEAN gatt_security_check_start(tGATT_CLCB *p_clcb) return status; } - +#endif // (SMP_INCLUDED == TRUE) #endif /* BLE_INCLUDED */ diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_main.c b/components/bt/host/bluedroid/stack/gatt/gatt_main.c index f92a2c392b..f2db5255a8 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_main.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_main.c @@ -102,8 +102,9 @@ void gatt_init (void) #endif /* #if GATT_DYNAMIC_MEMORY */ memset (&gatt_cb, 0, sizeof(tGATT_CB)); memset (&fixed_reg, 0, sizeof(tL2CAP_FIXED_CHNL_REG)); - +#if (GATTC_INCLUDED == TRUE) gatt_cb.auto_disc = TRUE; +#endif // (GATTC_INCLUDED == TRUE) gatt_cb.p_clcb_list = list_new(osi_free_func); gatt_cb.p_tcb_list = list_new(osi_free_func); #if defined(GATT_INITIAL_TRACE_LEVEL) @@ -111,11 +112,11 @@ void gatt_init (void) #else gatt_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */ #endif - gatt_cb.def_mtu_size = GATT_DEF_BLE_MTU_SIZE; - gatt_cb.sign_op_queue = fixed_queue_new(QUEUE_SIZE_MAX); +#if (GATTS_INCLUDED == TRUE) gatt_cb.srv_chg_clt_q = fixed_queue_new(QUEUE_SIZE_MAX); gatt_cb.pending_new_srv_start_q = fixed_queue_new(QUEUE_SIZE_MAX); gatt_cb.srv_chg_mode = GATTS_SEND_SERVICE_CHANGE_MODE; +#endif // (GATTS_INCLUDED == TRUE) /* First, register fixed L2CAP channel for ATT over BLE */ fixed_reg.fixed_chnl_opts.mode = L2CAP_FCR_BASIC_MODE; @@ -140,11 +141,10 @@ void gatt_init (void) #endif ///CLASSIC_BT_GATT_INCLUDED == TRUE BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_ATT, BTM_SEC_NONE, BT_PSM_ATT, 0, 0); BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_ATT, BTM_SEC_NONE, BT_PSM_ATT, 0, 0); - +#if (GATTS_INCLUDED == TRUE) gatt_cb.hdl_cfg.gatt_start_hdl = GATT_GATT_START_HANDLE; gatt_cb.hdl_cfg.gap_start_hdl = GATT_GAP_START_HANDLE; gatt_cb.hdl_cfg.app_start_hdl = GATT_APP_START_HANDLE; -#if (GATTS_INCLUDED == TRUE) gatt_profile_db_init(); #endif ///GATTS_INCLUDED == TRUE //init local MTU size @@ -165,19 +165,21 @@ void gatt_init (void) void gatt_free(void) { GATT_TRACE_DEBUG("gatt_free()"); - fixed_queue_free(gatt_cb.sign_op_queue, NULL); - gatt_cb.sign_op_queue = NULL; +#if (GATTS_INCLUDED == TRUE) fixed_queue_free(gatt_cb.srv_chg_clt_q, NULL); gatt_cb.srv_chg_clt_q = NULL; fixed_queue_free(gatt_cb.pending_new_srv_start_q, osi_free_func); gatt_cb.pending_new_srv_start_q = NULL; +#endif // (GATTS_INCLUDED == TRUE) list_node_t *p_node = NULL; tGATT_TCB *p_tcb = NULL; for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) { p_tcb = list_node(p_node); +#if (SMP_INCLUDED == TRUE) fixed_queue_free(p_tcb->pending_enc_clcb, NULL); p_tcb->pending_enc_clcb = NULL; +#endif // (SMP_INCLUDED == TRUE) fixed_queue_free(p_tcb->pending_ind_q, NULL); p_tcb->pending_ind_q = NULL; @@ -411,9 +413,11 @@ BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, // but here p_tcb is get from gatt_allocate_tcb_by_bdaddr(), is too old, so we get p_tcb again p_tcb = gatt_find_tcb_by_addr(bd_addr, transport); if(p_tcb != NULL) { +#if (SMP_INCLUDED == TRUE) if(p_tcb->pending_enc_clcb != NULL) { fixed_queue_free(p_tcb->pending_enc_clcb, NULL); } +#endif // (SMP_INCLUDED == TRUE) if(p_tcb->pending_ind_q != NULL) { fixed_queue_free(p_tcb->pending_ind_q, NULL); } @@ -450,8 +454,10 @@ static void gatt_le_connect_cback (UINT16 chan, BD_ADDR bd_addr, BOOLEAN connect { tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, transport); +#if (GATTS_INCLUDED == TRUE) BOOLEAN check_srv_chg = FALSE; tGATTS_SRV_CHG *p_srv_chg_clt = NULL; +#endif // (GATTS_INCLUDED == TRUE) /* ignore all fixed channel connect/disconnect on BR/EDR link for GATT */ if (transport == BT_TRANSPORT_BR_EDR) { @@ -461,7 +467,7 @@ static void gatt_le_connect_cback (UINT16 chan, BD_ADDR bd_addr, BOOLEAN connect GATT_TRACE_DEBUG ("GATT ATT protocol channel with BDA: %08x%04x is %s", (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3], (bd_addr[4] << 8) + bd_addr[5], (connected) ? "connected" : "disconnected"); - +#if (GATTS_INCLUDED == TRUE) if ((p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr)) != NULL) { check_srv_chg = TRUE; } else { @@ -469,6 +475,7 @@ static void gatt_le_connect_cback (UINT16 chan, BD_ADDR bd_addr, BOOLEAN connect gatt_add_a_bonded_dev_for_srv_chg(bd_addr); } } +#endif // #if (GATTS_INCLUDED == TRUE) if (connected) { /* do we have a channel initiating a connection? */ @@ -481,11 +488,11 @@ static void gatt_le_connect_cback (UINT16 chan, BD_ADDR bd_addr, BOOLEAN connect gatt_send_conn_cback(p_tcb); } - if (check_srv_chg) { #if (GATTS_INCLUDED == TRUE) + if (check_srv_chg) { gatt_chk_srv_chg (p_srv_chg_clt); -#endif ///GATTS_INCLUDED == TRUE } +#endif ///GATTS_INCLUDED == TRUE } /* this is incoming connection or background connection callback */ @@ -498,11 +505,11 @@ static void gatt_le_connect_cback (UINT16 chan, BD_ADDR bd_addr, BOOLEAN connect p_tcb->payload_size = GATT_DEF_BLE_MTU_SIZE; gatt_send_conn_cback (p_tcb); - if (check_srv_chg) { #if (GATTS_INCLUDED == TRUE) + if (check_srv_chg) { gatt_chk_srv_chg (p_srv_chg_clt); -#endif ///GATTS_INCLUDED == TRUE } +#endif ///GATTS_INCLUDED == TRUE } else { GATT_TRACE_ERROR("CCB max out, no resources"); } diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c index ae99c39a9f..02236abe90 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c @@ -104,6 +104,7 @@ void gatt_free_pending_ind(tGATT_TCB *p_tcb) p_tcb->pending_ind_q = NULL; } +#if (SMP_INCLUDED == TRUE) /******************************************************************************* ** ** Function gatt_free_pending_enc_queue @@ -127,6 +128,7 @@ void gatt_free_pending_enc_queue(tGATT_TCB *p_tcb) fixed_queue_free(p_tcb->pending_enc_clcb, NULL); p_tcb->pending_enc_clcb = NULL; } +#endif // (SMP_INCLUDED == TRUE) /******************************************************************************* ** @@ -154,6 +156,7 @@ void gatt_free_pending_prepare_write_queue(tGATT_TCB *p_tcb) p_tcb->prepare_write_record.error_code_app = GATT_SUCCESS; } +#if (GATTS_INCLUDED == TRUE) /******************************************************************************* ** ** Function gatt_delete_dev_from_srv_chg_clt_list @@ -248,7 +251,7 @@ tGATTS_PENDING_NEW_SRV_START *gatt_sr_is_new_srv_chg(tBT_UUID *p_app_uuid128, tB return p_buf; } - +#endif // (GATTS_INCLUDED == TRUE) /******************************************************************************* ** @@ -271,7 +274,7 @@ tGATT_VALUE *gatt_add_pending_ind(tGATT_TCB *p_tcb, tGATT_VALUE *p_ind) return p_buf; } - +#if (GATTS_INCLUDED == TRUE) /******************************************************************************* ** ** Function gatt_add_pending_new_srv_start @@ -327,7 +330,7 @@ tGATTS_SRV_CHG *gatt_add_srv_chg_clt(tGATTS_SRV_CHG *p_srv_chg) ** Returns Pointer to the allocated buffer, NULL no buffer available ** *******************************************************************************/ -#if (GATTS_INCLUDED == TRUE) + tGATT_HDL_LIST_ELEM *gatt_alloc_hdl_buffer(void) { UINT8 i; @@ -803,7 +806,7 @@ BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found return found; } - +#if (GATTS_INCLUDED == TRUE) /******************************************************************************* ** ** Function gatt_is_srv_chg_ind_pending @@ -874,7 +877,7 @@ tGATTS_SRV_CHG *gatt_is_bda_in_the_srv_chg_clt_list (BD_ADDR bda) return p_buf; } - +#endif // (GATTS_INCLUDED == TRUE) /******************************************************************************* ** @@ -1083,7 +1086,9 @@ tGATT_TCB *gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport) } if (allocated) { memset(p_tcb, 0, sizeof(tGATT_TCB)); +#if (SMP_INCLUDED == TRUE) p_tcb->pending_enc_clcb = fixed_queue_new(QUEUE_SIZE_MAX); +#endif // (SMP_INCLUDED == TRUE) p_tcb->pending_ind_q = fixed_queue_new(QUEUE_SIZE_MAX); p_tcb->in_use = TRUE; p_tcb->tcb_idx = i; @@ -1390,6 +1395,8 @@ void gatt_ind_ack_timeout(TIMER_LIST_ENT *p_tle) attp_send_cl_msg(((tGATT_TCB *)p_tle->param), 0, GATT_HANDLE_VALUE_CONF, NULL); } + +#if (GATTS_INCLUDED == TRUE) /******************************************************************************* ** ** Function gatt_sr_find_i_rcb_by_handle @@ -1422,7 +1429,7 @@ UINT8 gatt_sr_find_i_rcb_by_handle(UINT16 handle) ** Returns GATT_MAX_SR_PROFILES if not found. Otherwise index of th eservice. ** *******************************************************************************/ -#if (GATTS_INCLUDED == TRUE) + UINT8 gatt_sr_find_i_rcb_by_app_id(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst) { UINT8 i_rcb = 0; @@ -1446,7 +1453,7 @@ UINT8 gatt_sr_find_i_rcb_by_app_id(tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid } return i_rcb; } -#endif ///GATTS_INCLUDED == TRUE + /******************************************************************************* ** ** Function gatt_sr_find_i_rcb_by_handle @@ -1482,6 +1489,7 @@ UINT8 gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM *p_list ) return ii; } +#endif ///GATTS_INCLUDED == TRUE /******************************************************************************* ** ** Function gatt_sr_get_sec_info @@ -2370,12 +2378,14 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport) btu_free_timer (&p_tcb->ind_ack_timer_ent); btu_free_timer (&p_tcb->conf_timer_ent); gatt_free_pending_ind(p_tcb); +#if (SMP_INCLUDED == TRUE) gatt_free_pending_enc_queue(p_tcb); +#endif // (SMP_INCLUDED == TRUE) gatt_free_pending_prepare_write_queue(p_tcb); -#if (GATTS_INCLUDED) +#if (GATTS_INCLUDED == TRUE) fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, osi_free_func); p_tcb->sr_cmd.multi_rsp_q = NULL; -#endif /* #if (GATTS_INCLUDED) */ +#endif /* #if (GATTS_INCLUDED == TRUE) */ for (i = 0; i < GATT_MAX_APPS; i ++) { p_reg = &gatt_cb.cl_rcb[i]; if (p_reg->in_use && p_reg->app_cb.p_conn_cb) { @@ -2389,7 +2399,9 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport) GATT_TRACE_DEBUG ("exit gatt_cleanup_upon_disc "); BTM_Recovery_Pre_State(); } +#if (GATTS_INCLUDED == TRUE) gatt_delete_dev_from_srv_chg_clt_list(bda); +#endif // (GATTS_INCLUDED == TRUE) } /******************************************************************************* ** @@ -2840,7 +2852,7 @@ BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_ } #endif // #if (tGATT_BG_CONN_DEV == TRUE) - +#if (SMP_INCLUDED == TRUE) /******************************************************************************* ** ** Function gatt_add_pending_new_srv_start @@ -2858,10 +2870,11 @@ tGATT_PENDING_ENC_CLCB *gatt_add_pending_enc_channel_clcb(tGATT_TCB *p_tcb, tGAT if ((p_buf = (tGATT_PENDING_ENC_CLCB *)osi_malloc((UINT16)sizeof(tGATT_PENDING_ENC_CLCB))) != NULL) { GATT_TRACE_DEBUG ("enqueue a new pending encryption channel clcb"); p_buf->p_clcb = p_clcb; - fixed_queue_enqueue(p_tcb->pending_enc_clcb, p_buf, FIXED_QUEUE_MAX_TIMEOUT); + fixed_queue_enqueue(p_tcb->pending_enc_clcb, p_buf, FIXED_QUEUE_MAX_TIMEOUT); } return p_buf; } +#endif // (SMP_INCLUDED == TRUE) /******************************************************************************* ** ** Function gatt_update_listen_mode diff --git a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h index 8701c746d1..07a0ad5930 100644 --- a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -376,8 +376,11 @@ typedef struct{ }tGATT_PREPARE_WRITE_RECORD; typedef struct { +#if (SMP_INCLUDED == TRUE) fixed_queue_t *pending_enc_clcb; /* pending encryption channel q */ tGATT_SEC_ACTION sec_act; +#endif // (SMP_INCLUDED == TRUE) + BD_ADDR peer_bda; tBT_TRANSPORT transport; UINT32 trans_id; @@ -514,11 +517,11 @@ typedef struct { typedef struct { list_t *p_tcb_list; - fixed_queue_t *sign_op_queue; - +#if (GATTS_INCLUDED == TRUE) tGATT_SR_REG sr_reg[GATT_MAX_SR_PROFILES]; UINT16 next_handle; /* next available handle */ tGATT_SVC_CHG gattp_attr; /* GATT profile attribute service change */ +#endif // (GATTS_INCLUDED == TRUE) tGATT_IF gatt_if; #if (GATTS_INCLUDED == TRUE) tGATT_HDL_LIST_INFO hdl_list_info; @@ -526,13 +529,13 @@ typedef struct { tGATT_SRV_LIST_INFO srv_list_info; tGATT_SRV_LIST_ELEM srv_list[GATT_MAX_SR_PROFILES]; #endif ///GATTS_INCLUDED == TRUE +#if (GATTS_INCLUDED == TRUE) fixed_queue_t *srv_chg_clt_q; /* service change clients queue */ fixed_queue_t *pending_new_srv_start_q; /* pending new service start queue */ +#endif // (GATTS_INCLUDED == TRUE) tGATT_REG cl_rcb[GATT_MAX_APPS]; list_t *p_clcb_list; /* connection link control block*/ - tGATT_SCCB sccb[GATT_MAX_SCCB]; /* sign complete callback function GATT_MAX_SCCB <= GATT_CL_MAX_LCB */ UINT8 trace_level; - UINT16 def_mtu_size; #if GATT_CONFORMANCE_TESTING == TRUE BOOLEAN enable_err_rsp; @@ -556,13 +559,18 @@ typedef struct { tGATT_APPL_INFO cb_info; - +#if (GATTS_INCLUDED == TRUE) tGATT_HDL_CFG hdl_cfg; +#endif // (GATTS_INCLUDED == TRUE) #if (tGATT_BG_CONN_DEV == TRUE) tGATT_BG_CONN_DEV bgconn_dev[GATT_MAX_BG_CONN_DEV]; #endif // #if (tGATT_BG_CONN_DEV == TRUE) +#if (GATTC_INCLUDED == TRUE) BOOLEAN auto_disc; /* internal use: true for auto discovering after connected */ +#endif // (GATTC_INCLUDED == TRUE) +#if (GATTS_INCLUDED == TRUE) UINT8 srv_chg_mode; /* internal use: service change mode */ +#endif // (GATTS_INCLUDED == TRUE) tGATTS_RSP rsp; /* use to read internal service attribute */ } tGATT_CB; From c5c00198a43a9126ba80f261395cc222ba0c362a Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:17 +0800 Subject: [PATCH 107/226] fix(ble/bluedroid): delete unused pending_queue (cherry picked from commit d9a88c741413ea7f0fbb496278feb3b3f9ecca9e) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/stack/gatt/gatt_main.c | 6 -- .../bt/host/bluedroid/stack/gatt/gatt_sr.c | 28 -------- .../bt/host/bluedroid/stack/gatt/gatt_utils.c | 67 ++----------------- .../bluedroid/stack/gatt/include/gatt_int.h | 8 +-- 4 files changed, 9 insertions(+), 100 deletions(-) diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_main.c b/components/bt/host/bluedroid/stack/gatt/gatt_main.c index f2db5255a8..2e29ea52e3 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_main.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_main.c @@ -181,9 +181,6 @@ void gatt_free(void) p_tcb->pending_enc_clcb = NULL; #endif // (SMP_INCLUDED == TRUE) - fixed_queue_free(p_tcb->pending_ind_q, NULL); - p_tcb->pending_ind_q = NULL; - btu_free_timer(&p_tcb->conf_timer_ent); memset(&p_tcb->conf_timer_ent, 0, sizeof(TIMER_LIST_ENT)); @@ -418,9 +415,6 @@ BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, fixed_queue_free(p_tcb->pending_enc_clcb, NULL); } #endif // (SMP_INCLUDED == TRUE) - if(p_tcb->pending_ind_q != NULL) { - fixed_queue_free(p_tcb->pending_ind_q, NULL); - } gatt_tcb_free(p_tcb); } diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c index 585a4c921a..faa85bc9d1 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c @@ -1633,33 +1633,6 @@ static void gatts_proc_srv_chg_ind_ack(tGATT_TCB *p_tcb ) } } -/******************************************************************************* -** -** Function gatts_chk_pending_ind -** -** Description This function check any pending indication needs to be sent if -** there is a pending indication then sent the indication -** -** Returns void -** -*******************************************************************************/ -static void gatts_chk_pending_ind(tGATT_TCB *p_tcb ) -{ -#if (GATTS_INCLUDED == TRUE) - tGATT_VALUE *p_buf = (tGATT_VALUE *)fixed_queue_try_peek_first(p_tcb->pending_ind_q); - GATT_TRACE_DEBUG("gatts_chk_pending_ind"); - - if (p_buf ) { - GATTS_HandleValueIndication (p_buf->conn_id, - p_buf->handle, - p_buf->len, - p_buf->value); - osi_free(fixed_queue_try_remove_from_queue(p_tcb->pending_ind_q, - p_buf)); - } -#endif ///GATTS_INCLUDED == TRUE -} - /******************************************************************************* ** ** Function gatts_proc_ind_ack @@ -1686,7 +1659,6 @@ static BOOLEAN gatts_proc_ind_ack(tGATT_TCB *p_tcb, UINT16 ack_handle) #endif /* GATTS_ROBUST_CACHING_ENABLED */ } - gatts_chk_pending_ind(p_tcb); return continue_processing; } diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c index 02236abe90..cf2b1b0123 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c @@ -80,30 +80,6 @@ static const UINT8 base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x0 static UINT8 gatt_tcb_id[GATT_MAX_PHY_CHANNEL / 8 + 1]; -/******************************************************************************* -** -** Function gatt_free_pending_ind -** -** Description Free all pending indications -** -** Returns None -** -*******************************************************************************/ -void gatt_free_pending_ind(tGATT_TCB *p_tcb) -{ - GATT_TRACE_DEBUG("gatt_free_pending_ind"); - if (p_tcb->pending_ind_q == NULL) { - return; - } - - /* release all queued indications */ - while (!fixed_queue_is_empty(p_tcb->pending_ind_q)) { - osi_free(fixed_queue_dequeue(p_tcb->pending_ind_q, 0)); - } - fixed_queue_free(p_tcb->pending_ind_q, NULL); - p_tcb->pending_ind_q = NULL; -} - #if (SMP_INCLUDED == TRUE) /******************************************************************************* ** @@ -129,7 +105,7 @@ void gatt_free_pending_enc_queue(tGATT_TCB *p_tcb) p_tcb->pending_enc_clcb = NULL; } #endif // (SMP_INCLUDED == TRUE) - +#if (GATTS_INCLUDED == TRUE) /******************************************************************************* ** ** Function gatt_free_pending_prepare_write_queue @@ -155,6 +131,7 @@ void gatt_free_pending_prepare_write_queue(tGATT_TCB *p_tcb) p_tcb->prepare_write_record.total_num = 0; p_tcb->prepare_write_record.error_code_app = GATT_SUCCESS; } +#endif // (GATTS_INCLUDED == TRUE) #if (GATTS_INCLUDED == TRUE) /******************************************************************************* @@ -253,27 +230,6 @@ tGATTS_PENDING_NEW_SRV_START *gatt_sr_is_new_srv_chg(tBT_UUID *p_app_uuid128, tB } #endif // (GATTS_INCLUDED == TRUE) -/******************************************************************************* -** -** Function gatt_add_pending_ind -** -** Description Add a pending indication -** -** Returns Pointer to the current pending indication buffer, NULL no buffer available -** -*******************************************************************************/ -tGATT_VALUE *gatt_add_pending_ind(tGATT_TCB *p_tcb, tGATT_VALUE *p_ind) -{ - tGATT_VALUE *p_buf; - GATT_TRACE_DEBUG ("gatt_add_pending_ind"); - if ((p_buf = (tGATT_VALUE *)osi_malloc((UINT16)sizeof(tGATT_VALUE))) != NULL) { - GATT_TRACE_DEBUG ("enqueue a pending indication"); - memcpy(p_buf, p_ind, sizeof(tGATT_VALUE)); - fixed_queue_enqueue(p_tcb->pending_ind_q, p_buf, FIXED_QUEUE_MAX_TIMEOUT); - } - return p_buf; -} - #if (GATTS_INCLUDED == TRUE) /******************************************************************************* ** @@ -821,23 +777,10 @@ BOOLEAN gatt_is_srv_chg_ind_pending (tGATT_TCB *p_tcb) { BOOLEAN srv_chg_ind_pending = FALSE; - GATT_TRACE_DEBUG("gatt_is_srv_chg_ind_pending is_queue_empty=%d", - fixed_queue_is_empty(p_tcb->pending_ind_q)); + GATT_TRACE_DEBUG("gatt_is_srv_chg_ind_pending is_queue_empty=%d_%d", p_tcb->indicate_handle, gatt_cb.handle_of_h_r); if (p_tcb->indicate_handle == gatt_cb.handle_of_h_r) { srv_chg_ind_pending = TRUE; - } else if (! fixed_queue_is_empty(p_tcb->pending_ind_q)) { - list_t *list = fixed_queue_get_list(p_tcb->pending_ind_q); - for (const list_node_t *node = list_begin(list); - node != list_end(list); - node = list_next(node)) { - tGATT_VALUE *p_buf = (tGATT_VALUE *)list_node(node); - if (p_buf->handle == gatt_cb.handle_of_h_r) - { - srv_chg_ind_pending = TRUE; - break; - } - } } GATT_TRACE_DEBUG("srv_chg_ind_pending = %d", srv_chg_ind_pending); @@ -1089,7 +1032,6 @@ tGATT_TCB *gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport) #if (SMP_INCLUDED == TRUE) p_tcb->pending_enc_clcb = fixed_queue_new(QUEUE_SIZE_MAX); #endif // (SMP_INCLUDED == TRUE) - p_tcb->pending_ind_q = fixed_queue_new(QUEUE_SIZE_MAX); p_tcb->in_use = TRUE; p_tcb->tcb_idx = i; p_tcb->transport = transport; @@ -2377,11 +2319,12 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport) btu_free_timer (&p_tcb->ind_ack_timer_ent); btu_free_timer (&p_tcb->conf_timer_ent); - gatt_free_pending_ind(p_tcb); #if (SMP_INCLUDED == TRUE) gatt_free_pending_enc_queue(p_tcb); #endif // (SMP_INCLUDED == TRUE) +#if (GATTS_INCLUDED == TRUE) gatt_free_pending_prepare_write_queue(p_tcb); +#endif // (GATTS_INCLUDED == TRUE) #if (GATTS_INCLUDED == TRUE) fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, osi_free_func); p_tcb->sr_cmd.multi_rsp_q = NULL; diff --git a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h index 07a0ad5930..b0984f479c 100644 --- a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -399,7 +399,6 @@ typedef struct { tGATT_SR_CMD sr_cmd; #endif ///GATTS_INCLUDED == TRUE UINT16 indicate_handle; - fixed_queue_t *pending_ind_q; TIMER_LIST_ENT conf_timer_ent; /* peer confirm to indication timer */ @@ -410,17 +409,19 @@ typedef struct { TIMER_LIST_ENT ind_ack_timer_ent; /* local app confirm to indication timer */ UINT8 pending_cl_req; UINT8 next_slot_inq; /* index of next available slot in queue */ - +#if (GATTS_ROBUST_CACHING_ENABLED == TRUE) /* client supported feature */ UINT8 cl_supp_feat; /* server supported feature */ UINT8 sr_supp_feat; /* if false, should handle database out of sync */ BOOLEAN is_robust_cache_change_aware; - +#endif // (GATTS_ROBUST_CACHING_ENABLED == TRUE) BOOLEAN in_use; UINT8 tcb_idx; +#if (GATTS_INCLUDED == TRUE) tGATT_PREPARE_WRITE_RECORD prepare_write_record; /* prepare write packets record */ +#endif // (GATTS_INCLUDED == TRUE) } tGATT_TCB; @@ -660,7 +661,6 @@ extern tGATTS_SRV_CHG *gatt_is_bda_in_the_srv_chg_clt_list (BD_ADDR bda); extern BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx, tBT_TRANSPORT *p_transport); extern void gatt_set_srv_chg(void); extern void gatt_delete_dev_from_srv_chg_clt_list(BD_ADDR bd_addr); -extern tGATT_VALUE *gatt_add_pending_ind(tGATT_TCB *p_tcb, tGATT_VALUE *p_ind); extern tGATTS_PENDING_NEW_SRV_START *gatt_add_pending_new_srv_start( tGATTS_HNDL_RANGE *p_new_srv_start); extern void gatt_free_srvc_db_buffer_app_id(tBT_UUID *p_app_id); extern BOOLEAN gatt_update_listen_mode(void); From 8ab92698f14387924857d6bac491275fed1edbc6 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:17 +0800 Subject: [PATCH 108/226] fix(ble/bluedroid): Disable bluedroid host Qos (cherry picked from commit 47f13aa75b88234e9d742671c189d2bc0746ceb5) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/stack/btm/btm_acl.c | 5 ++++- components/bt/host/bluedroid/stack/btm/include/btm_int.h | 3 ++- components/bt/host/bluedroid/stack/btu/btu_hcif.c | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/components/bt/host/bluedroid/stack/btm/btm_acl.c b/components/bt/host/bluedroid/stack/btm/btm_acl.c index 6bd991c1f9..192b62408b 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_acl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_acl.c @@ -1891,6 +1891,7 @@ tBTM_STATUS BTM_RegAclLinkStatNotif(tBTM_ACL_LINK_STAT_CB *p_cb) return BTM_SUCCESS; } +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function BTM_SetQoS @@ -1972,7 +1973,7 @@ void btm_qos_setup_complete (UINT8 status, UINT16 handle, FLOW_SPEC *p_flow) (*p_cb)(&qossu); } } - +#endif // (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btm_qos_setup_timeout @@ -1987,7 +1988,9 @@ void btm_qos_setup_timeout (void *p_tle) { BTM_TRACE_DEBUG ("%s\n", __func__); +#if (CLASSIC_BT_INCLUDED == TRUE) btm_qos_setup_complete (HCI_ERR_HOST_TIMEOUT, 0, NULL); +#endif // (CLASSIC_BT_INCLUDED == TRUE) } /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index 4adea06b06..d4699329ad 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -201,10 +201,11 @@ tBTM_CMPL_CB *p_lnk_qual_cmpl_cb;/* Callback function to be called when TIMER_LIST_ENT txpwer_timer; tBTM_CMPL_CB *p_txpwer_cmpl_cb; /* Callback function to be called when */ /* read inq tx power function completes */ - +#if (CLASSIC_BT_INCLUDED == TRUE) TIMER_LIST_ENT qossu_timer; tBTM_CMPL_CB *p_qossu_cmpl_cb; /* Callback function to be called when */ /* qos setup function completes */ +#endif // (CLASSIC_BT_INCLUDED == TRUE) tBTM_ROLE_SWITCH_CMPL switch_role_ref_data; tBTM_CMPL_CB *p_switch_role_cb; /* Callback function to be called when */ diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 52365cf62c..728d2b178f 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -1702,8 +1702,10 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c break; case HCI_QOS_SETUP_COMP_EVT: + #if (CLASSIC_BT_INCLUDED == TRUE) /* Tell qos setup that we are done */ btm_qos_setup_complete(status, 0, NULL); + #endif // (CLASSIC_BT_INCLUDED == TRUE) break; case HCI_SWITCH_ROLE: From ed58eaeb20cc4b3d30207d32e444beb600e0069e Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:17 +0800 Subject: [PATCH 109/226] fix(ble/bluedroid): disable bluedroid role_change (cherry picked from commit 250553c50d333600a948a8dca8ad05d773b3fc22) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/stack/btm/btm_acl.c | 14 ++++++++++++-- components/bt/host/bluedroid/stack/btm/btm_pm.c | 3 ++- .../bt/host/bluedroid/stack/btm/include/btm_int.h | 5 +++++ components/bt/host/bluedroid/stack/btu/btu_hcif.c | 5 ++++- .../bt/host/bluedroid/stack/l2cap/l2c_utils.c | 6 ++++++ 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/components/bt/host/bluedroid/stack/btm/btm_acl.c b/components/bt/host/bluedroid/stack/btm/btm_acl.c index 192b62408b..24ffea9fa9 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_acl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_acl.c @@ -292,7 +292,9 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, UINT8 bdn[BTM_MAX_REM_BD_NAME_L p->conn_addr[0], p->conn_addr[1], p->conn_addr[2], p->conn_addr[3], p->conn_addr[4], p->conn_addr[5]); #endif #endif +#if (CLASSIC_BT_INCLUDED == TRUE) p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE; +#endif // (CLASSIC_BT_INCLUDED == TRUE) p->p_pm_mode_db = btm_pm_sm_alloc(); #if BTM_PM_DEBUG == TRUE @@ -384,7 +386,7 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, UINT8 bdn[BTM_MAX_REM_BD_NAME_L } } - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btm_acl_report_role_change @@ -408,6 +410,7 @@ void btm_acl_report_role_change (UINT8 hci_status, BD_ADDR bda) btm_cb.devcb.p_switch_role_cb = NULL; } } +#endif // (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** @@ -432,8 +435,10 @@ void btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport) if (p != (tACL_CONN *)NULL) { p->in_use = FALSE; +#if (CLASSIC_BT_INCLUDED == TRUE) /* if the disconnected channel has a pending role switch, clear it now */ btm_acl_report_role_change(HCI_ERR_NO_CONNECTION, bda); +#endif // (CLASSIC_BT_INCLUDED == TRUE) /* Only notify if link up has had a chance to be issued */ if (p->link_up_issued) { @@ -646,7 +651,7 @@ tBTM_STATUS BTM_GetRole (BD_ADDR remote_bd_addr, UINT8 *p_role) return (BTM_SUCCESS); } - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function BTM_SwitchRole @@ -865,6 +870,7 @@ void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable) #endif } } +#endif // (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function BTM_SetLinkPolicy @@ -1472,6 +1478,7 @@ void btm_process_clk_off_comp_evt (UINT16 hci_handle, UINT16 clock_offset) } +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btm_acl_role_changed @@ -1571,6 +1578,7 @@ void btm_acl_role_changed (UINT8 hci_status, BD_ADDR bd_addr, UINT8 new_role) #endif } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** @@ -2599,6 +2607,7 @@ UINT8 BTM_SetTraceLevel (UINT8 new_level) return (btm_cb.trace_level); } +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btm_cont_rswitch @@ -2653,6 +2662,7 @@ void btm_cont_rswitch (tACL_CONN *p, tBTM_SEC_DEV_REC *p_dev_rec, } } } +#endif // (CLASSIC_BT_INCLUDED == TRUE) #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/btm/btm_pm.c b/components/bt/host/bluedroid/stack/btm/btm_pm.c index 915cd43d55..aa94c88c90 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_pm.c +++ b/components/bt/host/bluedroid/stack/btm/btm_pm.c @@ -820,9 +820,10 @@ void btm_pm_proc_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode, U (*btm_cb.pm_reg_db[yy].cback)( p->remote_addr, mode, interval, hci_status); } } - +#if (CLASSIC_BT_INCLUDED == TRUE) /* If mode change was because of an active role switch or change link key */ btm_cont_rswitch(p, btm_find_dev(p->remote_addr), hci_status); +#endif // (CLASSIC_BT_INCLUDED == TRUE) } /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index d4699329ad..9a00c55afd 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -140,7 +140,10 @@ UINT8 legacy_auth_state; #define BTM_ACL_SWKEY_STATE_SWITCHING 3 #define BTM_ACL_SWKEY_STATE_ENCRYPTION_ON 4 #define BTM_ACL_SWKEY_STATE_IN_PROGRESS 5 + +#if (CLASSIC_BT_INCLUDED == TRUE) UINT8 switch_role_state; +#endif // (CLASSIC_BT_INCLUDED == TRUE) #define BTM_ACL_ENCRYPT_STATE_IDLE 0 #define BTM_ACL_ENCRYPT_STATE_ENCRYPT_OFF 1 /* encryption turning off */ @@ -207,9 +210,11 @@ tBTM_CMPL_CB *p_qossu_cmpl_cb; /* Callback function to be called when /* qos setup function completes */ #endif // (CLASSIC_BT_INCLUDED == TRUE) +#if (CLASSIC_BT_INCLUDED == TRUE) tBTM_ROLE_SWITCH_CMPL switch_role_ref_data; tBTM_CMPL_CB *p_switch_role_cb; /* Callback function to be called when */ /* requested switch role is completed */ +#endif // (CLASSIC_BT_INCLUDED == TRUE) #if (BLE_HOST_READ_TX_POWER_EN == TRUE) TIMER_LIST_ENT tx_power_timer; diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 728d2b178f..1cc4dc23d7 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -1025,8 +1025,9 @@ static void btu_hcif_encryption_change_evt (UINT8 *p) STREAM_TO_UINT8 (status, p); STREAM_TO_UINT16 (handle, p); STREAM_TO_UINT8 (encr_enable, p); - +#if (CLASSIC_BT_INCLUDED == TRUE) btm_acl_encrypt_change (handle, status, encr_enable); +#endif // (CLASSIC_BT_INCLUDED == TRUE) btm_sec_encrypt_change (handle, status, encr_enable); } #endif ///SMP_INCLUDED == TRUE @@ -1711,6 +1712,7 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c case HCI_SWITCH_ROLE: /* Tell BTM that the command failed */ /* read bd addr out of stored command */ + #if (CLASSIC_BT_INCLUDED == TRUE) if (p_cmd != NULL) { p_cmd++; STREAM_TO_BDADDR (bd_addr, p_cmd); @@ -1719,6 +1721,7 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c btm_acl_role_changed(status, NULL, BTM_ROLE_UNDEFINED); } l2c_link_role_changed (NULL, BTM_ROLE_UNDEFINED, HCI_ERR_COMMAND_DISALLOWED); + #endif // (CLASSIC_BT_INCLUDED == TRUE) break; case HCI_CREATE_CONNECTION: diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c index 0d3fed93d1..cd44976756 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c @@ -2274,8 +2274,11 @@ BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport) #if BTM_SCO_INCLUDED == TRUE BOOLEAN is_sco_active; #endif + +#if (CLASSIC_BT_INCLUDED == TRUE) list_node_t *p_node = NULL; tL2C_LCB *p_lcb_cur = NULL; +#endif // (CLASSIC_BT_INCLUDED == TRUE) #if (BLE_INCLUDED == TRUE) tBT_DEVICE_TYPE dev_type; @@ -2298,6 +2301,7 @@ BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport) } #endif +#if (CLASSIC_BT_INCLUDED == TRUE) /* If there is a connection where we perform as a slave, try to switch roles for this connection */ for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { @@ -2341,6 +2345,8 @@ BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport) p_lcb->link_state = LST_CONNECTING; return (l2cu_create_conn_after_switch (p_lcb)); +#endif // (CLASSIC_BT_INCLUDED == TRUE) + return false; } /******************************************************************************* From a8d0be7f2aeddb863b15068fd93871f1eb790468 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:19 +0800 Subject: [PATCH 110/226] fix(ble/bluedroid): disable read_local_name (cherry picked from commit 5f9680e3a016b65698eebf5a23e91ee55a036386) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/bta/dm/bta_dm_act.c | 8 ++++++++ components/bt/host/bluedroid/stack/btm/btm_devctl.c | 10 ++++++++-- .../bt/host/bluedroid/stack/btm/include/btm_int.h | 5 +++++ components/bt/host/bluedroid/stack/btu/btu_hcif.c | 2 ++ components/bt/host/bluedroid/stack/btu/btu_task.c | 2 ++ 5 files changed, 25 insertions(+), 2 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 77cbd7af18..044fe7de5e 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -536,7 +536,9 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status ) But then we have a few HCI commands being invoked above which were still in progress when the ENABLE_EVT was sent. So modified this to fetch the local name which forces the DM_ENABLE_EVT to be sent only after all the init steps are complete */ +#if (CLASSIC_BT_INCLUDED == TRUE) BTM_ReadLocalDeviceNameFromController((tBTM_CMPL_CB *)bta_dm_local_name_cback); +#endif // (CLASSIC_BT_INCLUDED == TRUE) bta_sys_rm_register((tBTA_SYS_CONN_CBACK *)bta_dm_rm_cback); @@ -551,6 +553,12 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status ) bta_dm_gattc_register(); #endif +#if (CLASSIC_BT_INCLUDED == TRUE) + // do nothing +#else + bta_dm_local_name_cback(NULL); +#endif + } else { APPL_TRACE_DEBUG(" --- ignored event"); } diff --git a/components/bt/host/bluedroid/stack/btm/btm_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index bc076e8692..db363f7ad5 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -88,7 +88,9 @@ void btm_dev_init (void) #endif btm_cb.devcb.reset_timer.param = (TIMER_PARAM_TYPE)TT_DEV_RESET; +#if (CLASSIC_BT_INCLUDED == TRUE) btm_cb.devcb.rln_timer.param = (TIMER_PARAM_TYPE)TT_DEV_RLN; +#endif // (CLASSIC_BT_INCLUDED == TRUE) btm_cb.btm_acl_pkt_types_supported = BTM_ACL_PKT_TYPES_MASK_DH1 + BTM_ACL_PKT_TYPES_MASK_DM1 + BTM_ACL_PKT_TYPES_MASK_DH3 + BTM_ACL_PKT_TYPES_MASK_DM3 + @@ -122,6 +124,7 @@ static void btm_db_reset (void) btm_inq_db_reset(); +#if (CLASSIC_BT_INCLUDED == TRUE) if (btm_cb.devcb.p_rln_cmpl_cb) { p_cb = btm_cb.devcb.p_rln_cmpl_cb; btm_cb.devcb.p_rln_cmpl_cb = NULL; @@ -130,6 +133,7 @@ static void btm_db_reset (void) (*p_cb)((void *) NULL); } } +#endif // (CLASSIC_BT_INCLUDED == TRUE) if (btm_cb.devcb.p_rssi_cmpl_cb) { p_cb = btm_cb.devcb.p_rssi_cmpl_cb; @@ -248,6 +252,7 @@ BOOLEAN BTM_IsDeviceUp (void) return controller_get_interface()->get_is_ready(); } +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btm_dev_timeout @@ -271,6 +276,7 @@ void btm_dev_timeout (TIMER_LIST_ENT *p_tle) } } } +#endif // (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** @@ -553,7 +559,7 @@ tBTM_STATUS BTM_ReadLocalDeviceName (char **p_name, tBT_DEVICE_TYPE name_type) #endif } - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function BTM_ReadLocalDeviceNameFromController @@ -611,7 +617,7 @@ void btm_read_local_name_complete (UINT8 *p, UINT16 evt_len) } } } - +#endif // (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function BTM_SetDeviceClass diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index 9a00c55afd..429a11437e 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -183,13 +183,18 @@ typedef struct { tBTM_DEV_STATUS_CB *p_dev_status_cb; /* Device status change callback */ tBTM_VS_EVT_CB *p_vend_spec_cb[BTM_MAX_VSE_CALLBACKS]; /* Register for vendor specific events */ +#if (CLASSIC_BT_INCLUDED == TRUE) tBTM_CMPL_CB *p_stored_link_key_cmpl_cb; /* Read/Write/Delete stored link key */ +#endif // (CLASSIC_BT_INCLUDED == TRUE) TIMER_LIST_ENT reset_timer; tBTM_CMPL_CB *p_reset_cmpl_cb; +#if (CLASSIC_BT_INCLUDED == TRUE) TIMER_LIST_ENT rln_timer; tBTM_CMPL_CB *p_rln_cmpl_cb; /* Callback function to be called when */ +#endif // (CLASSIC_BT_INCLUDED == TRUE) + /* read local name function complete */ TIMER_LIST_ENT rssi_timer; tBTM_CMPL_CB *p_rssi_cmpl_cb; /* Callback function to be called when */ diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 1cc4dc23d7..d018f6a83e 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -1216,7 +1216,9 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l break; #endif // #if (CLASSIC_BT_INCLUDED == TRUE) case HCI_READ_LOCAL_NAME: +#if (CLASSIC_BT_INCLUDED == TRUE) btm_read_local_name_complete (p, evt_len); +#endif // (CLASSIC_BT_INCLUDED == TRUE) break; case HCI_READ_RSSI: btm_read_rssi_complete (p, evt_len); diff --git a/components/bt/host/bluedroid/stack/btu/btu_task.c b/components/bt/host/bluedroid/stack/btu/btu_task.c index bffa6837b0..91c1f43fb7 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_task.c +++ b/components/bt/host/bluedroid/stack/btu/btu_task.c @@ -315,7 +315,9 @@ static void btu_general_alarm_process(void *param) switch (p_tle->event) { case BTU_TTYPE_BTM_DEV_CTL: +#if (CLASSIC_BT_INCLUDED == TRUE) btm_dev_timeout(p_tle); +#endif // (CLASSIC_BT_INCLUDED == TRUE) break; case BTU_TTYPE_L2CAP_LINK: From 2348342ff4bb0fa69510cd862dd7f1300c26c906 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:19 +0800 Subject: [PATCH 111/226] fix(ble/bluedroid): Disable bluedroid desire_role (cherry picked from commit 9ae4d9a14a20d152042d626f56daaf568ee21c89) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/stack/gap/include/gap_int.h | 1 - components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h | 3 ++- components/bt/host/bluedroid/stack/l2cap/l2c_api.c | 3 ++- components/bt/host/bluedroid/stack/l2cap/l2c_link.c | 2 ++ components/bt/host/bluedroid/stack/l2cap/l2c_main.c | 4 ++-- components/bt/host/bluedroid/stack/l2cap/l2c_utils.c | 6 ++++-- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/components/bt/host/bluedroid/stack/gap/include/gap_int.h b/components/bt/host/bluedroid/stack/gap/include/gap_int.h index 8f5472589c..25c48c69c8 100644 --- a/components/bt/host/bluedroid/stack/gap/include/gap_int.h +++ b/components/bt/host/bluedroid/stack/gap/include/gap_int.h @@ -129,7 +129,6 @@ typedef struct { typedef struct { tGAP_INFO blk[GAP_MAX_BLOCKS]; - tBTM_CMPL_CB *btm_cback[GAP_MAX_BLOCKS]; UINT8 trace_level; //tGAP_FINDADDR_CB findaddr_cb; /* Contains the control block for finding a device addr */ //tBTM_INQ_INFO *cur_inqptr; diff --git a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h index d17f82f4cc..abe75c18f4 100644 --- a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h +++ b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h @@ -490,9 +490,10 @@ typedef struct { list_t *p_ccb_pool; /* Channel Control Block pool */ tL2C_RCB rcb_pool[MAX_L2CAP_CLIENTS]; /* Registration info pool */ - +#if (CLASSIC_BT_INCLUDED == TRUE) UINT8 desire_role; /* desire to be master/slave when accepting a connection */ BOOLEAN disallow_switch; /* FALSE, to allow switch at create conn */ +#endif // (CLASSIC_BT_INCLUDED == TRUE) UINT16 num_lm_acl_bufs; /* # of ACL buffers on controller */ UINT16 idle_timeout; /* Idle timeout */ diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c index b7fbbbdcfc..07377901a7 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c @@ -863,7 +863,7 @@ UINT8 L2CA_SetTraceLevel (UINT8 new_level) return (l2cb.l2cap_trace_level); } - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function L2CA_SetDesireRole @@ -901,6 +901,7 @@ UINT8 L2CA_SetDesireRole (UINT8 new_role) return (l2cb.desire_role); } +#endif // (CLASSIC_BT_INCLUDED == TRUE) #if (CLASSIC_BT_INCLUDED == TRUE) diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c index 9cb412e748..c151231bd9 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c @@ -936,6 +936,7 @@ UINT8 l2c_link_pkts_rcvd (UINT16 *num_pkts, UINT16 *handles) return (num_found); } +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function l2c_link_role_changed @@ -973,6 +974,7 @@ void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status) } } } +#endif // (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c index dfdef99bef..3e911bdec7 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c @@ -877,13 +877,13 @@ void l2c_init (void) #endif - +#if (CLASSIC_BT_INCLUDED == TRUE) #ifdef L2CAP_DESIRED_LINK_ROLE l2cb.desire_role = L2CAP_DESIRED_LINK_ROLE; #else l2cb.desire_role = HCI_ROLE_SLAVE; #endif - +#endif // (CLASSIC_BT_INCLUDED == TRUE) /* Set the default idle timeout */ l2cb.idle_timeout = L2CAP_LINK_INACTIVITY_TOUT; diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c index cd44976756..52c1713cfc 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c @@ -369,6 +369,7 @@ uint8_t l2cu_ble_plcb_active_count(void) } +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function l2cu_get_conn_role @@ -385,6 +386,7 @@ UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb) { return l2cb.desire_role; } +#endif // (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** @@ -2373,7 +2375,7 @@ UINT8 l2cu_get_num_hi_priority (void) return no_hi; } - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function l2cu_create_conn_after_switch @@ -2448,7 +2450,7 @@ BOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb) return (TRUE); } - +#endif // (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** From 321704aff304f72945020862487b4d94e4b97c99 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:20 +0800 Subject: [PATCH 112/226] fix(ble/bluedroid): disable rsp timer and ind_ack timer (cherry picked from commit 7ff9484c468f0177d488cc4d663dda492197609c) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/stack/btm/btm_sec.c | 3 ++- components/bt/host/bluedroid/stack/btu/btu_task.c | 4 ++++ .../bt/host/bluedroid/stack/gap/include/gap_int.h | 2 ++ .../bt/host/bluedroid/stack/gatt/gatt_main.c | 5 ++++- .../bt/host/bluedroid/stack/gatt/gatt_utils.c | 14 +++++++++++++- .../host/bluedroid/stack/gatt/include/gatt_int.h | 4 +++- 6 files changed, 28 insertions(+), 4 deletions(-) diff --git a/components/bt/host/bluedroid/stack/btm/btm_sec.c b/components/bt/host/bluedroid/stack/btm/btm_sec.c index 94f05ff98f..2a04bb38ee 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_sec.c +++ b/components/bt/host/bluedroid/stack/btm/btm_sec.c @@ -2641,6 +2641,7 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_o ** Returns void ** *******************************************************************************/ +#if (CLASSIC_BT_INCLUDED == TRUE) #if (SMP_INCLUDED == TRUE) void btm_sec_conn_req (UINT8 *bda, UINT8 *dc) { @@ -2701,7 +2702,7 @@ void btm_sec_conn_req (UINT8 *bda, UINT8 *dc) } } #endif ///SMP_INCLUDED == TRUE - +#endif // (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btm_sec_bond_cancel_complete diff --git a/components/bt/host/bluedroid/stack/btu/btu_task.c b/components/bt/host/bluedroid/stack/btu/btu_task.c index 91c1f43fb7..f6ce7e4426 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_task.c +++ b/components/bt/host/bluedroid/stack/btu/btu_task.c @@ -376,11 +376,15 @@ static void btu_general_alarm_process(void *param) break; case BTU_TTYPE_ATT_WAIT_FOR_RSP: +#if (GATTC_INCLUDED == TRUE) gatt_rsp_timeout(p_tle); +#endif // (GATTC_INCLUDED == TRUE) break; case BTU_TTYPE_ATT_WAIT_FOR_IND_ACK: +#if (GATTC_INCLUDED == TRUE) gatt_ind_ack_timeout(p_tle); +#endif // (GATTC_INCLUDED == TRUE) break; #if (defined(SMP_INCLUDED) && SMP_INCLUDED == TRUE) diff --git a/components/bt/host/bluedroid/stack/gap/include/gap_int.h b/components/bt/host/bluedroid/stack/gap/include/gap_int.h index 25c48c69c8..dc6353c325 100644 --- a/components/bt/host/bluedroid/stack/gap/include/gap_int.h +++ b/components/bt/host/bluedroid/stack/gap/include/gap_int.h @@ -128,7 +128,9 @@ typedef struct { } tGAP_CLCB; typedef struct { +#if (CLASSIC_BT_INCLUDED == TRUE) tGAP_INFO blk[GAP_MAX_BLOCKS]; +#endif // (CLASSIC_BT_INCLUDED == TRUE) UINT8 trace_level; //tGAP_FINDADDR_CB findaddr_cb; /* Contains the control block for finding a device addr */ //tBTM_INQ_INFO *cur_inqptr; diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_main.c b/components/bt/host/bluedroid/stack/gatt/gatt_main.c index 2e29ea52e3..15ea739ee6 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_main.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_main.c @@ -180,12 +180,15 @@ void gatt_free(void) fixed_queue_free(p_tcb->pending_enc_clcb, NULL); p_tcb->pending_enc_clcb = NULL; #endif // (SMP_INCLUDED == TRUE) - +#if (GATTS_INCLUDED == TRUE) btu_free_timer(&p_tcb->conf_timer_ent); memset(&p_tcb->conf_timer_ent, 0, sizeof(TIMER_LIST_ENT)); +#endif // (GATTS_INCLUDED == TRUE) +#if (GATTC_INCLUDED == TRUE) btu_free_timer(&p_tcb->ind_ack_timer_ent); memset(&p_tcb->ind_ack_timer_ent, 0, sizeof(TIMER_LIST_ENT)); +#endif // #if (GATTC_INCLUDED == TRUE) #if (GATTS_INCLUDED == TRUE) fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, NULL); diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c index cf2b1b0123..113f43952f 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c @@ -1247,6 +1247,8 @@ void gatt_start_rsp_timer(UINT16 clcb_idx) btu_start_timer (&p_clcb->rsp_timer_ent, BTU_TTYPE_ATT_WAIT_FOR_RSP, GATT_WAIT_FOR_RSP_TOUT); } + +#if (GATTS_INCLUDED == TRUE) /******************************************************************************* ** ** Function gatt_start_conf_timer @@ -1262,6 +1264,9 @@ void gatt_start_conf_timer(tGATT_TCB *p_tcb) btu_start_timer (&p_tcb->conf_timer_ent, BTU_TTYPE_ATT_WAIT_FOR_RSP, GATT_WAIT_FOR_RSP_TOUT); } +#endif // (GATTS_INCLUDED == TRUE) + +#if (GATTC_INCLUDED == TRUE) /******************************************************************************* ** ** Function gatt_start_ind_ack_timer @@ -1279,6 +1284,7 @@ void gatt_start_ind_ack_timer(tGATT_TCB *p_tcb) GATT_WAIT_FOR_IND_ACK_TOUT); } + /******************************************************************************* ** ** Function gatt_rsp_timeout @@ -1337,6 +1343,7 @@ void gatt_ind_ack_timeout(TIMER_LIST_ENT *p_tle) attp_send_cl_msg(((tGATT_TCB *)p_tle->param), 0, GATT_HANDLE_VALUE_CONF, NULL); } +#endif // (GATTC_INCLUDED == TRUE) #if (GATTS_INCLUDED == TRUE) /******************************************************************************* @@ -2095,6 +2102,7 @@ BOOLEAN gatt_find_specific_app_in_hold_link(tGATT_TCB *p_tcb, tGATT_IF p_gatt_if return found; } +#if (GATTC_INCLUDED == TRUE) /******************************************************************************* ** ** Function gatt_cmd_enq @@ -2148,6 +2156,7 @@ tGATT_CLCB *gatt_cmd_dequeue(tGATT_TCB *p_tcb, UINT8 *p_op_code) return p_clcb; } +#endif // (GATTC_INCLUDED == TRUE) /******************************************************************************* ** @@ -2316,9 +2325,12 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport) gatt_clcb_dealloc(p_clcb); } } - +#if (GATTC_INCLUDED == TRUE) btu_free_timer (&p_tcb->ind_ack_timer_ent); +#endif // #if (GATTC_INCLUDED == TRUE) +#if (GATTS_INCLUDED == TRUE) btu_free_timer (&p_tcb->conf_timer_ent); +#endif // (GATTS_INCLUDED == TRUE) #if (SMP_INCLUDED == TRUE) gatt_free_pending_enc_queue(p_tcb); #endif // (SMP_INCLUDED == TRUE) diff --git a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h index b0984f479c..dbb4582742 100644 --- a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -397,16 +397,18 @@ typedef struct { /* server response data */ #if (GATTS_INCLUDED == TRUE) tGATT_SR_CMD sr_cmd; -#endif ///GATTS_INCLUDED == TRUE UINT16 indicate_handle; TIMER_LIST_ENT conf_timer_ent; /* peer confirm to indication timer */ +#endif ///GATTS_INCLUDED == TRUE UINT8 prep_cnt[GATT_MAX_APPS]; +#if (GATTC_INCLUDED == TRUE) UINT8 ind_count; tGATT_CMD_Q cl_cmd_q[GATT_CL_MAX_LCB]; TIMER_LIST_ENT ind_ack_timer_ent; /* local app confirm to indication timer */ +#endif // (GATTC_INCLUDED == TRUE) UINT8 pending_cl_req; UINT8 next_slot_inq; /* index of next available slot in queue */ #if (GATTS_ROBUST_CACHING_ENABLED == TRUE) From 7431008e7911840141792452d17cf52c690e4428 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:20 +0800 Subject: [PATCH 113/226] fix(ble/bluedroid): delete BTA_HOST_INTERLEAVE_SEARCH (cherry picked from commit 609b649ef961a26ee9b87ffbb000aa6c620f4eb1) Co-authored-by: zhiweijian --- .../host/bluedroid/bta/include/bta/bta_api.h | 3 - .../bt/host/bluedroid/stack/btm/btm_inq.c | 109 ------------------ .../bluedroid/stack/btm/include/btm_int.h | 3 - .../bluedroid/stack/include/stack/btm_api.h | 16 --- 4 files changed, 131 deletions(-) diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index a75e48943b..09e41fed28 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -293,9 +293,6 @@ typedef struct { BOOLEAN report_dup; /* report duplicated inquiry response with higher RSSI value */ tBTA_DM_INQ_FILT filter_type; /* Filter condition type. */ tBTA_DM_INQ_COND filter_cond; /* Filter condition data. */ -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - UINT8 intl_duration[4];/*duration array storing the interleave scan's time portions*/ -#endif } tBTA_DM_INQ; /* Config EIR callback */ diff --git a/components/bt/host/bluedroid/stack/btm/btm_inq.c b/components/bt/host/bluedroid/stack/btm/btm_inq.c index c74f2b4396..b6b7c47205 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_inq.c +++ b/components/bt/host/bluedroid/stack/btm/btm_inq.c @@ -718,9 +718,6 @@ tBTM_STATUS BTM_CancelInquiry(void) { tBTM_STATUS status = BTM_SUCCESS; tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - UINT8 active_mode = p_inq->inq_active; -#endif BTM_TRACE_API ("BTM_CancelInquiry called\n"); /*** Make sure the device is ready ***/ @@ -745,9 +742,6 @@ tBTM_STATUS BTM_CancelInquiry(void) /* Initiate the cancel inquiry */ else { if (((p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK) != 0) -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - && (active_mode & BTM_BR_INQUIRY_MASK) -#endif ) { if (!btsnd_hcic_inq_cancel()) { status = BTM_NO_RESOURCES; @@ -755,9 +749,6 @@ tBTM_STATUS BTM_CancelInquiry(void) } #if BLE_INCLUDED == TRUE if (((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0) -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - && (active_mode & BTM_BLE_INQ_ACTIVE_MASK) -#endif ) { btm_ble_stop_inquiry(); } @@ -852,13 +843,6 @@ tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p return (BTM_ILLEGAL_VALUE); } -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - if (p_inq->next_state == BTM_FINISH) { - return BTM_ILLEGAL_VALUE; - } -#endif - - /* Save the inquiry parameters to be used upon the completion of setting/clearing the inquiry filter */ p_inq->inqparms = *p_inqparms; @@ -870,38 +854,12 @@ tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p p_inq->inq_active = p_inqparms->mode; BTM_TRACE_DEBUG("BTM_StartInquiry: p_inq->inq_active = 0x%02x\n", p_inq->inq_active); - - /* interleave scan minimal conditions */ -#if (BLE_INCLUDED==TRUE && (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)) - - /* check if both modes are present */ - if ((p_inqparms->mode & BTM_BLE_INQUIRY_MASK) && (p_inqparms->mode & BTM_BR_INQUIRY_MASK)) { - BTM_TRACE_API("BTM:Interleave Inquiry Mode Set\n"); - p_inqparms->duration = p_inqparms->intl_duration[p_inq->next_state]; - p_inq->inqparms.duration = p_inqparms->duration; - } else { - BTM_TRACE_API("BTM:Single Mode: No interleaving, Mode:0x%02x\n", p_inqparms->mode); - p_inq->next_state = BTM_NO_INTERLEAVING; - } -#endif - - - /* start LE inquiry here if requested */ #if BLE_INCLUDED == TRUE if ((p_inqparms->mode & BTM_BLE_INQUIRY_MASK) -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - && (p_inq->next_state == BTM_BLE_ONE || p_inq->next_state == BTM_BLE_TWO || - p_inq->next_state == BTM_NO_INTERLEAVING) -#endif ) { -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - p_inq->inq_active = (p_inqparms->mode & BTM_BLE_INQUIRY_MASK); - BTM_TRACE_API("BTM:Starting LE Scan with duration %d and activeMode:0x%02x\n", - p_inqparms->duration, (p_inqparms->mode & BTM_BLE_INQUIRY_MASK)); -#endif if (!controller_get_interface()->supports_ble()) { p_inq->inqparms.mode &= ~ BTM_BLE_INQUIRY_MASK; status = BTM_ILLEGAL_VALUE; @@ -912,27 +870,7 @@ tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p BTM_TRACE_ERROR("Err Starting LE Inquiry.\n"); p_inq->inqparms.mode &= ~ BTM_BLE_INQUIRY_MASK; } -#if (!defined(BTA_HOST_INTERLEAVE_SEARCH) || BTA_HOST_INTERLEAVE_SEARCH == FALSE) p_inqparms->mode &= ~BTM_BLE_INQUIRY_MASK; -#endif - -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - if (p_inq->next_state == BTM_NO_INTERLEAVING) { - p_inq->next_state = BTM_FINISH; - } else { - BTM_TRACE_API("BTM:Interleaving: started LE scan, Advancing to next state: %d\n", - p_inq->next_state + 1); - p_inq->next_state += 1; - } - /* reset next_state if status <> BTM_Started */ - if (status != BTM_CMD_STARTED) { - p_inq->next_state = BTM_BR_ONE; - } - - /* if interleave scan..return here */ - return status; -#endif - BTM_TRACE_DEBUG("BTM_StartInquiry: mode = %02x\n", p_inqparms->mode); } @@ -944,11 +882,6 @@ tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p } /* BR/EDR inquiry portion */ -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - if ((p_inq->next_state == BTM_BR_ONE || p_inq->next_state == BTM_BR_TWO || - p_inq->next_state == BTM_NO_INTERLEAVING )) { - p_inq->inq_active = (p_inqparms->mode & BTM_BR_INQUIRY_MASK); -#endif /* If a filter is specified, then save it for later and clear the current filter. The setting of the filter is done upon completion of clearing of the previous filter. @@ -977,25 +910,6 @@ tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p p_inq->state = BTM_INQ_INACTIVE_STATE; } -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - if (p_inq->next_state == BTM_NO_INTERLEAVING) { - p_inq->next_state = BTM_FINISH; - } else { - BTM_TRACE_API("BTM:Interleaving: Started BTM inq, Advancing to next state: %d\n", - p_inq->next_state + 1); - p_inq->next_state += 1; - } - } - if (status != BTM_CMD_STARTED) { - /* Some error beginning the scan process. - Reset the next_state parameter.. Do we need to reset the inq_active also? - */ - BTM_TRACE_API("BTM:Interleaving: Error in Starting inquiry, status: 0x%02x\n", status); - p_inq->next_state = BTM_BR_ONE; - } -#endif - - return (status); } @@ -2053,22 +1967,7 @@ void btm_process_inq_complete (UINT8 status, UINT8 mode) tBTM_CMPL_CB *p_inq_cb = btm_cb.btm_inq_vars.p_inq_cmpl_cb; tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - /* inquiry inactive case happens when inquiry is cancelled. - Make mode 0 for no further inquiries from the current inquiry process - */ - if (status != HCI_SUCCESS || p_inq->next_state == BTM_FINISH || !p_inq->inq_active) { - /* re-initialize for next inquiry request */ - p_inq->next_state = BTM_BR_ONE; - /* make the mode 0 here */ - p_inq->inqparms.mode &= ~(p_inq->inqparms.mode); - - } -#endif - -#if (!defined(BTA_HOST_INTERLEAVE_SEARCH) || BTA_HOST_INTERLEAVE_SEARCH == FALSE) p_inq->inqparms.mode &= ~(mode); -#endif if (p_inq->scan_type == INQ_LE_OBSERVE && !p_inq->inq_active) { /*end of LE observe*/ @@ -2117,14 +2016,6 @@ void btm_process_inq_complete (UINT8 status, UINT8 mode) (p_inq_cb)((tBTM_INQUIRY_CMPL *) &p_inq->inq_cmpl_info); } } -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - if (p_inq->inqparms.mode != 0 && !(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE)) { - /* make inquiry inactive for next iteration */ - p_inq->inq_active = BTM_INQUIRY_INACTIVE; - /* call the inquiry again */ - BTM_StartInquiry(&p_inq->inqparms, p_inq->p_inq_results_cb, p_inq->p_inq_cmpl_cb); - } -#endif } if (p_inq->inqparms.mode == 0 && p_inq->scan_type == INQ_GENERAL) { //this inquiry is complete p_inq->scan_type = INQ_NONE; diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index 429a11437e..57fa5f002d 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -389,9 +389,6 @@ typedef struct { UINT8 state; /* Current state that the inquiry process is in */ UINT8 inq_active; /* Bit Mask indicating type of inquiry is active */ BOOLEAN no_inc_ssp; /* TRUE, to stop inquiry on incoming SSP */ -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - btm_inq_state next_state; /*interleaving state to determine next mode to be inquired*/ -#endif } tBTM_INQUIRY_VAR_ST; /* The MSB of the clock offset field indicates that the offset is valid if TRUE */ diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_api.h index 3415df5de3..74af148f03 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_api.h @@ -80,19 +80,6 @@ enum { typedef uint8_t tBTM_STATUS; -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) -typedef enum { - BTM_BR_ONE, /*0 First state or BR/EDR scan 1*/ - BTM_BLE_ONE, /*1BLE scan 1*/ - BTM_BR_TWO, /*2 BR/EDR scan 2*/ - BTM_BLE_TWO, /*3 BLE scan 2*/ - BTM_FINISH, /*4 End of Interleave Scan, or normal scan*/ - BTM_NO_INTERLEAVING /*5 No Interleaving*/ -} btm_inq_state; -#endif - - - /************************* ** Device Control Types **************************/ @@ -647,9 +634,6 @@ typedef struct { /* contains the parameters passed to the inquiry fun BOOLEAN report_dup; /* report duplicated inquiry response with higher RSSI value */ UINT8 filter_cond_type; /* new devices, BD ADDR, COD, or No filtering */ tBTM_INQ_FILT_COND filter_cond; /* filter value based on filter cond type */ -#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE) - UINT8 intl_duration[4]; /*duration array storing the interleave scan's time portions*/ -#endif } tBTM_INQ_PARMS; #define BTM_INQ_RESULT_BR 0x01 From f1e1ae5730860ee2d743d6ecec93f23f75704983 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:20 +0800 Subject: [PATCH 114/226] fix(ble/bluedroid): delete BLE_HOST_BLE_MULTI_ADV_EN (cherry picked from commit b8f23218796f2c23a0e64014bcee34bdf3fbeafe) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 117 --- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 136 --- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 6 - .../bluedroid/bta/dm/include/bta_dm_int.h | 45 - .../host/bluedroid/bta/include/bta/bta_api.h | 77 -- .../common/include/common/bt_target.h | 9 - .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 34 - .../bluedroid/stack/btm/btm_ble_multi_adv.c | 843 ------------------ .../bt/host/bluedroid/stack/btm/btm_devctl.c | 4 +- .../bluedroid/stack/btm/include/btm_ble_int.h | 8 - .../stack/include/stack/btm_ble_api.h | 125 --- 11 files changed, 1 insertion(+), 1403 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 044fe7de5e..b85dcfaea3 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -633,13 +633,6 @@ void bta_dm_disable (tBTA_DM_MSG *p_data) btm_ble_resolving_list_cleanup (); //by TH, because cmn_ble_vsc_cb.max_filter has something mistake as btm_ble_adv_filter_cleanup #endif -#if BLE_INCLUDED == TRUE -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - // btm_ble_multi_adv_init is called when the host is enabled, so btm_ble_multi_adv_cleanup is called when the host is disabled. - btm_ble_multi_adv_cleanup(); -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) -#endif - } /******************************************************************************* @@ -5776,116 +5769,6 @@ void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data) } #endif // #if (BLE_42_ADV_EN == TRUE) -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) -/******************************************************************************* -** -** Function bta_dm_ble_multi_adv_enb -** -** Description This function enables a single advertising instance -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data) -{ - tBTM_STATUS btm_status = 0; - - bta_dm_cb.p_multi_adv_cback = p_data->ble_multi_adv_enb.p_cback; - if (BTM_BleMaxMultiAdvInstanceCount() > 0 && NULL != p_data->ble_multi_adv_enb.p_ref) { - btm_status = BTM_BleEnableAdvInstance((tBTM_BLE_ADV_PARAMS *) - p_data->ble_multi_adv_enb.p_params, - p_data->ble_multi_adv_enb.p_cback, - p_data->ble_multi_adv_enb.p_ref); - } - - if (BTM_CMD_STARTED != btm_status) { - bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_ENB_EVT, 0xFF, - p_data->ble_multi_adv_enb.p_ref, BTA_FAILURE); - } -} -/******************************************************************************* -** -** Function bta_dm_ble_multi_adv_param_upd -** -** Description This function updates multiple advertising instance parameters -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data) -{ - tBTM_STATUS btm_status = 0; - void *p_ref = NULL; - - if (BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_param.inst_id > 0 - && p_data->ble_multi_adv_param.inst_id < BTM_BleMaxMultiAdvInstanceCount()) { - btm_status = BTM_BleUpdateAdvInstParam(p_data->ble_multi_adv_param.inst_id, - (tBTM_BLE_ADV_PARAMS *)p_data->ble_multi_adv_param.p_params); - } - - if (BTM_CMD_STARTED != btm_status) { - p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_param.inst_id); - bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_PARAM_EVT, - p_data->ble_multi_adv_param.inst_id, p_ref, BTA_FAILURE); - } -} -/******************************************************************************* -** -** Function bta_dm_ble_multi_adv_data -** -** Description This function write multiple advertising instance adv data -** or scan response data -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data) -{ - tBTM_STATUS btm_status = 0; - void *p_ref = NULL; - - if (BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_data.inst_id > 0 - && p_data->ble_multi_adv_data.inst_id < BTM_BleMaxMultiAdvInstanceCount()) { - btm_status = BTM_BleCfgAdvInstData(p_data->ble_multi_adv_data.inst_id, - p_data->ble_multi_adv_data.is_scan_rsp, - p_data->ble_multi_adv_data.data_mask, - (tBTM_BLE_ADV_DATA *)p_data->ble_multi_adv_data.p_data); - } - - if (BTM_CMD_STARTED != btm_status) { - p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_data.inst_id); - bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DATA_EVT, - p_data->ble_multi_adv_data.inst_id, p_ref, BTA_FAILURE); - } - -} -/******************************************************************************* -** -** Function btm_dm_ble_multi_adv_disable -** -** Description This function disable a single adv instance -** -** Parameters: -** -*******************************************************************************/ -void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data) -{ - tBTM_STATUS btm_status = 0; - void *p_ref = NULL; - - if (BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_disable.inst_id > 0 - && p_data->ble_multi_adv_disable.inst_id < BTM_BleMaxMultiAdvInstanceCount()) { - btm_status = BTM_BleDisableAdvInstance(p_data->ble_multi_adv_disable.inst_id); - } - - if (BTM_CMD_STARTED != btm_status) { - p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_disable.inst_id); - bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DISABLE_EVT, - p_data->ble_multi_adv_disable.inst_id, p_ref, BTA_FAILURE); - } -} -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - #if (BLE_42_DTM_TEST_EN == TRUE) void bta_dm_ble_gap_dtm_tx_start(tBTA_DM_MSG *p_data) { diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 6dcce7beac..fb154ab6cf 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -2258,142 +2258,6 @@ void BTA_DmBleSetKeyMaterial(const uint8_t *session_key, const uint8_t *iv) } #endif -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) -/******************************************************************************* -** -** Function BTA_BleEnableAdvInstance -** -** Description This function enable a Multi-ADV instance with the specified -** adv parameters -** -** Parameters p_params: pointer to the adv parameter structure. -** p_cback: callback function associated to this adv instance. -** p_ref: reference data pointer to this adv instance. -** -** Returns BTA_SUCCESS if command started successfully; otherwise failure. -** -*******************************************************************************/ -void BTA_BleEnableAdvInstance (tBTA_BLE_ADV_PARAMS *p_params, - tBTA_BLE_MULTI_ADV_CBACK *p_cback, - void *p_ref) -{ - ///This function just used for vendor debug - tBTA_DM_API_BLE_MULTI_ADV_ENB *p_msg; - UINT16 len = sizeof(tBTA_BLE_ADV_PARAMS) + sizeof(tBTA_DM_API_BLE_MULTI_ADV_ENB); - - APPL_TRACE_API ("BTA_BleEnableAdvInstance"); - - if ((p_msg = (tBTA_DM_API_BLE_MULTI_ADV_ENB *) osi_malloc(len)) != NULL) { - memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_MULTI_ADV_ENB)); - - p_msg->hdr.event = BTA_DM_API_BLE_MULTI_ADV_ENB_EVT; - p_msg->p_cback = (void *)p_cback; - if (p_params != NULL) { - p_msg->p_params = (void *)(p_msg + 1); - memcpy(p_msg->p_params, p_params, sizeof(tBTA_BLE_ADV_PARAMS)); - } - p_msg->p_ref = p_ref; - - bta_sys_sendmsg(p_msg); - } -} - -/******************************************************************************* -** -** Function BTA_BleUpdateAdvInstParam -** -** Description This function update a Multi-ADV instance with the specified -** adv parameters. -** -** Parameters inst_id: Adv instance to update the parameter. -** p_params: pointer to the adv parameter structure. -** -** Returns BTA_SUCCESS if command started successfully; otherwise failure. -** -*******************************************************************************/ -void BTA_BleUpdateAdvInstParam (UINT8 inst_id, tBTA_BLE_ADV_PARAMS *p_params) -{ - ///This function just used for vendor debug - tBTA_DM_API_BLE_MULTI_ADV_PARAM *p_msg; - UINT16 len = sizeof(tBTA_BLE_ADV_PARAMS) + sizeof(tBTA_DM_API_BLE_MULTI_ADV_PARAM); - - APPL_TRACE_API ("BTA_BleUpdateAdvInstParam"); - if ((p_msg = (tBTA_DM_API_BLE_MULTI_ADV_PARAM *) osi_malloc(len)) != NULL) { - memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_MULTI_ADV_PARAM)); - p_msg->hdr.event = BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT; - p_msg->inst_id = inst_id; - p_msg->p_params = (void *)(p_msg + 1); - memcpy(p_msg->p_params, p_params, sizeof(tBTA_BLE_ADV_PARAMS)); - - bta_sys_sendmsg(p_msg); - } -} - -/******************************************************************************* -** -** Function BTA_BleCfgAdvInstData -** -** Description This function configure a Multi-ADV instance with the specified -** adv data or scan response data. -** -** Parameter inst_id: Adv instance to configure the adv data or scan response. -** is_scan_rsp: is the data scan response or adv data. -** data_mask: adv data type as bit mask. -** p_data: pointer to the ADV data structure tBTA_BLE_ADV_DATA. This -** memory space can not be freed until BTA_BLE_MULTI_ADV_DATA_EVT -** is sent to application. -** -** Returns BTA_SUCCESS if command started successfully; otherwise failure. -** -*******************************************************************************/ -void BTA_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp, - tBTA_BLE_AD_MASK data_mask, - tBTA_BLE_ADV_DATA *p_data) -{ - ///This function just used for vendor debug - tBTA_DM_API_BLE_MULTI_ADV_DATA *p_msg; - UINT16 len = sizeof(tBTA_DM_API_BLE_MULTI_ADV_DATA) ; - - APPL_TRACE_API ("BTA_BleCfgAdvInstData"); - - if ((p_msg = (tBTA_DM_API_BLE_MULTI_ADV_DATA *) osi_malloc(len)) != NULL) { - memset(p_msg, 0, len); - p_msg->hdr.event = BTA_DM_API_BLE_MULTI_ADV_DATA_EVT; - p_msg->inst_id = inst_id; - p_msg->is_scan_rsp = is_scan_rsp; - p_msg->data_mask = data_mask; - p_msg->p_data = p_data; - - bta_sys_sendmsg(p_msg); - } -} - -/******************************************************************************* -** -** Function BTA_BleDisableAdvInstance -** -** Description This function disable a Multi-ADV instance. -** -** Parameter inst_id: instance ID to disable. -** -** Returns BTA_SUCCESS if command started successfully; otherwise failure. -** -*******************************************************************************/ -void BTA_BleDisableAdvInstance (UINT8 inst_id) //this function just used for vendor debug -{ - tBTA_DM_API_BLE_MULTI_ADV_DISABLE *p_msg; - - APPL_TRACE_API ("BTA_BleDisableAdvInstance: %d", inst_id); - if ((p_msg = (tBTA_DM_API_BLE_MULTI_ADV_DISABLE *) - osi_malloc(sizeof(tBTA_DM_API_BLE_MULTI_ADV_DISABLE))) != NULL) { - memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_MULTI_ADV_DISABLE)); - p_msg->hdr.event = BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT; - p_msg->inst_id = inst_id; - bta_sys_sendmsg(p_msg); - } -} -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - /******************************************************************************* ** ** Function BTA_DmBleCfgFilterCondition diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 8ac39f6a06..6a800d8a5a 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -195,12 +195,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_scan_filter_param_setup, /* BTA_DM_API_SCAN_FILTER_SETUP_EVT */ bta_dm_enable_scan_filter, /* BTA_DM_API_SCAN_FILTER_ENABLE_EVT */ #endif -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - bta_dm_ble_multi_adv_enb, /* BTA_DM_API_BLE_MULTI_ADV_ENB_EVT */ - bta_dm_ble_multi_adv_upd_param, /* BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT */ - bta_dm_ble_multi_adv_data, /* BTA_DM_API_BLE_MULTI_ADV_DATA_EVT */ - btm_dm_ble_multi_adv_disable, /* BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT */ -#endif // BLE_HOST_BLE_MULTI_ADV_EN #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) bta_dm_ble_setup_storage, /* BTA_DM_API_BLE_SETUP_STORAGE_EVT */ #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 4646267ff7..4854ce6a4e 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -181,12 +181,6 @@ enum { BTA_DM_API_SCAN_FILTER_SETUP_EVT, BTA_DM_API_SCAN_FILTER_ENABLE_EVT, #endif -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - BTA_DM_API_BLE_MULTI_ADV_ENB_EVT, - BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT, - BTA_DM_API_BLE_MULTI_ADV_DATA_EVT, - BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT, -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) BTA_DM_API_BLE_SETUP_STORAGE_EVT, #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) @@ -971,35 +965,6 @@ typedef struct { } tBTA_DM_API_BLE_FEATURE; -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) -/* multi adv data structure */ -typedef struct { - BT_HDR hdr; - tBTA_BLE_MULTI_ADV_CBACK *p_cback; - void *p_ref; - tBTA_BLE_ADV_PARAMS *p_params; -} tBTA_DM_API_BLE_MULTI_ADV_ENB; - -typedef struct { - BT_HDR hdr; - UINT8 inst_id; - tBTA_BLE_ADV_PARAMS *p_params; -} tBTA_DM_API_BLE_MULTI_ADV_PARAM; - -typedef struct { - BT_HDR hdr; - UINT8 inst_id; - BOOLEAN is_scan_rsp; - tBTA_BLE_AD_MASK data_mask; - tBTA_BLE_ADV_DATA *p_data; -} tBTA_DM_API_BLE_MULTI_ADV_DATA; - -typedef struct { - BT_HDR hdr; - UINT8 inst_id; -} tBTA_DM_API_BLE_MULTI_ADV_DISABLE; -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - typedef struct { BT_HDR hdr; UINT32 data_mask; @@ -1928,13 +1893,6 @@ typedef union { tBTA_DM_APT_CLEAR_ADDR clear_addr; tBTA_DM_API_SET_RPA_TIMEOUT set_rpa_timeout; tBTA_DM_API_ADD_DEV_TO_RESOLVING_LIST add_dev_to_resolving_list; - -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - tBTA_DM_API_BLE_MULTI_ADV_ENB ble_multi_adv_enb; - tBTA_DM_API_BLE_MULTI_ADV_PARAM ble_multi_adv_param; - tBTA_DM_API_BLE_MULTI_ADV_DATA ble_multi_adv_data; - tBTA_DM_API_BLE_MULTI_ADV_DISABLE ble_multi_adv_disable; -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) tBTA_DM_API_SET_STORAGE_CONFIG ble_set_storage; #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) @@ -2202,9 +2160,6 @@ typedef struct { tBTA_DM_BLE_PF_CFG_CBACK *p_scan_filt_cfg_cback; tBTA_DM_BLE_PF_STATUS_CBACK *p_scan_filt_status_cback; tBTA_DM_BLE_PF_PARAM_CBACK *p_scan_filt_param_cback; -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - tBTA_BLE_MULTI_ADV_CBACK *p_multi_adv_cback; -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) #if (BLE_HOST_ENERGY_INFO_EN == TRUE) tBTA_BLE_ENERGY_INFO_CBACK *p_energy_info_cback; #endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 09e41fed28..105747a3f8 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1050,22 +1050,6 @@ typedef union { /* Security callback */ typedef void (tBTA_DM_SEC_CBACK)(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data); -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) -#define BTA_BLE_MULTI_ADV_ILLEGAL 0 - -/* multi adv callback event */ -#define BTA_BLE_MULTI_ADV_ENB_EVT 1 -#define BTA_BLE_MULTI_ADV_DISABLE_EVT 2 -#define BTA_BLE_MULTI_ADV_PARAM_EVT 3 -#define BTA_BLE_MULTI_ADV_DATA_EVT 4 - -typedef UINT8 tBTA_BLE_MULTI_ADV_EVT; - -/* multi adv callback */ -typedef void (tBTA_BLE_MULTI_ADV_CBACK)(tBTA_BLE_MULTI_ADV_EVT event, - UINT8 inst_id, void *p_ref, tBTA_STATUS status); -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - typedef UINT32 tBTA_DM_BLE_REF_VALUE; #define BTA_DM_BLE_PF_ENABLE_EVT BTM_BLE_PF_ENABLE @@ -3075,67 +3059,6 @@ extern void BTA_DmUpdateDuplicateExceptionalList(UINT8 subcode, UINT32 type, *******************************************************************************/ extern void BTA_DmBleBroadcast (BOOLEAN start, tBTA_START_STOP_ADV_CMPL_CBACK *p_start_stop_adv_cb); -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) -/******************************************************************************* -** -** Function BTA_BleEnableAdvInstance -** -** Description This function enables the Multi ADV instance feature -** -** Parameters p_params Pointer to ADV param user defined structure -** p_cback Pointer to Multi ADV callback structure -** p_ref - Reference pointer -** -** Returns None -** -*******************************************************************************/ -extern void BTA_BleEnableAdvInstance (tBTA_BLE_ADV_PARAMS *p_params, - tBTA_BLE_MULTI_ADV_CBACK *p_cback, void *p_ref); - -/******************************************************************************* -** -** Function BTA_BleUpdateAdvInstParam -** -** Description This function updates the Multi ADV instance params -** -** Parameters inst_id Instance ID -** p_params Pointer to ADV param user defined structure -** -** Returns None -** -*******************************************************************************/ -extern void BTA_BleUpdateAdvInstParam (UINT8 inst_id, - tBTA_BLE_ADV_PARAMS *p_params); - -/******************************************************************************* -** -** Function BTA_BleCfgAdvInstData -** -** Description This function is called to configure the ADV instance data -** -** Parameters inst_id - Instance ID -** is_scan_rsp - Boolean value Scan response -** Pointer to User defined ADV data structure -** Returns None -** -*******************************************************************************/ -extern void BTA_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp, - tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_data); - -/******************************************************************************* -** -** Function BTA_BleDisableAdvInstance -** -** Description This function is called to disable the ADV instance -** -** Parameters inst_id - Instance ID to be disabled -** -** Returns None -** -*******************************************************************************/ -extern void BTA_BleDisableAdvInstance(UINT8 inst_id); -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - /******************************************************************************* ** ** Function BTA_DmBleUpdateConnectionParams 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 7674298d4c..22e0e2c213 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -848,11 +848,6 @@ #define BT_CLASSIC_BQB_INCLUDED FALSE #endif -/* This feature is used to enable interleaved scan*/ -#ifndef BTA_HOST_INTERLEAVE_SEARCH -#define BTA_HOST_INTERLEAVE_SEARCH FALSE -#endif - #ifndef BT_USE_TRACES #define BT_USE_TRACES FALSE #endif @@ -1621,10 +1616,6 @@ #define BLE_ANDROID_CONTROLLER_SCAN_FILTER FALSE #endif -#ifndef BLE_HOST_BLE_MULTI_ADV_EN -#define BLE_HOST_BLE_MULTI_ADV_EN FALSE -#endif - #ifndef BLE_HOST_TRACK_ADVERTISER_EN #define BLE_HOST_TRACK_ADVERTISER_EN FALSE #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index ad382d49b4..e49cccaa77 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -767,11 +767,6 @@ static void btm_ble_vendor_capability_vsc_cmpl_cback (tBTM_VSC_CMPL *p_vcs_cplt_ __func__, status, btm_cb.cmn_ble_vsc_cb.max_irk_list_sz, btm_cb.cmn_ble_vsc_cb.adv_inst_max, btm_cb.cmn_ble_vsc_cb.rpa_offloading, btm_cb.cmn_ble_vsc_cb.energy_support, btm_cb.cmn_ble_vsc_cb.extended_scan_support); -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - if (BTM_BleMaxMultiAdvInstanceCount() > 0) { - btm_ble_multi_adv_init(); - } -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) if (btm_cb.cmn_ble_vsc_cb.max_filter > 0) { btm_ble_adv_filter_init(); } @@ -949,12 +944,6 @@ BOOLEAN BTM_BleConfigPrivacy(BOOLEAN privacy_mode, tBTM_SET_LOCAL_PRIVACY_CBACK btm_gen_resolvable_private_addr((void *)btm_gen_resolve_paddr_low); #endif -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - if (BTM_BleMaxMultiAdvInstanceCount() > 0) { - btm_ble_multi_adv_enb_privacy(privacy_mode); - } -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - /* 4.2 controller only allow privacy 1.2 or mixed mode, resolvable private address in controller */ if (controller_get_interface()->supports_ble_privacy()) { #if (defined(GAP_INCLUDED) && GAP_INCLUDED == TRUE && GATTS_INCLUDED == TRUE) @@ -1224,23 +1213,6 @@ void BTM_BleConfigConnParams(uint16_t int_min, uint16_t int_max, uint16_t latenc #endif } -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) -/******************************************************************************* -** -** Function BTM_BleMaxMultiAdvInstanceCount -** -** Description Returns max number of multi adv instances supported by controller -** -** Returns Max multi adv instance count -** -*******************************************************************************/ -extern UINT8 BTM_BleMaxMultiAdvInstanceCount(void) -{ - return btm_cb.cmn_ble_vsc_cb.adv_inst_max < BTM_BLE_MULTI_ADV_MAX ? - btm_cb.cmn_ble_vsc_cb.adv_inst_max : BTM_BLE_MULTI_ADV_MAX; -} -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - #if BLE_PRIVACY_SPT == TRUE /******************************************************************************* ** @@ -4363,12 +4335,6 @@ void btm_ble_timeout(TIMER_LIST_ENT *p_tle) /* refresh the random addr */ btm_gen_resolvable_private_addr((void *)btm_gen_resolve_paddr_low); #endif - } else { -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - if (BTM_BleMaxMultiAdvInstanceCount() > 0) { - btm_ble_multi_adv_configure_rpa((tBTM_BLE_MULTI_ADV_INST *)p_tle->param); - } -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) } } break; diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c b/components/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c index 31d60546f1..75b5e9e1bc 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c @@ -23,848 +23,5 @@ #if (BLE_INCLUDED == TRUE) -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) -#include "stack/bt_types.h" -#include "stack/hcimsgs.h" -#include "stack/btu.h" -#include "btm_int.h" -//#include "bt_utils.h" -#include "stack/hcidefs.h" -#include "stack/btm_ble_api.h" -/************************************************************************************ -** Constants & Macros -************************************************************************************/ -/* length of each multi adv sub command */ -#define BTM_BLE_MULTI_ADV_ENB_LEN 3 -#define BTM_BLE_MULTI_ADV_SET_PARAM_LEN 24 -#define BTM_BLE_MULTI_ADV_WRITE_DATA_LEN (BTM_BLE_AD_DATA_LEN + 3) -#define BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN 8 - -#define BTM_BLE_MULTI_ADV_CB_EVT_MASK 0xF0 -#define BTM_BLE_MULTI_ADV_SUBCODE_MASK 0x0F - -/************************************************************************************ -** Static variables -************************************************************************************/ -#if BTM_DYNAMIC_MEMORY == FALSE -tBTM_BLE_MULTI_ADV_CB btm_multi_adv_cb; -tBTM_BLE_MULTI_ADV_INST_IDX_Q btm_multi_adv_idx_q; -#else -tBTM_BLE_MULTI_ADV_CB *btm_multi_adv_cb_ptr; -tBTM_BLE_MULTI_ADV_INST_IDX_Q *btm_multi_adv_idx_q_ptr; -#define btm_multi_adv_cb (*btm_multi_adv_cb_ptr) -#define btm_multi_adv_idx_q (*btm_multi_adv_idx_q_ptr) -#endif - -/************************************************************************************ -** Externs -************************************************************************************/ -extern void btm_ble_update_dmt_flag_bits(UINT8 *flag_value, - const UINT16 connect_mode, const UINT16 disc_mode); - -/******************************************************************************* -** -** Function btm_ble_multi_adv_enq_op_q -** -** Description enqueue a multi adv operation in q to check command complete -** status. -** -** Returns void -** -*******************************************************************************/ -void btm_ble_multi_adv_enq_op_q(UINT8 opcode, UINT8 inst_id, UINT8 cb_evt) -{ - tBTM_BLE_MULTI_ADV_OPQ *p_op_q = &btm_multi_adv_cb.op_q; - - p_op_q->p_inst_id[p_op_q->next_idx] = inst_id; - - p_op_q->p_sub_code[p_op_q->next_idx] = (opcode | (cb_evt << 4)); - - p_op_q->next_idx = (p_op_q->next_idx + 1) % BTM_BleMaxMultiAdvInstanceCount(); -} - -/******************************************************************************* -** -** Function btm_ble_multi_adv_deq_op_q -** -** Description dequeue a multi adv operation from q when command complete -** is received. -** -** Returns void -** -*******************************************************************************/ -void btm_ble_multi_adv_deq_op_q(UINT8 *p_opcode, UINT8 *p_inst_id, UINT8 *p_cb_evt) -{ - tBTM_BLE_MULTI_ADV_OPQ *p_op_q = &btm_multi_adv_cb.op_q; - - *p_inst_id = p_op_q->p_inst_id[p_op_q->pending_idx] & 0x7F; - *p_cb_evt = (p_op_q->p_sub_code[p_op_q->pending_idx] >> 4); - *p_opcode = (p_op_q->p_sub_code[p_op_q->pending_idx] & BTM_BLE_MULTI_ADV_SUBCODE_MASK); - - p_op_q->pending_idx = (p_op_q->pending_idx + 1) % BTM_BleMaxMultiAdvInstanceCount(); -} - -/******************************************************************************* -** -** Function btm_ble_multi_adv_vsc_cmpl_cback -** -** Description Multi adv VSC complete callback -** -** Parameters -** -** Returns void -** -*******************************************************************************/ -void btm_ble_multi_adv_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params) -{ - UINT8 status, subcode; - UINT8 *p = p_params->p_param_buf, inst_id; - UINT16 len = p_params->param_len; - tBTM_BLE_MULTI_ADV_INST *p_inst ; - UINT8 cb_evt = 0, opcode; - - if (len < 2) { - BTM_TRACE_ERROR("wrong length for btm_ble_multi_adv_vsc_cmpl_cback"); - return; - } - - STREAM_TO_UINT8(status, p); - STREAM_TO_UINT8(subcode, p); - - btm_ble_multi_adv_deq_op_q(&opcode, &inst_id, &cb_evt); - - BTM_TRACE_DEBUG("op_code = %02x inst_id = %d cb_evt = %02x", opcode, inst_id, cb_evt); - - if (opcode != subcode || inst_id == 0) { - BTM_TRACE_ERROR("get unexpected VSC cmpl, expect: %d get: %d", subcode, opcode); - return; - } - - p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1]; - - switch (subcode) { - case BTM_BLE_MULTI_ADV_ENB: { - BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_ENB status = %d", status); - - /* Mark as not in use here, if instance cannot be enabled */ - if (HCI_SUCCESS != status && BTM_BLE_MULTI_ADV_ENB_EVT == cb_evt) { - btm_multi_adv_cb.p_adv_inst[inst_id - 1].in_use = FALSE; - } - break; - } - - case BTM_BLE_MULTI_ADV_SET_PARAM: { - BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_SET_PARAM status = %d", status); - break; - } - - case BTM_BLE_MULTI_ADV_WRITE_ADV_DATA: { - BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_WRITE_ADV_DATA status = %d", status); - break; - } - - case BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA: { - BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA status = %d", status); - break; - } - - case BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR: { - BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR status = %d", status); - break; - } - - default: - break; - } - - if (cb_evt != 0 && p_inst->p_cback != NULL) { - (p_inst->p_cback)(cb_evt, inst_id, p_inst->p_ref, status); - } - return; -} - -/******************************************************************************* -** -** Function btm_ble_enable_multi_adv -** -** Description This function enable the customer specific feature in controller -** -** Parameters enable: enable or disable -** inst_id: adv instance ID, can not be 0 -** -** Returns status -** -*******************************************************************************/ -tBTM_STATUS btm_ble_enable_multi_adv (BOOLEAN enable, UINT8 inst_id, UINT8 cb_evt) -{ - UINT8 param[BTM_BLE_MULTI_ADV_ENB_LEN], *pp; - UINT8 enb = enable ? 1 : 0; - tBTM_STATUS rt; - - pp = param; - memset(param, 0, BTM_BLE_MULTI_ADV_ENB_LEN); - - UINT8_TO_STREAM (pp, BTM_BLE_MULTI_ADV_ENB); - UINT8_TO_STREAM (pp, enb); - UINT8_TO_STREAM (pp, inst_id); - - BTM_TRACE_EVENT (" btm_ble_enable_multi_adv: enb %d, Inst ID %d", enb, inst_id); - - if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF, - BTM_BLE_MULTI_ADV_ENB_LEN, - param, - btm_ble_multi_adv_vsc_cmpl_cback)) - == BTM_CMD_STARTED) { - btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_ENB, inst_id, cb_evt); - } - return rt; -} - -/******************************************************************************* -** -** Function btm_ble_multi_adv_set_params -** -** Description This function enable the customer specific feature in controller -** -** Parameters advertise parameters used for this instance. -** -** Returns status -** -*******************************************************************************/ -tBTM_STATUS btm_ble_multi_adv_set_params (tBTM_BLE_MULTI_ADV_INST *p_inst, - tBTM_BLE_ADV_PARAMS *p_params, - UINT8 cb_evt) -{ - UINT8 param[BTM_BLE_MULTI_ADV_SET_PARAM_LEN], *pp; - tBTM_STATUS rt; - BD_ADDR dummy = {0, 0, 0, 0, 0, 0}; - - pp = param; - memset(param, 0, BTM_BLE_MULTI_ADV_SET_PARAM_LEN); - - UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_SET_PARAM); - - UINT16_TO_STREAM (pp, p_params->adv_int_min); - UINT16_TO_STREAM (pp, p_params->adv_int_max); - UINT8_TO_STREAM (pp, p_params->adv_type); - -#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) - if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) { - UINT8_TO_STREAM (pp, BLE_ADDR_RANDOM); - BDADDR_TO_STREAM (pp, p_inst->rpa); - } else -#endif - { - UINT8_TO_STREAM (pp, BLE_ADDR_PUBLIC); - BDADDR_TO_STREAM (pp, controller_get_interface()->get_address()->address); - } - - BTM_TRACE_EVENT (" btm_ble_multi_adv_set_params,Min %d, Max %d,adv_type %d", - p_params->adv_int_min, p_params->adv_int_max, p_params->adv_type); - - UINT8_TO_STREAM (pp, 0); - BDADDR_TO_STREAM (pp, dummy); - - if (p_params->channel_map == 0 || p_params->channel_map > BTM_BLE_DEFAULT_ADV_CHNL_MAP) { - p_params->channel_map = BTM_BLE_DEFAULT_ADV_CHNL_MAP; - } - UINT8_TO_STREAM (pp, p_params->channel_map); - - if (p_params->adv_filter_policy >= AP_SCAN_CONN_POLICY_MAX) { - p_params->adv_filter_policy = AP_SCAN_CONN_ALL; - } - UINT8_TO_STREAM (pp, p_params->adv_filter_policy); - - UINT8_TO_STREAM (pp, p_inst->inst_id); - - if (p_params->tx_power > BTM_BLE_ADV_TX_POWER_MAX) { - p_params->tx_power = BTM_BLE_ADV_TX_POWER_MAX; - } - UINT8_TO_STREAM (pp, btm_ble_map_adv_tx_power(p_params->tx_power)); - - BTM_TRACE_EVENT("set_params:Chnl Map %d,adv_fltr policy %d,ID:%d, TX Power%d", - p_params->channel_map, p_params->adv_filter_policy, p_inst->inst_id, p_params->tx_power); - - if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF, - BTM_BLE_MULTI_ADV_SET_PARAM_LEN, - param, - btm_ble_multi_adv_vsc_cmpl_cback)) - == BTM_CMD_STARTED) { - p_inst->adv_evt = p_params->adv_type; - -#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) - if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) { - /* start timer */ - p_inst->raddr_timer_ent.param = (TIMER_PARAM_TYPE) p_inst; - btu_start_timer_oneshot(&p_inst->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR, - BTM_BLE_PRIVATE_ADDR_INT); - } -#endif - btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_SET_PARAM, p_inst->inst_id, cb_evt); - } - return rt; -} - -/******************************************************************************* -** -** Function btm_ble_multi_adv_write_rpa -** -** Description This function write the random address for the adv instance into -** controller -** -** Parameters -** -** Returns status -** -*******************************************************************************/ -tBTM_STATUS btm_ble_multi_adv_write_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst, BD_ADDR random_addr) -{ - UINT8 param[BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN], *pp = param; - tBTM_STATUS rt; - - BTM_TRACE_EVENT ("%s-BD_ADDR:%02x-%02x-%02x-%02x-%02x-%02x,inst_id:%d", - __FUNCTION__, random_addr[5], random_addr[4], random_addr[3], random_addr[2], - random_addr[1], random_addr[0], p_inst->inst_id); - - memset(param, 0, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN); - - UINT8_TO_STREAM (pp, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR); - BDADDR_TO_STREAM(pp, random_addr); - UINT8_TO_STREAM(pp, p_inst->inst_id); - - if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF, - BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN, - param, - btm_ble_multi_adv_vsc_cmpl_cback)) == BTM_CMD_STARTED) { - /* start a periodical timer to refresh random addr */ - btu_stop_timer_oneshot(&p_inst->raddr_timer_ent); - p_inst->raddr_timer_ent.param = (TIMER_PARAM_TYPE) p_inst; - btu_start_timer_oneshot(&p_inst->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR, - BTM_BLE_PRIVATE_ADDR_INT); - - btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR, p_inst->inst_id, 0); - } - return rt; -} - -/******************************************************************************* -** -** Function btm_ble_multi_adv_gen_rpa_cmpl -** -** Description RPA generation completion callback for each adv instance. Will -** continue write the new RPA into controller. -** -** Returns none. -** -*******************************************************************************/ -void btm_ble_multi_adv_gen_rpa_cmpl(tBTM_RAND_ENC *p) -{ -#if (SMP_INCLUDED == TRUE) - tSMP_ENC output; - UINT8 index = 0; - tBTM_BLE_MULTI_ADV_INST *p_inst = NULL; - - /* Retrieve the index of adv instance from stored Q */ - if (btm_multi_adv_idx_q.front == -1) { - BTM_TRACE_ERROR(" %s can't locate advertise instance", __FUNCTION__); - return; - } else { - index = btm_multi_adv_idx_q.inst_index_queue[btm_multi_adv_idx_q.front]; - if (btm_multi_adv_idx_q.front == btm_multi_adv_idx_q.rear) { - btm_multi_adv_idx_q.front = -1; - btm_multi_adv_idx_q.rear = -1; - } else { - btm_multi_adv_idx_q.front = (btm_multi_adv_idx_q.front + 1) % BTM_BLE_MULTI_ADV_MAX; - } - } - - p_inst = &(btm_multi_adv_cb.p_adv_inst[index]); - - BTM_TRACE_EVENT ("btm_ble_multi_adv_gen_rpa_cmpl inst_id = %d", p_inst->inst_id); - if (p) { - p->param_buf[2] &= (~BLE_RESOLVE_ADDR_MASK); - p->param_buf[2] |= BLE_RESOLVE_ADDR_MSB; - - p_inst->rpa[2] = p->param_buf[0]; - p_inst->rpa[1] = p->param_buf[1]; - p_inst->rpa[0] = p->param_buf[2]; - - if (!SMP_Encrypt(btm_cb.devcb.id_keys.irk, BT_OCTET16_LEN, p->param_buf, 3, &output)) { - BTM_TRACE_DEBUG("generate random address failed"); - } else { - /* set hash to be LSB of rpAddress */ - p_inst->rpa[5] = output.param_buf[0]; - p_inst->rpa[4] = output.param_buf[1]; - p_inst->rpa[3] = output.param_buf[2]; - } - - if (p_inst->inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD && - p_inst->inst_id < BTM_BleMaxMultiAdvInstanceCount()) { - /* set it to controller */ - btm_ble_multi_adv_write_rpa(p_inst, p_inst->rpa); - } - } -#endif -} - -/******************************************************************************* -** -** Function btm_ble_multi_adv_configure_rpa -** -** Description This function set the random address for the adv instance -** -** Parameters advertise parameters used for this instance. -** -** Returns none -** -*******************************************************************************/ -void btm_ble_multi_adv_configure_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst) -{ - if (btm_multi_adv_idx_q.front == (btm_multi_adv_idx_q.rear + 1) % BTM_BLE_MULTI_ADV_MAX) { - BTM_TRACE_ERROR("outstanding rand generation exceeded max allowed "); - return; - } else { - if (btm_multi_adv_idx_q.front == -1) { - btm_multi_adv_idx_q.front = 0; - btm_multi_adv_idx_q.rear = 0; - } else { - btm_multi_adv_idx_q.rear = (btm_multi_adv_idx_q.rear + 1) % BTM_BLE_MULTI_ADV_MAX; - } - btm_multi_adv_idx_q.inst_index_queue[btm_multi_adv_idx_q.rear] = p_inst->index; - } - btm_gen_resolvable_private_addr((void *)btm_ble_multi_adv_gen_rpa_cmpl); -} - -/******************************************************************************* -** -** Function btm_ble_multi_adv_reenable -** -** Description This function re-enable adv instance upon a connection establishment. -** -** Parameters advertise parameters used for this instance. -** -** Returns none. -** -*******************************************************************************/ -void btm_ble_multi_adv_reenable(UINT8 inst_id) -{ - tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1]; - - if (TRUE == p_inst->in_use) { - if (p_inst->adv_evt != BTM_BLE_CONNECT_DIR_EVT) { - btm_ble_enable_multi_adv (TRUE, p_inst->inst_id, 0); - } else - /* mark directed adv as disabled if adv has been stopped */ - { - (p_inst->p_cback)(BTM_BLE_MULTI_ADV_DISABLE_EVT, p_inst->inst_id, p_inst->p_ref, 0); - p_inst->in_use = FALSE; - } - } -} - -/******************************************************************************* -** -** Function btm_ble_multi_adv_enb_privacy -** -** Description This function enable/disable privacy setting in multi adv -** -** Parameters enable: enable or disable the adv instance. -** -** Returns none. -** -*******************************************************************************/ -void btm_ble_multi_adv_enb_privacy(BOOLEAN enable) -{ - UINT8 i; - tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[0]; - - for (i = 0; i < BTM_BleMaxMultiAdvInstanceCount() - 1; i ++, p_inst++) { - p_inst->in_use = FALSE; - if (enable) { - btm_ble_multi_adv_configure_rpa (p_inst); - } else { - btu_stop_timer_oneshot(&p_inst->raddr_timer_ent); - } - } -} - -/******************************************************************************* -** -** Function BTM_BleEnableAdvInstance -** -** Description This function enable a Multi-ADV instance with the specified -** adv parameters -** -** Parameters p_params: pointer to the adv parameter structure, set as default -** adv parameter when the instance is enabled. -** p_cback: callback function for the adv instance. -** p_ref: reference data attach to the adv instance to be enabled. -** -** Returns status -** -*******************************************************************************/ -tBTM_STATUS BTM_BleEnableAdvInstance (tBTM_BLE_ADV_PARAMS *p_params, - tBTM_BLE_MULTI_ADV_CBACK *p_cback, void *p_ref) -{ - UINT8 i; - tBTM_STATUS rt = BTM_NO_RESOURCES; - tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[0]; - - BTM_TRACE_EVENT("BTM_BleEnableAdvInstance called"); - - if (0 == btm_cb.cmn_ble_vsc_cb.adv_inst_max) { - BTM_TRACE_ERROR("Controller does not support Multi ADV"); - return BTM_ERR_PROCESSING; - } - - if (NULL == p_inst) { - BTM_TRACE_ERROR("Invalid instance in BTM_BleEnableAdvInstance"); - return BTM_ERR_PROCESSING; - } - - for (i = 0; i < BTM_BleMaxMultiAdvInstanceCount() - 1; i ++, p_inst++) { - if (FALSE == p_inst->in_use) { - p_inst->in_use = TRUE; - /* configure adv parameter */ - if (p_params) { - rt = btm_ble_multi_adv_set_params(p_inst, p_params, 0); - } else { - rt = BTM_CMD_STARTED; - } - - /* enable adv */ - BTM_TRACE_EVENT("btm_ble_enable_multi_adv being called with inst_id:%d", - p_inst->inst_id); - - if (BTM_CMD_STARTED == rt) { - if ((rt = btm_ble_enable_multi_adv (TRUE, p_inst->inst_id, - BTM_BLE_MULTI_ADV_ENB_EVT)) == BTM_CMD_STARTED) { - p_inst->p_cback = p_cback; - p_inst->p_ref = p_ref; - } - } - - if (BTM_CMD_STARTED != rt) { - p_inst->in_use = FALSE; - BTM_TRACE_ERROR("BTM_BleEnableAdvInstance failed"); - } - break; - } - } - return rt; -} - -/******************************************************************************* -** -** Function BTM_BleUpdateAdvInstParam -** -** Description This function update a Multi-ADV instance with the specified -** adv parameters. -** -** Parameters inst_id: adv instance ID -** p_params: pointer to the adv parameter structure. -** -** Returns status -** -*******************************************************************************/ -tBTM_STATUS BTM_BleUpdateAdvInstParam (UINT8 inst_id, tBTM_BLE_ADV_PARAMS *p_params) -{ - tBTM_STATUS rt = BTM_ILLEGAL_VALUE; - tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1]; - - BTM_TRACE_EVENT("BTM_BleUpdateAdvInstParam called with inst_id:%d", inst_id); - - if (0 == btm_cb.cmn_ble_vsc_cb.adv_inst_max) { - BTM_TRACE_ERROR("Controller does not support Multi ADV"); - return BTM_ERR_PROCESSING; - } - - if (inst_id < BTM_BleMaxMultiAdvInstanceCount() && - inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD && - p_params != NULL) { - if (FALSE == p_inst->in_use) { - BTM_TRACE_DEBUG("adv instance %d is not active", inst_id); - return BTM_WRONG_MODE; - } else { - btm_ble_enable_multi_adv(FALSE, inst_id, 0); - } - - if (BTM_CMD_STARTED == btm_ble_multi_adv_set_params(p_inst, p_params, 0)) { - rt = btm_ble_enable_multi_adv(TRUE, inst_id, BTM_BLE_MULTI_ADV_PARAM_EVT); - } - } - return rt; -} - -/******************************************************************************* -** -** Function BTM_BleCfgAdvInstData -** -** Description This function configure a Multi-ADV instance with the specified -** adv data or scan response data. -** -** Parameters inst_id: adv instance ID -** is_scan_rsp: is this scan response. if no, set as adv data. -** data_mask: adv data mask. -** p_data: pointer to the adv data structure. -** -** Returns status -** -*******************************************************************************/ -tBTM_STATUS BTM_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp, - tBTM_BLE_AD_MASK data_mask, - tBTM_BLE_ADV_DATA *p_data) -{ - UINT8 param[BTM_BLE_MULTI_ADV_WRITE_DATA_LEN], *pp = param; - UINT8 sub_code = (is_scan_rsp) ? - BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA : BTM_BLE_MULTI_ADV_WRITE_ADV_DATA; - UINT8 *p_len; - tBTM_STATUS rt; - UINT8 *pp_temp = (UINT8 *)(param + BTM_BLE_MULTI_ADV_WRITE_DATA_LEN - 1); - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - if (0 == cmn_ble_vsc_cb.adv_inst_max) { - BTM_TRACE_ERROR("Controller does not support Multi ADV"); - return BTM_ERR_PROCESSING; - } - - btm_ble_update_dmt_flag_bits(&p_data->flag, btm_cb.btm_inq_vars.connectable_mode, - btm_cb.btm_inq_vars.discoverable_mode); - - BTM_TRACE_EVENT("BTM_BleCfgAdvInstData called with inst_id:%d", inst_id); - if (inst_id > BTM_BLE_MULTI_ADV_MAX || inst_id == BTM_BLE_MULTI_ADV_DEFAULT_STD) { - return BTM_ILLEGAL_VALUE; - } - - memset(param, 0, BTM_BLE_MULTI_ADV_WRITE_DATA_LEN); - - UINT8_TO_STREAM(pp, sub_code); - p_len = pp ++; - btm_ble_build_adv_data(&data_mask, &pp, p_data); - *p_len = (UINT8)(pp - param - 2); - UINT8_TO_STREAM(pp_temp, inst_id); - - if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF, - (UINT8)BTM_BLE_MULTI_ADV_WRITE_DATA_LEN, - param, - btm_ble_multi_adv_vsc_cmpl_cback)) - == BTM_CMD_STARTED) { - btm_ble_multi_adv_enq_op_q(sub_code, inst_id, BTM_BLE_MULTI_ADV_DATA_EVT); - } - return rt; -} - -/******************************************************************************* -** -** Function BTM_BleDisableAdvInstance -** -** Description This function disables a Multi-ADV instance. -** -** Parameters inst_id: adv instance ID -** -** Returns status -** -*******************************************************************************/ -tBTM_STATUS BTM_BleDisableAdvInstance (UINT8 inst_id) -{ - tBTM_STATUS rt = BTM_ILLEGAL_VALUE; - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - - BTM_TRACE_EVENT("BTM_BleDisableAdvInstance with inst_id:%d", inst_id); - - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - - if (0 == cmn_ble_vsc_cb.adv_inst_max) { - BTM_TRACE_ERROR("Controller does not support Multi ADV"); - return BTM_ERR_PROCESSING; - } - - if (inst_id < BTM_BleMaxMultiAdvInstanceCount() && - inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD) { - if ((rt = btm_ble_enable_multi_adv(FALSE, inst_id, BTM_BLE_MULTI_ADV_DISABLE_EVT)) - == BTM_CMD_STARTED) { - btm_ble_multi_adv_configure_rpa(&btm_multi_adv_cb.p_adv_inst[inst_id - 1]); - btu_stop_timer_oneshot(&btm_multi_adv_cb.p_adv_inst[inst_id - 1].raddr_timer_ent); - btm_multi_adv_cb.p_adv_inst[inst_id - 1].in_use = FALSE; - } - } - return rt; -} -/******************************************************************************* -** -** Function btm_ble_multi_adv_vse_cback -** -** Description VSE callback for multi adv events. -** -** Returns -** -*******************************************************************************/ -void btm_ble_multi_adv_vse_cback(UINT8 len, UINT8 *p) -{ - UINT8 sub_event; - UINT8 adv_inst; - UINT16 conn_handle; - tACL_CONN *p_acl_cb = NULL; - /* Check if this is a BLE RSSI vendor specific event */ - STREAM_TO_UINT8(sub_event, p); - len--; - - BTM_TRACE_EVENT("btm_ble_multi_adv_vse_cback called with event:%d", sub_event); - if ((sub_event == HCI_VSE_SUBCODE_BLE_MULTI_ADV_ST_CHG) && (len >= 4)) { - STREAM_TO_UINT8(adv_inst, p); - ++p; - STREAM_TO_UINT16(conn_handle, p); - - if ((p_acl_cb = btm_handle_to_acl(conn_handle)) != NULL) { -#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) - if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE && - adv_inst <= BTM_BLE_MULTI_ADV_MAX && adv_inst != BTM_BLE_MULTI_ADV_DEFAULT_STD) { - memcpy(p_acl_cb->conn_addr, btm_multi_adv_cb.p_adv_inst[adv_inst - 1].rpa, - BD_ADDR_LEN); - } -#endif - } - - if (adv_inst < BTM_BleMaxMultiAdvInstanceCount() && - adv_inst != BTM_BLE_MULTI_ADV_DEFAULT_STD) { - BTM_TRACE_EVENT("btm_ble_multi_adv_reenable called"); - btm_ble_multi_adv_reenable(adv_inst); - } - /* re-enable connectibility */ - else if (adv_inst == BTM_BLE_MULTI_ADV_DEFAULT_STD) { - if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE) { - btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode ); - } - } - - } - -} -/******************************************************************************* -** -** Function btm_ble_multi_adv_init -** -** Description This function initialize the multi adv control block. -** -** Parameters None -** -** Returns void -** -*******************************************************************************/ -void btm_ble_multi_adv_init(void) -{ -#if BTM_DYNAMIC_MEMORY == TRUE - btm_multi_adv_cb_ptr = (tBTM_BLE_MULTI_ADV_CB *)osi_malloc(sizeof(tBTM_BLE_MULTI_ADV_CB)); - btm_multi_adv_idx_q_ptr = (tBTM_BLE_MULTI_ADV_INST_IDX_Q *)osi_malloc(sizeof(tBTM_BLE_MULTI_ADV_INST_IDX_Q)); - if (btm_multi_adv_cb_ptr == NULL || btm_multi_adv_idx_q_ptr == NULL) { - BTM_TRACE_ERROR("%s malloc failed", __func__); - return; - } -#endif - - UINT8 i = 0; - memset(&btm_multi_adv_cb, 0, sizeof(tBTM_BLE_MULTI_ADV_CB)); - memset (&btm_multi_adv_idx_q, 0, sizeof (tBTM_BLE_MULTI_ADV_INST_IDX_Q)); - btm_multi_adv_idx_q.front = -1; - btm_multi_adv_idx_q.rear = -1; - - if (btm_cb.cmn_ble_vsc_cb.adv_inst_max > 0) { - btm_multi_adv_cb.p_adv_inst = osi_malloc( sizeof(tBTM_BLE_MULTI_ADV_INST) * - (btm_cb.cmn_ble_vsc_cb.adv_inst_max)); - memset(btm_multi_adv_cb.p_adv_inst, 0, sizeof(tBTM_BLE_MULTI_ADV_INST) * - (btm_cb.cmn_ble_vsc_cb.adv_inst_max)); - - btm_multi_adv_cb.op_q.p_sub_code = osi_malloc( sizeof(UINT8) * - (btm_cb.cmn_ble_vsc_cb.adv_inst_max)); - memset(btm_multi_adv_cb.op_q.p_sub_code, 0, - sizeof(UINT8) * (btm_cb.cmn_ble_vsc_cb.adv_inst_max)); - - btm_multi_adv_cb.op_q.p_inst_id = osi_malloc( sizeof(UINT8) * - (btm_cb.cmn_ble_vsc_cb.adv_inst_max)); - memset(btm_multi_adv_cb.op_q.p_inst_id, 0, - sizeof(UINT8) * (btm_cb.cmn_ble_vsc_cb.adv_inst_max)); - } - - /* Initialize adv instance indices and IDs. */ - for (i = 0; i < btm_cb.cmn_ble_vsc_cb.adv_inst_max; i++) { - btm_multi_adv_cb.p_adv_inst[i].index = i; - btm_multi_adv_cb.p_adv_inst[i].inst_id = i + 1; - } - - BTM_RegisterForVSEvents(btm_ble_multi_adv_vse_cback, TRUE); -} - -/******************************************************************************* -** -** Function btm_ble_multi_adv_cleanup -** -** Description This function cleans up multi adv control block. -** -** Parameters -** Returns void -** -*******************************************************************************/ -void btm_ble_multi_adv_cleanup(void) -{ -#if BTM_DYNAMIC_MEMORY == TRUE - if (btm_multi_adv_cb_ptr == NULL) - { - BTM_TRACE_WARNING("%s memory has been freed", __func__); - return; - } -#endif - if (btm_multi_adv_cb.p_adv_inst) { - osi_free(btm_multi_adv_cb.p_adv_inst); - btm_multi_adv_cb.p_adv_inst = NULL; - } - - if (btm_multi_adv_cb.op_q.p_sub_code) { - osi_free(btm_multi_adv_cb.op_q.p_sub_code); - btm_multi_adv_cb.op_q.p_sub_code = NULL; - } - - if (btm_multi_adv_cb.op_q.p_inst_id) { - osi_free(btm_multi_adv_cb.op_q.p_inst_id); - btm_multi_adv_cb.op_q.p_inst_id = NULL; - } - -#if BTM_DYNAMIC_MEMORY == TRUE - if(btm_multi_adv_cb_ptr) { - osi_free(btm_multi_adv_cb_ptr); - btm_multi_adv_cb_ptr = NULL; - } - if(btm_multi_adv_idx_q_ptr) { - osi_free(btm_multi_adv_idx_q_ptr); - btm_multi_adv_idx_q_ptr = NULL; - } -#endif -} - -/******************************************************************************* -** -** Function btm_ble_multi_adv_get_ref -** -** Description This function obtains the reference pointer for the instance ID provided -** -** Parameters inst_id - Instance ID -** -** Returns void* -** -*******************************************************************************/ -void *btm_ble_multi_adv_get_ref(UINT8 inst_id) -{ - tBTM_BLE_MULTI_ADV_INST *p_inst = NULL; - - if (inst_id < BTM_BleMaxMultiAdvInstanceCount()) { - p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1]; - if (NULL != p_inst) { - return p_inst->p_ref; - } - } - - return NULL; -} -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index db363f7ad5..c0163335ca 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -179,9 +179,7 @@ static void reset_complete(void) #if (tGATT_BG_CONN_DEV == TRUE) gatt_reset_bgdev_list(); #endif // #if (tGATT_BG_CONN_DEV == TRUE) -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - btm_ble_multi_adv_init(); -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) + #endif btm_pm_reset(); diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index c8181086f7..3a4dac8068 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -518,14 +518,6 @@ void btm_ble_add_default_entry_to_resolving_list(void); void btm_ble_set_privacy_mode_complete(UINT8 *p, UINT16 evt_len); #endif -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) -void btm_ble_multi_adv_configure_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst); -void btm_ble_multi_adv_init(void); -void *btm_ble_multi_adv_get_ref(UINT8 inst_id); -void btm_ble_multi_adv_cleanup(void); -void btm_ble_multi_adv_reenable(UINT8 inst_id); -void btm_ble_multi_adv_enb_privacy(BOOLEAN enable); -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) char btm_ble_map_adv_tx_power(int tx_power_index); void btm_ble_batchscan_init(void); void btm_ble_batchscan_cleanup(void); 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 33522b7aef..499e9798c5 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 @@ -394,9 +394,6 @@ typedef UINT8 tBTM_BLE_ADV_TX_POWER; /* adv tx power in dBm */ typedef struct { -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - UINT8 adv_inst_max; /* max adv instance supported in controller */ -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) UINT8 rpa_offloading; UINT16 tot_scan_results_strg; UINT8 max_irk_list_sz; @@ -500,40 +497,6 @@ typedef struct { tBTM_BLE_ADV_TX_POWER tx_power; } tBTM_BLE_ADV_PARAMS; -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) -typedef struct { - UINT8 *p_sub_code; /* dynamic array to store sub code */ - UINT8 *p_inst_id; /* dynamic array to store instance id */ - UINT8 pending_idx; - UINT8 next_idx; -} tBTM_BLE_MULTI_ADV_OPQ; - -typedef void (tBTM_BLE_MULTI_ADV_CBACK)(tBTM_BLE_MULTI_ADV_EVT evt, UINT8 inst_id, - void *p_ref, tBTM_STATUS status); - -typedef struct { - UINT8 inst_id; - BOOLEAN in_use; - UINT8 adv_evt; - BD_ADDR rpa; - TIMER_LIST_ENT raddr_timer_ent; - tBTM_BLE_MULTI_ADV_CBACK *p_cback; - void *p_ref; - UINT8 index; -} tBTM_BLE_MULTI_ADV_INST; - -typedef struct { - UINT8 inst_index_queue[BTM_BLE_MULTI_ADV_MAX]; - int front; - int rear; -} tBTM_BLE_MULTI_ADV_INST_IDX_Q; - -typedef struct { - tBTM_BLE_MULTI_ADV_INST *p_adv_inst; /* dynamic array to store adv instance */ - tBTM_BLE_MULTI_ADV_OPQ op_q; -} tBTM_BLE_MULTI_ADV_CB; -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - typedef UINT8 tGATT_IF; typedef void (tBTM_BLE_SCAN_THRESHOLD_CBACK)(tBTM_BLE_REF_VALUE ref_value); @@ -3005,20 +2968,6 @@ BOOLEAN BTM_BleLocalPrivacyEnabled(void); //extern void BTM_BleEnableMixedPrivacyMode(BOOLEAN mixed_on); -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) -/******************************************************************************* -** -** Function BTM_BleMaxMultiAdvInstanceCount -** -** Description Returns max number of multi adv instances supported by controller -** -** Returns Max multi adv instance count -** -*******************************************************************************/ -//extern -UINT8 BTM_BleMaxMultiAdvInstanceCount(void); -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) - /******************************************************************************* ** ** Function BTM_BleSetConnectableMode @@ -3198,80 +3147,6 @@ BOOLEAN BTM_BleSecurityProcedureIsRunning (BD_ADDR bd_addr); //extern UINT8 BTM_BleGetSupportedKeySize (BD_ADDR bd_addr); -#if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) -/*******************************************************************************/ -/* Multi ADV API */ -/******************************************************************************* -** -** Function BTM_BleEnableAdvInstance -** -** Description This function enable a Multi-ADV instance with the specified -** adv parameters -** -** Parameters p_params: pointer to the adv parameter structure, set as default -** adv parameter when the instance is enabled. -** p_cback: callback function for the adv instance. -** p_ref: reference data attach to the adv instance to be enabled. -** -** Returns status -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleEnableAdvInstance (tBTM_BLE_ADV_PARAMS *p_params, - tBTM_BLE_MULTI_ADV_CBACK *p_cback, - void *p_ref); - -/******************************************************************************* -** -** Function BTM_BleUpdateAdvInstParam -** -** Description This function update a Multi-ADV instance with the specified -** adv parameters. -** -** Parameters inst_id: adv instance ID -** p_params: pointer to the adv parameter structure. -** -** Returns status -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleUpdateAdvInstParam (UINT8 inst_id, tBTM_BLE_ADV_PARAMS *p_params); - -/******************************************************************************* -** -** Function BTM_BleCfgAdvInstData -** -** Description This function configure a Multi-ADV instance with the specified -** adv data or scan response data. -** -** Parameters inst_id: adv instance ID -** is_scan_rsp: is this scacn response, if no set as adv data. -** data_mask: adv data mask. -** p_data: pointer to the adv data structure. -** -** Returns status -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp, - tBTM_BLE_AD_MASK data_mask, - tBTM_BLE_ADV_DATA *p_data); - -/******************************************************************************* -** -** Function BTM_BleDisableAdvInstance -** -** Description This function disable a Multi-ADV instance. -** -** Parameters inst_id: adv instance ID -** -** Returns status -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleDisableAdvInstance (UINT8 inst_id); - -#endif // #if (BLE_HOST_BLE_MULTI_ADV_EN == TRUE) /******************************************************************************* ** From 0dcb512b3b6f0c07bcfa9db6056c16c8672a1569 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:21 +0800 Subject: [PATCH 115/226] fix(ble/bluedroid): Delete BLE_HOST_TRACK_ADVERTISER_EN (cherry picked from commit 66315bc6b6436d0ed89dddd60c2039b998c2a55d) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 35 ------ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 28 ----- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 4 +- .../bluedroid/bta/dm/include/bta_dm_int.h | 17 +-- .../host/bluedroid/bta/include/bta/bta_api.h | 30 ----- .../common/include/common/bt_target.h | 4 - .../bluedroid/stack/btm/btm_ble_batchscan.c | 109 ------------------ .../stack/include/stack/btm_ble_api.h | 37 ------ 8 files changed, 2 insertions(+), 262 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index b85dcfaea3..5b526ae9d1 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6504,41 +6504,6 @@ void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data) } #endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) -/******************************************************************************* -** -** Function bta_dm_ble_track_advertiser -** -** Description This function tracks the specific advertiser -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_ble_track_advertiser(tBTA_DM_MSG *p_data) -{ - tBTM_STATUS btm_status = 0; - BD_ADDR bda; - memset(&bda, 0 , sizeof(BD_ADDR)); - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - tBTA_DM_BLE_TRACK_ADV_DATA track_adv_data; - - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - - if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) { - btm_status = BTM_BleTrackAdvertiser((tBTM_BLE_TRACK_ADV_CBACK *) - p_data->ble_track_advert.p_track_adv_cback, - p_data->ble_track_advert.ref_value); - } - - if (BTM_CMD_STARTED != btm_status) { - memset(&track_adv_data, 0, sizeof(tBTA_DM_BLE_TRACK_ADV_DATA)); - track_adv_data.advertiser_info_present = NO_ADV_INFO_PRESENT; /* Indicates failure */ - track_adv_data.client_if = (UINT8)p_data->ble_track_advert.ref_value; - p_data->ble_track_advert.p_track_adv_cback(&track_adv_data); - } -} -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) - /******************************************************************************* ** ** Function bta_ble_scan_setup_cb diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index fb154ab6cf..3090e5783c 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -1884,34 +1884,6 @@ extern void BTA_DmBleReadScanReports(tBTA_BLE_BATCH_SCAN_MODE scan_type, } #endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) -/******************************************************************************* -** -** Function BTA_DmBleTrackAdvertiser -** -** Description This function is called to track advertiser -** -** Parameters ref_value - Reference value -** p_track_adv_cback - Track ADV callback -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleTrackAdvertiser(tBTA_DM_BLE_REF_VALUE ref_value, - tBTA_BLE_TRACK_ADV_CBACK *p_track_adv_cback) -{ - tBTA_DM_API_TRACK_ADVERTISER *p_msg; - - if ((p_msg = (tBTA_DM_API_TRACK_ADVERTISER *) - osi_malloc(sizeof(tBTA_DM_API_TRACK_ADVERTISER))) != NULL) { - p_msg->hdr.event = BTA_DM_API_BLE_TRACK_ADVERTISER_EVT; - p_msg->p_track_adv_cback = p_track_adv_cback; - p_msg->ref_value = ref_value; - bta_sys_sendmsg(p_msg); - } -} -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) - #endif /******************************************************************************* diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 6a800d8a5a..1f76dc4b7a 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -205,9 +205,7 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) bta_dm_ble_read_scan_reports, /* BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT */ #endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) - bta_dm_ble_track_advertiser, /* BTA_DM_API_BLE_TRACK_ADVERTISER_EVT */ -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) + #if (BLE_HOST_ENERGY_INFO_EN == TRUE) bta_dm_ble_get_energy_info, /* BTA_DM_API_BLE_ENERGY_INFO_EVT */ #endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 4854ce6a4e..68917fed6e 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -191,9 +191,7 @@ enum { #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT, #endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) - BTA_DM_API_BLE_TRACK_ADVERTISER_EVT, -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) + #if (BLE_HOST_ENERGY_INFO_EN == TRUE) BTA_DM_API_BLE_ENERGY_INFO_EVT, #endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) @@ -1019,13 +1017,6 @@ typedef struct { } tBTA_DM_API_READ_SCAN_REPORTS; #endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) -typedef struct { - BT_HDR hdr; - tBTA_DM_BLE_REF_VALUE ref_value; - tBTA_BLE_TRACK_ADV_CBACK *p_track_adv_cback; -} tBTA_DM_API_TRACK_ADVERTISER; -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) #if (BLE_HOST_ENERGY_INFO_EN == TRUE) typedef struct { @@ -1905,9 +1896,6 @@ typedef union { #if (BLE_HOST_BATCH_SCAN_EN == TRUE) tBTA_DM_API_DISABLE_SCAN ble_disable_scan; #endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) - tBTA_DM_API_TRACK_ADVERTISER ble_track_advert; -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) #if (BLE_HOST_ENERGY_INFO_EN == TRUE) tBTA_DM_API_ENERGY_INFO ble_energy_info; #endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) @@ -2532,9 +2520,6 @@ extern void bta_dm_ble_enable_batch_scan(tBTA_DM_MSG *p_data); extern void bta_dm_ble_disable_batch_scan(tBTA_DM_MSG *p_data); extern void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data); -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) -extern void bta_dm_ble_track_advertiser(tBTA_DM_MSG *p_data); -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) #if (BLE_HOST_ENERGY_INFO_EN == TRUE) extern void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data); diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 105747a3f8..3a57b33709 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -540,9 +540,6 @@ enum { }; typedef tBTM_BLE_BATCH_SCAN_EVT tBTA_BLE_BATCH_SCAN_EVT; -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) -typedef tBTM_BLE_TRACK_ADV_ACTION tBTA_BLE_TRACK_ADV_ACTION; -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) // #endif /* BLE customer specific feature function type definitions */ @@ -1307,9 +1304,6 @@ typedef UINT8 tBTA_DM_BLE_ADV_STATE; typedef UINT8 tBTA_DM_BLE_ADV_INFO_PRESENT; typedef UINT8 tBTA_DM_BLE_RSSI_VALUE; typedef UINT16 tBTA_DM_BLE_ADV_INFO_TIMESTAMP; -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) -typedef tBTM_BLE_TRACK_ADV_DATA tBTA_DM_BLE_TRACK_ADV_DATA; -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) typedef void (tBTA_BLE_SCAN_THRESHOLD_CBACK)(tBTA_DM_BLE_REF_VALUE ref_value); @@ -1327,14 +1321,6 @@ typedef void (tBTA_START_STOP_ADV_CMPL_CBACK) (tBTA_STATUS status); typedef void (tBTA_CLEAR_ADV_CMPL_CBACK) (tBTA_STATUS status); -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) -typedef void (tBTA_BLE_TRACK_ADV_CMPL_CBACK)(int action, tBTA_STATUS status, - tBTA_DM_BLE_PF_AVBL_SPACE avbl_space, - tBTA_DM_BLE_REF_VALUE ref_value); - -typedef void (tBTA_BLE_TRACK_ADV_CBACK)(tBTA_DM_BLE_TRACK_ADV_DATA *p_adv_data); -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) - #if (BLE_HOST_ENERGY_INFO_EN == TRUE) typedef void (tBTA_BLE_ENERGY_INFO_CBACK)(tBTA_DM_BLE_TX_TIME_MS tx_time, tBTA_DM_BLE_RX_TIME_MS rx_time, @@ -3292,22 +3278,6 @@ extern void BTA_DmBleCfgFilterCondition(tBTA_DM_BLE_SCAN_COND_OP action, tBTA_DM_BLE_PF_CFG_CBACK *p_cmpl_cback, tBTA_DM_BLE_REF_VALUE ref_value); -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) -/******************************************************************************* -** -** Function BTA_DmBleTrackAdvertiser -** -** Description This function is called to track the advertiser -** -** Parameters ref_value - Reference value -** p_track_adv_cback - ADV callback -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleTrackAdvertiser(tBTA_DM_BLE_REF_VALUE ref_value, - tBTA_BLE_TRACK_ADV_CBACK *p_track_adv_cback); -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) #if (BLE_HOST_ENERGY_INFO_EN == TRUE) /******************************************************************************* 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 22e0e2c213..66cf81c1be 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1616,10 +1616,6 @@ #define BLE_ANDROID_CONTROLLER_SCAN_FILTER FALSE #endif -#ifndef BLE_HOST_TRACK_ADVERTISER_EN -#define BLE_HOST_TRACK_ADVERTISER_EN FALSE -#endif - #ifndef BLE_HOST_ENERGY_INFO_EN #define BLE_HOST_ENERGY_INFO_EN FALSE #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c b/components/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c index b4b586431c..86b4b18f1c 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c @@ -33,18 +33,9 @@ #if BTM_DYNAMIC_MEMORY == FALSE tBTM_BLE_BATCH_SCAN_CB ble_batchscan_cb; -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) -tBTM_BLE_ADV_TRACK_CB ble_advtrack_cb; -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) #else tBTM_BLE_BATCH_SCAN_CB *ble_batchscan_cb_ptr; -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) -tBTM_BLE_ADV_TRACK_CB *ble_advtrack_cb_ptr; -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) #define ble_batchscan_cb (*ble_batchscan_cb_ptr) -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) -#define ble_advtrack_cb (*ble_advtrack_cb_ptr) -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) #endif /* length of each batch scan command */ @@ -73,10 +64,6 @@ void btm_ble_batchscan_cleanup(void); *******************************************************************************/ void btm_ble_batchscan_filter_track_adv_vse_cback(UINT8 len, UINT8 *p) { -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) - tBTM_BLE_TRACK_ADV_DATA adv_data; - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) UINT8 sub_event = 0; STREAM_TO_UINT8(sub_event, p); @@ -86,54 +73,6 @@ void btm_ble_batchscan_filter_track_adv_vse_cback(UINT8 len, UINT8 *p) ble_batchscan_cb.p_thres_cback(ble_batchscan_cb.ref_value); return; } -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) - if (HCI_VSE_SUBCODE_BLE_TRACKING_SUB_EVT == sub_event && NULL != ble_advtrack_cb.p_track_cback) { - if (len < 10) { - return; - } - - memset(&adv_data, 0 , sizeof(tBTM_BLE_TRACK_ADV_DATA)); - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - adv_data.client_if = (UINT8)ble_advtrack_cb.ref_value; - if (cmn_ble_vsc_cb.version_supported > BTM_VSC_CHIP_CAPABILITY_L_VERSION) { - STREAM_TO_UINT8(adv_data.filt_index, p); - STREAM_TO_UINT8(adv_data.advertiser_state, p); - STREAM_TO_UINT8(adv_data.advertiser_info_present, p); - STREAM_TO_BDADDR(adv_data.bd_addr.address, p); - STREAM_TO_UINT8(adv_data.addr_type, p); - - /* Extract the adv info details */ - if (ADV_INFO_PRESENT == adv_data.advertiser_info_present) { - STREAM_TO_UINT8(adv_data.tx_power, p); - STREAM_TO_UINT8(adv_data.rssi_value, p); - STREAM_TO_UINT16(adv_data.time_stamp, p); - - STREAM_TO_UINT8(adv_data.adv_pkt_len, p); - if (adv_data.adv_pkt_len > 0) { - adv_data.p_adv_pkt_data = osi_malloc(adv_data.adv_pkt_len); - memcpy(adv_data.p_adv_pkt_data, p, adv_data.adv_pkt_len); - } - - STREAM_TO_UINT8(adv_data.scan_rsp_len, p); - if (adv_data.scan_rsp_len > 0) { - adv_data.p_scan_rsp_data = osi_malloc(adv_data.scan_rsp_len); - memcpy(adv_data.p_scan_rsp_data, p, adv_data.scan_rsp_len); - } - } - } else { - /* Based on L-release version */ - STREAM_TO_UINT8(adv_data.filt_index, p); - STREAM_TO_UINT8(adv_data.addr_type, p); - STREAM_TO_BDADDR(adv_data.bd_addr.address, p); - STREAM_TO_UINT8(adv_data.advertiser_state, p); - } - - BTM_TRACE_EVENT("track_adv_vse_cback called: %d, %d, %d", adv_data.filt_index, - adv_data.addr_type, adv_data.advertiser_state); - ble_advtrack_cb.p_track_cback(&adv_data); - return; - } -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) } /******************************************************************************* @@ -867,41 +806,6 @@ tBTM_STATUS BTM_BleReadScanReports(tBTM_BLE_BATCH_SCAN_MODE scan_mode, } #endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) -/******************************************************************************* -** -** Function BTM_BleTrackAdvertiser -** -** Description This function is called to setup the callback for tracking advertisers -** -** Parameters: p_track_cback - Tracking callback pointer -** ref_value - Reference value -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -tBTM_STATUS BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK *p_track_cback, - tBTM_BLE_REF_VALUE ref_value) -{ - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - BTM_TRACE_EVENT (" BTM_BleTrackAdvertiser"); - if (!controller_get_interface()->supports_ble()) { - return BTM_ILLEGAL_VALUE; - } - - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - - if (0 == cmn_ble_vsc_cb.tot_scan_results_strg) { - BTM_TRACE_ERROR("Controller does not support scan storage"); - return BTM_ERR_PROCESSING; - } - - ble_advtrack_cb.p_track_cback = p_track_cback; - ble_advtrack_cb.ref_value = ref_value; - return BTM_CMD_STARTED; -} -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) - /******************************************************************************* ** ** Function btm_ble_batchscan_init @@ -917,9 +821,6 @@ void btm_ble_batchscan_init(void) { #if BTM_DYNAMIC_MEMORY == TRUE ble_batchscan_cb_ptr = (tBTM_BLE_BATCH_SCAN_CB *)osi_malloc(sizeof(tBTM_BLE_BATCH_SCAN_CB)); -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) - ble_advtrack_cb_ptr = (tBTM_BLE_ADV_TRACK_CB *)osi_malloc(sizeof(tBTM_BLE_ADV_TRACK_CB)); -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) if (ble_batchscan_cb_ptr == NULL || ble_advtrack_cb_ptr == NULL) { BTM_TRACE_ERROR("%s malloc failed", __func__); return; @@ -927,9 +828,6 @@ void btm_ble_batchscan_init(void) #endif BTM_TRACE_EVENT (" btm_ble_batchscan_init"); memset(&ble_batchscan_cb, 0, sizeof(tBTM_BLE_BATCH_SCAN_CB)); -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) - memset(&ble_advtrack_cb, 0, sizeof(tBTM_BLE_ADV_TRACK_CB)); -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) BTM_RegisterForVSEvents(btm_ble_batchscan_filter_track_adv_vse_cback, TRUE); } @@ -957,17 +855,10 @@ void btm_ble_batchscan_cleanup(void) } memset(&ble_batchscan_cb, 0, sizeof(tBTM_BLE_BATCH_SCAN_CB)); -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) - memset(&ble_advtrack_cb, 0, sizeof(tBTM_BLE_ADV_TRACK_CB)); -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) #if BTM_DYNAMIC_MEMORY == TRUE osi_free(ble_batchscan_cb_ptr); ble_batchscan_cb_ptr = NULL; -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) - osi_free(ble_advtrack_cb_ptr); - ble_advtrack_cb_ptr = NULL; -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) #endif } 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 499e9798c5..bcd928bc17 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 @@ -922,26 +922,6 @@ typedef UINT8 tBTM_BLE_CONN_TYPE; #define ADV_INFO_PRESENT 0x00 #define NO_ADV_INFO_PRESENT 0x01 -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) -typedef btgatt_track_adv_info_t tBTM_BLE_TRACK_ADV_DATA; - -typedef void (tBTM_BLE_TRACK_ADV_CBACK)(tBTM_BLE_TRACK_ADV_DATA *p_track_adv_data); - -typedef UINT8 tBTM_BLE_TRACK_ADV_EVT; - -typedef struct { - tBTM_BLE_REF_VALUE ref_value; - tBTM_BLE_TRACK_ADV_CBACK *p_track_cback; -} tBTM_BLE_ADV_TRACK_CB; - -enum { - BTM_BLE_TRACK_ADV_ADD, - BTM_BLE_TRACK_ADV_REMOVE -}; - -typedef UINT8 tBTM_BLE_TRACK_ADV_ACTION; -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) - #define BTM_BLE_MULTI_ADV_INVALID 0 #define BTM_BLE_BATCH_SCAN_ENABLE_EVT 1 @@ -2351,23 +2331,6 @@ tBTM_STATUS BTM_BleReadScanReports(tBLE_SCAN_MODE scan_mode, tBTM_BLE_REF_VALUE ref_value); #endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) -#if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) -/******************************************************************************* -** -** Function BTM_BleTrackAdvertiser -** -** Description This function is called to read batch scan reports -** -** Parameters p_track_cback - Tracking callback -** ref_value - Reference value -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK *p_track_cback, - tBTM_BLE_REF_VALUE ref_value); -#endif // #if (BLE_HOST_TRACK_ADVERTISER_EN == TRUE) /******************************************************************************* ** From b024b659baa8fb376e8d800aa2e11d9f00d7226d Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:22 +0800 Subject: [PATCH 116/226] fix(ble/bluedroid): delete BLE_HOST_READ_SCAN_REPORTS_EN (cherry picked from commit c3a185ae80fc71f9550c247df40421eb3ff18ae6) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 29 --------- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 28 --------- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 3 - .../bluedroid/bta/dm/include/bta_dm_int.h | 15 ----- .../common/include/common/bt_target.h | 4 -- .../bluedroid/stack/btm/btm_ble_batchscan.c | 61 ------------------- .../stack/include/stack/btm_ble_api.h | 19 ------ 7 files changed, 159 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 5b526ae9d1..5069330138 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6475,35 +6475,6 @@ void bta_dm_ble_disable_batch_scan (tBTA_DM_MSG *p_data) } #endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) -#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) -/******************************************************************************* -** -** Function bta_dm_ble_read_scan_reports -** -** Description This function reads the batch scan reports -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data) -{ - tBTM_STATUS btm_status = 0; - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - - if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) { - btm_status = BTM_BleReadScanReports(p_data->ble_read_reports.scan_type, - p_data->ble_read_reports.ref_value); - } - - if (BTM_CMD_STARTED != btm_status) { - bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, p_data->ble_enable_scan.ref_value, - btm_status); - } -} -#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) - /******************************************************************************* ** ** Function bta_ble_scan_setup_cb diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 3090e5783c..be7f5444c5 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -1856,34 +1856,6 @@ extern void BTA_DmBleDisableBatchScan(tBTA_DM_BLE_REF_VALUE ref_value) } #endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) -#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) -/******************************************************************************* -** -** Function BTA_DmBleReadScanReports -** -** Description This function is called to read scan reports -** -** Parameters scan_type -Batch scan mode -** ref_value - Reference value -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleReadScanReports(tBTA_BLE_BATCH_SCAN_MODE scan_type, - tBTA_DM_BLE_REF_VALUE ref_value) -{ - tBTA_DM_API_READ_SCAN_REPORTS *p_msg; - - if ((p_msg = (tBTA_DM_API_READ_SCAN_REPORTS *) - osi_malloc(sizeof(tBTA_DM_API_READ_SCAN_REPORTS))) != NULL) { - p_msg->hdr.event = BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT; - p_msg->scan_type = scan_type; - p_msg->ref_value = ref_value; - bta_sys_sendmsg(p_msg); - } -} -#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) - #endif /******************************************************************************* diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 1f76dc4b7a..6b3cf65538 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -202,9 +202,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_enable_batch_scan, /* BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT */ bta_dm_ble_disable_batch_scan, /* BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT */ #endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) -#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) - bta_dm_ble_read_scan_reports, /* BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT */ -#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) #if (BLE_HOST_ENERGY_INFO_EN == TRUE) bta_dm_ble_get_energy_info, /* BTA_DM_API_BLE_ENERGY_INFO_EVT */ diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 68917fed6e..612f5793cc 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -188,9 +188,6 @@ enum { BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT, BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT, #endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) -#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) - BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT, -#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) #if (BLE_HOST_ENERGY_INFO_EN == TRUE) BTA_DM_API_BLE_ENERGY_INFO_EVT, @@ -1009,15 +1006,6 @@ typedef struct { } tBTA_DM_API_DISABLE_SCAN; #endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) -#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) -typedef struct { - BT_HDR hdr; - tBTA_BLE_BATCH_SCAN_MODE scan_type; - tBTA_DM_BLE_REF_VALUE ref_value; -} tBTA_DM_API_READ_SCAN_REPORTS; -#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) - - #if (BLE_HOST_ENERGY_INFO_EN == TRUE) typedef struct { BT_HDR hdr; @@ -1890,9 +1878,6 @@ typedef union { #if (BLE_HOST_BATCH_SCAN_EN == TRUE) tBTA_DM_API_ENABLE_SCAN ble_enable_scan; #endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) -#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) - tBTA_DM_API_READ_SCAN_REPORTS ble_read_reports; -#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) #if (BLE_HOST_BATCH_SCAN_EN == TRUE) tBTA_DM_API_DISABLE_SCAN ble_disable_scan; #endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) 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 66cf81c1be..89fad9dcf9 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1661,10 +1661,6 @@ #define BLE_HOST_SETUP_STORAGE_EN FALSE #endif -#ifndef BLE_HOST_READ_SCAN_REPORTS_EN -#define BLE_HOST_READ_SCAN_REPORTS_EN FALSE -#endif - #ifndef BLE_HOST_BATCH_SCAN_EN #define BLE_HOST_BATCH_SCAN_EN FALSE #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c b/components/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c index 86b4b18f1c..d678d96f6e 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c @@ -745,67 +745,6 @@ tBTM_STATUS BTM_BleDisableBatchScan(tBTM_BLE_REF_VALUE ref_value) return status; } -#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) -/******************************************************************************* -** -** Function BTM_BleReadScanReports -** -** Description This function is called to start reading batch scan reports -** -** Parameters: scan_mode - Batch scan mode -** ref_value - Reference value -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -tBTM_STATUS BTM_BleReadScanReports(tBTM_BLE_BATCH_SCAN_MODE scan_mode, - tBTM_BLE_REF_VALUE ref_value) -{ - tBTM_STATUS status = BTM_NO_RESOURCES; - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - UINT8 read_scan_mode = 0; - UINT8 *p_data = NULL, num_records = 0; - UINT16 data_len = 0; - - BTM_TRACE_EVENT (" BTM_BleReadScanReports; %d, %d", scan_mode, ref_value); - - if (!controller_get_interface()->supports_ble()) { - return BTM_ILLEGAL_VALUE; - } - - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - - if (0 == cmn_ble_vsc_cb.tot_scan_results_strg) { - BTM_TRACE_ERROR("Controller does not support batch scan"); - return BTM_ERR_PROCESSING; - } - - /* Check if the requested scan mode has already been setup by the user */ - read_scan_mode = ble_batchscan_cb.scan_mode & BTM_BLE_BATCH_SCAN_MODE_ACTI; - if (0 == read_scan_mode) { - read_scan_mode = ble_batchscan_cb.scan_mode & BTM_BLE_BATCH_SCAN_MODE_PASS; - } - - /* Check only for modes, as scan reports can be called after disabling batch scan */ - if (read_scan_mode > 0 && (BTM_BLE_BATCH_SCAN_MODE_PASS == scan_mode || - BTM_BLE_BATCH_SCAN_MODE_ACTI == scan_mode)) { - status = btm_ble_batchscan_enq_rep_q(scan_mode, ref_value); - if (BTM_SUCCESS == status) { - status = btm_ble_read_batchscan_reports(scan_mode, ref_value); - if (BTM_CMD_STARTED != status) { - btm_ble_batchscan_deq_rep_data(scan_mode, &ref_value, - &num_records, &p_data, &data_len); - } - } - } else { - BTM_TRACE_ERROR("Illegal read scan params: %d, %d, %d", read_scan_mode, scan_mode, - ble_batchscan_cb.cur_state); - return BTM_ILLEGAL_VALUE; - } - return status; -} -#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) - /******************************************************************************* ** ** Function btm_ble_batchscan_init 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 bcd928bc17..e68ec80b1c 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 @@ -2313,25 +2313,6 @@ tBTM_STATUS BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode, //extern tBTM_STATUS BTM_BleDisableBatchScan(tBTM_BLE_REF_VALUE ref_value); -#if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) -/******************************************************************************* -** -** Function BTM_BleReadScanReports -** -** Description This function is called to read batch scan reports -** -** Parameters tBLE_SCAN_MODE scan_mode - Scan mode report to be read out - tBTM_BLE_SCAN_REP_CBACK* p_cback - Reports callback -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleReadScanReports(tBLE_SCAN_MODE scan_mode, - tBTM_BLE_REF_VALUE ref_value); -#endif // #if (BLE_HOST_READ_SCAN_REPORTS_EN == TRUE) - - /******************************************************************************* ** ** Function BTM_BleWriteScanRsp From da9f2b38eacb2880ef2c3591d0b716e753ccc345 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:23 +0800 Subject: [PATCH 117/226] fix(ble/bluedroid): Delete BLE_HOST_BATCH_SCAN_EN (cherry picked from commit 25b0e1e68464901fc14779a8f87c509da5234c32) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 60 -- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 61 -- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 4 - .../bluedroid/bta/dm/include/bta_dm_int.h | 28 +- .../common/include/common/bt_target.h | 4 - .../bluedroid/stack/btm/btm_ble_batchscan.c | 773 ------------------ 6 files changed, 1 insertion(+), 929 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 5069330138..769b494461 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6415,66 +6415,6 @@ void bta_dm_ble_setup_storage (tBTA_DM_MSG *p_data) } #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) -#if (BLE_HOST_BATCH_SCAN_EN == TRUE) -/******************************************************************************* -** -** Function bta_dm_ble_enable_batch_scan -** -** Description This function sets up the parameters and enables batch scan -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_ble_enable_batch_scan (tBTA_DM_MSG *p_data) -{ - tBTM_STATUS btm_status = 0; - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - - if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) { - btm_status = BTM_BleEnableBatchScan(p_data->ble_enable_scan.scan_mode, - p_data->ble_enable_scan.scan_int, - p_data->ble_enable_scan.scan_window, - p_data->ble_enable_scan.discard_rule, - p_data->ble_enable_scan.addr_type, - p_data->ble_enable_scan.ref_value); - } - - if (BTM_CMD_STARTED != btm_status) { - bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_ENABLE_EVT, p_data->ble_enable_scan.ref_value, - btm_status); - } -} - -/******************************************************************************* -** -** Function bta_dm_ble_disable_batch_scan -** -** Description This function disables the batch scan -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_ble_disable_batch_scan (tBTA_DM_MSG *p_data) -{ - UNUSED(p_data); - tBTM_STATUS btm_status = 0; - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - - if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) { - btm_status = BTM_BleDisableBatchScan(p_data->ble_disable_scan.ref_value); - } - - if (BTM_CMD_STARTED != btm_status) { - bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_DISABLE_EVT, p_data->ble_enable_scan.ref_value, - btm_status); - } -} -#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) - /******************************************************************************* ** ** Function bta_ble_scan_setup_cb diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index be7f5444c5..b3ab0579c6 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -1795,67 +1795,6 @@ extern void BTA_DmBleSetStorageParams(UINT8 batch_scan_full_max, } #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) -#if (BLE_HOST_BATCH_SCAN_EN == TRUE) -/******************************************************************************* -** -** Function BTA_DmBleEnableBatchScan -** -** Description This function is called to enable the batch scan -** -** Parameters scan_mode -Batch scan mode -** scan_interval - Scan interval -** scan_window - Scan window -** discard_rule -Discard rules -** addr_type - Address type -** ref_value - Reference value -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleEnableBatchScan(tBTA_BLE_BATCH_SCAN_MODE scan_mode, - UINT32 scan_interval, UINT32 scan_window, - tBTA_BLE_DISCARD_RULE discard_rule, - tBLE_ADDR_TYPE addr_type, - tBTA_DM_BLE_REF_VALUE ref_value) -{ - tBTA_DM_API_ENABLE_SCAN *p_msg; - - if ((p_msg = (tBTA_DM_API_ENABLE_SCAN *) osi_malloc(sizeof(tBTA_DM_API_ENABLE_SCAN))) != NULL) { - p_msg->hdr.event = BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT; - p_msg->scan_mode = scan_mode; - p_msg->scan_int = scan_interval; - p_msg->scan_window = scan_window; - p_msg->discard_rule = discard_rule; - p_msg->addr_type = addr_type; - p_msg->ref_value = ref_value; - bta_sys_sendmsg(p_msg); - } -} - -/******************************************************************************* -** -** Function BTA_DmBleDisableBatchScan -** -** Description This function is called to disable the batch scan -** -** Parameters ref_value - Reference value -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleDisableBatchScan(tBTA_DM_BLE_REF_VALUE ref_value) -{ - tBTA_DM_API_DISABLE_SCAN *p_msg; - - if ((p_msg = (tBTA_DM_API_DISABLE_SCAN *) - osi_malloc(sizeof(tBTA_DM_API_DISABLE_SCAN))) != NULL) { - p_msg->hdr.event = BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT; - p_msg->ref_value = ref_value; - bta_sys_sendmsg(p_msg); - } -} -#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) - #endif /******************************************************************************* diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 6b3cf65538..e0c52d8628 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -198,10 +198,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) bta_dm_ble_setup_storage, /* BTA_DM_API_BLE_SETUP_STORAGE_EVT */ #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) -#if (BLE_HOST_BATCH_SCAN_EN == TRUE) - bta_dm_ble_enable_batch_scan, /* BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT */ - bta_dm_ble_disable_batch_scan, /* BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT */ -#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) #if (BLE_HOST_ENERGY_INFO_EN == TRUE) bta_dm_ble_get_energy_info, /* BTA_DM_API_BLE_ENERGY_INFO_EVT */ diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 612f5793cc..a54839e683 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -184,10 +184,6 @@ enum { #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) BTA_DM_API_BLE_SETUP_STORAGE_EVT, #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) -#if (BLE_HOST_BATCH_SCAN_EN == TRUE) - BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT, - BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT, -#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) #if (BLE_HOST_ENERGY_INFO_EN == TRUE) BTA_DM_API_BLE_ENERGY_INFO_EVT, @@ -989,23 +985,6 @@ typedef struct { } tBTA_DM_API_SET_STORAGE_CONFIG; #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) -#if (BLE_HOST_BATCH_SCAN_EN == TRUE) -typedef struct { - BT_HDR hdr; - tBTA_BLE_BATCH_SCAN_MODE scan_mode; - UINT32 scan_int; - UINT32 scan_window; - tBTA_BLE_DISCARD_RULE discard_rule; - tBLE_ADDR_TYPE addr_type; - tBTA_DM_BLE_REF_VALUE ref_value; -} tBTA_DM_API_ENABLE_SCAN; - -typedef struct { - BT_HDR hdr; - tBTA_DM_BLE_REF_VALUE ref_value; -} tBTA_DM_API_DISABLE_SCAN; -#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) - #if (BLE_HOST_ENERGY_INFO_EN == TRUE) typedef struct { BT_HDR hdr; @@ -1875,12 +1854,7 @@ typedef union { #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) tBTA_DM_API_SET_STORAGE_CONFIG ble_set_storage; #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) -#if (BLE_HOST_BATCH_SCAN_EN == TRUE) - tBTA_DM_API_ENABLE_SCAN ble_enable_scan; -#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) -#if (BLE_HOST_BATCH_SCAN_EN == TRUE) - tBTA_DM_API_DISABLE_SCAN ble_disable_scan; -#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) + #if (BLE_HOST_ENERGY_INFO_EN == TRUE) tBTA_DM_API_ENERGY_INFO ble_energy_info; #endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) 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 89fad9dcf9..53d5ad9f65 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1661,10 +1661,6 @@ #define BLE_HOST_SETUP_STORAGE_EN FALSE #endif -#ifndef BLE_HOST_BATCH_SCAN_EN -#define BLE_HOST_BATCH_SCAN_EN FALSE -#endif - #ifndef BLE_HOST_BG_CONNECT_EN #define BLE_HOST_BG_CONNECT_EN FALSE #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c b/components/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c index d678d96f6e..6fb140e210 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_batchscan.c @@ -29,779 +29,6 @@ #include "stack/hcimsgs.h" #if (BLE_INCLUDED == TRUE) -#if (BLE_HOST_BATCH_SCAN_EN == TRUE) -#if BTM_DYNAMIC_MEMORY == FALSE -tBTM_BLE_BATCH_SCAN_CB ble_batchscan_cb; -#else -tBTM_BLE_BATCH_SCAN_CB *ble_batchscan_cb_ptr; -#define ble_batchscan_cb (*ble_batchscan_cb_ptr) -#endif - -/* length of each batch scan command */ -#define BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN 4 -#define BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN 12 -#define BTM_BLE_BATCH_SCAN_ENB_DISB_LEN 2 -#define BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN 2 - -#define BTM_BLE_BATCH_SCAN_CB_EVT_MASK 0xF0 -#define BTM_BLE_BATCH_SCAN_SUBCODE_MASK 0x0F - -/******************************************************************************* -** Local functions -*******************************************************************************/ -void btm_ble_batchscan_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params); -void btm_ble_batchscan_cleanup(void); - -/******************************************************************************* -** -** Function btm_ble_batchscan_filter_track_adv_vse_cback -** -** Description VSE callback for batch scan, filter, and tracking events. -** -** Returns None -** -*******************************************************************************/ -void btm_ble_batchscan_filter_track_adv_vse_cback(UINT8 len, UINT8 *p) -{ - UINT8 sub_event = 0; - STREAM_TO_UINT8(sub_event, p); - - BTM_TRACE_EVENT("btm_ble_batchscan_filter_track_adv_vse_cback called with event:%x", sub_event); - if (HCI_VSE_SUBCODE_BLE_THRESHOLD_SUB_EVT == sub_event && - NULL != ble_batchscan_cb.p_thres_cback) { - ble_batchscan_cb.p_thres_cback(ble_batchscan_cb.ref_value); - return; - } -} - -/******************************************************************************* -** -** Function btm_ble_batchscan_enq_op_q -** -** Description enqueue a batchscan operation in q to check command complete -** status -** -** Returns void -** -*******************************************************************************/ -void btm_ble_batchscan_enq_op_q(UINT8 opcode, tBTM_BLE_BATCH_SCAN_STATE cur_state, - UINT8 cb_evt, tBTM_BLE_REF_VALUE ref_value) -{ - ble_batchscan_cb.op_q.sub_code[ble_batchscan_cb.op_q.next_idx] = (opcode | (cb_evt << 4)); - ble_batchscan_cb.op_q.cur_state[ble_batchscan_cb.op_q.next_idx] = cur_state; - ble_batchscan_cb.op_q.ref_value[ble_batchscan_cb.op_q.next_idx] = ref_value; - BTM_TRACE_DEBUG("btm_ble_batchscan_enq_op_q: subcode:%d, Cur_state:%d, ref_value:%d", - ble_batchscan_cb.op_q.sub_code[ble_batchscan_cb.op_q.next_idx], - ble_batchscan_cb.op_q.cur_state[ble_batchscan_cb.op_q.next_idx], - ble_batchscan_cb.op_q.ref_value[ble_batchscan_cb.op_q.next_idx]); - ble_batchscan_cb.op_q.next_idx = (ble_batchscan_cb.op_q.next_idx + 1) - % BTM_BLE_BATCH_SCAN_MAX; -} - -/******************************************************************************* -** -** Function btm_ble_batchscan_enq_rep_q -** -** Description enqueue a batchscan report operation in q to check command complete -** status -** -** Returns void -** -*******************************************************************************/ -tBTM_STATUS btm_ble_batchscan_enq_rep_q(UINT8 report_format, tBTM_BLE_REF_VALUE ref_value) -{ - int i = 0; - for (i = 0; i < BTM_BLE_BATCH_REP_MAIN_Q_SIZE; i++) { - if (report_format == ble_batchscan_cb.main_rep_q.rep_mode[i]) { - return BTM_ILLEGAL_VALUE; - } - } - - ble_batchscan_cb.main_rep_q.rep_mode[ble_batchscan_cb.main_rep_q.next_idx] = report_format; - ble_batchscan_cb.main_rep_q.ref_value[ble_batchscan_cb.main_rep_q.next_idx] = ref_value; - ble_batchscan_cb.main_rep_q.num_records[ble_batchscan_cb.main_rep_q.next_idx] = 0; - ble_batchscan_cb.main_rep_q.data_len[ble_batchscan_cb.main_rep_q.next_idx] = 0; - ble_batchscan_cb.main_rep_q.p_data[ble_batchscan_cb.main_rep_q.next_idx] = NULL; - BTM_TRACE_DEBUG("btm_ble_batchscan_enq_rep_q: index:%d, rep %d, ref %d", - ble_batchscan_cb.main_rep_q.next_idx, report_format, ref_value); - - ble_batchscan_cb.main_rep_q.next_idx = (ble_batchscan_cb.main_rep_q.next_idx + 1) - % BTM_BLE_BATCH_REP_MAIN_Q_SIZE; - return BTM_SUCCESS; -} - -/******************************************************************************* -** -** Function btm_ble_batchscan_enq_rep_data -** -** Description setup the data in the main report queue -** -** Returns void -** -*******************************************************************************/ -void btm_ble_batchscan_enq_rep_data(UINT8 report_format, UINT8 num_records, UINT8 *p_data, - UINT8 data_len) -{ - int index = 0, len = 0; - UINT8 *p_orig_data = NULL, *p_app_data = NULL; - - for (index = 0; index < BTM_BLE_BATCH_REP_MAIN_Q_SIZE; index++) { - if (report_format == ble_batchscan_cb.main_rep_q.rep_mode[index]) { - break; - } - } - - BTM_TRACE_DEBUG("btm_ble_batchscan_enq_rep_data: index:%d, rep %d, num %d len : %d", - index, report_format, num_records, data_len); - - if (index < BTM_BLE_BATCH_REP_MAIN_Q_SIZE && data_len > 0 && num_records > 0) { - len = ble_batchscan_cb.main_rep_q.data_len[index]; - p_orig_data = ble_batchscan_cb.main_rep_q.p_data[index]; - if (NULL != p_orig_data) { - p_app_data = osi_malloc(len + data_len); - memcpy(p_app_data, p_orig_data, len); - memcpy(p_app_data + len, p_data, data_len); - osi_free(p_orig_data); - ble_batchscan_cb.main_rep_q.p_data[index] = p_app_data; - ble_batchscan_cb.main_rep_q.num_records[index] += num_records; - ble_batchscan_cb.main_rep_q.data_len[index] += data_len; - } else { - p_app_data = osi_malloc(data_len); - memcpy(p_app_data, p_data, data_len); - ble_batchscan_cb.main_rep_q.p_data[index] = p_app_data; - ble_batchscan_cb.main_rep_q.num_records[index] = num_records; - ble_batchscan_cb.main_rep_q.data_len[index] = data_len; - } - } -} - -/******************************************************************************* -** -** Function btm_ble_batchscan_deq_rep_q -** -** Description dequeue a batchscan report in q when command complete -** is received -** -** Returns void -** -*******************************************************************************/ -void btm_ble_batchscan_deq_rep_data(UINT8 report_format, tBTM_BLE_REF_VALUE *p_ref_value, - UINT8 *p_num_records, UINT8 **p_data, UINT16 *p_data_len) -{ - int index = 0; - - for (index = 0; index < BTM_BLE_BATCH_REP_MAIN_Q_SIZE; index++) { - if (report_format == ble_batchscan_cb.main_rep_q.rep_mode[index]) { - break; - } - } - - if (BTM_BLE_BATCH_REP_MAIN_Q_SIZE == index) { - BTM_TRACE_ERROR("btm_ble_batchscan_deq_rep_data: rep_format:%d not found", report_format); - return; - } - - *p_num_records = ble_batchscan_cb.main_rep_q.num_records[index]; - *p_ref_value = ble_batchscan_cb.main_rep_q.ref_value[index]; - *p_data = ble_batchscan_cb.main_rep_q.p_data[index]; - *p_data_len = ble_batchscan_cb.main_rep_q.data_len[index]; - - ble_batchscan_cb.main_rep_q.p_data[index] = NULL; - ble_batchscan_cb.main_rep_q.data_len[index] = 0; - ble_batchscan_cb.main_rep_q.rep_mode[index] = 0; - ble_batchscan_cb.main_rep_q.ref_value[index] = 0; - ble_batchscan_cb.main_rep_q.num_records[index] = 0; - - BTM_TRACE_DEBUG("btm_ble_batchscan_deq_rep_data: index:%d, rep %d, num %d, data_len %d", - index, report_format, *p_num_records, *p_data_len); - - ble_batchscan_cb.main_rep_q.pending_idx = (ble_batchscan_cb.main_rep_q.pending_idx + 1) - % BTM_BLE_BATCH_SCAN_MAX; -} - -/******************************************************************************* -** -** Function btm_ble_batchscan_deq_op_q -** -** Description dequeue a batch scan operation from q when command complete -** is received -** -** Returns void -** -*******************************************************************************/ -void btm_ble_batchscan_deq_op_q(UINT8 *p_opcode, tBTM_BLE_BATCH_SCAN_STATE *cur_state, - UINT8 *p_cb_evt, tBTM_BLE_REF_VALUE *p_ref) -{ - *p_cb_evt = (ble_batchscan_cb.op_q.sub_code[ble_batchscan_cb.op_q.pending_idx] >> 4); - *p_opcode = (ble_batchscan_cb.op_q.sub_code[ble_batchscan_cb.op_q.pending_idx] - & BTM_BLE_BATCH_SCAN_SUBCODE_MASK); - *p_ref = ble_batchscan_cb.op_q.ref_value[ble_batchscan_cb.op_q.pending_idx]; - *cur_state = (ble_batchscan_cb.op_q.cur_state[ble_batchscan_cb.op_q.pending_idx]); - ble_batchscan_cb.op_q.pending_idx = (ble_batchscan_cb.op_q.pending_idx + 1) - % BTM_BLE_BATCH_SCAN_MAX; -} - -/******************************************************************************* -** -** Function btm_ble_read_batchscan_reports -** -** Description This function reads the reports from controller -** -** Parameters scan_mode - The mode for which the reports are to be read out from the controller -** ref_value - Reference value -** -** Returns status -** -*******************************************************************************/ -tBTM_STATUS btm_ble_read_batchscan_reports(tBTM_BLE_BATCH_SCAN_MODE scan_mode, - tBTM_BLE_REF_VALUE ref_value) -{ - tBTM_STATUS status = BTM_NO_RESOURCES; - UINT8 param[BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN], *pp; - pp = param; - - memset(param, 0, BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN); - - UINT8_TO_STREAM (pp, BTM_BLE_BATCH_SCAN_READ_RESULTS); - UINT8_TO_STREAM (pp, scan_mode); - - if ((status = BTM_VendorSpecificCommand (HCI_BLE_BATCH_SCAN_OCF, - BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN, param, btm_ble_batchscan_vsc_cmpl_cback)) - != BTM_CMD_STARTED) { - BTM_TRACE_ERROR("btm_ble_read_batchscan_reports %d", status); - return BTM_ILLEGAL_VALUE; - } - - if (BTM_CMD_STARTED == status) { - /* The user needs to be provided scan read reports event */ - btm_ble_batchscan_enq_op_q(BTM_BLE_BATCH_SCAN_READ_RESULTS, ble_batchscan_cb.cur_state, - BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, ref_value); - } - - return status; -} - -/******************************************************************************* -** -** Function btm_ble_batchscan_vsc_cmpl_cback -** -** Description Batch scan VSC complete callback -** -** Parameters p_params - VSC completed callback parameters -** -** Returns void -** -*******************************************************************************/ -void btm_ble_batchscan_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params) -{ - UINT8 *p = p_params->p_param_buf; - UINT16 len = p_params->param_len; - tBTM_BLE_REF_VALUE ref_value = 0; - - UINT8 status = 0, subcode = 0, opcode = 0; - UINT8 report_format = 0, num_records = 0, cb_evt = 0; - UINT16 data_len = 0; - tBTM_BLE_BATCH_SCAN_STATE cur_state = 0; - tBTM_STATUS btm_status = 0; - UINT8 *p_data = NULL; - - if (len < 2) { - BTM_TRACE_ERROR("wrong length for btm_ble_batch_scan_vsc_cmpl_cback"); - btm_ble_batchscan_deq_op_q(&opcode, &cur_state, &cb_evt, &ref_value); - return; - } - - STREAM_TO_UINT8(status, p); - STREAM_TO_UINT8(subcode, p); - - btm_ble_batchscan_deq_op_q(&opcode, &cur_state, &cb_evt, &ref_value); - - BTM_TRACE_DEBUG("btm_ble_batchscan op_code = %02x state = %02x cb_evt = %02x,ref_value=%d", - opcode, cur_state, cb_evt, ref_value); - - if (opcode != subcode) { - BTM_TRACE_ERROR("Got unexpected VSC cmpl, expected: %d got: %d", subcode, opcode); - return; - } - - switch (subcode) { - case BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE: { - if (BTM_SUCCESS == status && BTM_BLE_SCAN_ENABLE_CALLED == cur_state) { - ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLED_STATE; - } else if (BTM_BLE_SCAN_ENABLE_CALLED == cur_state) { - BTM_TRACE_ERROR("SCAN_ENB_DISAB_CUST_FEATURE - Invalid state after enb"); - ble_batchscan_cb.cur_state = BTM_BLE_SCAN_INVALID_STATE; - } - - BTM_TRACE_DEBUG("BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEAT status = %d, state: %d,evt=%d", - status, ble_batchscan_cb.cur_state, cb_evt); - - if (cb_evt != 0 && NULL != ble_batchscan_cb.p_setup_cback) { - ble_batchscan_cb.p_setup_cback(cb_evt, ref_value, status); - } - break; - } - - case BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM: { - BTM_TRACE_DEBUG("BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM status = %d, evt=%d", - status, cb_evt); - if (cb_evt != 0 && NULL != ble_batchscan_cb.p_setup_cback) { - ble_batchscan_cb.p_setup_cback(cb_evt, ref_value, status); - } - break; - } - - case BTM_BLE_BATCH_SCAN_SET_PARAMS: { - BTM_TRACE_DEBUG("BTM_BLE_BATCH_SCAN_SET_PARAMS status = %d,evt=%d", status, cb_evt); - - if (BTM_BLE_SCAN_DISABLE_CALLED == cur_state) { - if (BTM_SUCCESS == status) { - ble_batchscan_cb.cur_state = BTM_BLE_SCAN_DISABLED_STATE; - } else { - BTM_TRACE_ERROR("BTM_BLE_BATCH_SCAN_SET_PARAMS - Invalid state after disabled"); - ble_batchscan_cb.cur_state = BTM_BLE_SCAN_INVALID_STATE; - } - } - - if (cb_evt != 0 && NULL != ble_batchscan_cb.p_setup_cback) { - ble_batchscan_cb.p_setup_cback(cb_evt, ref_value, status); - } - break; - } - - case BTM_BLE_BATCH_SCAN_READ_RESULTS: { - if (cb_evt != 0 && NULL != ble_batchscan_cb.p_scan_rep_cback) { - STREAM_TO_UINT8(report_format, p); - STREAM_TO_UINT8(num_records, p); - p = (uint8_t *)(p_params->p_param_buf + 4); - BTM_TRACE_DEBUG("BTM_BLE_BATCH_SCAN_READ_RESULTS status=%d,len=%d,rec=%d", - status, len - 4, num_records); - - if (0 == num_records) { - btm_ble_batchscan_deq_rep_data(report_format, &ref_value, &num_records, - &p_data, &data_len); - if (NULL != ble_batchscan_cb.p_scan_rep_cback) { - ble_batchscan_cb.p_scan_rep_cback(ref_value, report_format, num_records, - data_len, p_data, status); - } - } else { - if ((len - 4) > 0) { - btm_ble_batchscan_enq_rep_data(report_format, num_records, p, len - 4); - /* More records could be in the buffer and needs to be pulled out */ - btm_status = btm_ble_read_batchscan_reports(report_format, ref_value); - if (BTM_CMD_STARTED != btm_status) { - btm_ble_batchscan_deq_rep_data(report_format, &ref_value, &num_records, - &p_data, &data_len); - /* Send whatever is available, in case of a command failure */ - if (NULL != ble_batchscan_cb.p_scan_rep_cback && NULL != p_data) { - ble_batchscan_cb.p_scan_rep_cback(ref_value, report_format, - num_records, data_len, p_data, status); - } - } - } - } - } - break; - } - - default: - break; - } - - return; -} - -/******************************************************************************* -** -** Function btm_ble_set_storage_config -** -** Description This function writes the storage configuration in controller -** -** Parameters batch_scan_full_max -Max storage space (in %) allocated to full scanning -** batch_scan_trunc_max -Max storage space (in %) allocated to truncated scanning -** batch_scan_notify_threshold - Setup notification level based on total space -** -** Returns status -** -*******************************************************************************/ -tBTM_STATUS btm_ble_set_storage_config(UINT8 batch_scan_full_max, UINT8 batch_scan_trunc_max, - UINT8 batch_scan_notify_threshold) -{ - tBTM_STATUS status = BTM_NO_RESOURCES; - UINT8 param[BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN], *pp; - - pp = param; - memset(param, 0, BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN); - - UINT8_TO_STREAM (pp, BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM); - UINT8_TO_STREAM (pp, batch_scan_full_max); - UINT8_TO_STREAM (pp, batch_scan_trunc_max); - UINT8_TO_STREAM (pp, batch_scan_notify_threshold); - - if ((status = BTM_VendorSpecificCommand (HCI_BLE_BATCH_SCAN_OCF, - BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN, param, - btm_ble_batchscan_vsc_cmpl_cback)) != BTM_CMD_STARTED) { - BTM_TRACE_ERROR("btm_ble_set_storage_config %d", status); - return BTM_ILLEGAL_VALUE; - } - - return status; -} - -/******************************************************************************* -** -** Function btm_ble_set_batchscan_param -** -** Description This function writes the batch scan params in controller -** -** Parameters scan_mode -Batch scan mode -** scan_interval - Scan interval -** scan_window - Scan window -** discard_rule -Discard rules -** addr_type - Address type -** -** Returns status -** -*******************************************************************************/ -tBTM_STATUS btm_ble_set_batchscan_param(tBTM_BLE_BATCH_SCAN_MODE scan_mode, - UINT32 scan_interval, UINT32 scan_window, tBLE_ADDR_TYPE addr_type, - tBTM_BLE_DISCARD_RULE discard_rule) -{ - tBTM_STATUS status = BTM_NO_RESOURCES; - UINT8 scan_param[BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN], *pp_scan; - - pp_scan = scan_param; - memset(scan_param, 0, BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN); - - // Override param and decide addr_type based on own addr type - // TODO: Remove upper layer parameter? - addr_type = btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type; - - UINT8_TO_STREAM (pp_scan, BTM_BLE_BATCH_SCAN_SET_PARAMS); - UINT8_TO_STREAM (pp_scan, scan_mode); - UINT32_TO_STREAM (pp_scan, scan_window); - UINT32_TO_STREAM (pp_scan, scan_interval); - UINT8_TO_STREAM (pp_scan, addr_type); - UINT8_TO_STREAM (pp_scan, discard_rule); - - if ((status = BTM_VendorSpecificCommand (HCI_BLE_BATCH_SCAN_OCF, - BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN, - scan_param, btm_ble_batchscan_vsc_cmpl_cback)) != BTM_CMD_STARTED) { - BTM_TRACE_ERROR("btm_ble_set_batchscan_param %d", status); - return BTM_ILLEGAL_VALUE; - } - - return status; -} - -/******************************************************************************* -** -** Function btm_ble_enable_disable_batchscan -** -** Description This function enables the customer specific feature in controller -** -** Parameters enable_disable: true - enable, false - disable -** -** Returns status -** -*******************************************************************************/ -tBTM_STATUS btm_ble_enable_disable_batchscan(BOOLEAN should_enable) -{ - tBTM_STATUS status = BTM_NO_RESOURCES; - UINT8 shld_enable = 0x01; - UINT8 enable_param[BTM_BLE_BATCH_SCAN_ENB_DISB_LEN], *pp_enable; - - if (!should_enable) { - shld_enable = 0x00; - } - - if (should_enable) { - pp_enable = enable_param; - memset(enable_param, 0, BTM_BLE_BATCH_SCAN_ENB_DISB_LEN); - - UINT8_TO_STREAM (pp_enable, BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE); - UINT8_TO_STREAM (pp_enable, shld_enable); - - if ((status = BTM_VendorSpecificCommand(HCI_BLE_BATCH_SCAN_OCF, - BTM_BLE_BATCH_SCAN_ENB_DISB_LEN, enable_param, - btm_ble_batchscan_vsc_cmpl_cback)) != BTM_CMD_STARTED) { - status = BTM_MODE_UNSUPPORTED; - BTM_TRACE_ERROR("btm_ble_enable_disable_batchscan %d", status); - return BTM_ILLEGAL_VALUE; - } - } else if ((status = btm_ble_set_batchscan_param(BTM_BLE_BATCH_SCAN_MODE_DISABLE, - ble_batchscan_cb.scan_interval, ble_batchscan_cb.scan_window, - ble_batchscan_cb.addr_type, ble_batchscan_cb.discard_rule)) != BTM_CMD_STARTED) { - status = BTM_MODE_UNSUPPORTED; - BTM_TRACE_ERROR("btm_ble_enable_disable_batchscan %d", status); - return BTM_ILLEGAL_VALUE; - } - - if (should_enable) { - ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLE_CALLED; - } else { - ble_batchscan_cb.cur_state = BTM_BLE_SCAN_DISABLE_CALLED; - } - return status; -} - -#if (BLE_HOST_SETUP_STORAGE_EN == TRUE) -/******************************************************************************* -** -** Function BTM_BleSetStorageConfig -** -** Description This function is called to write storage config params. -** -** Parameters: batch_scan_full_max - Max storage space (in %) allocated to full style -** batch_scan_trunc_max - Max storage space (in %) allocated to trunc style -** batch_scan_notify_threshold - Setup notification level based on total space -** p_setup_cback - Setup callback pointer -** p_thres_cback - Threshold callback pointer -** p_rep_cback - Reports callback pointer -** ref_value - Reference value -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -tBTM_STATUS BTM_BleSetStorageConfig(UINT8 batch_scan_full_max, UINT8 batch_scan_trunc_max, - UINT8 batch_scan_notify_threshold, - tBTM_BLE_SCAN_SETUP_CBACK *p_setup_cback, - tBTM_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback, - tBTM_BLE_SCAN_REP_CBACK *p_rep_cback, - tBTM_BLE_REF_VALUE ref_value) -{ - tBTM_STATUS status = BTM_NO_RESOURCES; - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - - BTM_TRACE_EVENT (" BTM_BleSetStorageConfig: %d, %d, %d, %d, %d", - ble_batchscan_cb.cur_state, ref_value, batch_scan_full_max, batch_scan_trunc_max, - batch_scan_notify_threshold); - - if (!controller_get_interface()->supports_ble()) { - return BTM_ILLEGAL_VALUE; - } - - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - - if (0 == cmn_ble_vsc_cb.tot_scan_results_strg) { - BTM_TRACE_ERROR("Controller does not support batch scan"); - return BTM_ERR_PROCESSING; - } - - ble_batchscan_cb.p_setup_cback = p_setup_cback; - ble_batchscan_cb.p_thres_cback = p_thres_cback; - ble_batchscan_cb.p_scan_rep_cback = p_rep_cback; - ble_batchscan_cb.ref_value = ref_value; - - if (batch_scan_full_max > BTM_BLE_ADV_SCAN_FULL_MAX || - batch_scan_trunc_max > BTM_BLE_ADV_SCAN_TRUNC_MAX || - batch_scan_notify_threshold > BTM_BLE_ADV_SCAN_THR_MAX) { - BTM_TRACE_ERROR("Illegal set storage config params"); - return BTM_ILLEGAL_VALUE; - } - - if (BTM_BLE_SCAN_INVALID_STATE == ble_batchscan_cb.cur_state || - BTM_BLE_SCAN_DISABLED_STATE == ble_batchscan_cb.cur_state || - BTM_BLE_SCAN_DISABLE_CALLED == ble_batchscan_cb.cur_state) { - status = btm_ble_enable_disable_batchscan(TRUE); - if (BTM_CMD_STARTED != status) { - return status; - } - - ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLE_CALLED; - btm_ble_batchscan_enq_op_q(BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE, - BTM_BLE_SCAN_ENABLE_CALLED, 0, ref_value); - } - - status = btm_ble_set_storage_config(batch_scan_full_max, batch_scan_trunc_max, - batch_scan_notify_threshold); - if (BTM_CMD_STARTED != status) { - return status; - } - /* The user needs to be provided scan config storage event */ - btm_ble_batchscan_enq_op_q(BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM, ble_batchscan_cb.cur_state, - BTM_BLE_BATCH_SCAN_CFG_STRG_EVT, ref_value); - - return status; -} -#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) - -/******************************************************************************* -** -** Function BTM_BleEnableBatchScan -** -** Description This function is called to configure and enable batch scanning -** -** Parameters: scan_mode -Batch scan mode -** scan_interval - Scan interval value -** scan_window - Scan window value -** discard_rule - Data discard rule -** ref_value - Reference value -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -tBTM_STATUS BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode, - UINT32 scan_interval, UINT32 scan_window, tBLE_ADDR_TYPE addr_type, - tBTM_BLE_DISCARD_RULE discard_rule, tBTM_BLE_REF_VALUE ref_value) -{ - tBTM_STATUS status = BTM_NO_RESOURCES; - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - BTM_TRACE_EVENT (" BTM_BleEnableBatchScan: %d, %d, %d, %d, %d, %d", - scan_mode, scan_interval, scan_window, addr_type, discard_rule, ref_value); - - if (!controller_get_interface()->supports_ble()) { - return BTM_ILLEGAL_VALUE; - } - - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - - if (0 == cmn_ble_vsc_cb.tot_scan_results_strg) { - BTM_TRACE_ERROR("Controller does not support batch scan"); - return BTM_ERR_PROCESSING; - } - - BTM_TRACE_DEBUG("BTM_BleEnableBatchScan: %d, %x, %x, %d, %d", scan_mode, scan_interval, - scan_window, discard_rule, ble_batchscan_cb.cur_state); - - /* Only 16 bits will be used for scan interval and scan window as per agreement with Google */ - /* So the standard LE range would suffice for scan interval and scan window */ - if ((BTM_BLE_ISVALID_PARAM(scan_interval, BTM_BLE_SCAN_INT_MIN, BTM_BLE_SCAN_INT_MAX) || - BTM_BLE_ISVALID_PARAM(scan_window, BTM_BLE_SCAN_WIN_MIN, BTM_BLE_SCAN_WIN_MAX)) - && (BTM_BLE_BATCH_SCAN_MODE_PASS == scan_mode || BTM_BLE_BATCH_SCAN_MODE_ACTI == scan_mode - || BTM_BLE_BATCH_SCAN_MODE_PASS_ACTI == scan_mode) - && (BTM_BLE_DISCARD_OLD_ITEMS == discard_rule || - BTM_BLE_DISCARD_LOWER_RSSI_ITEMS == discard_rule)) { - if (BTM_BLE_SCAN_INVALID_STATE == ble_batchscan_cb.cur_state || - BTM_BLE_SCAN_DISABLED_STATE == ble_batchscan_cb.cur_state || - BTM_BLE_SCAN_DISABLE_CALLED == ble_batchscan_cb.cur_state) { - status = btm_ble_enable_disable_batchscan(TRUE); - if (BTM_CMD_STARTED != status) { - return status; - } - btm_ble_batchscan_enq_op_q(BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE, - BTM_BLE_SCAN_ENABLE_CALLED, 0, ref_value); - } - - ble_batchscan_cb.scan_mode = scan_mode; - ble_batchscan_cb.scan_interval = scan_interval; - ble_batchscan_cb.scan_window = scan_window; - ble_batchscan_cb.addr_type = addr_type; - ble_batchscan_cb.discard_rule = discard_rule; - /* This command starts batch scanning, if enabled */ - status = btm_ble_set_batchscan_param(scan_mode, scan_interval, scan_window, addr_type, - discard_rule); - if (BTM_CMD_STARTED != status) { - return status; - } - - /* The user needs to be provided scan enable event */ - btm_ble_batchscan_enq_op_q(BTM_BLE_BATCH_SCAN_SET_PARAMS, ble_batchscan_cb.cur_state, - BTM_BLE_BATCH_SCAN_ENABLE_EVT, ref_value); - } else { - BTM_TRACE_ERROR("Illegal enable scan params"); - return BTM_ILLEGAL_VALUE; - } - return status; -} - -/******************************************************************************* -** -** Function BTM_BleDisableBatchScan -** -** Description This function is called to disable batch scanning -** -** Parameters: ref_value - Reference value -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -tBTM_STATUS BTM_BleDisableBatchScan(tBTM_BLE_REF_VALUE ref_value) -{ - tBTM_STATUS status = BTM_NO_RESOURCES; - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - BTM_TRACE_EVENT (" BTM_BleDisableBatchScan"); - - if (!controller_get_interface()->supports_ble()) { - return BTM_ILLEGAL_VALUE; - } - - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - - if (0 == cmn_ble_vsc_cb.tot_scan_results_strg) { - BTM_TRACE_ERROR("Controller does not support batch scan"); - return BTM_ERR_PROCESSING; - } - - status = btm_ble_enable_disable_batchscan(FALSE); - if (BTM_CMD_STARTED == status) { - /* The user needs to be provided scan disable event */ - btm_ble_batchscan_enq_op_q(BTM_BLE_BATCH_SCAN_SET_PARAMS, - BTM_BLE_SCAN_DISABLE_CALLED, BTM_BLE_BATCH_SCAN_DISABLE_EVT, - ref_value); - } - - return status; -} - -/******************************************************************************* -** -** Function btm_ble_batchscan_init -** -** Description This function initialize the batch scan control block. -** -** Parameters None -** -** Returns status -** -*******************************************************************************/ -void btm_ble_batchscan_init(void) -{ -#if BTM_DYNAMIC_MEMORY == TRUE - ble_batchscan_cb_ptr = (tBTM_BLE_BATCH_SCAN_CB *)osi_malloc(sizeof(tBTM_BLE_BATCH_SCAN_CB)); - if (ble_batchscan_cb_ptr == NULL || ble_advtrack_cb_ptr == NULL) { - BTM_TRACE_ERROR("%s malloc failed", __func__); - return; - } -#endif - BTM_TRACE_EVENT (" btm_ble_batchscan_init"); - memset(&ble_batchscan_cb, 0, sizeof(tBTM_BLE_BATCH_SCAN_CB)); - BTM_RegisterForVSEvents(btm_ble_batchscan_filter_track_adv_vse_cback, TRUE); -} - -/******************************************************************************* -** -** Function btm_ble_batchscan_cleanup -** -** Description This function cleans the batch scan control block. -** -** Parameters None -** -** Returns void -** -*******************************************************************************/ -void btm_ble_batchscan_cleanup(void) -{ - int index = 0; - BTM_TRACE_EVENT (" btm_ble_batchscan_cleanup"); - - for (index = 0; index < BTM_BLE_BATCH_REP_MAIN_Q_SIZE; index++) { - if (NULL != ble_batchscan_cb.main_rep_q.p_data[index]) { - osi_free(ble_batchscan_cb.main_rep_q.p_data[index]); - ble_batchscan_cb.main_rep_q.p_data[index] = NULL; - } - } - - memset(&ble_batchscan_cb, 0, sizeof(tBTM_BLE_BATCH_SCAN_CB)); - -#if BTM_DYNAMIC_MEMORY == TRUE - osi_free(ble_batchscan_cb_ptr); - ble_batchscan_cb_ptr = NULL; - -#endif -} - -#endif // #if (BLE_HOST_BATCH_SCAN_EN == TRUE) #endif From d80a17fa153a518d05405b1edfd571bed280a655 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:23 +0800 Subject: [PATCH 118/226] fix(ble/bluedroid): Delete BLE_HOST_CONN_SCAN_PARAM_EN (cherry picked from commit b175f3cc97700f06c04bb9d3748d9c17200ff642) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 17 -------- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 27 ------------ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 3 -- .../bluedroid/bta/dm/include/bta_dm_int.h | 18 -------- .../common/include/common/bt_target.h | 4 -- .../bt/host/bluedroid/stack/btm/btm_ble.c | 42 ------------------- 6 files changed, 111 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 769b494461..f4652cab73 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -5300,23 +5300,6 @@ void bta_dm_ble_set_scan_fil_params(tBTA_DM_MSG *p_data) } #endif // #if (BLE_42_SCAN_EN == TRUE) -#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) -/******************************************************************************* -** -** Function bta_dm_ble_set_conn_scan_params -** -** Description This function set the preferred connection scan parameters. -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_ble_set_conn_scan_params (tBTA_DM_MSG *p_data) -{ - BTM_BleSetConnScanParams(p_data->ble_set_conn_scan_params.scan_int, - p_data->ble_set_conn_scan_params.scan_window); -} -#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) - /******************************************************************************* ** ** Function bta_dm_ble_update_conn_params diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index b3ab0579c6..c72d688ebe 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -1456,33 +1456,6 @@ void BTA_DmSetBlePrefConnParams(BD_ADDR bd_addr, #endif } -#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) -/******************************************************************************* -** -** Function BTA_DmSetBleConnScanParams -** -** Description This function is called to set scan parameters used in -** BLE connection request -** -** Parameters: scan_interval - scan interval -** scan_window - scan window -** -** Returns void -** -*******************************************************************************/ -void BTA_DmSetBleConnScanParams(UINT32 scan_interval, UINT32 scan_window) -{ - tBTA_DM_API_BLE_SCAN_PARAMS *p_msg; - if ((p_msg = (tBTA_DM_API_BLE_SCAN_PARAMS *)osi_malloc(sizeof(tBTA_DM_API_BLE_SCAN_PARAMS))) != NULL) { - memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_SCAN_PARAMS)); - p_msg->hdr.event = BTA_DM_API_BLE_CONN_SCAN_PARAM_EVT; - p_msg->scan_int = scan_interval; - p_msg->scan_window = scan_window; - bta_sys_sendmsg(p_msg); - } -} -#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) - #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index e0c52d8628..eeea850b1b 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -142,9 +142,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { #endif ///SMP_INCLUDED == TRUE bta_dm_ble_set_bg_conn_type, bta_dm_ble_set_conn_params, /* BTA_DM_API_BLE_CONN_PARAM_EVT */ -#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) - bta_dm_ble_set_conn_scan_params, /* BTA_DM_API_BLE_CONN_SCAN_PARAM_EVT */ -#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) bta_dm_ble_set_scan_params, /* BTA_DM_API_BLE_SCAN_PARAM_EVT */ #endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index a54839e683..275de8c370 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -128,9 +128,6 @@ enum { #endif ///SMP_INCLUDED == TRUE BTA_DM_API_BLE_SET_BG_CONN_TYPE, BTA_DM_API_BLE_CONN_PARAM_EVT, -#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) - BTA_DM_API_BLE_CONN_SCAN_PARAM_EVT, -#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) BTA_DM_API_BLE_SCAN_PARAM_EVT, #endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) @@ -871,15 +868,6 @@ typedef struct { tBLE_SCAN_PARAM_SETUP_CBACK scan_param_setup_cback; } tBTA_DM_API_BLE_SCAN_FILTER_PARAMS; -#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) -/* set scan parameter for BLE connections */ -typedef struct { - BT_HDR hdr; - UINT16 scan_int; - UINT16 scan_window; -} tBTA_DM_API_BLE_CONN_SCAN_PARAMS; -#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) - /* Data type for start/stop observe */ typedef struct { BT_HDR hdr; @@ -1822,9 +1810,6 @@ typedef union { tBTA_DM_API_BLE_SEC_GRANT ble_sec_grant; tBTA_DM_API_BLE_SET_BG_CONN_TYPE ble_set_bd_conn_type; tBTA_DM_API_BLE_CONN_PARAMS ble_set_conn_params; -#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) - tBTA_DM_API_BLE_CONN_SCAN_PARAMS ble_set_conn_scan_params; -#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) tBTA_DM_API_BLE_SCAN_PARAMS ble_set_scan_params; #endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) @@ -2406,9 +2391,6 @@ extern void bta_dm_ble_set_bg_conn_type (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_conn_params (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_scan_params(tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_scan_fil_params(tBTA_DM_MSG *p_data); -#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) -extern void bta_dm_ble_set_conn_scan_params (tBTA_DM_MSG *p_data); -#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE) extern void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data); #endif /* ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE) */ 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 53d5ad9f65..e41c055bcc 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1653,10 +1653,6 @@ #define BLE_HOST_BLE_SCAN_PARAM_UNUSED FALSE #endif -#ifndef BLE_HOST_CONN_SCAN_PARAM_EN -#define BLE_HOST_CONN_SCAN_PARAM_EN FALSE -#endif - #ifndef BLE_HOST_SETUP_STORAGE_EN #define BLE_HOST_SETUP_STORAGE_EN FALSE #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble.c b/components/bt/host/bluedroid/stack/btm/btm_ble.c index a99614e93c..60601893da 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble.c @@ -549,48 +549,6 @@ void BTM_BleSecureConnectionCreateOobData(void) #endif } -#if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) -/****************************************************************************** -** -** Function BTM_BleSetConnScanParams -** -** Description Set scan parameter used in BLE connection request -** -** Parameters: scan_interval: scan interval -** scan_window: scan window -** -** Returns void -** -*******************************************************************************/ -void BTM_BleSetConnScanParams (UINT32 scan_interval, UINT32 scan_window) -{ -#if SMP_INCLUDED == TRUE - tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb; - BOOLEAN new_param = FALSE; - - if (BTM_BLE_ISVALID_PARAM(scan_interval, BTM_BLE_SCAN_INT_MIN, BTM_BLE_SCAN_INT_MAX) && - BTM_BLE_ISVALID_PARAM(scan_window, BTM_BLE_SCAN_WIN_MIN, BTM_BLE_SCAN_WIN_MAX)) { - if (p_ble_cb->scan_int != scan_interval) { - p_ble_cb->scan_int = scan_interval; - new_param = TRUE; - } - - if (p_ble_cb->scan_win != scan_window) { - p_ble_cb->scan_win = scan_window; - new_param = TRUE; - } -#if (tGATT_BG_CONN_DEV == TRUE) - if (new_param && p_ble_cb->conn_state == BLE_BG_CONN) { - btm_ble_suspend_bg_conn(); - } -#endif // #if (tGATT_BG_CONN_DEV == TRUE) - } else { - BTM_TRACE_ERROR("Illegal Connection Scan Parameters"); - } -#endif -} -#endif // #if (BLE_HOST_CONN_SCAN_PARAM_EN == TRUE) - /******************************************************** ** ** Function BTM_BleSetPrefConnParams From 4222c6d3091bf9bc825430ca67d06adcc903caea Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:24 +0800 Subject: [PATCH 119/226] fix(ble/bluedroid): Delete BLE_HOST_BLE_SCAN_PARAM_UNUSED (cherry picked from commit 5fdcc3bdea170a47eac4364502edb514f28760ce) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 20 ------ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 36 ----------- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 3 - .../bluedroid/bta/dm/include/bta_dm_int.h | 6 -- .../common/include/common/bt_target.h | 4 -- .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 61 ------------------- .../stack/include/stack/btm_ble_api.h | 23 ------- 7 files changed, 153 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index f4652cab73..867c3fb91d 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -5246,26 +5246,6 @@ void bta_dm_ble_set_conn_params (tBTA_DM_MSG *p_data) p_data->ble_set_conn_params.slave_latency, p_data->ble_set_conn_params.supervision_tout); } -#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) -/******************************************************************************* -** -** Function bta_dm_ble_set_conn_scan_params -** -** Description This function sets BLE scan parameters. -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_ble_set_scan_params(tBTA_DM_MSG *p_data) -{ - BTM_BleSetScanParams(p_data->ble_set_scan_params.client_if, - p_data->ble_set_scan_params.scan_int, - p_data->ble_set_scan_params.scan_window, - p_data->ble_set_scan_params.scan_mode, - p_data->ble_set_scan_params.scan_param_setup_cback); -} -#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) - #if (BLE_42_SCAN_EN == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index c72d688ebe..1d9102129f 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -1456,42 +1456,6 @@ void BTA_DmSetBlePrefConnParams(BD_ADDR bd_addr, #endif } -#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) -/******************************************************************************* -** -** Function BTA_DmSetBleScanParams -** -** Description This function is called to set scan parameters -** -** Parameters: client_if - Client IF -** scan_interval - scan interval -** scan_window - scan window -** scan_mode - scan mode -** scan_param_setup_status_cback - Set scan param status callback -** -** Returns void -** -*******************************************************************************/ -void BTA_DmSetBleScanParams(tGATT_IF client_if, UINT32 scan_interval, - UINT32 scan_window, tBLE_SCAN_MODE scan_mode, - tBLE_SCAN_PARAM_SETUP_CBACK scan_param_setup_cback) -{ - tBTA_DM_API_BLE_SCAN_PARAMS *p_msg; - - if ((p_msg = (tBTA_DM_API_BLE_SCAN_PARAMS *)osi_malloc(sizeof(tBTA_DM_API_BLE_SCAN_PARAMS))) != NULL) { - memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_SCAN_PARAMS)); - p_msg->hdr.event = BTA_DM_API_BLE_SCAN_PARAM_EVT; - p_msg->client_if = client_if; - p_msg->scan_int = scan_interval; - p_msg->scan_window = scan_window; - p_msg->scan_mode = scan_mode; - p_msg->scan_param_setup_cback = scan_param_setup_cback; - - bta_sys_sendmsg(p_msg); - } -} -#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) - #if (BLE_42_SCAN_EN == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index eeea850b1b..7d3f183dd7 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -142,9 +142,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { #endif ///SMP_INCLUDED == TRUE bta_dm_ble_set_bg_conn_type, bta_dm_ble_set_conn_params, /* BTA_DM_API_BLE_CONN_PARAM_EVT */ -#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) - bta_dm_ble_set_scan_params, /* BTA_DM_API_BLE_SCAN_PARAM_EVT */ -#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) #if (BLE_42_SCAN_EN == TRUE) bta_dm_ble_set_scan_fil_params, /* BTA_DM_API_BLE_SCAN_FIL_PARAM_EVT */ #endif // #if (BLE_42_SCAN_EN == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 275de8c370..8f80a2bc82 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -128,9 +128,6 @@ enum { #endif ///SMP_INCLUDED == TRUE BTA_DM_API_BLE_SET_BG_CONN_TYPE, BTA_DM_API_BLE_CONN_PARAM_EVT, -#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) - BTA_DM_API_BLE_SCAN_PARAM_EVT, -#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) /*******This event added by Yulong at 2016/10/25 to support the scan filter setting for the APP******/ #if (BLE_42_SCAN_EN == TRUE) @@ -1810,9 +1807,6 @@ typedef union { tBTA_DM_API_BLE_SEC_GRANT ble_sec_grant; tBTA_DM_API_BLE_SET_BG_CONN_TYPE ble_set_bd_conn_type; tBTA_DM_API_BLE_CONN_PARAMS ble_set_conn_params; -#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) - tBTA_DM_API_BLE_SCAN_PARAMS ble_set_scan_params; -#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) tBTA_DM_API_BLE_SCAN_FILTER_PARAMS ble_set_scan_fil_params; tBTA_DM_API_BLE_OBSERVE ble_observe; tBTA_DM_API_BLE_SCAN ble_scan; 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 e41c055bcc..d05f079194 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1649,10 +1649,6 @@ #define BLE_HOST_BLE_OBSERVE_EN FALSE #endif -#ifndef BLE_HOST_BLE_SCAN_PARAM_UNUSED -#define BLE_HOST_BLE_SCAN_PARAM_UNUSED FALSE -#endif - #ifndef BLE_HOST_SETUP_STORAGE_EN #define BLE_HOST_SETUP_STORAGE_EN FALSE #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index e49cccaa77..e81c86f80a 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -1625,67 +1625,6 @@ void BTM_BleReadAdvParams (UINT16 *adv_int_min, UINT16 *adv_int_max, } } -#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) -/******************************************************************************* -** -** Function BTM_BleSetScanParams -** -** Description This function is called to set scan parameters. -** -** Parameters client_if - Client IF -** scan_interval - Scan interval -** scan_window - Scan window -** scan_mode - Scan mode -** scan_setup_status_cback - Scan param setup status callback -** -** Returns void -** -*******************************************************************************/ -void BTM_BleSetScanParams(tGATT_IF client_if, UINT32 scan_interval, UINT32 scan_window, - tBLE_SCAN_MODE scan_mode, - tBLE_SCAN_PARAM_SETUP_CBACK scan_setup_status_cback) -{ - tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; - UINT32 max_scan_interval; - UINT32 max_scan_window; - - BTM_TRACE_EVENT ("%s\n", __func__); - if (!controller_get_interface()->supports_ble()) { - return; - } - - /* If not supporting extended scan support, use the older range for checking */ - if (btm_cb.cmn_ble_vsc_cb.extended_scan_support == 0) { - max_scan_interval = BTM_BLE_SCAN_INT_MAX; - max_scan_window = BTM_BLE_SCAN_WIN_MAX; - } else { - /* If supporting extended scan support, use the new extended range for checking */ - max_scan_interval = BTM_BLE_EXT_SCAN_INT_MAX; - max_scan_window = BTM_BLE_EXT_SCAN_WIN_MAX; - } - - if (BTM_BLE_ISVALID_PARAM(scan_interval, BTM_BLE_SCAN_INT_MIN, max_scan_interval) && - BTM_BLE_ISVALID_PARAM(scan_window, BTM_BLE_SCAN_WIN_MIN, max_scan_window) && - (scan_mode == BTM_BLE_SCAN_MODE_ACTI || scan_mode == BTM_BLE_SCAN_MODE_PASS)) { - p_cb->scan_type = scan_mode; - p_cb->scan_interval = scan_interval; - p_cb->scan_window = scan_window; - - if (scan_setup_status_cback != NULL) { - scan_setup_status_cback(client_if, BTM_SUCCESS); - } - } else { - if (scan_setup_status_cback != NULL) { - scan_setup_status_cback(client_if, BTM_ILLEGAL_VALUE); - } - - BTM_TRACE_ERROR("Illegal params: scan_interval = %d scan_window = %d\n", - scan_interval, scan_window); - } - -} -#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) - #if (BLE_42_SCAN_EN == TRUE) tBTM_STATUS BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, UINT32 scan_window, tBLE_SCAN_MODE scan_mode, UINT8 addr_type_own, UINT8 scan_duplicate_filter, tBTM_BLE_SFP scan_filter_policy, 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 e68ec80b1c..54511558f6 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 @@ -2193,29 +2193,6 @@ void BTM_BleReadAdvParams (UINT16 *adv_int_min, UINT16 *adv_int_max, //extern void BTM_BleObtainVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb); -#if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) -/******************************************************************************* -** -** Function BTM_BleSetScanParams -** -** Description This function is called to set Scan parameters. -** -** Parameters client_if - Client IF value -** scan_interval - Scan interval -** scan_window - Scan window -** scan_type - Scan type -** scan_setup_status_cback - Scan setup status callback -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_BleSetScanParams(tGATT_IF client_if, UINT32 scan_interval, - UINT32 scan_window, tBLE_SCAN_MODE scan_type, - tBLE_SCAN_PARAM_SETUP_CBACK scan_setup_status_cback); - -#endif // #if (BLE_HOST_BLE_SCAN_PARAM_UNUSED == TRUE) - /******************************************************************************* ** ** Function BTM_BleSetScanFilterParams From d0117acc34101551eea12b9db79a14e0616c6e93 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:24 +0800 Subject: [PATCH 120/226] fix(ble/bluedroid): Delete BLE_HOST_STOP_ADV_UNUSED (cherry picked from commit 0e9b36cb559a8f20a3b98a8d75ebca2e84498b97) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 22 --------------- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 27 ------------------- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 3 --- .../bluedroid/bta/dm/include/bta_dm_int.h | 8 ------ .../host/bluedroid/bta/include/bta/bta_api.h | 3 --- .../common/include/common/bt_target.h | 4 --- 6 files changed, 67 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 867c3fb91d..4e41c74625 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -5346,28 +5346,6 @@ void bta_dm_ble_clear_rand_address(tBTA_DM_MSG *p_data) BTM_BleClearRandAddress(); } -#if (BLE_HOST_STOP_ADV_UNUSED == TRUE) -/******************************************************************************* -** -** Function bta_dm_ble_stop_advertising -** -** Description This function stop the BLE avdertising for the device. -** -** Parameters: void -** Explanation: This function added by Yulong at 2016/10/19 -*******************************************************************************/ -void bta_dm_ble_stop_advertising(tBTA_DM_MSG *p_data) -{ - if (p_data->hdr.event != BTA_DM_API_BLE_STOP_ADV_EVT) { - APPL_TRACE_ERROR("Invalid BTA event,can't stop the BLE adverting\n"); - } -#if (BLE_42_ADV_EN == TRUE) - btm_ble_stop_adv(); -#endif // #if (BLE_42_ADV_EN == TRUE) -} -#endif // #if (BLE_HOST_STOP_ADV_UNUSED == TRUE) - - #if BLE_PRIVACY_SPT == TRUE /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 1d9102129f..4396e0eaf8 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -2636,33 +2636,6 @@ extern void BTA_DmBleScan(BOOLEAN start, UINT32 duration, } #endif // #if (BLE_42_SCAN_EN == TRUE) -#if (BLE_HOST_STOP_ADV_UNUSED == TRUE) -/******************************************************************************* -** -** Function BTA_DmBleStopAdvertising -** -** Description This function set the random address for the APP -** -** Parameters void -** -** Returns void -** -** -*******************************************************************************/ -extern void BTA_DmBleStopAdvertising(void) -{ - BT_HDR *p_msg; - - APPL_TRACE_API("BTA_DmBleStopAdvertising\n"); - - if ((p_msg = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) { - memset(p_msg, 0, sizeof(BT_HDR)); - p_msg->event = BTA_DM_API_BLE_STOP_ADV_EVT; - bta_sys_sendmsg(p_msg); - } -} -#endif // #if (BLE_HOST_STOP_ADV_UNUSED == TRUE) - /******************************************************************************* ** ** Function BTA_DmSetRandAddress diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 7d3f183dd7..759d948d5b 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -161,9 +161,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { Yulong at 2016/10/19 to support stop the ble advertising setting by the APP */ -#if (BLE_HOST_STOP_ADV_UNUSED == TRUE) - bta_dm_ble_stop_advertising, /* BTA_DM_API_BLE_STOP_ADV_EVT */ -#endif // #if (BLE_HOST_STOP_ADV_UNUSED == TRUE) #if BLE_PRIVACY_SPT == TRUE bta_dm_ble_config_local_privacy, /* BTA_DM_API_LOCAL_PRIVACY_EVT */ #endif diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 8f80a2bc82..a673121a50 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -144,11 +144,6 @@ enum { support the random address setting for the APP******/ BTA_DM_API_SET_RAND_ADDR_EVT, BTA_DM_API_CLEAR_RAND_ADDR_EVT, - /*******This event added by Yulong at 2016/10/19 to - support stop the ble advertising setting by the APP******/ -#if (BLE_HOST_STOP_ADV_UNUSED == TRUE) - BTA_DM_API_BLE_STOP_ADV_EVT, -#endif // #if (BLE_HOST_STOP_ADV_UNUSED == TRUE) #if BLE_PRIVACY_SPT == TRUE BTA_DM_API_LOCAL_PRIVACY_EVT, #endif @@ -2394,9 +2389,6 @@ extern void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data); extern void bta_dm_ble_disconnect (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_rand_address(tBTA_DM_MSG *p_data); extern void bta_dm_ble_clear_rand_address(tBTA_DM_MSG *p_data); -#if (BLE_HOST_STOP_ADV_UNUSED == TRUE) -extern void bta_dm_ble_stop_advertising(tBTA_DM_MSG *p_data); -#endif // #if (BLE_HOST_STOP_ADV_UNUSED == TRUE) extern void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data); extern void bta_dm_ble_config_local_icon (tBTA_DM_MSG *p_data); #if (BT_GATTS_KEY_MATERIAL_CHAR == TRUE) diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 3a57b33709..7594df6a31 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -2865,9 +2865,6 @@ extern void BTA_DmBleScan(BOOLEAN start, UINT32 duration, tBTA_DM_SEARCH_CBACK *p_results_cb, tBTA_START_STOP_SCAN_CMPL_CBACK *p_start_stop_scan_cb); -#if (BLE_HOST_STOP_ADV_UNUSED == TRUE) -extern void BTA_DmBleStopAdvertising(void); -#endif // #if (BLE_HOST_STOP_ADV_UNUSED == TRUE) extern void BTA_DmSetRandAddress(BD_ADDR rand_addr, tBTA_SET_RAND_ADDR_CBACK *p_set_rand_addr_cback); extern void BTA_DmClearRandAddress(void); 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 d05f079194..d3d8a62555 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1641,10 +1641,6 @@ #define BLE_HOST_READ_TX_POWER_EN FALSE #endif -#ifndef BLE_HOST_STOP_ADV_UNUSED -#define BLE_HOST_STOP_ADV_UNUSED FALSE -#endif - #ifndef BLE_HOST_BLE_OBSERVE_EN #define BLE_HOST_BLE_OBSERVE_EN FALSE #endif From 88a2282f3a67f7187a6fb56de8e74d38b8240a4d Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:24 +0800 Subject: [PATCH 121/226] fix(ble/bluedroid): delete BLE_HOST_BLE_OBSERVE_EN (cherry picked from commit 08f9511e25a60c61c77cba92fc0c5454cfc037dd) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 42 ------------------- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 42 ------------------- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 3 -- .../bluedroid/bta/dm/include/bta_dm_int.h | 3 -- .../common/include/common/bt_target.h | 4 -- 5 files changed, 94 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 4e41c74625..55f44c0a1c 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -5391,48 +5391,6 @@ void bta_dm_ble_set_key_material (tBTA_DM_MSG *p_data) } #endif -#if (BLE_HOST_BLE_OBSERVE_EN == TRUE) -/******************************************************************************* -** -** Function bta_dm_ble_observe -** -** Description This function set the preferred connection scan parameters. -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_ble_observe (tBTA_DM_MSG *p_data) -{ - tBTM_STATUS status; - if (p_data->ble_observe.start) { - /*Save the callback to be called when a scan results are available */ - bta_dm_search_cb.p_scan_cback = p_data->ble_observe.p_cback; - - if ((status = BTM_BleObserve(TRUE, p_data->ble_observe.duration, - bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb)) != BTM_CMD_STARTED) { - APPL_TRACE_WARNING(" %s start observe failed. status=0x%x\n", __FUNCTION__, status); - } - - if (p_data->ble_observe.p_start_scan_cback) { - status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE); - p_data->ble_observe.p_start_scan_cback(status); - } - } else { - bta_dm_search_cb.p_scan_cback = NULL; - status = BTM_BleObserve(FALSE, 0, NULL, NULL); - - if (status != BTM_CMD_STARTED){ - APPL_TRACE_WARNING(" %s stop observe failed, status=0x%x\n", __FUNCTION__, status); - } - - if (p_data->ble_observe.p_stop_scan_cback) { - status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE); - p_data->ble_observe.p_stop_scan_cback(status); - } - } -} -#endif // #if (BLE_HOST_BLE_OBSERVE_EN == TRUE) - /******************************************************************************* ** ** Function bta_dm_ble_scan diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 4396e0eaf8..beba7cacfa 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -2550,48 +2550,6 @@ void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev, tBTA_TRANSPORT transpor #endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) #if BLE_INCLUDED == TRUE -#if (BLE_HOST_BLE_OBSERVE_EN == TRUE) -/******************************************************************************* -** -** Function BTA_DmBleObserve -** -** Description This procedure keep the device listening for advertising -** events from a broadcast device. -** -** Parameters start: start or stop observe. -** -** Returns void - -** -** Returns void. -** -*******************************************************************************/ -extern void BTA_DmBleObserve(BOOLEAN start, UINT32 duration, - tBTA_DM_SEARCH_CBACK *p_results_cb, - tBTA_START_STOP_SCAN_CMPL_CBACK *p_start_stop_scan_cb) -{ - tBTA_DM_API_BLE_OBSERVE *p_msg; - - APPL_TRACE_API("BTA_DmBleObserve:start = %d ", start); - - if ((p_msg = (tBTA_DM_API_BLE_OBSERVE *) osi_malloc(sizeof(tBTA_DM_API_BLE_OBSERVE))) != NULL) { - memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_OBSERVE)); - - p_msg->hdr.event = BTA_DM_API_BLE_OBSERVE_EVT; - p_msg->start = start; - p_msg->duration = duration; - p_msg->p_cback = p_results_cb; - if (start){ - p_msg->p_start_scan_cback = p_start_stop_scan_cb; - } - else { - p_msg->p_stop_scan_cback = p_start_stop_scan_cb; - } - - bta_sys_sendmsg(p_msg); - } -} -#endif // #if (BLE_HOST_BLE_OBSERVE_EN == TRUE) #if (BLE_42_SCAN_EN == TRUE) /******************************************************************************* diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 759d948d5b..6c268432f2 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -145,9 +145,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { #if (BLE_42_SCAN_EN == TRUE) bta_dm_ble_set_scan_fil_params, /* BTA_DM_API_BLE_SCAN_FIL_PARAM_EVT */ #endif // #if (BLE_42_SCAN_EN == TRUE) -#if (BLE_HOST_BLE_OBSERVE_EN == TRUE) - bta_dm_ble_observe, /* BTA_DM_API_BLE_OBSERVE_EVT */ -#endif // #if (BLE_HOST_BLE_OBSERVE_EN == TRUE) #if (BLE_42_SCAN_EN == TRUE) bta_dm_ble_scan, /* BTA_DM_API_BLE_SCAN_EVT */ #endif // #if (BLE_42_SCAN_EN == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index a673121a50..d9ac819965 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -133,9 +133,6 @@ enum { #if (BLE_42_SCAN_EN == TRUE) BTA_DM_API_BLE_SCAN_FIL_PARAM_EVT, #endif // #if (BLE_42_SCAN_EN == TRUE) -#if (BLE_HOST_BLE_OBSERVE_EN == TRUE) - BTA_DM_API_BLE_OBSERVE_EVT, -#endif // #if (BLE_HOST_BLE_OBSERVE_EN == TRUE) #if (BLE_42_SCAN_EN == TRUE) BTA_DM_API_BLE_SCAN_EVT, #endif // #if (BLE_42_SCAN_EN == TRUE) 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 d3d8a62555..ec50f78ca0 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1641,10 +1641,6 @@ #define BLE_HOST_READ_TX_POWER_EN FALSE #endif -#ifndef BLE_HOST_BLE_OBSERVE_EN -#define BLE_HOST_BLE_OBSERVE_EN FALSE -#endif - #ifndef BLE_HOST_SETUP_STORAGE_EN #define BLE_HOST_SETUP_STORAGE_EN FALSE #endif From 94055319c863c175452c0072012d0aa2373cbc7d Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:25 +0800 Subject: [PATCH 122/226] fix(ble/bluedroid): Delete BLE_ANDROID_CONTROLLER_SCAN_FILTER (cherry picked from commit 702292d451dfe403625f1aeee9198a59bcb55181) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 136 -- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 220 --- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 5 - .../bluedroid/bta/dm/include/bta_dm_int.h | 44 - .../host/bluedroid/bta/include/bta/bta_api.h | 148 -- .../common/include/common/bt_target.h | 4 - .../bluedroid/stack/btm/btm_ble_adv_filter.c | 1281 ----------------- .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 4 +- 8 files changed, 1 insertion(+), 1841 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 55f44c0a1c..348da66043 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6353,142 +6353,6 @@ void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_v } } - -#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE -/******************************************************************************* -** -** Function bta_ble_scan_pf_cmpl -** -** Description ADV payload filtering operation complete callback -** -** -** Returns TRUE if handled, otherwise FALSE. -** -*******************************************************************************/ -static void bta_ble_scan_cfg_cmpl(tBTM_BLE_PF_ACTION action, tBTM_BLE_SCAN_COND_OP cfg_op, - tBTM_BLE_PF_AVBL_SPACE avbl_space, tBTM_STATUS status, - tBTM_BLE_REF_VALUE ref_value) -{ - tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE; - - APPL_TRACE_DEBUG("bta_ble_scan_cfg_cmpl: %d, %d, %d, %d", action, cfg_op, avbl_space, status); - - if (bta_dm_cb.p_scan_filt_cfg_cback) { - bta_dm_cb.p_scan_filt_cfg_cback(action, cfg_op, avbl_space, st, ref_value); - } -} - -/******************************************************************************* -** -** Function bta_dm_cfg_filter_cond -** -** Description This function configure adv payload filtering condition -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data) -{ - tBTM_STATUS st = BTM_MODE_UNSUPPORTED; - tBTA_STATUS status = BTA_FAILURE; - - tBTM_BLE_VSC_CB cmn_vsc_cb; - - APPL_TRACE_DEBUG("bta_dm_cfg_filter_cond"); - BTM_BleGetVendorCapabilities(&cmn_vsc_cb); - if (0 != cmn_vsc_cb.filter_support) { - if ((st = BTM_BleCfgFilterCondition(p_data->ble_cfg_filter_cond.action, - p_data->ble_cfg_filter_cond.cond_type, - (tBTM_BLE_PF_FILT_INDEX)p_data->ble_cfg_filter_cond.filt_index, - (tBTM_BLE_PF_COND_PARAM *)p_data->ble_cfg_filter_cond.p_cond_param, - bta_ble_scan_cfg_cmpl, p_data->ble_cfg_filter_cond.ref_value)) - == BTM_CMD_STARTED) { - bta_dm_cb.p_scan_filt_cfg_cback = p_data->ble_cfg_filter_cond.p_filt_cfg_cback; - return; - } - } - - if (p_data->ble_cfg_filter_cond.p_filt_cfg_cback) { - p_data->ble_cfg_filter_cond.p_filt_cfg_cback(BTA_DM_BLE_PF_CONFIG_EVT, - p_data->ble_cfg_filter_cond.cond_type, 0, status, - p_data->ble_cfg_filter_cond.ref_value); - } - return; -} - -/******************************************************************************* -** -** Function bta_dm_enable_scan_filter -** -** Description This function enable/disable adv payload filtering condition -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data) -{ - tBTM_STATUS st = BTM_MODE_UNSUPPORTED; - tBTA_STATUS status = BTA_FAILURE; - - tBTM_BLE_VSC_CB cmn_vsc_cb; - APPL_TRACE_DEBUG("bta_dm_enable_scan_filter"); - BTM_BleGetVendorCapabilities(&cmn_vsc_cb); - - if (0 != cmn_vsc_cb.filter_support) { - if ((st = BTM_BleEnableDisableFilterFeature(p_data->ble_enable_scan_filt.action, - p_data->ble_enable_scan_filt.p_filt_status_cback, - (tBTM_BLE_REF_VALUE)p_data->ble_enable_scan_filt.ref_value)) == BTM_CMD_STARTED) { - bta_dm_cb.p_scan_filt_status_cback = p_data->ble_enable_scan_filt.p_filt_status_cback; - } - return; - } - - if (p_data->ble_enable_scan_filt.p_filt_status_cback) { - p_data->ble_enable_scan_filt.p_filt_status_cback (BTA_DM_BLE_PF_ENABLE_EVT, - p_data->ble_enable_scan_filt.ref_value, status); - } - -} - -/******************************************************************************* -** -** Function bta_dm_scan_filter_param_setup -** -** Description This function sets up scan filter params -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data) -{ - tBTM_STATUS st = BTM_MODE_UNSUPPORTED; - tBTA_STATUS status = BTA_FAILURE; - - tBTM_BLE_VSC_CB cmn_vsc_cb; - - APPL_TRACE_DEBUG("bta_dm_scan_filter_param_setup"); - BTM_BleGetVendorCapabilities(&cmn_vsc_cb); - if (0 != cmn_vsc_cb.filter_support) { - if ((st = BTM_BleAdvFilterParamSetup(p_data->ble_scan_filt_param_setup.action, - p_data->ble_scan_filt_param_setup.filt_index, - (tBTM_BLE_PF_FILT_PARAMS *)&p_data->ble_scan_filt_param_setup.filt_params, - p_data->ble_scan_filt_param_setup.p_target, - p_data->ble_scan_filt_param_setup.p_filt_param_cback, - p_data->ble_scan_filt_param_setup.ref_value)) == BTM_CMD_STARTED) { - bta_dm_cb.p_scan_filt_param_cback = p_data->ble_scan_filt_param_setup.p_filt_param_cback; - return; - } - } - - if (p_data->ble_scan_filt_param_setup.p_filt_param_cback) { - p_data->ble_scan_filt_param_setup.p_filt_param_cback (BTA_DM_BLE_PF_ENABLE_EVT, 0, - p_data->ble_scan_filt_param_setup.ref_value, status); - } - - return; -} -#endif - #if (BLE_HOST_ENERGY_INFO_EN == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index beba7cacfa..20f1ad773d 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -2078,187 +2078,6 @@ void BTA_DmBleSetKeyMaterial(const uint8_t *session_key, const uint8_t *iv) } #endif -/******************************************************************************* -** -** Function BTA_DmBleCfgFilterCondition -** -** Description This function is called to configure the adv data payload filter -** condition. -** -** Parameters action: to read/write/clear -** cond_type: filter condition type -** filt_index - Filter index -** p_cond: filter condition parameter -** p_cmpl_back - Command completed callback -** ref_value - Reference value -** -** Returns void -** -*******************************************************************************/ -void BTA_DmBleCfgFilterCondition(tBTA_DM_BLE_SCAN_COND_OP action, - tBTA_DM_BLE_PF_COND_TYPE cond_type, - tBTA_DM_BLE_PF_FILT_INDEX filt_index, - tBTA_DM_BLE_PF_COND_PARAM *p_cond, - tBTA_DM_BLE_PF_CFG_CBACK *p_cmpl_cback, - tBTA_DM_BLE_REF_VALUE ref_value) -{ -#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE - tBTA_DM_API_CFG_FILTER_COND *p_msg; - APPL_TRACE_API ("BTA_DmBleCfgFilterCondition: %d, %d", action, cond_type); - - UINT16 len = sizeof(tBTA_DM_API_CFG_FILTER_COND) + - sizeof(tBTA_DM_BLE_PF_COND_PARAM); - UINT8 *p; - - if (NULL != p_cond) { - switch (cond_type) { - case BTA_DM_BLE_PF_SRVC_DATA_PATTERN: - case BTA_DM_BLE_PF_MANU_DATA: - /* Length of pattern and pattern mask and other elements in */ - /* tBTA_DM_BLE_PF_MANU_COND */ - len += ((p_cond->manu_data.data_len) * 2) + - sizeof(UINT16) + sizeof(UINT16) + sizeof(UINT8); - break; - - case BTA_DM_BLE_PF_LOCAL_NAME: - len += ((p_cond->local_name.data_len) + sizeof(UINT8)); - break; - - case BTM_BLE_PF_SRVC_UUID: - case BTM_BLE_PF_SRVC_SOL_UUID: - len += sizeof(tBLE_BD_ADDR) + sizeof(tBTA_DM_BLE_PF_COND_MASK); - break; - - default: - break; - } - } - - if ((p_msg = (tBTA_DM_API_CFG_FILTER_COND *) osi_malloc(len)) != NULL) { - memset (p_msg, 0, len); - - p_msg->hdr.event = BTA_DM_API_CFG_FILTER_COND_EVT; - p_msg->action = action; - p_msg->cond_type = cond_type; - p_msg->filt_index = filt_index; - p_msg->p_filt_cfg_cback = p_cmpl_cback; - p_msg->ref_value = ref_value; - if (p_cond) { - p_msg->p_cond_param = (tBTA_DM_BLE_PF_COND_PARAM *)(p_msg + 1); - memcpy(p_msg->p_cond_param, p_cond, sizeof(tBTA_DM_BLE_PF_COND_PARAM)); - - p = (UINT8 *)(p_msg->p_cond_param + 1); - - if (cond_type == BTA_DM_BLE_PF_SRVC_DATA_PATTERN || - cond_type == BTA_DM_BLE_PF_MANU_DATA) { - p_msg->p_cond_param->manu_data.p_pattern = p; - p_msg->p_cond_param->manu_data.data_len = p_cond->manu_data.data_len; - memcpy(p_msg->p_cond_param->manu_data.p_pattern, p_cond->manu_data.p_pattern, - p_cond->manu_data.data_len); - p += p_cond->manu_data.data_len; - - if (cond_type == BTA_DM_BLE_PF_MANU_DATA) { - p_msg->p_cond_param->manu_data.company_id_mask = - p_cond->manu_data.company_id_mask; - if ( p_cond->manu_data.p_pattern_mask != NULL) { - p_msg->p_cond_param->manu_data.p_pattern_mask = p; - memcpy(p_msg->p_cond_param->manu_data.p_pattern_mask, - p_cond->manu_data.p_pattern_mask, p_cond->manu_data.data_len); - } - } - } else if (cond_type == BTA_DM_BLE_PF_LOCAL_NAME) { - p_msg->p_cond_param->local_name.p_data = p; - p_msg->p_cond_param->local_name.data_len = - p_cond->local_name.data_len; - memcpy(p_msg->p_cond_param->local_name.p_data, - p_cond->local_name.p_data, p_cond->local_name.data_len); - } else if ((cond_type == BTM_BLE_PF_SRVC_UUID - || cond_type == BTM_BLE_PF_SRVC_SOL_UUID)) { - if (p_cond->srvc_uuid.p_target_addr != NULL) { - p_msg->p_cond_param->srvc_uuid.p_target_addr = (tBLE_BD_ADDR *)(p); - p_msg->p_cond_param->srvc_uuid.p_target_addr->type = - p_cond->srvc_uuid.p_target_addr->type; - memcpy(p_msg->p_cond_param->srvc_uuid.p_target_addr->bda, - p_cond->srvc_uuid.p_target_addr->bda, BD_ADDR_LEN); - p = (UINT8 *)( p_msg->p_cond_param->srvc_uuid.p_target_addr + 1); - } - if (p_cond->srvc_uuid.p_uuid_mask) { - p_msg->p_cond_param->srvc_uuid.p_uuid_mask = (tBTA_DM_BLE_PF_COND_MASK *)p; - memcpy(p_msg->p_cond_param->srvc_uuid.p_uuid_mask, - p_cond->srvc_uuid.p_uuid_mask, sizeof(tBTA_DM_BLE_PF_COND_MASK)); - } - } - } - - bta_sys_sendmsg(p_msg); - } -#else - UNUSED(action); - UNUSED(cond_type); - UNUSED(filt_index); - UNUSED(p_cond); - UNUSED(p_cmpl_cback); - UNUSED(ref_value); -#endif -} - -/******************************************************************************* -** -** Function BTA_DmBleScanFilterSetup -** -** Description This function is called to setup the adv data payload filter param -** -** Parameters p_target: enable the filter condition on a target device; if NULL -** filt_index - Filter index -** p_filt_params -Filter parameters -** ref_value - Reference value -** action - Add, delete or clear -** p_cmpl_back - Command completed callback -** -** Returns void -** -*******************************************************************************/ -void BTA_DmBleScanFilterSetup(UINT8 action, tBTA_DM_BLE_PF_FILT_INDEX filt_index, - tBTA_DM_BLE_PF_FILT_PARAMS *p_filt_params, - tBLE_BD_ADDR *p_target, - tBTA_DM_BLE_PF_PARAM_CBACK *p_cmpl_cback, - tBTA_DM_BLE_REF_VALUE ref_value) -{ -#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE - tBTA_DM_API_SCAN_FILTER_PARAM_SETUP *p_msg; - APPL_TRACE_API ("BTA_DmBleScanFilterSetup: %d", action); - - UINT16 len = sizeof(tBTA_DM_API_SCAN_FILTER_PARAM_SETUP) + sizeof(tBLE_BD_ADDR); - - if ((p_msg = (tBTA_DM_API_SCAN_FILTER_PARAM_SETUP *) osi_malloc(len)) != NULL) { - memset (p_msg, 0, len); - - p_msg->hdr.event = BTA_DM_API_SCAN_FILTER_SETUP_EVT; - p_msg->action = action; - p_msg->filt_index = filt_index; - if (p_filt_params) { - memcpy(&p_msg->filt_params, p_filt_params, sizeof(tBTA_DM_BLE_PF_FILT_PARAMS)); - } - p_msg->p_filt_param_cback = p_cmpl_cback; - p_msg->ref_value = ref_value; - - if (p_target) { - p_msg->p_target = (tBLE_BD_ADDR *)(p_msg + 1); - memcpy(p_msg->p_target, p_target, sizeof(tBLE_BD_ADDR)); - } - - bta_sys_sendmsg(p_msg); - } -#else - UNUSED(action); - UNUSED(filt_index); - UNUSED(p_filt_params); - UNUSED(p_target); - UNUSED(p_cmpl_cback); - UNUSED(ref_value); -#endif -} - #if (BLE_HOST_ENERGY_INFO_EN == TRUE) /******************************************************************************* ** @@ -2287,45 +2106,6 @@ void BTA_DmBleGetEnergyInfo(tBTA_BLE_ENERGY_INFO_CBACK *p_cmpl_cback) } #endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) -/******************************************************************************* -** -** Function BTA_DmEnableScanFilter -** -** Description This function is called to enable the adv data payload filter -** -** Parameters action - enable or disable the APCF feature -** p_cmpl_cback - Command completed callback -** ref_value - Reference value -** -** Returns void -** -*******************************************************************************/ -void BTA_DmEnableScanFilter(UINT8 action, tBTA_DM_BLE_PF_STATUS_CBACK *p_cmpl_cback, - tBTA_DM_BLE_REF_VALUE ref_value) -{ -#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE - tBTA_DM_API_ENABLE_SCAN_FILTER *p_msg; - APPL_TRACE_API ("BTA_DmEnableScanFilter: %d\n", action); - - UINT16 len = sizeof(tBTA_DM_API_ENABLE_SCAN_FILTER) + sizeof(tBLE_BD_ADDR); - - if ((p_msg = (tBTA_DM_API_ENABLE_SCAN_FILTER *) osi_malloc(len)) != NULL) { - memset (p_msg, 0, len); - - p_msg->hdr.event = BTA_DM_API_SCAN_FILTER_ENABLE_EVT; - p_msg->action = action; - p_msg->ref_value = ref_value; - p_msg->p_filt_status_cback = p_cmpl_cback; - - bta_sys_sendmsg(p_msg); - } -#else - UNUSED(action); - UNUSED(p_cmpl_cback); - UNUSED(ref_value); -#endif -} - /******************************************************************************* ** ** Function BTA_DmBleUpdateConnectionParams diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 6c268432f2..16485d606d 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -178,11 +178,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_broadcast, /* BTA_DM_API_BLE_BROADCAST_EVT */ #endif // #if (BLE_42_ADV_EN == TRUE) bta_dm_ble_set_data_length, /* BTA_DM_API_SET_DATA_LENGTH_EVT */ -#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE - bta_dm_cfg_filter_cond, /* BTA_DM_API_CFG_FILTER_COND_EVT */ - bta_dm_scan_filter_param_setup, /* BTA_DM_API_SCAN_FILTER_SETUP_EVT */ - bta_dm_enable_scan_filter, /* BTA_DM_API_SCAN_FILTER_ENABLE_EVT */ -#endif #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) bta_dm_ble_setup_storage, /* BTA_DM_API_BLE_SETUP_STORAGE_EVT */ #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index d9ac819965..30659dcd39 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -162,11 +162,6 @@ enum { BTA_DM_API_BLE_BROADCAST_EVT, #endif // #if (BLE_42_ADV_EN == TRUE) BTA_DM_API_SET_DATA_LENGTH_EVT, -#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE - BTA_DM_API_CFG_FILTER_COND_EVT, - BTA_DM_API_SCAN_FILTER_SETUP_EVT, - BTA_DM_API_SCAN_FILTER_ENABLE_EVT, -#endif #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) BTA_DM_API_BLE_SETUP_STORAGE_EVT, #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) @@ -1278,35 +1273,6 @@ typedef struct { UINT16 timeout; } tBTA_DM_API_UPDATE_CONN_PARAM; -#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE -typedef struct { - BT_HDR hdr; - tBTA_DM_BLE_SCAN_COND_OP action; - tBTA_DM_BLE_PF_COND_TYPE cond_type; - tBTA_DM_BLE_PF_FILT_INDEX filt_index; - tBTA_DM_BLE_PF_COND_PARAM *p_cond_param; - tBTA_DM_BLE_PF_CFG_CBACK *p_filt_cfg_cback; - tBTA_DM_BLE_REF_VALUE ref_value; -} tBTA_DM_API_CFG_FILTER_COND; - -typedef struct { - BT_HDR hdr; - UINT8 action; - tBTA_DM_BLE_PF_STATUS_CBACK *p_filt_status_cback; - tBTA_DM_BLE_REF_VALUE ref_value; -} tBTA_DM_API_ENABLE_SCAN_FILTER; - -typedef struct { - BT_HDR hdr; - UINT8 action; - tBTA_DM_BLE_PF_FILT_INDEX filt_index; - tBTA_DM_BLE_PF_FILT_PARAMS filt_params; - tBLE_BD_ADDR *p_target; - tBTA_DM_BLE_PF_PARAM_CBACK *p_filt_param_cback; - tBTA_DM_BLE_REF_VALUE ref_value; -} tBTA_DM_API_SCAN_FILTER_PARAM_SETUP; -#endif - #if (BLE_50_DTM_TEST_EN == TRUE) typedef struct { BT_HDR hdr; @@ -1811,11 +1777,6 @@ typedef union { tBTA_DM_API_BLE_ADV_PARAMS_ALL ble_set_adv_params_all; tBTA_DM_API_SET_ADV_CONFIG ble_set_adv_data; tBTA_DM_API_SET_ADV_CONFIG_RAW ble_set_adv_data_raw; -#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE - tBTA_DM_API_SCAN_FILTER_PARAM_SETUP ble_scan_filt_param_setup; - tBTA_DM_API_CFG_FILTER_COND ble_cfg_filter_cond; - tBTA_DM_API_ENABLE_SCAN_FILTER ble_enable_scan_filt; -#endif tBTA_DM_API_UPDATE_CONN_PARAM ble_update_conn_params; tBTA_DM_API_BLE_SET_DATA_LENGTH ble_set_data_length; tBTA_DM_APT_SET_DEV_ADDR set_addr; @@ -2402,11 +2363,6 @@ extern void bta_dm_ble_update_duplicate_exceptional_list(tBTA_DM_MSG *p_data); #if SMP_INCLUDED == TRUE extern void bta_dm_co_security_param_init(void); #endif -#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE -extern void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data); -extern void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data); -extern void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data); -#endif extern void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data); extern void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data); extern void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data); diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 7594df6a31..3627a42205 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -573,7 +573,6 @@ enum { BTA_DM_BLE_SCAN_COND_DELETE, BTA_DM_BLE_SCAN_COND_CLEAR = 2 }; -typedef UINT8 tBTA_DM_BLE_SCAN_COND_OP; /* ADV payload filtering vendor specific call event */ enum { @@ -581,18 +580,6 @@ enum { BTA_BLE_SCAN_PF_COND_EVT }; -/* filter selection bit index */ -#define BTA_DM_BLE_PF_ADDR_FILTER BTM_BLE_PF_ADDR_FILTER -#define BTA_DM_BLE_PF_SRVC_DATA BTM_BLE_PF_SRVC_DATA -#define BTA_DM_BLE_PF_SRVC_UUID BTM_BLE_PF_SRVC_UUID -#define BTA_DM_BLE_PF_SRVC_SOL_UUID BTM_BLE_PF_SRVC_SOL_UUID -#define BTA_DM_BLE_PF_LOCAL_NAME BTM_BLE_PF_LOCAL_NAME -#define BTA_DM_BLE_PF_MANU_DATA BTM_BLE_PF_MANU_DATA -#define BTA_DM_BLE_PF_SRVC_DATA_PATTERN BTM_BLE_PF_SRVC_DATA_PATTERN -#define BTA_DM_BLE_PF_TYPE_ALL BTM_BLE_PF_TYPE_ALL -#define BTA_DM_BLE_PF_TYPE_MAX BTM_BLE_PF_TYPE_MAX -typedef UINT8 tBTA_DM_BLE_PF_COND_TYPE; - typedef union { UINT16 uuid16_mask; UINT32 uuid32_mask; @@ -628,18 +615,6 @@ typedef struct { as data pattern, set to all 0xff, match exact data */ } tBTA_DM_BLE_PF_SRVC_PATTERN_COND; -typedef union { - tBLE_BD_ADDR target_addr; - tBTA_DM_BLE_PF_LOCAL_NAME_COND local_name; /* local name filtering */ - tBTA_DM_BLE_PF_MANU_COND manu_data; /* manufacturer data filtering */ - tBTA_DM_BLE_PF_UUID_COND srvc_uuid; /* service UUID filtering */ - tBTA_DM_BLE_PF_UUID_COND solicitate_uuid; /* solicited service UUID filtering */ - tBTA_DM_BLE_PF_SRVC_PATTERN_COND srvc_data; /* service data pattern */ -} tBTA_DM_BLE_PF_COND_PARAM; - -typedef UINT8 tBTA_DM_BLE_PF_FILT_INDEX; -typedef UINT8 tBTA_DM_BLE_PF_AVBL_SPACE; - typedef INT8 tBTA_DM_RSSI_VALUE; typedef UINT8 tBTA_DM_LINK_QUALITY_VALUE; @@ -1049,64 +1024,6 @@ typedef void (tBTA_DM_SEC_CBACK)(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data); typedef UINT32 tBTA_DM_BLE_REF_VALUE; -#define BTA_DM_BLE_PF_ENABLE_EVT BTM_BLE_PF_ENABLE -#define BTA_DM_BLE_PF_CONFIG_EVT BTM_BLE_PF_CONFIG -typedef UINT8 tBTA_DM_BLE_PF_EVT; - -#define BTA_DM_BLE_PF_ENABLE 1 -#define BTA_DM_BLE_PF_CONFIG 2 -typedef UINT8 tBTA_DM_BLE_PF_ACTION; - -/* Config callback */ -typedef void (tBTA_DM_BLE_PF_CFG_CBACK) (tBTA_DM_BLE_PF_ACTION action, - tBTA_DM_BLE_PF_COND_TYPE cfg_cond, - tBTA_DM_BLE_PF_AVBL_SPACE avbl_space, tBTA_STATUS status, - tBTA_DM_BLE_REF_VALUE ref_value); -/* Param callback */ -typedef void (tBTA_DM_BLE_PF_PARAM_CBACK) (UINT8 action_type, tBTA_DM_BLE_PF_AVBL_SPACE avbl_space, - tBTA_DM_BLE_REF_VALUE ref_value, tBTA_STATUS status); - -/* Status callback */ -typedef void (tBTA_DM_BLE_PF_STATUS_CBACK) (UINT8 action, tBTA_STATUS status, - tBTA_DM_BLE_REF_VALUE ref_value); - - -#define BTA_DM_BLE_PF_BRDCAST_ADDR_FILT 1 -#define BTA_DM_BLE_PF_SERV_DATA_CHG_FILT 2 -#define BTA_DM_BLE_PF_SERV_UUID 4 -#define BTA_DM_BLE_PF_SERV_SOLC_UUID 8 -#define BTA_DM_BLE_PF_LOC_NAME_CHECK 16 -#define BTA_DM_BLE_PF_MANUF_NAME_CHECK 32 -#define BTA_DM_BLE_PF_SERV_DATA_CHECK 64 -typedef UINT16 tBTA_DM_BLE_PF_FEAT_SEL; - -#define BTA_DM_BLE_PF_LIST_LOGIC_OR 1 -#define BTA_DM_BLE_PF_LIST_LOGIC_AND 2 -typedef UINT16 tBTA_DM_BLE_PF_LIST_LOGIC_TYPE; - -#define BTA_DM_BLE_PF_FILT_LOGIC_OR 0 -#define BTA_DM_BLE_PF_FILT_LOGIC_AND 1 -typedef UINT16 tBTA_DM_BLE_PF_FILT_LOGIC_TYPE; - -typedef UINT8 tBTA_DM_BLE_PF_RSSI_THRESHOLD; -typedef UINT8 tBTA_DM_BLE_PF_DELIVERY_MODE; -typedef UINT16 tBTA_DM_BLE_PF_TIMEOUT; -typedef UINT8 tBTA_DM_BLE_PF_TIMEOUT_CNT; -typedef UINT16 tBTA_DM_BLE_PF_ADV_TRACK_ENTRIES; - -typedef struct { - tBTA_DM_BLE_PF_FEAT_SEL feat_seln; - tBTA_DM_BLE_PF_LIST_LOGIC_TYPE list_logic_type; - tBTA_DM_BLE_PF_FILT_LOGIC_TYPE filt_logic_type; - tBTA_DM_BLE_PF_RSSI_THRESHOLD rssi_high_thres; - tBTA_DM_BLE_PF_RSSI_THRESHOLD rssi_low_thres; - tBTA_DM_BLE_PF_DELIVERY_MODE dely_mode; - tBTA_DM_BLE_PF_TIMEOUT found_timeout; - tBTA_DM_BLE_PF_TIMEOUT lost_timeout; - tBTA_DM_BLE_PF_TIMEOUT_CNT found_timeout_cnt; - tBTA_DM_BLE_PF_ADV_TRACK_ENTRIES num_of_tracking_entries; -} tBTA_DM_BLE_PF_FILT_PARAMS; - /* Search callback events */ #define BTA_DM_INQ_RES_EVT 0 /* Inquiry result for a peer device. */ #define BTA_DM_INQ_CMPL_EVT 1 /* Inquiry complete. */ @@ -3211,71 +3128,6 @@ extern void BTA_DmBleReadScanReports(tBTA_BLE_BATCH_SCAN_MODE scan_type, *******************************************************************************/ extern void BTA_DmBleDisableBatchScan(tBTA_DM_BLE_REF_VALUE ref_value); -/******************************************************************************* -** -** Function BTA_DmEnableScanFilter -** -** Description This function is called to enable the adv data payload filter -** -** Parameters action - enable or disable the APCF feature -** p_cmpl_cback - Command completed callback -** ref_value - Reference value -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmEnableScanFilter(UINT8 action, - tBTA_DM_BLE_PF_STATUS_CBACK *p_cmpl_cback, - tBTA_DM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTA_DmBleScanFilterSetup -** -** Description This function is called to setup the filter params -** -** Parameters p_target: enable the filter condition on a target device; if NULL -** filt_index - Filter index -** p_filt_params -Filter parameters -** ref_value - Reference value -** action - Add, delete or clear -** p_cmpl_back - Command completed callback -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleScanFilterSetup(UINT8 action, - tBTA_DM_BLE_PF_FILT_INDEX filt_index, - tBTA_DM_BLE_PF_FILT_PARAMS *p_filt_params, - tBLE_BD_ADDR *p_target, - tBTA_DM_BLE_PF_PARAM_CBACK *p_cmpl_cback, - tBTA_DM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTA_DmBleCfgFilterCondition -** -** Description This function is called to configure the adv data payload filter -** condition. -** -** Parameters action: to read/write/clear -** cond_type: filter condition type -** filt_index - Filter index -** p_cond: filter condition parameter -** p_cmpl_back - Command completed callback -** ref_value - Reference value -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleCfgFilterCondition(tBTA_DM_BLE_SCAN_COND_OP action, - tBTA_DM_BLE_PF_COND_TYPE cond_type, - tBTA_DM_BLE_PF_FILT_INDEX filt_index, - tBTA_DM_BLE_PF_COND_PARAM *p_cond, - tBTA_DM_BLE_PF_CFG_CBACK *p_cmpl_cback, - tBTA_DM_BLE_REF_VALUE ref_value); - - #if (BLE_HOST_ENERGY_INFO_EN == TRUE) /******************************************************************************* ** 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 ec50f78ca0..61dbe2e0e5 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1612,10 +1612,6 @@ #define BLE_INCLUDED FALSE #endif -#ifndef BLE_ANDROID_CONTROLLER_SCAN_FILTER -#define BLE_ANDROID_CONTROLLER_SCAN_FILTER FALSE -#endif - #ifndef BLE_HOST_ENERGY_INFO_EN #define BLE_HOST_ENERGY_INFO_EN FALSE #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c b/components/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c index 7eef55e912..8f00b9d690 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c @@ -22,1286 +22,5 @@ #include "common/bt_target.h" #if (BLE_INCLUDED == TRUE) -#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE -#include "stack/bt_types.h" -#include "stack/hcimsgs.h" -#include "stack/btu.h" -#include "btm_int.h" -#include "osi/allocator.h" -#include "stack/hcidefs.h" -#include "stack/btm_ble_api.h" -#include "device/controller.h" -#define BTM_BLE_ADV_FILT_META_HDR_LENGTH 3 -#define BTM_BLE_ADV_FILT_FEAT_SELN_LEN 13 -#define BTM_BLE_ADV_FILT_TRACK_NUM 2 - -#define BTM_BLE_PF_SELECT_NONE 0 - -/* BLE meta vsc header: 1 bytes of sub_code, 1 byte of PCF action */ -#define BTM_BLE_META_HDR_LENGTH 3 -#define BTM_BLE_PF_FEAT_SEL_LEN 18 -#define BTM_BLE_PCF_ENABLE_LEN 2 - -#define BTM_BLE_META_ADDR_LEN 7 -#define BTM_BLE_META_UUID_LEN 40 - -#define BTM_BLE_PF_BIT_TO_MASK(x) (UINT16)(1 << (x)) - - -#if BTM_DYNAMIC_MEMORY == FALSE -tBTM_BLE_ADV_FILTER_CB btm_ble_adv_filt_cb; -tBTM_BLE_VSC_CB cmn_ble_adv_vsc_cb; -#else -tBTM_BLE_ADV_FILTER_CB *btm_ble_adv_filt_cb_ptr; -tBTM_BLE_VSC_CB *cmn_ble_adv_vsc_cb_ptr; -#define btm_ble_adv_filt_cb (*btm_ble_adv_filt_cb_ptr) -#define cmn_ble_adv_vsc_cb (*cmn_ble_adv_vsc_cb_ptr) -#endif - -static const BD_ADDR na_bda = {0}; - -static UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action, - UINT8 cond_type, tBLE_BD_ADDR *p_bd_addr, UINT8 num_available); - -#define BTM_BLE_SET_SCAN_PF_OPCODE(x, y) (((x)<<4)|y) -#define BTM_BLE_GET_SCAN_PF_SUBCODE(x) ((x) >> 4) -#define BTM_BLE_GET_SCAN_PF_ACTION(x) ((x) & 0x0f) -#define BTM_BLE_INVALID_COUNTER 0xff - - -/* length of each multi adv sub command */ -#define BTM_BLE_ADV_FILTER_ENB_LEN 3 - -/* length of each batch scan command */ -#define BTM_BLE_ADV_FILTER_CLEAR_LEN 3 -#define BTM_BLE_ADV_FILTER_LEN 2 - -#define BTM_BLE_ADV_FILT_CB_EVT_MASK 0xF0 -#define BTM_BLE_ADV_FILT_SUBCODE_MASK 0x0F - -/******************************************************************************* -** -** Function btm_ble_obtain_vsc_details -** -** Description This function obtains the VSC details -** -** Parameters -** -** Returns status -** -*******************************************************************************/ -tBTM_STATUS btm_ble_obtain_vsc_details(void) -{ - tBTM_STATUS st = BTM_SUCCESS; - -#if BLE_VND_INCLUDED == TRUE - BTM_BleGetVendorCapabilities(&cmn_ble_adv_vsc_cb); - if (0 == cmn_ble_adv_vsc_cb.max_filter) { - st = BTM_MODE_UNSUPPORTED; - return st; - } -#else - cmn_ble_adv_vsc_cb.max_filter = BTM_BLE_MAX_FILTER_COUNTER; -#endif - return st; -} - -/******************************************************************************* -** -** Function btm_ble_advfilt_enq_op_q -** -** Description enqueue an adv filter operation in q to check command complete -** status -** -** Returns void -** -*******************************************************************************/ -void btm_ble_advfilt_enq_op_q(UINT8 action, UINT8 ocf, tBTM_BLE_FILT_CB_EVT cb_evt, - tBTM_BLE_REF_VALUE ref, tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback, - tBTM_BLE_PF_PARAM_CBACK *p_filt_param_cback) -{ - btm_ble_adv_filt_cb.op_q.action_ocf[btm_ble_adv_filt_cb.op_q.next_idx] = (action | (ocf << 4)); - btm_ble_adv_filt_cb.op_q.ref_value[btm_ble_adv_filt_cb.op_q.next_idx] = ref; - btm_ble_adv_filt_cb.op_q.cb_evt[btm_ble_adv_filt_cb.op_q.next_idx] = cb_evt; - btm_ble_adv_filt_cb.op_q.p_scan_cfg_cback[btm_ble_adv_filt_cb.op_q.next_idx] = p_cmpl_cback; - btm_ble_adv_filt_cb.op_q.p_filt_param_cback[btm_ble_adv_filt_cb.op_q.next_idx] - = p_filt_param_cback; - BTM_TRACE_DEBUG("btm_ble_advfilt_enq_op_q: act_ocf:%d, action:%d, ocf:%d,cb_evt;%d, cback:%p", - btm_ble_adv_filt_cb.op_q.action_ocf[btm_ble_adv_filt_cb.op_q.next_idx], action, - ocf, cb_evt, p_cmpl_cback); - btm_ble_adv_filt_cb.op_q.next_idx = (btm_ble_adv_filt_cb.op_q.next_idx + 1) - % BTM_BLE_PF_TYPE_MAX; -} - -/******************************************************************************* -** -** Function btm_ble_advfilt_deq_op_q -** -** Description dequeue an adv filter operation from q when command complete -** is received -** -** Returns void -** -*******************************************************************************/ -void btm_ble_advfilt_deq_op_q(UINT8 *p_action, UINT8 *p_ocf, tBTM_BLE_FILT_CB_EVT *p_cb_evt, - tBTM_BLE_REF_VALUE *p_ref, tBTM_BLE_PF_CFG_CBACK **p_cmpl_cback, - tBTM_BLE_PF_PARAM_CBACK **p_filt_param_cback) -{ - *p_ocf = (btm_ble_adv_filt_cb.op_q.action_ocf[btm_ble_adv_filt_cb.op_q.pending_idx] >> 4); - *p_action = (btm_ble_adv_filt_cb.op_q.action_ocf[btm_ble_adv_filt_cb.op_q.pending_idx] - & BTM_BLE_ADV_FILT_SUBCODE_MASK); - *p_ref = btm_ble_adv_filt_cb.op_q.ref_value[btm_ble_adv_filt_cb.op_q.pending_idx]; - *p_cb_evt = btm_ble_adv_filt_cb.op_q.cb_evt[btm_ble_adv_filt_cb.op_q.pending_idx]; - *p_cmpl_cback = btm_ble_adv_filt_cb.op_q.p_scan_cfg_cback[btm_ble_adv_filt_cb.op_q.pending_idx]; - *p_filt_param_cback = - btm_ble_adv_filt_cb.op_q.p_filt_param_cback[btm_ble_adv_filt_cb.op_q.pending_idx]; - - btm_ble_adv_filt_cb.op_q.pending_idx = (btm_ble_adv_filt_cb.op_q.pending_idx + 1) - % BTM_BLE_PF_TYPE_MAX; - BTM_TRACE_DEBUG("btm_ble_advfilt_deq_op_q: ocf:%d, action:%d, ref_value:%d, cb_evt:%x", - *p_ocf, *p_action, *p_ref, *p_cb_evt); -} - -/******************************************************************************* -** -** Function btm_ble_condtype_to_ocf -** -** Description Convert cond_type to OCF -** -** Returns Returns ocf value -** -*******************************************************************************/ -UINT8 btm_ble_condtype_to_ocf(UINT8 cond_type) -{ - UINT8 ocf = 0; - - switch (cond_type) { - case BTM_BLE_PF_ADDR_FILTER: - ocf = BTM_BLE_META_PF_ADDR; - break; - case BTM_BLE_PF_SRVC_UUID: - ocf = BTM_BLE_META_PF_UUID; - break; - case BTM_BLE_PF_SRVC_SOL_UUID: - ocf = BTM_BLE_META_PF_SOL_UUID; - break; - case BTM_BLE_PF_LOCAL_NAME: - ocf = BTM_BLE_META_PF_LOCAL_NAME; - break; - case BTM_BLE_PF_MANU_DATA: - ocf = BTM_BLE_META_PF_MANU_DATA; - break; - case BTM_BLE_PF_SRVC_DATA_PATTERN: - ocf = BTM_BLE_META_PF_SRVC_DATA; - break; - case BTM_BLE_PF_TYPE_ALL: - ocf = BTM_BLE_META_PF_ALL; - break; - default: - ocf = BTM_BLE_PF_TYPE_MAX; - break; - } - return ocf; -} - -/******************************************************************************* -** -** Function btm_ble_ocf_to_condtype -** -** Description Convert OCF to cond type -** -** Returns Returns condtype value -** -*******************************************************************************/ -UINT8 btm_ble_ocf_to_condtype(UINT8 ocf) -{ - UINT8 cond_type = 0; - - switch (ocf) { - case BTM_BLE_META_PF_FEAT_SEL: - cond_type = BTM_BLE_META_PF_FEAT_SEL; - break; - case BTM_BLE_META_PF_ADDR: - cond_type = BTM_BLE_PF_ADDR_FILTER; - break; - case BTM_BLE_META_PF_UUID: - cond_type = BTM_BLE_PF_SRVC_UUID; - break; - case BTM_BLE_META_PF_SOL_UUID: - cond_type = BTM_BLE_PF_SRVC_SOL_UUID; - break; - case BTM_BLE_META_PF_LOCAL_NAME: - cond_type = BTM_BLE_PF_LOCAL_NAME; - break; - case BTM_BLE_META_PF_MANU_DATA: - cond_type = BTM_BLE_PF_MANU_DATA; - break; - case BTM_BLE_META_PF_SRVC_DATA: - cond_type = BTM_BLE_PF_SRVC_DATA_PATTERN; - break; - case BTM_BLE_META_PF_ALL: - cond_type = BTM_BLE_PF_TYPE_ALL; - break; - default: - cond_type = BTM_BLE_PF_TYPE_MAX; - break; - } - return cond_type; -} - -/******************************************************************************* -** -** Function btm_ble_scan_pf_cmpl_cback -** -** Description the BTM BLE customer feature VSC complete callback for ADV PF filtering -** -** Returns pointer to the counter if found; NULL otherwise. -** -*******************************************************************************/ -void btm_ble_scan_pf_cmpl_cback(tBTM_VSC_CMPL *p_params) -{ - UINT8 status = 0; - UINT8 *p = p_params->p_param_buf, op_subcode = 0, action = 0xff; - UINT16 evt_len = p_params->param_len; - UINT8 ocf = BTM_BLE_META_PF_ALL, cond_type = 0; - UINT8 num_avail = 0, cb_evt = 0; - tBTM_BLE_REF_VALUE ref_value = 0; - tBTM_BLE_PF_CFG_CBACK *p_scan_cfg_cback = NULL; - tBTM_BLE_PF_PARAM_CBACK *p_filt_param_cback = NULL; - - if (evt_len < 3 || evt_len > 4) { - BTM_TRACE_ERROR("%s cannot interpret APCF callback status = %d, length = %d", - __func__, status, evt_len); - btm_ble_advfilt_deq_op_q(&action, &ocf, &cb_evt, &ref_value, &p_scan_cfg_cback, - &p_filt_param_cback); - return; - } - - btm_ble_advfilt_deq_op_q(&action, &ocf, &cb_evt, &ref_value, &p_scan_cfg_cback, - &p_filt_param_cback); - - STREAM_TO_UINT8(status, p); - STREAM_TO_UINT8(op_subcode, p); - STREAM_TO_UINT8(action, p); - - /* Ignore the event, if it is not the same one expected */ - if (3 == evt_len) { - if (ocf != op_subcode) { - BTM_TRACE_ERROR("btm_ble_scan_pf_cmpl_cback:3-Incorrect opcode :%d, %d, %d, %d, %d, %d", - ocf, op_subcode, action, evt_len, ref_value, status); - return; - } else { - if (NULL != btm_ble_adv_filt_cb.p_filt_stat_cback) { - btm_ble_adv_filt_cb.p_filt_stat_cback(action, status, ref_value); - } - BTM_TRACE_DEBUG("btm_ble_scan_pf_cmpl_cback enabled/disabled, %d, %d, %d, %d", - ocf, action, status, ref_value); - return; - } - } - - if (4 == evt_len && ocf != op_subcode) { - BTM_TRACE_ERROR("btm_ble_scan_pf_cmpl_cback:4-Incorrect opcode: %d, %d, %d, %d, %d", - ocf, op_subcode, action, status, ref_value); - return; - } - - STREAM_TO_UINT8(num_avail, p); - switch (op_subcode) { - case BTM_BLE_META_PF_ADDR: - case BTM_BLE_META_PF_UUID: - case BTM_BLE_META_PF_SOL_UUID: - case BTM_BLE_META_PF_LOCAL_NAME: - case BTM_BLE_META_PF_MANU_DATA: - case BTM_BLE_META_PF_SRVC_DATA: - cond_type = btm_ble_ocf_to_condtype(ocf); - BTM_TRACE_DEBUG("btm_ble_scan_pf_cmpl_cback Recd: %d, %d, %d, %d, %d, %d", op_subcode, - ocf, action, status, ref_value, num_avail); - if (HCI_SUCCESS == status) { - if (memcmp(&btm_ble_adv_filt_cb.cur_filter_target.bda, &na_bda, BD_ADDR_LEN) == 0) { - btm_ble_cs_update_pf_counter(action, cond_type, NULL, num_avail); - } else { - btm_ble_cs_update_pf_counter(action, cond_type, - &btm_ble_adv_filt_cb.cur_filter_target, num_avail); - } - } - - /* send ADV PF operation complete */ - btm_ble_adv_filt_cb.op_type = 0; - break; - - case BTM_BLE_META_PF_FEAT_SEL: - BTM_TRACE_DEBUG("btm_ble_scan_pf_cmpl_cback-Feat sel event: %d, %d, %d, %d", - action, status, ref_value, num_avail); - break; - - default: - BTM_TRACE_ERROR("btm_ble_scan_pf_cmpl_cback: unknown operation: %d", op_subcode); - break; - } - - BTM_TRACE_DEBUG("btm_ble_scan_pf_cmpl_cback: calling the cback: %d", cb_evt); - switch (cb_evt) { - case BTM_BLE_FILT_CFG: - if (NULL != p_scan_cfg_cback) { - p_scan_cfg_cback(action, cond_type, num_avail, status, ref_value); - } - break; - case BTM_BLE_FILT_ADV_PARAM: - if (NULL != p_filt_param_cback) { - p_filt_param_cback(action, num_avail, ref_value, status); - } - break; - default: - break; - } -} - -/******************************************************************************* -** -** Function btm_ble_find_addr_filter_counter -** -** Description find the per bd address ADV payload filter counter by BD_ADDR. -** -** Returns pointer to the counter if found; NULL otherwise. -** -*******************************************************************************/ -tBTM_BLE_PF_COUNT *btm_ble_find_addr_filter_counter(tBLE_BD_ADDR *p_le_bda) -{ - UINT8 i; - tBTM_BLE_PF_COUNT *p_addr_filter = &btm_ble_adv_filt_cb.p_addr_filter_count[1]; - - if (p_le_bda == NULL) { - return &btm_ble_adv_filt_cb.p_addr_filter_count[0]; - } - - for (i = 0; i < cmn_ble_adv_vsc_cb.max_filter; i ++, p_addr_filter ++) { - if (p_addr_filter->in_use && - memcmp(p_le_bda->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0) { - return p_addr_filter; - } - } - return NULL; -} - -/******************************************************************************* -** -** Function btm_ble_alloc_addr_filter_counter -** -** Description allocate the per device adv payload filter counter. -** -** Returns pointer to the counter if allocation succeed; NULL otherwise. -** -*******************************************************************************/ -tBTM_BLE_PF_COUNT *btm_ble_alloc_addr_filter_counter(BD_ADDR bd_addr) -{ - UINT8 i; - tBTM_BLE_PF_COUNT *p_addr_filter = &btm_ble_adv_filt_cb.p_addr_filter_count[1]; - - for (i = 0; i < cmn_ble_adv_vsc_cb.max_filter; i ++, p_addr_filter ++) { - if (memcmp(na_bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0) { - memcpy(p_addr_filter->bd_addr, bd_addr, BD_ADDR_LEN); - p_addr_filter->in_use = TRUE; - return p_addr_filter; - } - } - return NULL; -} -/******************************************************************************* -** -** Function btm_ble_dealloc_addr_filter_counter -** -** Description de-allocate the per device adv payload filter counter. -** -** Returns TRUE if deallocation succeed; FALSE otherwise. -** -*******************************************************************************/ -BOOLEAN btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR *p_bd_addr, UINT8 filter_type) -{ - UINT8 i; - tBTM_BLE_PF_COUNT *p_addr_filter = &btm_ble_adv_filt_cb.p_addr_filter_count[1]; - BOOLEAN found = FALSE; - - if (BTM_BLE_PF_TYPE_ALL == filter_type && NULL == p_bd_addr) { - memset(&btm_ble_adv_filt_cb.p_addr_filter_count[0], 0, sizeof(tBTM_BLE_PF_COUNT)); - } - - for (i = 0; i < cmn_ble_adv_vsc_cb.max_filter; i ++, p_addr_filter ++) { - if ((p_addr_filter->in_use) && (NULL == p_bd_addr || - (memcmp(p_bd_addr->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0)) { - found = TRUE; - memset(p_addr_filter, 0, sizeof(tBTM_BLE_PF_COUNT)); - - if (NULL != p_bd_addr) { - break; - } - } - } - return found; -} - -/******************************************************************************* -** -** Function btm_ble_update_pf_local_name -** -** Description this function update(add,delete or clear) the adv local name filtering condition. -** -** -** Returns BTM_SUCCESS if successful, -** BTM_ILLEGAL_VALUE if parameter is not valid. -** -*******************************************************************************/ -tBTM_STATUS btm_ble_update_pf_local_name(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_FILT_INDEX filt_index, - tBTM_BLE_PF_COND_PARAM *p_cond) -{ - tBTM_BLE_PF_LOCAL_NAME_COND *p_local_name = (p_cond == NULL) ? NULL : &p_cond->local_name; - UINT8 param[BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH], - *p = param, - len = BTM_BLE_ADV_FILT_META_HDR_LENGTH; - tBTM_STATUS st = BTM_ILLEGAL_VALUE; - - memset(param, 0, BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH); - - UINT8_TO_STREAM(p, BTM_BLE_META_PF_LOCAL_NAME); - UINT8_TO_STREAM(p, action); - - /* Filter index */ - UINT8_TO_STREAM(p, filt_index); - - if (BTM_BLE_SCAN_COND_ADD == action || - BTM_BLE_SCAN_COND_DELETE == action) { - if (NULL == p_local_name) { - return st; - } - - if (p_local_name->data_len > BTM_BLE_PF_STR_LEN_MAX) { - p_local_name->data_len = BTM_BLE_PF_STR_LEN_MAX; - } - - ARRAY_TO_STREAM(p, p_local_name->p_data, p_local_name->data_len); - len += p_local_name->data_len; - } - - /* send local name filter */ - if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, - len, - param, - btm_ble_scan_pf_cmpl_cback)) - != BTM_NO_RESOURCES) { - memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); - } else { - BTM_TRACE_ERROR("Local Name PF filter update failed"); - } - - return st; -} - - -/******************************************************************************* -** -** Function btm_ble_update_srvc_data_change -** -** Description this function update(add/remove) service data change filter. -** -** -** Returns BTM_SUCCESS if successful, -** BTM_ILLEGAL_VALUE if parameter is not valid. -** -*******************************************************************************/ -tBTM_STATUS btm_ble_update_srvc_data_change(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_FILT_INDEX filt_index, - tBTM_BLE_PF_COND_PARAM *p_cond) -{ - tBTM_STATUS st = BTM_ILLEGAL_VALUE; - tBLE_BD_ADDR *p_bd_addr = p_cond ? &p_cond->target_addr : NULL; - UINT8 num_avail = (action == BTM_BLE_SCAN_COND_ADD) ? 0 : 1; - - if (btm_ble_cs_update_pf_counter (action, BTM_BLE_PF_SRVC_DATA, p_bd_addr, num_avail) - != BTM_BLE_INVALID_COUNTER) { - st = BTM_SUCCESS; - } - - return st; -} - -/******************************************************************************* -** -** Function btm_ble_update_pf_manu_data -** -** Description this function update(add,delete or clear) the adv manufacturer -** data filtering condition. -** -** -** Returns BTM_SUCCESS if successful, -** BTM_ILLEGAL_VALUE if parameter is not valid. -** -*******************************************************************************/ -tBTM_STATUS btm_ble_update_pf_manu_data(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_FILT_INDEX filt_index, - tBTM_BLE_PF_COND_PARAM *p_data, - tBTM_BLE_PF_COND_TYPE cond_type, - tBTM_BLE_FILT_CB_EVT cb_evt, - tBTM_BLE_REF_VALUE ref_value) -{ - tBTM_BLE_PF_MANU_COND *p_manu_data = (p_data == NULL) ? NULL : &p_data->manu_data; - tBTM_BLE_PF_SRVC_PATTERN_COND *p_srvc_data = (p_data == NULL) ? NULL : &p_data->srvc_data; - - UINT8 param[BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH], - *p = param, - len = BTM_BLE_ADV_FILT_META_HDR_LENGTH; - tBTM_STATUS st = BTM_ILLEGAL_VALUE; - - if (NULL == p_data) { - return st; - } - - memset(param, 0, BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX - + BTM_BLE_ADV_FILT_META_HDR_LENGTH); - - if (BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type) { - UINT8_TO_STREAM(p, BTM_BLE_META_PF_SRVC_DATA); - } else { - UINT8_TO_STREAM(p, BTM_BLE_META_PF_MANU_DATA); - } - - UINT8_TO_STREAM(p, action); - - /* Filter index */ - UINT8_TO_STREAM(p, filt_index); - - if (BTM_BLE_SCAN_COND_ADD == action || BTM_BLE_SCAN_COND_DELETE == action) { - if (BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type) { - if (NULL == p_srvc_data) { - return st; - } - if (p_srvc_data->data_len > (BTM_BLE_PF_STR_LEN_MAX - 2)) { - p_srvc_data->data_len = (BTM_BLE_PF_STR_LEN_MAX - 2); - } - - if (p_srvc_data->data_len > 0) { - ARRAY_TO_STREAM(p, p_srvc_data->p_pattern, p_srvc_data->data_len); - len += (p_srvc_data->data_len); - ARRAY_TO_STREAM(p, p_srvc_data->p_pattern_mask, p_srvc_data->data_len); - } - - len += (p_srvc_data->data_len); - BTM_TRACE_DEBUG("Service data length: %d", len); - } else { - if (NULL == p_manu_data) { - BTM_TRACE_ERROR("btm_ble_update_pf_manu_data - No manuf data"); - return st; - } - BTM_TRACE_EVENT("btm_ble_update_pf_manu_data length: %d", - p_manu_data->data_len); - if (p_manu_data->data_len > (BTM_BLE_PF_STR_LEN_MAX - 2)) { - p_manu_data->data_len = (BTM_BLE_PF_STR_LEN_MAX - 2); - } - - UINT16_TO_STREAM(p, p_manu_data->company_id); - if (p_manu_data->data_len > 0 && p_manu_data->p_pattern_mask != NULL) { - ARRAY_TO_STREAM(p, p_manu_data->p_pattern, p_manu_data->data_len); - len += (p_manu_data->data_len + 2); - } else { - len += 2; - } - - if (p_manu_data->company_id_mask != 0) { - UINT16_TO_STREAM (p, p_manu_data->company_id_mask); - } else { - memset(p, 0xff, 2); - p += 2; - } - len += 2; - - if (p_manu_data->data_len > 0 && p_manu_data->p_pattern_mask != NULL) { - ARRAY_TO_STREAM(p, p_manu_data->p_pattern_mask, p_manu_data->data_len); - len += (p_manu_data->data_len); - } - - BTM_TRACE_DEBUG("Manuf data length: %d", len); - } - } - - /* send manufacturer*/ - if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, - len, - param, - btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES) { - memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); - } else { - BTM_TRACE_ERROR("manufacturer data PF filter update failed"); - } - - return st; -} - -/******************************************************************************* -** -** Function btm_ble_cs_update_pf_counter -** -** Description this function is to update the adv data payload filter counter -** -** Returns current number of the counter; BTM_BLE_INVALID_COUNTER if -** counter update failed. -** -*******************************************************************************/ -UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action, - UINT8 cond_type, tBLE_BD_ADDR *p_bd_addr, - UINT8 num_available) -{ - tBTM_BLE_PF_COUNT *p_addr_filter = NULL; - UINT8 *p_counter = NULL; - - btm_ble_obtain_vsc_details(); - - if (cond_type > BTM_BLE_PF_TYPE_ALL) { - BTM_TRACE_ERROR("unknown PF filter condition type %d", cond_type); - return BTM_BLE_INVALID_COUNTER; - } - - /* for these three types of filter, always generic */ - if (BTM_BLE_PF_ADDR_FILTER == cond_type || - BTM_BLE_PF_MANU_DATA == cond_type || - BTM_BLE_PF_LOCAL_NAME == cond_type || - BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type) { - p_bd_addr = NULL; - } - - if ((p_addr_filter = btm_ble_find_addr_filter_counter(p_bd_addr)) == NULL && - BTM_BLE_SCAN_COND_ADD == action) { - p_addr_filter = btm_ble_alloc_addr_filter_counter(p_bd_addr->bda); - } - - if (NULL != p_addr_filter) { - /* all filter just cleared */ - if ((BTM_BLE_PF_TYPE_ALL == cond_type && BTM_BLE_SCAN_COND_CLEAR == action) || - /* or bd address filter been deleted */ - (BTM_BLE_PF_ADDR_FILTER == cond_type && - (BTM_BLE_SCAN_COND_DELETE == action || BTM_BLE_SCAN_COND_CLEAR == action))) { - btm_ble_dealloc_addr_filter_counter(p_bd_addr, cond_type); - } - /* if not feature selection, update new addition/reduction of the filter counter */ - else if (cond_type != BTM_BLE_PF_TYPE_ALL) { - p_counter = p_addr_filter->pf_counter; - if (num_available > 0) { - p_counter[cond_type] += 1; - } - - BTM_TRACE_DEBUG("counter = %d, maxfilt = %d, num_avbl=%d", - p_counter[cond_type], cmn_ble_adv_vsc_cb.max_filter, num_available); - return p_counter[cond_type]; - } - } else { - BTM_TRACE_ERROR("no matching filter counter found"); - } - /* no matching filter located and updated */ - return BTM_BLE_INVALID_COUNTER; -} - - -/******************************************************************************* -** -** Function btm_ble_update_addr_filter -** -** Description this function update(add,delete or clear) the address filter of adv. -** -** -** Returns BTM_SUCCESS if successful, -** BTM_ILLEGAL_VALUE if parameter is not valid. -** -*******************************************************************************/ -tBTM_STATUS btm_ble_update_addr_filter(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_FILT_INDEX filt_index, - tBTM_BLE_PF_COND_PARAM *p_cond) -{ - UINT8 param[BTM_BLE_META_ADDR_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH], - * p = param; - tBTM_STATUS st = BTM_ILLEGAL_VALUE; - tBLE_BD_ADDR *p_addr = (p_cond == NULL) ? NULL : &p_cond->target_addr; - - memset(param, 0, BTM_BLE_META_ADDR_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH); - - UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR); - UINT8_TO_STREAM(p, action); - - /* Filter index */ - UINT8_TO_STREAM(p, filt_index); - - if (BTM_BLE_SCAN_COND_ADD == action || - BTM_BLE_SCAN_COND_DELETE == action) { - if (NULL == p_addr) { - return st; - } - - BDADDR_TO_STREAM(p, p_addr->bda); - UINT8_TO_STREAM(p, p_addr->type); - } - /* send address filter */ - if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, - (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN), - param, - btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES) { - memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); - } else { - BTM_TRACE_ERROR("Broadcaster Address Filter Update failed"); - } - return st; -} - -/******************************************************************************* -** -** Function btm_ble_update_uuid_filter -** -** Description this function update(add,delete or clear) service UUID filter. -** -** -** Returns BTM_SUCCESS if successful, -** BTM_ILLEGAL_VALUE if parameter is not valid. -** -*******************************************************************************/ -tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_FILT_INDEX filt_index, - tBTM_BLE_PF_COND_TYPE filter_type, - tBTM_BLE_PF_COND_PARAM *p_cond, - tBTM_BLE_FILT_CB_EVT cb_evt, - tBTM_BLE_REF_VALUE ref_value) -{ - UINT8 param[BTM_BLE_META_UUID_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH], - * p = param, - len = BTM_BLE_ADV_FILT_META_HDR_LENGTH; - tBTM_STATUS st = BTM_ILLEGAL_VALUE; - tBTM_BLE_PF_UUID_COND *p_uuid_cond; - UINT8 evt_type; - - memset(param, 0, BTM_BLE_META_UUID_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH); - - if (BTM_BLE_PF_SRVC_UUID == filter_type) { - evt_type = BTM_BLE_META_PF_UUID; - p_uuid_cond = p_cond ? &p_cond->srvc_uuid : NULL; - } else { - evt_type = BTM_BLE_META_PF_SOL_UUID; - p_uuid_cond = p_cond ? &p_cond->solicitate_uuid : NULL; - } - - if (NULL == p_uuid_cond && action != BTM_BLE_SCAN_COND_CLEAR) { - BTM_TRACE_ERROR("Illegal param for add/delete UUID filter"); - return st; - } - - /* need to add address filter first, if adding per bda UUID filter without address filter */ - if (BTM_BLE_SCAN_COND_ADD == action && NULL != p_uuid_cond && - p_uuid_cond->p_target_addr && - btm_ble_find_addr_filter_counter(p_uuid_cond->p_target_addr) == NULL) { - UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR); - UINT8_TO_STREAM(p, action); - - /* Filter index */ - UINT8_TO_STREAM(p, filt_index); - - BDADDR_TO_STREAM(p, p_uuid_cond->p_target_addr->bda); - UINT8_TO_STREAM(p, p_uuid_cond->p_target_addr->type); - - /* send address filter */ - if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, - (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN), - param, - btm_ble_scan_pf_cmpl_cback)) == BTM_NO_RESOURCES) { - BTM_TRACE_ERROR("Update Address filter into controller failed."); - return st; - } - - btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_ADDR, cb_evt, ref_value, NULL, NULL); - BTM_TRACE_DEBUG("Updated Address filter"); - } - - p = param; - UINT8_TO_STREAM(p, evt_type); - UINT8_TO_STREAM(p, action); - - /* Filter index */ - UINT8_TO_STREAM(p, filt_index); - - if ((BTM_BLE_SCAN_COND_ADD == action || - BTM_BLE_SCAN_COND_DELETE == action) && - NULL != p_uuid_cond) { - if (p_uuid_cond->uuid.len == LEN_UUID_16) { - UINT16_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid16); - len += LEN_UUID_16; - } else if (p_uuid_cond->uuid.len == LEN_UUID_32) { /*4 bytes */ - UINT32_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid32); - len += LEN_UUID_32; - } else if (p_uuid_cond->uuid.len == LEN_UUID_128) { - ARRAY_TO_STREAM (p, p_uuid_cond->uuid.uu.uuid128, LEN_UUID_128); - len += LEN_UUID_128; - } else { - BTM_TRACE_ERROR("illegal UUID length: %d", p_uuid_cond->uuid.len); - return BTM_ILLEGAL_VALUE; - } - - if (NULL != p_uuid_cond->p_uuid_mask) { - if (p_uuid_cond->uuid.len == LEN_UUID_16) { - UINT16_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid16_mask); - len += LEN_UUID_16; - } else if (p_uuid_cond->uuid.len == LEN_UUID_32) { /*4 bytes */ - UINT32_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid32_mask); - len += LEN_UUID_32; - } else if (p_uuid_cond->uuid.len == LEN_UUID_128) { - ARRAY_TO_STREAM (p, p_uuid_cond->p_uuid_mask->uuid128_mask, LEN_UUID_128); - len += LEN_UUID_128; - } - } else { - memset(p, 0xff, p_uuid_cond->uuid.len); - len += p_uuid_cond->uuid.len; - } - BTM_TRACE_DEBUG("btm_ble_update_uuid_filter : %d, %d, %d, %d", filter_type, evt_type, - p_uuid_cond->uuid.len, len); - } - - /* send UUID filter update */ - if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, - len, - param, - btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES) { - if (p_uuid_cond && p_uuid_cond->p_target_addr) { - memcpy(&btm_ble_adv_filt_cb.cur_filter_target, p_uuid_cond->p_target_addr, - sizeof(tBLE_BD_ADDR)); - } - else { - memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); - } - } else { - BTM_TRACE_ERROR("UUID filter updating failed"); - } - - return st; -} - - -/******************************************************************************* -** -** Function btm_ble_clear_scan_pf_filter -** -** Description clear all adv payload filter by de-select all the adv pf feature bits -** -** -** Returns BTM_SUCCESS if successful, -** BTM_ILLEGAL_VALUE if parameter is not valid. -** -*******************************************************************************/ -tBTM_STATUS btm_ble_clear_scan_pf_filter(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_FILT_INDEX filt_index, - tBTM_BLE_PF_COND_PARAM *p_cond, - tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback, - tBTM_BLE_FILT_CB_EVT cb_evt, - tBTM_BLE_REF_VALUE ref_value) -{ - tBLE_BD_ADDR *p_target = (p_cond == NULL) ? NULL : &p_cond->target_addr; - tBTM_BLE_PF_COUNT *p_bda_filter; - tBTM_STATUS st = BTM_WRONG_MODE; - UINT8 param[20], *p; - - if (BTM_BLE_SCAN_COND_CLEAR != action) { - BTM_TRACE_ERROR("unable to perform action:%d for generic adv filter type", action); - return BTM_ILLEGAL_VALUE; - } - - p = param; - memset(param, 0, 20); - - p_bda_filter = btm_ble_find_addr_filter_counter(p_target); - - if (NULL == p_bda_filter || - /* not a generic filter */ - (p_target != NULL)) { - BTM_TRACE_ERROR("Error: Can not clear filter, No PF filter has been configured!"); - return st; - } - - /* clear the general filter entry */ - if (NULL == p_target) { - /* clear manufacturer data filter */ - st = btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL, - BTM_BLE_PF_MANU_DATA, cb_evt, ref_value); - if (BTM_CMD_STARTED == st) { - btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_MANU_DATA, cb_evt, - ref_value, NULL, NULL); - } - - /* clear local name filter */ - st = btm_ble_update_pf_local_name(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL); - if (BTM_CMD_STARTED == st) { - btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_LOCAL_NAME, cb_evt, - ref_value, NULL, NULL); - } - - /* update the counter for service data */ - st = btm_ble_update_srvc_data_change(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL); - - /* clear UUID filter */ - st = btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index, - BTM_BLE_PF_SRVC_UUID, NULL, cb_evt, ref_value); - if (BTM_CMD_STARTED == st) { - btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_UUID, cb_evt, ref_value, NULL, NULL); - } - - st = btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index, - BTM_BLE_PF_SRVC_SOL_UUID, NULL, cb_evt, ref_value); - if (BTM_CMD_STARTED == st) { - btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_SOL_UUID, cb_evt, - ref_value, NULL, NULL); - } - - /* clear service data filter */ - st = btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL, - BTM_BLE_PF_SRVC_DATA_PATTERN, cb_evt, ref_value); - if (BTM_CMD_STARTED == st) { - btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_SRVC_DATA, cb_evt, - ref_value, NULL, NULL); - } - } - - /* select feature based on control block settings */ - UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); - UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR); - - /* Filter index */ - UINT8_TO_STREAM(p, filt_index); - - /* set PCF selection */ - UINT32_TO_STREAM(p, BTM_BLE_PF_SELECT_NONE); - /* set logic condition as OR as default */ - UINT8_TO_STREAM(p, BTM_BLE_PF_LOGIC_OR); - - if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, - (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_PF_FEAT_SEL_LEN), - param, - btm_ble_scan_pf_cmpl_cback)) - != BTM_NO_RESOURCES) { - if (p_target) { - memcpy(&btm_ble_adv_filt_cb.cur_filter_target, p_target, sizeof(tBLE_BD_ADDR)); - } else { - memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); - } - } - return st; -} - -/******************************************************************************* -** -** Function BTM_BleAdvFilterParamSetup -** -** Description This function is called to setup the adv data payload filter -** condition. -** -** Parameters action - Type of action to be performed -** filt_index - Filter index -** p_filt_params - Filter parameters -** p_target - Target device -** p_cmpl_back - Callback pointer -** ref_value - reference value -** -** Returns void -** -*******************************************************************************/ -tBTM_STATUS BTM_BleAdvFilterParamSetup(int action, tBTM_BLE_PF_FILT_INDEX filt_index, - tBTM_BLE_PF_FILT_PARAMS *p_filt_params, - tBLE_BD_ADDR *p_target, tBTM_BLE_PF_PARAM_CBACK *p_cmpl_cback, - tBTM_BLE_REF_VALUE ref_value) -{ - tBTM_STATUS st = BTM_WRONG_MODE; - tBTM_BLE_PF_COUNT *p_bda_filter = NULL; - UINT8 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN + - BTM_BLE_ADV_FILT_TRACK_NUM; - UINT8 param[len], *p; - - if (BTM_SUCCESS != btm_ble_obtain_vsc_details()) { - return st; - } - - p = param; - memset(param, 0, len); - BTM_TRACE_EVENT (" BTM_BleAdvFilterParamSetup"); - - if (BTM_BLE_SCAN_COND_ADD == action) { - p_bda_filter = btm_ble_find_addr_filter_counter(p_target); - if (NULL == p_bda_filter) { - BTM_TRACE_ERROR("BD Address not found!"); - return st; - } - - BTM_TRACE_DEBUG("BTM_BleAdvFilterParamSetup : Feat mask:%d", p_filt_params->feat_seln); - /* select feature based on control block settings */ - UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); - UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_ADD); - - /* Filter index */ - UINT8_TO_STREAM(p, filt_index); - - /* set PCF selection */ - UINT16_TO_STREAM(p, p_filt_params->feat_seln); - /* set logic type */ - UINT16_TO_STREAM(p, p_filt_params->logic_type); - /* set logic condition */ - UINT8_TO_STREAM(p, p_filt_params->filt_logic_type); - /* set RSSI high threshold */ - UINT8_TO_STREAM(p, p_filt_params->rssi_high_thres); - /* set delivery mode */ - UINT8_TO_STREAM(p, p_filt_params->dely_mode); - - if (0x01 == p_filt_params->dely_mode) { - /* set onfound timeout */ - UINT16_TO_STREAM(p, p_filt_params->found_timeout); - /* set onfound timeout count*/ - UINT8_TO_STREAM(p, p_filt_params->found_timeout_cnt); - /* set RSSI low threshold */ - UINT8_TO_STREAM(p, p_filt_params->rssi_low_thres); - /* set onlost timeout */ - UINT16_TO_STREAM(p, p_filt_params->lost_timeout); - /* set num_of_track_entries for firmware greater than L-release version */ - if (cmn_ble_adv_vsc_cb.version_supported > BTM_VSC_CHIP_CAPABILITY_L_VERSION) { - UINT16_TO_STREAM(p, p_filt_params->num_of_tracking_entries); - } - } - - if (cmn_ble_adv_vsc_cb.version_supported == BTM_VSC_CHIP_CAPABILITY_L_VERSION) { - len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN; - } else { - len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN + - BTM_BLE_ADV_FILT_TRACK_NUM; - } - - if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, - (UINT8)len, - param, - btm_ble_scan_pf_cmpl_cback)) - == BTM_NO_RESOURCES) { - return st; - } - btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_ADV_PARAM, - ref_value, NULL, p_cmpl_cback); - } else if (BTM_BLE_SCAN_COND_DELETE == action) { - /* select feature based on control block settings */ - UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); - UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_DELETE); - /* Filter index */ - UINT8_TO_STREAM(p, filt_index); - - if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, - (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH), - param, - btm_ble_scan_pf_cmpl_cback)) - == BTM_NO_RESOURCES) { - return st; - } - btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_ADV_PARAM, - ref_value, NULL, p_cmpl_cback); - } else if (BTM_BLE_SCAN_COND_CLEAR == action) { - /* Deallocate all filters here */ - btm_ble_dealloc_addr_filter_counter(NULL, BTM_BLE_PF_TYPE_ALL); - - /* select feature based on control block settings */ - UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); - UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR); - - if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, - (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH - 1), - param, - btm_ble_scan_pf_cmpl_cback)) - == BTM_NO_RESOURCES) { - return st; - } - btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_ADV_PARAM, - ref_value, NULL, p_cmpl_cback); - } - - return st; -} - -/******************************************************************************* -** -** Function BTM_BleEnableDisableFilterFeature -** -** Description This function is called to enable / disable the APCF feature -** -** Parameters enable the generic scan condition. -** enable: enable or disable the filter condition -** p_stat_cback - Status callback pointer -** ref_value - Ref value -** Returns void -** -*******************************************************************************/ -tBTM_STATUS BTM_BleEnableDisableFilterFeature(UINT8 enable, - tBTM_BLE_PF_STATUS_CBACK *p_stat_cback, - tBTM_BLE_REF_VALUE ref_value) -{ - UINT8 param[20], *p; - tBTM_STATUS st = BTM_WRONG_MODE; - - if (BTM_SUCCESS != btm_ble_obtain_vsc_details()) { - return st; - } - - p = param; - memset(param, 0, 20); - - /* enable the content filter in controller */ - p = param; - UINT8_TO_STREAM(p, BTM_BLE_META_PF_ENABLE); - /* enable adv data payload filtering */ - UINT8_TO_STREAM(p, enable); - - if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, - BTM_BLE_PCF_ENABLE_LEN, param, - btm_ble_scan_pf_cmpl_cback)) == BTM_CMD_STARTED) { - btm_ble_adv_filt_cb.p_filt_stat_cback = p_stat_cback; - btm_ble_advfilt_enq_op_q(enable, BTM_BLE_META_PF_ENABLE, BTM_BLE_FILT_ENABLE_DISABLE, - ref_value, NULL, NULL); - } - return st; -} - -/******************************************************************************* -** -** Function BTM_BleCfgFilterCondition -** -** Description This function is called to configure the adv data payload filter -** condition. -** -** Parameters action: to read/write/clear -** cond_type: filter condition type. -** filt_index - Filter index -** p_cond: filter condition parameter -** p_cmpl_cback - Config callback pointer -** ref_value - Reference value -** -** Returns void -** -*******************************************************************************/ -tBTM_STATUS BTM_BleCfgFilterCondition(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_COND_TYPE cond_type, - tBTM_BLE_PF_FILT_INDEX filt_index, - tBTM_BLE_PF_COND_PARAM *p_cond, - tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback, - tBTM_BLE_REF_VALUE ref_value) -{ - tBTM_STATUS st = BTM_ILLEGAL_VALUE; - UINT8 ocf = 0; - BTM_TRACE_EVENT (" BTM_BleCfgFilterCondition action:%d, cond_type:%d, index:%d", action, - cond_type, filt_index); - - if (BTM_SUCCESS != btm_ble_obtain_vsc_details()) { - return st; - } - - switch (cond_type) { - /* write service data filter */ - case BTM_BLE_PF_SRVC_DATA_PATTERN: - /* write manufacturer data filter */ - case BTM_BLE_PF_MANU_DATA: - st = btm_ble_update_pf_manu_data(action, filt_index, p_cond, cond_type, 0, ref_value); - break; - - /* write local name filter */ - case BTM_BLE_PF_LOCAL_NAME: - st = btm_ble_update_pf_local_name(action, filt_index, p_cond); - break; - - /* filter on advertiser address */ - case BTM_BLE_PF_ADDR_FILTER: - st = btm_ble_update_addr_filter(action, filt_index, p_cond); - break; - - /* filter on service/solicited UUID */ - case BTM_BLE_PF_SRVC_UUID: - case BTM_BLE_PF_SRVC_SOL_UUID: - st = btm_ble_update_uuid_filter(action, filt_index, cond_type, p_cond, 0, ref_value); - break; - - case BTM_BLE_PF_SRVC_DATA: - st = btm_ble_update_srvc_data_change(action, filt_index, p_cond); - break; - - case BTM_BLE_PF_TYPE_ALL: /* only used to clear filter */ - st = btm_ble_clear_scan_pf_filter(action, filt_index, p_cond, p_cmpl_cback, - 0, ref_value); - break; - - default: - BTM_TRACE_WARNING("condition type [%d] not supported currently.", cond_type); - break; - } - - if (BTM_CMD_STARTED == st && cond_type != BTM_BLE_PF_TYPE_ALL) { - ocf = btm_ble_condtype_to_ocf(cond_type); - btm_ble_advfilt_enq_op_q(action, ocf, BTM_BLE_FILT_CFG, ref_value, p_cmpl_cback, NULL); - } else if (BTM_CMD_STARTED == st && BTM_BLE_PF_TYPE_ALL == cond_type) { - btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_CFG, - ref_value, p_cmpl_cback, NULL); - } - return st; -} - -/******************************************************************************* -** -** Function btm_ble_adv_filter_init -** -** Description This function initializes the adv filter control block -** -** Parameters -** -** Returns status -** -*******************************************************************************/ -void btm_ble_adv_filter_init(void) -{ -#if BTM_DYNAMIC_MEMORY == TRUE - btm_ble_adv_filt_cb_ptr = (tBTM_BLE_ADV_FILTER_CB *)osi_malloc(sizeof(tBTM_BLE_ADV_FILTER_CB)); - cmn_ble_adv_vsc_cb_ptr = (tBTM_BLE_VSC_CB *)osi_malloc(sizeof(tBTM_BLE_VSC_CB)); - if (btm_ble_adv_filt_cb_ptr == NULL || cmn_ble_adv_vsc_cb_ptr == NULL) { - BTM_TRACE_ERROR("%s malloc failed", __func__); - return; - } - memset((void *)btm_ble_adv_filt_cb_ptr, 0, sizeof(tBTM_BLE_ADV_FILTER_CB)); - memset((void *)cmn_ble_adv_vsc_cb_ptr, 0, sizeof(tBTM_BLE_VSC_CB)); -#endif - memset(&btm_ble_adv_filt_cb, 0, sizeof(tBTM_BLE_ADV_FILTER_CB)); - if (BTM_SUCCESS != btm_ble_obtain_vsc_details()) { - return; - } - - if (cmn_ble_adv_vsc_cb.max_filter > 0) { - btm_ble_adv_filt_cb.p_addr_filter_count = - (tBTM_BLE_PF_COUNT *) osi_malloc( sizeof(tBTM_BLE_PF_COUNT) * cmn_ble_adv_vsc_cb.max_filter); - } -} - -/******************************************************************************* -** -** Function btm_ble_adv_filter_cleanup -** -** Description This function de-initializes the adv filter control block -** -** Parameters -** -** Returns status -** -*******************************************************************************/ -void btm_ble_adv_filter_cleanup(void) -{ - if (btm_ble_adv_filt_cb.p_addr_filter_count) { - osi_free(btm_ble_adv_filt_cb.p_addr_filter_count); - btm_ble_adv_filt_cb.p_addr_filter_count = NULL; - } - -#if BTM_DYNAMIC_MEMORY == TRUE - osi_free(btm_ble_adv_filt_cb_ptr); - btm_ble_adv_filt_cb_ptr = NULL; - osi_free(cmn_ble_adv_vsc_cb_ptr); - cmn_ble_adv_vsc_cb_ptr = NULL; -#endif -} - -#endif // #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index e81c86f80a..870d1f1e3c 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -4579,9 +4579,7 @@ void btm_ble_init (void) osi_event_bind(p_cb->adv_rpt_ready, btu_get_current_thread(), 0); #endif // #if (BLE_42_SCAN_EN == TRUE) #if BLE_VND_INCLUDED == FALSE -#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE - btm_ble_adv_filter_init(); -#endif // #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE + #endif #if (BLE_VENDOR_HCI_EN == TRUE) BTM_RegisterForVSEvents(btm_ble_vs_evt_callback, TRUE); From 9574a4bb3b92f6050322274bd5c927117aaffa8a Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:25 +0800 Subject: [PATCH 123/226] fix(ble/bluedroid): Delete BLE_VND_INCLUDED (cherry picked from commit 57c52bd4ec211a4e3238fe83e16bc19d021a07cf) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 32 ----- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 19 +-- .../bluedroid/bta/dm/include/bta_dm_int.h | 3 - .../common/include/common/bt_target.h | 8 -- .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 112 ------------------ .../bluedroid/stack/btm/include/btm_ble_int.h | 6 +- .../stack/include/stack/btm_ble_api.h | 24 ---- 7 files changed, 2 insertions(+), 202 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 348da66043..c5be0386f6 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -125,10 +125,6 @@ static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data); extern tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void); #endif -#if BLE_VND_INCLUDED == TRUE -static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result); -#endif - #ifndef BTA_DM_BLE_ADV_CHNL_MAP #define BTA_DM_BLE_ADV_CHNL_MAP (BTM_BLE_ADV_CHNL_37|BTM_BLE_ADV_CHNL_38|BTM_BLE_ADV_CHNL_39) #endif @@ -527,10 +523,6 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status ) BTM_RegBusyLevelNotif (bta_dm_bl_change_cback, NULL, BTM_BL_UPDATE_MASK | BTM_BL_ROLE_CHG_MASK); BTM_RegAclLinkStatNotif (bta_dm_acl_link_stat_cback); -#if BLE_VND_INCLUDED == TRUE - BTM_BleReadControllerFeatures (bta_dm_ctrl_features_rd_cmpl_cback); -#endif - /* Earlier, we used to invoke BTM_ReadLocalAddr which was just copying the bd_addr from the control block and invoking the callback which was sending the DM_ENABLE_EVT. But then we have a few HCI commands being invoked above which were still in progress @@ -6737,28 +6729,4 @@ static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data) #endif /* #if (GATTC_INCLUDED == TRUE) */ #endif /* BTA_GATT_INCLUDED */ -#if BLE_VND_INCLUDED == TRUE -/******************************************************************************* -** -** Function bta_dm_ctrl_features_rd_cmpl_cback -** -** Description callback to handle controller feature read complete -** -** Parameters: -** -*******************************************************************************/ -static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result) -{ - APPL_TRACE_DEBUG("%s status = %d ", __FUNCTION__, result); - if (result == BTM_SUCCESS) { - if (bta_dm_cb.p_sec_cback) { - bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL); - } - } else { - APPL_TRACE_ERROR("%s Ctrl BLE feature read failed: status :%d", __FUNCTION__, result); - } - -} -#endif /* BLE_VND_INCLUDED */ - #endif /* BLE_INCLUDED */ diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 20f1ad773d..4d75920004 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -2837,25 +2837,8 @@ void BTA_VendorCleanup (void) { tBTM_BLE_VSC_CB cmn_ble_vsc_cb; BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - -#if (BLE_INCLUDED == TRUE && BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE) - btm_ble_adv_filter_cleanup(); // when BLE_VND_INCLUDED is false, this function will be ignore, so move it out of "if" - -#if 0 //by TH, comment out temporarily - if (cmn_ble_vsc_cb.max_filter > 0) { - btm_ble_adv_filter_cleanup(); -#if BLE_PRIVACY_SPT == TRUE - btm_ble_resolving_list_cleanup (); -#endif - } -#endif - - if (cmn_ble_vsc_cb.tot_scan_results_strg > 0) { - btm_ble_batchscan_cleanup(); - } -#endif - } + #if (BLE_50_FEATURE_SUPPORT == TRUE) void BTA_DmBleGapReadPHY(BD_ADDR addr) { diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 30659dcd39..0da68cf308 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -2036,9 +2036,6 @@ typedef struct { tBTA_DM_SEC_CBACK *p_sec_cback; #if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) tBTA_BLE_SCAN_SETUP_CBACK *p_setup_cback; - tBTA_DM_BLE_PF_CFG_CBACK *p_scan_filt_cfg_cback; - tBTA_DM_BLE_PF_STATUS_CBACK *p_scan_filt_status_cback; - tBTA_DM_BLE_PF_PARAM_CBACK *p_scan_filt_param_cback; #if (BLE_HOST_ENERGY_INFO_EN == TRUE) tBTA_BLE_ENERGY_INFO_CBACK *p_energy_info_cback; #endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) 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 61dbe2e0e5..8d9e0037d8 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1664,14 +1664,6 @@ #define BLE_LOCAL_PRIVACY_ENABLED TRUE #endif -/* - * Toggles support for vendor specific extensions such as RPA offloading, - * feature discovery, multi-adv etc. - */ -#ifndef BLE_VND_INCLUDED -#define BLE_VND_INCLUDED FALSE -#endif - #ifndef BTM_BLE_ADV_TX_POWER #ifdef CONFIG_IDF_TARGET_ESP32 #define BTM_BLE_ADV_TX_POWER {-12, -9, -6, -3, 0, 3, 6, 9} diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index 870d1f1e3c..53adaa7bbc 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -66,10 +66,6 @@ static tBTM_BLE_VSC_CB *cmn_ble_gap_vsc_cb_ptr; #define cmn_ble_gap_vsc_cb (*cmn_ble_gap_vsc_cb_ptr) #endif -#if BLE_VND_INCLUDED == TRUE -static tBTM_BLE_CTRL_FEATURES_CBACK *p_ctrl_le_feature_rd_cmpl_cback = NULL; -#endif - tBTM_CallbackFunc conn_callback_func; // BLE vendor HCI event callback #if (BLE_VENDOR_HCI_EN == TRUE) @@ -716,78 +712,6 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_s return status; } #endif // #if (BLE_42_ADV_EN == TRUE) -#if BLE_VND_INCLUDED == TRUE -/******************************************************************************* -** -** Function btm_vsc_brcm_features_complete -** -** Description Command Complete callback for HCI_BLE_VENDOR_CAP_OCF -** -** Returns void -** -*******************************************************************************/ -static void btm_ble_vendor_capability_vsc_cmpl_cback (tBTM_VSC_CMPL *p_vcs_cplt_params) -{ - UINT8 status = 0xFF; - UINT8 *p; - - BTM_TRACE_DEBUG("%s", __func__); - - /* Check status of command complete event */ - if ((p_vcs_cplt_params->opcode == HCI_BLE_VENDOR_CAP_OCF) && - (p_vcs_cplt_params->param_len > 0)) { - p = p_vcs_cplt_params->p_param_buf; - STREAM_TO_UINT8(status, p); - } - - if (status == HCI_SUCCESS) { - STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.adv_inst_max, p); - STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.rpa_offloading, p); - STREAM_TO_UINT16(btm_cb.cmn_ble_vsc_cb.tot_scan_results_strg, p); - STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.max_irk_list_sz, p); - STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.filter_support, p); - STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.max_filter, p); - STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.energy_support, p); - - if (p_vcs_cplt_params->param_len > BTM_VSC_CHIP_CAPABILITY_RSP_LEN_L_RELEASE) { - STREAM_TO_UINT16(btm_cb.cmn_ble_vsc_cb.version_supported, p); - } else { - btm_cb.cmn_ble_vsc_cb.version_supported = BTM_VSC_CHIP_CAPABILITY_L_VERSION; - } - - if (btm_cb.cmn_ble_vsc_cb.version_supported >= BTM_VSC_CHIP_CAPABILITY_M_VERSION) { - STREAM_TO_UINT16(btm_cb.cmn_ble_vsc_cb.total_trackable_advertisers, p); - STREAM_TO_UINT16(btm_cb.cmn_ble_vsc_cb.extended_scan_support, p); - STREAM_TO_UINT16(btm_cb.cmn_ble_vsc_cb.debug_logging_supported, p); - } - btm_cb.cmn_ble_vsc_cb.values_read = TRUE; - } - - BTM_TRACE_DEBUG("%s: stat=%d, irk=%d, ADV ins:%d, rpa=%d, ener=%d, ext_scan=%d", - __func__, status, btm_cb.cmn_ble_vsc_cb.max_irk_list_sz, - btm_cb.cmn_ble_vsc_cb.adv_inst_max, btm_cb.cmn_ble_vsc_cb.rpa_offloading, - btm_cb.cmn_ble_vsc_cb.energy_support, btm_cb.cmn_ble_vsc_cb.extended_scan_support); - if (btm_cb.cmn_ble_vsc_cb.max_filter > 0) { - btm_ble_adv_filter_init(); - } - -#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) - /* VS capability included and non-4.2 device */ - if (btm_cb.cmn_ble_vsc_cb.max_irk_list_sz > 0 && - controller_get_interface()->get_ble_resolving_list_max_size() == 0) { - btm_ble_resolving_list_init(btm_cb.cmn_ble_vsc_cb.max_irk_list_sz); - } -#endif - - if (btm_cb.cmn_ble_vsc_cb.tot_scan_results_strg > 0) { - btm_ble_batchscan_init(); - } - - if (p_ctrl_le_feature_rd_cmpl_cback != NULL) { - p_ctrl_le_feature_rd_cmpl_cback(status); - } -} -#endif /******************************************************************************* ** @@ -809,40 +733,6 @@ extern void BTM_BleGetVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb) } } -/****************************************************************************** -** -** Function BTM_BleReadControllerFeatures -** -** Description Reads BLE specific controller features -** -** Parameters: tBTM_BLE_CTRL_FEATURES_CBACK : Callback to notify when features are read -** -** Returns void -** -*******************************************************************************/ -extern void BTM_BleReadControllerFeatures(tBTM_BLE_CTRL_FEATURES_CBACK *p_vsc_cback) -{ - if (TRUE == btm_cb.cmn_ble_vsc_cb.values_read) { - return; - } - -#if BLE_VND_INCLUDED == TRUE - BTM_TRACE_DEBUG("BTM_BleReadControllerFeatures"); - - p_ctrl_le_feature_rd_cmpl_cback = p_vsc_cback; - if ( BTM_VendorSpecificCommand (HCI_BLE_VENDOR_CAP_OCF, - 0, - NULL, - btm_ble_vendor_capability_vsc_cmpl_cback) - != BTM_CMD_STARTED) { - BTM_TRACE_ERROR("LE Get_Vendor Capabilities Command Failed."); - } -#else - UNUSED(p_vsc_cback); -#endif - return ; -} - void BTM_VendorHciEchoCmdCallback(tBTM_VSC_CMPL *p1) { #if (!CONFIG_BT_STACK_NO_LOG) @@ -4578,9 +4468,7 @@ void btm_ble_init (void) assert(p_cb->adv_rpt_ready != NULL); osi_event_bind(p_cb->adv_rpt_ready, btu_get_current_thread(), 0); #endif // #if (BLE_42_SCAN_EN == TRUE) -#if BLE_VND_INCLUDED == FALSE -#endif #if (BLE_VENDOR_HCI_EN == TRUE) BTM_RegisterForVSEvents(btm_ble_vs_evt_callback, TRUE); #endif // #if (BLE_VENDOR_HCI_EN == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index 3a4dac8068..cbd0082991 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -518,11 +518,7 @@ void btm_ble_add_default_entry_to_resolving_list(void); void btm_ble_set_privacy_mode_complete(UINT8 *p, UINT16 evt_len); #endif -char btm_ble_map_adv_tx_power(int tx_power_index); -void btm_ble_batchscan_init(void); -void btm_ble_batchscan_cleanup(void); -void btm_ble_adv_filter_init(void); -void btm_ble_adv_filter_cleanup(void); +char btm_ble_map_adv_tx_power(int tx_power_index);; BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request); BOOLEAN btm_ble_clear_topology_mask(tBTM_BLE_STATE_MASK request_state); BOOLEAN btm_ble_set_topology_mask(tBTM_BLE_STATE_MASK request_state); 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 54511558f6..b3d9da2290 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 @@ -394,17 +394,8 @@ typedef UINT8 tBTM_BLE_ADV_TX_POWER; /* adv tx power in dBm */ typedef struct { - UINT8 rpa_offloading; - UINT16 tot_scan_results_strg; - UINT8 max_irk_list_sz; - UINT8 filter_support; - UINT8 max_filter; - UINT8 energy_support; BOOLEAN values_read; - UINT16 version_supported; - UINT16 total_trackable_advertisers; UINT8 extended_scan_support; - UINT8 debug_logging_supported; } tBTM_BLE_VSC_CB; /* slave preferred connection interval range */ @@ -948,7 +939,6 @@ typedef struct { } tBTM_BLE_ENERGY_INFO_CB; typedef BOOLEAN (tBTM_BLE_SEL_CBACK)(BD_ADDR random_bda, UINT8 *p_remote_name); -typedef void (tBTM_BLE_CTRL_FEATURES_CBACK)(tBTM_STATUS status); /* callback function for SMP signing algorithm, signed data in little endian order with tlen bits long */ typedef void (tBTM_BLE_SIGN_CBACK)(void *p_ref_data, UINT8 *p_signing_data); @@ -2672,20 +2662,6 @@ void BTM_BleSetPrefConnParams (BD_ADDR bd_addr, //extern void BTM_BleSetConnScanParams (UINT32 scan_interval, UINT32 scan_window); -/****************************************************************************** -** -** Function BTM_BleReadControllerFeatures -** -** Description Reads BLE specific controller features -** -** Parameters: tBTM_BLE_CTRL_FEATURES_CBACK : Callback to notify when features are read -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_BleReadControllerFeatures(tBTM_BLE_CTRL_FEATURES_CBACK *p_vsc_cback); - /******************************************************************************* ** ** Function BTM_CheckAdvData From 2617f9be12898b7994594f4da0921091c889154c Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:26 +0800 Subject: [PATCH 124/226] fix(ble/bluedroid): delete BLE_HOST_ENERGY_INFO_EN (cherry picked from commit b4c4b3e410eea674e558ca86e220175c1b7f9e3a) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 50 ----------- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 28 ------ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 4 - .../bluedroid/bta/dm/include/bta_dm_int.h | 22 ----- .../host/bluedroid/bta/include/bta/bta_api.h | 34 -------- .../common/include/common/bt_target.h | 5 -- .../bluedroid/stack/btm/btm_ble_cont_energy.c | 86 ------------------- .../stack/include/stack/btm_ble_api.h | 27 ------ .../bluedroid/stack/include/stack/hcidefs.h | 4 +- 9 files changed, 1 insertion(+), 259 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index c5be0386f6..4315077671 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6345,56 +6345,6 @@ void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_v } } -#if (BLE_HOST_ENERGY_INFO_EN == TRUE) -/******************************************************************************* -** -** Function bta_ble_enable_scan_cmpl -** -** Description ADV payload filtering enable / disable complete callback -** -** -** Returns None -** -*******************************************************************************/ -static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time, - tBTM_BLE_RX_TIME_MS rx_time, - tBTM_BLE_IDLE_TIME_MS idle_time, - tBTM_BLE_ENERGY_USED energy_used, - tBTM_STATUS status) -{ - tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE; - tBTA_DM_CONTRL_STATE ctrl_state = 0; -#if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE) - if (BTA_SUCCESS == st) { - ctrl_state = bta_dm_pm_obtain_controller_state(); - } -#endif - if (bta_dm_cb.p_energy_info_cback) { - bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used, ctrl_state, st); - } -} - -/******************************************************************************* -** -** Function bta_dm_ble_get_energy_info -** -** Description This function obtains the energy info -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data) -{ - tBTM_STATUS btm_status = 0; - - bta_dm_cb.p_energy_info_cback = p_data->ble_energy_info.p_energy_info_cback; - btm_status = BTM_BleGetEnergyInfo(bta_ble_energy_info_cmpl); - if (BTM_CMD_STARTED != btm_status) { - bta_ble_energy_info_cmpl(0, 0, 0, 0, btm_status); - } -} -#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) - #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE) #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT #define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000 diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 4d75920004..c35abf2e97 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -2078,34 +2078,6 @@ void BTA_DmBleSetKeyMaterial(const uint8_t *session_key, const uint8_t *iv) } #endif -#if (BLE_HOST_ENERGY_INFO_EN == TRUE) -/******************************************************************************* -** -** Function BTA_DmBleGetEnergyInfo -** -** Description This function is called to obtain the energy info -** -** Parameters p_cmpl_cback - Command complete callback -** -** Returns void -** -*******************************************************************************/ -void BTA_DmBleGetEnergyInfo(tBTA_BLE_ENERGY_INFO_CBACK *p_cmpl_cback) -{ - tBTA_DM_API_ENERGY_INFO *p_msg; - APPL_TRACE_API ("BTA_DmBleGetEnergyInfo"); - - UINT16 len = sizeof(tBTA_DM_API_ENERGY_INFO) + sizeof(tBLE_BD_ADDR); - - if ((p_msg = (tBTA_DM_API_ENERGY_INFO *) osi_malloc(len)) != NULL) { - memset (p_msg, 0, len); - p_msg->hdr.event = BTA_DM_API_BLE_ENERGY_INFO_EVT; - p_msg->p_energy_info_cback = p_cmpl_cback; - bta_sys_sendmsg(p_msg); - } -} -#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) - /******************************************************************************* ** ** Function BTA_DmBleUpdateConnectionParams diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 16485d606d..b2734dcea8 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -181,10 +181,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) bta_dm_ble_setup_storage, /* BTA_DM_API_BLE_SETUP_STORAGE_EVT */ #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) - -#if (BLE_HOST_ENERGY_INFO_EN == TRUE) - bta_dm_ble_get_energy_info, /* BTA_DM_API_BLE_ENERGY_INFO_EVT */ -#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) bta_dm_ble_disconnect, /* BTA_DM_API_BLE_DISCONNECT_EVT */ #endif #if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 0da68cf308..c9fd1b1e88 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -166,9 +166,6 @@ enum { BTA_DM_API_BLE_SETUP_STORAGE_EVT, #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) -#if (BLE_HOST_ENERGY_INFO_EN == TRUE) - BTA_DM_API_BLE_ENERGY_INFO_EVT, -#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) BTA_DM_API_BLE_DISCONNECT_EVT, #endif @@ -957,13 +954,6 @@ typedef struct { } tBTA_DM_API_SET_STORAGE_CONFIG; #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) -#if (BLE_HOST_ENERGY_INFO_EN == TRUE) -typedef struct { - BT_HDR hdr; - tBTA_BLE_ENERGY_INFO_CBACK *p_energy_info_cback; -} tBTA_DM_API_ENERGY_INFO; -#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) - typedef struct { BT_HDR hdr; BD_ADDR remote_bda; @@ -1786,10 +1776,6 @@ typedef union { #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) tBTA_DM_API_SET_STORAGE_CONFIG ble_set_storage; #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) - -#if (BLE_HOST_ENERGY_INFO_EN == TRUE) - tBTA_DM_API_ENERGY_INFO ble_energy_info; -#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) tBTA_DM_API_BLE_DISCONNECT ble_disconnect; tBTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST ble_duplicate_exceptional_list; #if (BLE_50_FEATURE_SUPPORT == TRUE) @@ -2036,9 +2022,6 @@ typedef struct { tBTA_DM_SEC_CBACK *p_sec_cback; #if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) tBTA_BLE_SCAN_SETUP_CBACK *p_setup_cback; -#if (BLE_HOST_ENERGY_INFO_EN == TRUE) - tBTA_BLE_ENERGY_INFO_CBACK *p_energy_info_cback; -#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) #endif UINT16 state; BOOLEAN disabling; @@ -2397,11 +2380,6 @@ extern void bta_dm_ble_enable_batch_scan(tBTA_DM_MSG *p_data); extern void bta_dm_ble_disable_batch_scan(tBTA_DM_MSG *p_data); extern void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data); - -#if (BLE_HOST_ENERGY_INFO_EN == TRUE) -extern void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data); -#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) - #endif extern void bta_dm_set_encryption(tBTA_DM_MSG *p_data); extern void bta_dm_confirm(tBTA_DM_MSG *p_data); diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 3627a42205..3f8c0524e4 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1205,16 +1205,6 @@ typedef void (tBTA_DM_ENCRYPT_CBACK) (BD_ADDR bd_addr, tBTA_TRANSPORT transport, #define BTA_DM_BLE_SEC_MITM BTM_BLE_SEC_ENCRYPT_MITM typedef tBTM_BLE_SEC_ACT tBTA_DM_BLE_SEC_ACT; -typedef tBTM_BLE_TX_TIME_MS tBTA_DM_BLE_TX_TIME_MS; -typedef tBTM_BLE_RX_TIME_MS tBTA_DM_BLE_RX_TIME_MS; -typedef tBTM_BLE_IDLE_TIME_MS tBTA_DM_BLE_IDLE_TIME_MS; -typedef tBTM_BLE_ENERGY_USED tBTA_DM_BLE_ENERGY_USED; - -#define BTA_DM_CONTRL_UNKNOWN 0 /* Unknown state */ -#define BTA_DM_CONTRL_ACTIVE 1 /* ACL link on, SCO link ongoing, sniff mode */ -#define BTA_DM_CONTRL_SCAN 2 /* Scan state - paging/inquiry/trying to connect*/ -#define BTA_DM_CONTRL_IDLE 3 /* Idle state - page scan, LE advt, inquiry scan */ - typedef UINT8 tBTA_DM_CONTRL_STATE; typedef UINT8 tBTA_DM_BLE_ADV_STATE; @@ -1238,15 +1228,6 @@ typedef void (tBTA_START_STOP_ADV_CMPL_CBACK) (tBTA_STATUS status); typedef void (tBTA_CLEAR_ADV_CMPL_CBACK) (tBTA_STATUS status); -#if (BLE_HOST_ENERGY_INFO_EN == TRUE) -typedef void (tBTA_BLE_ENERGY_INFO_CBACK)(tBTA_DM_BLE_TX_TIME_MS tx_time, - tBTA_DM_BLE_RX_TIME_MS rx_time, - tBTA_DM_BLE_IDLE_TIME_MS idle_time, - tBTA_DM_BLE_ENERGY_USED energy_used, - tBTA_DM_CONTRL_STATE ctrl_state, - tBTA_STATUS status); -#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) - #else typedef UINT8 tBTA_DM_BLE_SEC_ACT; #endif @@ -3128,21 +3109,6 @@ extern void BTA_DmBleReadScanReports(tBTA_BLE_BATCH_SCAN_MODE scan_type, *******************************************************************************/ extern void BTA_DmBleDisableBatchScan(tBTA_DM_BLE_REF_VALUE ref_value); -#if (BLE_HOST_ENERGY_INFO_EN == TRUE) -/******************************************************************************* -** -** Function BTA_DmBleGetEnergyInfo -** -** Description This function is called to obtain the energy info -** -** Parameters p_cmpl_cback - Command complete callback -** -** Returns void -** -*******************************************************************************/ -extern void BTA_DmBleGetEnergyInfo(tBTA_BLE_ENERGY_INFO_CBACK *p_cmpl_cback); -#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) - /******************************************************************************* ** ** Function BTA_BrcmInit 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 8d9e0037d8..2eaa8ffe18 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1612,11 +1612,6 @@ #define BLE_INCLUDED FALSE #endif -#ifndef BLE_HOST_ENERGY_INFO_EN -#define BLE_HOST_ENERGY_INFO_EN FALSE -#endif - - #ifndef BLE_HOST_ENABLE_TEST_MODE_EN #define BLE_HOST_ENABLE_TEST_MODE_EN FALSE #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_cont_energy.c b/components/bt/host/bluedroid/stack/btm/btm_ble_cont_energy.c index 4b68fe807b..671662e8be 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_cont_energy.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_cont_energy.c @@ -20,91 +20,5 @@ #include "common/bt_target.h" #if (BLE_INCLUDED == TRUE) -#if (BLE_HOST_ENERGY_INFO_EN == TRUE) -#include "stack/bt_types.h" -#include "stack/hcimsgs.h" -#include "stack/btu.h" -#include "btm_int.h" -//#include "bt_utils.h" -#include "stack/hcidefs.h" -#include "stack/btm_ble_api.h" - -tBTM_BLE_ENERGY_INFO_CB ble_energy_info_cb; - -/******************************************************************************* -** -** Function btm_ble_cont_energy_cmpl_cback -** -** Description Controller VSC complete callback -** -** Parameters -** -** Returns void -** -*******************************************************************************/ -void btm_ble_cont_energy_cmpl_cback (tBTM_VSC_CMPL *p_params) -{ - UINT8 *p = p_params->p_param_buf; - UINT16 len = p_params->param_len; - UINT8 status = 0; - UINT32 total_tx_time = 0, total_rx_time = 0, total_idle_time = 0, total_energy_used = 0; - - if (len < 17) { - BTM_TRACE_ERROR("wrong length for btm_ble_cont_energy_cmpl_cback"); - return; - } - - STREAM_TO_UINT8(status, p); - STREAM_TO_UINT32(total_tx_time, p); - STREAM_TO_UINT32(total_rx_time, p); - STREAM_TO_UINT32(total_idle_time, p); - STREAM_TO_UINT32(total_energy_used, p); - - BTM_TRACE_DEBUG("energy_info status=%d,tx_t=%u, rx_t=%u, ener_used=%u, idle_t=%u", - status, total_tx_time, total_rx_time, total_energy_used, total_idle_time); - - if (NULL != ble_energy_info_cb.p_ener_cback) { - ble_energy_info_cb.p_ener_cback(total_tx_time, total_rx_time, total_idle_time, - total_energy_used, status); - } - - return; -} - -/******************************************************************************* -** -** Function BTM_BleGetEnergyInfo -** -** Description This function obtains the energy info -** -** Parameters p_ener_cback - Callback pointer -** -** Returns status -** -*******************************************************************************/ -tBTM_STATUS BTM_BleGetEnergyInfo(tBTM_BLE_ENERGY_INFO_CBACK *p_ener_cback) -{ - tBTM_STATUS status = BTM_ILLEGAL_VALUE; - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - - BTM_TRACE_EVENT("BTM_BleGetEnergyInfo\n"); - - if (0 == cmn_ble_vsc_cb.energy_support) { - BTM_TRACE_ERROR("Controller does not support get energy info\n"); - return BTM_ERR_PROCESSING; - } - - ble_energy_info_cb.p_ener_cback = p_ener_cback; - if ((status = BTM_VendorSpecificCommand (HCI_BLE_ENERGY_INFO_OCF, 0, NULL, - btm_ble_cont_energy_cmpl_cback)) != BTM_CMD_STARTED) { - BTM_TRACE_ERROR("BTM_BleGetEnergyInfo status: %d", status); - return BTM_ILLEGAL_VALUE; - } - - return status; -} -#endif // #if (BLE_HOST_ENERGY_INFO_EN == TRUE) #endif 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 b3d9da2290..cda8df761c 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 @@ -924,19 +924,6 @@ typedef UINT8 tBTM_BLE_CONN_TYPE; typedef UINT8 tBTM_BLE_BATCH_SCAN_EVT; -typedef UINT32 tBTM_BLE_TX_TIME_MS; -typedef UINT32 tBTM_BLE_RX_TIME_MS; -typedef UINT32 tBTM_BLE_IDLE_TIME_MS; -typedef UINT32 tBTM_BLE_ENERGY_USED; - -typedef void (tBTM_BLE_ENERGY_INFO_CBACK)(tBTM_BLE_TX_TIME_MS tx_time, tBTM_BLE_RX_TIME_MS rx_time, - tBTM_BLE_IDLE_TIME_MS idle_time, - tBTM_BLE_ENERGY_USED energy_used, - tBTM_STATUS status); - -typedef struct { - tBTM_BLE_ENERGY_INFO_CBACK *p_ener_cback; -} tBTM_BLE_ENERGY_INFO_CB; typedef BOOLEAN (tBTM_BLE_SEL_CBACK)(BD_ADDR random_bda, UINT8 *p_remote_name); @@ -3105,20 +3092,6 @@ tBTM_STATUS BTM_BleEnableDisableFilterFeature(UINT8 enable, tBTM_BLE_PF_STATUS_CBACK *p_stat_cback, tBTM_BLE_REF_VALUE ref_value); -/******************************************************************************* -** -** Function BTM_BleGetEnergyInfo -** -** Description This function obtains the energy info -** -** Parameters p_ener_cback - Callback pointer -** -** Returns status -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleGetEnergyInfo(tBTM_BLE_ENERGY_INFO_CBACK *p_ener_cback); - /******************************************************************************* ** ** Function BTM_SetBleDataLength diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index 9365de9d54..afefed4680 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -491,7 +491,7 @@ #define HCI_SUBCODE_BLE_BATCH_SCAN 0x02 #define HCI_SUBCODE_BLE_ADV_FILTER 0x03 #define HCI_SUBCODE_BLE_TRACK_ADV 0x04 -#define HCI_SUBCODE_BLE_ENERGY_INFO 0x05 + #define HCI_SUBCODE_BLE_EXTENDED_SCAN_PARAMS 0x06 #define HCI_SUBCODE_BLE_LONG_ADV 0x07 #define HCI_SUBCODE_BLE_DUPLICATE_EXCEPTIONAL_LIST 0x08 @@ -542,8 +542,6 @@ #define HCI_BLE_ADV_FILTER_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_ADV_FILTER) /* Tracking OCF */ #define HCI_BLE_TRACK_ADV_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_TRACK_ADV) -/* Energy info OCF */ -#define HCI_BLE_ENERGY_INFO_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_ENERGY_INFO) /* Extended BLE Scan parameters OCF */ #define HCI_BLE_EXTENDED_SCAN_PARAMS_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_EXTENDED_SCAN_PARAMS) /* BLE update duplicate scan exceptional list */ From 7a8c53b78cf6a7216a1405ad4ac48996aa33e4f1 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:26 +0800 Subject: [PATCH 125/226] fix(ble/bluedroid): Delete BLE_HOST_ENABLE_TEST_MODE_EN (cherry picked from commit f08ff1448b4eb50a0d1f85f08c5b7b47f535000a) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 34 ----------- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 47 --------------- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 4 -- .../bluedroid/bta/dm/include/bta_dm_int.h | 4 -- .../common/include/common/bt_target.h | 4 -- .../bt/host/bluedroid/stack/btm/btm_devctl.c | 59 ------------------- 6 files changed, 152 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 4315077671..dfe1c952f4 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -4659,40 +4659,6 @@ void bta_dm_eir_update_uuid(tBT_UUID uuid, BOOLEAN adding) } #endif -#if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE) -/******************************************************************************* -** -** Function bta_dm_enable_test_mode -** -** Description enable test mode -** -** -** Returns void -** -*******************************************************************************/ -void bta_dm_enable_test_mode(tBTA_DM_MSG *p_data) -{ - UNUSED(p_data); - BTM_EnableTestMode(); -} - -/******************************************************************************* -** -** Function bta_dm_disable_test_mode -** -** Description disable test mode -** -** -** Returns void -** -*******************************************************************************/ -void bta_dm_disable_test_mode(tBTA_DM_MSG *p_data) -{ - UNUSED(p_data); - BTM_DeviceReset(NULL); -} -#endif // #if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE) - #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index c35abf2e97..e67dc84186 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -110,53 +110,6 @@ tBTA_STATUS BTA_DisableBluetooth(void) return BTA_SUCCESS; } -#if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE) -/******************************************************************************* -** -** Function BTA_EnableTestMode -** -** Description Enables bluetooth device under test mode -** -** -** Returns tBTA_STATUS -** -*******************************************************************************/ -tBTA_STATUS BTA_EnableTestMode(void) -{ - BT_HDR *p_msg; - - APPL_TRACE_API("BTA_EnableTestMode"); - - if ((p_msg = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) { - p_msg->event = BTA_DM_API_ENABLE_TEST_MODE_EVT; - bta_sys_sendmsg(p_msg); - return BTA_SUCCESS; - } - return BTA_FAILURE; -} - -/******************************************************************************* -** -** Function BTA_DisableTestMode -** -** Description Disable bluetooth device under test mode -** -** -** Returns None -** -*******************************************************************************/ -void BTA_DisableTestMode(void) -{ - BT_HDR *p_msg; - - APPL_TRACE_API("BTA_DisableTestMode"); - - if ((p_msg = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) { - p_msg->event = BTA_DM_API_DISABLE_TEST_MODE_EVT; - bta_sys_sendmsg(p_msg); - } -} -#endif // #if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index b2734dcea8..cbcf05c0a9 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -183,10 +183,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) bta_dm_ble_disconnect, /* BTA_DM_API_BLE_DISCONNECT_EVT */ #endif -#if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE) - bta_dm_enable_test_mode, /* BTA_DM_API_ENABLE_TEST_MODE_EVT */ - bta_dm_disable_test_mode, /* BTA_DM_API_DISABLE_TEST_MODE_EVT */ -#endif // #if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE) #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) bta_dm_execute_callback, /* BTA_DM_API_EXECUTE_CBACK_EVT */ #endif // #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index c9fd1b1e88..88fd5dc159 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -169,10 +169,6 @@ enum { BTA_DM_API_BLE_DISCONNECT_EVT, #endif -#if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE) - BTA_DM_API_ENABLE_TEST_MODE_EVT, - BTA_DM_API_DISABLE_TEST_MODE_EVT, -#endif // #if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE) #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) BTA_DM_API_EXECUTE_CBACK_EVT, #endif // #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) 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 2eaa8ffe18..0b77119217 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1612,10 +1612,6 @@ #define BLE_INCLUDED FALSE #endif -#ifndef BLE_HOST_ENABLE_TEST_MODE_EN -#define BLE_HOST_ENABLE_TEST_MODE_EN FALSE -#endif - #ifndef BLE_HOST_EXECUTE_CBACK_EN #define BLE_HOST_EXECUTE_CBACK_EN FALSE #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index c0163335ca..9698c439ab 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -1095,65 +1095,6 @@ tBTM_STATUS BTM_WriteVoiceSettings(UINT16 settings) return (BTM_NO_RESOURCES); } -#if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE) -/******************************************************************************* -** -** Function BTM_EnableTestMode -** -** Description Send HCI the enable device under test command. -** -** Note: Controller can only be taken out of this mode by -** resetting the controller. -** -** Returns -** BTM_SUCCESS Command sent. -** BTM_NO_RESOURCES If out of resources to send the command. -** -** -*******************************************************************************/ -tBTM_STATUS BTM_EnableTestMode(void) -{ - UINT8 cond; - - BTM_TRACE_EVENT ("BTM: BTM_EnableTestMode"); - - /* set auto accept connection as this is needed during test mode */ - /* Allocate a buffer to hold HCI command */ - cond = HCI_DO_AUTO_ACCEPT_CONNECT; - if (!btsnd_hcic_set_event_filter(HCI_FILTER_CONNECTION_SETUP, - HCI_FILTER_COND_NEW_DEVICE, - &cond, sizeof(cond))) { - return (BTM_NO_RESOURCES); - } - - /* put device to connectable mode */ - if (BTM_SetConnectability(BTM_CONNECTABLE, BTM_DEFAULT_CONN_WINDOW, - BTM_DEFAULT_CONN_INTERVAL) != BTM_SUCCESS) { - return BTM_NO_RESOURCES; - } - - /* put device to discoverable mode */ - if (BTM_SetDiscoverability(BTM_GENERAL_DISCOVERABLE, BTM_DEFAULT_DISC_WINDOW, - BTM_DEFAULT_DISC_INTERVAL) != BTM_SUCCESS) { - return BTM_NO_RESOURCES; - } - - /* mask off all of event from controller */ - hci_layer_get_interface()->transmit_command( - hci_packet_factory_get_interface()->make_set_event_mask((const bt_event_mask_t *)("\x00\x00\x00\x00\x00\x00\x00\x00")), - NULL, - NULL, - NULL); - - /* Send the HCI command */ - if (btsnd_hcic_enable_test_mode ()) { - return (BTM_SUCCESS); - } else { - return (BTM_NO_RESOURCES); - } -} -#endif // #if (BLE_HOST_ENABLE_TEST_MODE_EN == TRUE) - #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** From 41ab91471afa413d348f0891c09088afa08d0af0 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:26 +0800 Subject: [PATCH 126/226] fix(ble/bluedroid): Delete BLE_HOST_EXECUTE_CBACK_EN (cherry picked from commit 436fe484fe3698ad54c3313953d913d951caf864) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 22 ---------------- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 25 ------------------- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 3 --- .../bluedroid/bta/dm/include/bta_dm_int.h | 15 ----------- .../common/include/common/bt_target.h | 4 --- 5 files changed, 69 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index dfe1c952f4..55e3589c35 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -4659,28 +4659,6 @@ void bta_dm_eir_update_uuid(tBT_UUID uuid, BOOLEAN adding) } #endif -#if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) -/******************************************************************************* -** -** Function bta_dm_execute_callback -** -** Description Just execute a generic call back in the context of the BTU/BTA tack -** -** -** Returns void -** -*******************************************************************************/ -void bta_dm_execute_callback(tBTA_DM_MSG *p_data) -{ - /* sanity check */ - if (p_data->exec_cback.p_exec_cback == NULL) { - return; - } - - p_data->exec_cback.p_exec_cback(p_data->exec_cback.p_param); -} -#endif // #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) - /******************************************************************************* ** ** Function bta_dm_encrypt_cback diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index e67dc84186..1dc86e925c 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -1175,31 +1175,6 @@ tBTA_STATUS BTA_DmRemoveLocalDiRecord(UINT32 handle) } #endif ///SDP_INCLUDED == TRUE -#if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) -/******************************************************************************* -** -** Function bta_dmexecutecallback -** -** Description This function will request BTA to execute a call back in the context of BTU task -** This API was named in lower case because it is only intended -** for the internal customers(like BTIF). -** -** Returns void -** -*******************************************************************************/ -void bta_dmexecutecallback (tBTA_DM_EXEC_CBACK *p_callback, void *p_param) -{ - tBTA_DM_API_EXECUTE_CBACK *p_msg; - - if ((p_msg = (tBTA_DM_API_EXECUTE_CBACK *) osi_malloc(sizeof(tBTA_DM_API_EXECUTE_CBACK))) != NULL) { - p_msg->hdr.event = BTA_DM_API_EXECUTE_CBACK_EVT; - p_msg->p_param = p_param; - p_msg->p_exec_cback = p_callback; - bta_sys_sendmsg(p_msg); - } -} -#endif // #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) - /******************************************************************************* ** ** Function BTA_DmAddBleKey diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index cbcf05c0a9..cc80d0ffc1 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -183,9 +183,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) bta_dm_ble_disconnect, /* BTA_DM_API_BLE_DISCONNECT_EVT */ #endif -#if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) - bta_dm_execute_callback, /* BTA_DM_API_EXECUTE_CBACK_EVT */ -#endif // #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) #if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE) bta_dm_remove_all_acl, /* BTA_DM_API_REMOVE_ALL_ACL_EVT */ #endif // #if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 88fd5dc159..79e9e3fc93 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -169,9 +169,6 @@ enum { BTA_DM_API_BLE_DISCONNECT_EVT, #endif -#if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) - BTA_DM_API_EXECUTE_CBACK_EVT, -#endif // #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) #if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE) BTA_DM_API_REMOVE_ALL_ACL_EVT, #endif // #if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE) @@ -724,15 +721,6 @@ typedef struct { UINT8 transport; } tBTA_DM_API_REMOVE_DEVICE; -#if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) -/* data type for BTA_DM_API_EXECUTE_CBACK_EVT */ -typedef struct { - BT_HDR hdr; - void *p_param; - tBTA_DM_EXEC_CBACK *p_exec_cback; -} tBTA_DM_API_EXECUTE_CBACK; -#endif // #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) - /* data type for tBTA_DM_API_SET_ENCRYPTION */ typedef struct { BT_HDR hdr; @@ -1738,9 +1726,6 @@ typedef union { #endif /* #if (BTA_DM_QOS_INCLUDED == TRUE) */ tBTA_DM_API_DI_DISC di_disc; -#if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) - tBTA_DM_API_EXECUTE_CBACK exec_cback; -#endif // #if (BLE_HOST_EXECUTE_CBACK_EN == TRUE) tBTA_DM_API_SET_ENCRYPTION set_encryption; #if BLE_INCLUDED == TRUE 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 0b77119217..45d3ebd60f 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1612,10 +1612,6 @@ #define BLE_INCLUDED FALSE #endif -#ifndef BLE_HOST_EXECUTE_CBACK_EN -#define BLE_HOST_EXECUTE_CBACK_EN FALSE -#endif - #ifndef BLE_HOST_REMOVE_ALL_ACL_EN #define BLE_HOST_REMOVE_ALL_ACL_EN FALSE #endif From 819590604c4c5633fa66f6d5dec04129358609fc Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:27 +0800 Subject: [PATCH 127/226] fix(ble/bluedroid): Delete BLE_HOST_REMOVE_ALL_ACL_EN (cherry picked from commit ad04f39cf9789ef4bd33b390d6c783fca33f488c) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 31 ------------------- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 3 -- .../bluedroid/bta/dm/include/bta_dm_int.h | 16 ---------- .../common/include/common/bt_target.h | 4 --- 4 files changed, 54 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 55e3589c35..f6817785d9 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -1290,37 +1290,6 @@ void bta_dm_close_acl(tBTA_DM_MSG *p_data) } #endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) -#if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE) -/******************************************************************************* -** -** Function bta_dm_remove_all_acl -** -** Description This function forces to close all the ACL links specified by link type -**** -*******************************************************************************/ -void bta_dm_remove_all_acl(tBTA_DM_MSG *p_data) -{ - const tBTA_DM_LINK_TYPE link_type = p_data->remove_all_acl.link_type; - tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; - - APPL_TRACE_DEBUG("%s link type = %d", __func__, link_type); - - for (UINT8 i = 0; i < bta_dm_cb.device_list.count; i++) { - BD_ADDR addr = {0}; - bdcpy(addr, bta_dm_cb.device_list.peer_device[i].peer_bdaddr); -#if defined (BLE_INCLUDED) && (BLE_INCLUDED == TRUE) - transport = bta_dm_cb.device_list.peer_device[i].transport; -#endif - if ((link_type == BTA_DM_LINK_TYPE_ALL) || - ((link_type == BTA_DM_LINK_TYPE_LE) && (transport == BT_TRANSPORT_LE)) || - ((link_type == BTA_DM_LINK_TYPE_BR_EDR) && (transport == BT_TRANSPORT_BR_EDR))) { - /* Disconnect the ACL link */ - btm_remove_acl(addr, transport); - } - } -} -#endif // #if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE) - /******************************************************************************* ** ** Function bta_dm_bond diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index cc80d0ffc1..3a3a383852 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -183,9 +183,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { #endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) bta_dm_ble_disconnect, /* BTA_DM_API_BLE_DISCONNECT_EVT */ #endif -#if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE) - bta_dm_remove_all_acl, /* BTA_DM_API_REMOVE_ALL_ACL_EVT */ -#endif // #if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE) bta_dm_remove_device, /* BTA_DM_API_REMOVE_DEVICE_EVT */ bta_dm_ble_set_channels, /* BTA_DM_API_BLE_SET_CHANNELS_EVT */ bta_dm_update_white_list, /* BTA_DM_API_UPDATE_WHITE_LIST_EVT */ diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 79e9e3fc93..e53ddf4192 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -169,9 +169,6 @@ enum { BTA_DM_API_BLE_DISCONNECT_EVT, #endif -#if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE) - BTA_DM_API_REMOVE_ALL_ACL_EVT, -#endif // #if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE) BTA_DM_API_REMOVE_DEVICE_EVT, BTA_DM_API_BLE_SET_CHANNELS_EVT, BTA_DM_API_UPDATE_WHITE_LIST_EVT, @@ -1229,15 +1226,6 @@ typedef struct { } tBTA_DM_API_REMOVE_ACL; #endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) -#if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE) -/* data type for BTA_DM_API_REMOVE_ALL_ACL_EVT */ -typedef struct { - BT_HDR hdr; - tBTA_DM_LINK_TYPE link_type; - -} tBTA_DM_API_REMOVE_ALL_ACL; -#endif // #if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE) - typedef struct { BT_HDR hdr; BD_ADDR bd_addr; @@ -1813,9 +1801,6 @@ typedef union { #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) tBTA_DM_API_REMOVE_ACL remove_acl; #endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) -#if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE) - tBTA_DM_API_REMOVE_ALL_ACL remove_all_acl; -#endif // #if (BLE_HOST_REMOVE_ALL_ACL_EN == TRUE) #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) @@ -2423,7 +2408,6 @@ extern void bta_dm_disable_test_mode(tBTA_DM_MSG *p_data); extern void bta_dm_execute_callback(tBTA_DM_MSG *p_data); -extern void bta_dm_remove_all_acl(tBTA_DM_MSG *p_data); #if (BLE_50_FEATURE_SUPPORT == TRUE) extern void bta_dm_ble_gap_read_phy(tBTA_DM_MSG *p_data); 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 45d3ebd60f..74c423686c 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1612,10 +1612,6 @@ #define BLE_INCLUDED FALSE #endif -#ifndef BLE_HOST_REMOVE_ALL_ACL_EN -#define BLE_HOST_REMOVE_ALL_ACL_EN FALSE -#endif - #ifndef BLE_HOST_REMOVE_AN_ACL_EN #define BLE_HOST_REMOVE_AN_ACL_EN FALSE #endif From fae64d3fd8f7a33c69a937c811c6847cd9c14d4d Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:27 +0800 Subject: [PATCH 128/226] fix(ble/bluedroid): Delete BLE_HOST_REMOVE_AN_ACL_EN (cherry picked from commit 5a1a3b9ebaa5282df5987c1d5a0b2b7a90a86226) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 48 ------------------- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 34 ------------- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 3 -- .../bluedroid/bta/dm/include/bta_dm_int.h | 18 ------- .../common/include/common/bt_target.h | 4 -- 5 files changed, 107 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index f6817785d9..c7cc7ed318 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -1242,54 +1242,6 @@ void bta_dm_add_device (tBTA_DM_MSG *p_data) } } -#if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) -/******************************************************************************* -** -** Function bta_dm_close_acl -** -** Description This function forces to close the connection to a remote device -** and optionally remove the device from security database if -** required. -**** -*******************************************************************************/ -void bta_dm_close_acl(tBTA_DM_MSG *p_data) -{ - tBTA_DM_API_REMOVE_ACL *p_remove_acl = &p_data->remove_acl; - UINT8 index; - - APPL_TRACE_DEBUG("bta_dm_close_acl"); - - if (BTM_IsAclConnectionUp(p_remove_acl->bd_addr, p_remove_acl->transport)) { - for (index = 0; index < bta_dm_cb.device_list.count; index ++) { - if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, p_remove_acl->bd_addr)) { - break; - } - } - if (index != bta_dm_cb.device_list.count) { - if (p_remove_acl->remove_dev) { - bta_dm_cb.device_list.peer_device[index].remove_dev_pending = TRUE; - } - } else { - APPL_TRACE_ERROR("unknown device, remove ACL failed"); - } - /* Disconnect the ACL link */ - btm_remove_acl(p_remove_acl->bd_addr, p_remove_acl->transport); - } - /* if to remove the device from security database ? do it now */ - else if (p_remove_acl->remove_dev) { - if (!BTM_SecDeleteDevice(p_remove_acl->bd_addr, p_remove_acl->transport)) { - APPL_TRACE_ERROR("delete device from security database failed."); - } -#if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE) - /* need to remove all pending background connection if any */ - BTA_GATTC_CancelOpen(0, p_remove_acl->bd_addr, FALSE); -#endif - } - /* otherwise, no action needed */ - -} -#endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) - /******************************************************************************* ** ** Function bta_dm_bond diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 1dc86e925c..68c3dfb059 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -2195,40 +2195,6 @@ void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_DM_ENCR } #endif ///SMP_INCLUDED == TRUE -#if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) -/******************************************************************************* -** -** Function BTA_DmCloseACL -** -** Description This function force to close an ACL connection and remove the -** device from the security database list of known devices. -** -** Parameters: bd_addr - Address of the peer device -** remove_dev - remove device or not after link down -** -** Returns void -** -*******************************************************************************/ -void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev, tBTA_TRANSPORT transport) -{ - tBTA_DM_API_REMOVE_ACL *p_msg; - - APPL_TRACE_API("BTA_DmCloseACL"); - - if ((p_msg = (tBTA_DM_API_REMOVE_ACL *) osi_malloc(sizeof(tBTA_DM_API_REMOVE_ACL))) != NULL) { - memset(p_msg, 0, sizeof(tBTA_DM_API_REMOVE_ACL)); - - p_msg->hdr.event = BTA_DM_API_REMOVE_ACL_EVT; - - memcpy(p_msg->bd_addr, bd_addr, BD_ADDR_LEN); - p_msg->remove_dev = remove_dev; - p_msg->transport = transport; - - bta_sys_sendmsg(p_msg); - } -} -#endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) - #if BLE_INCLUDED == TRUE #if (BLE_42_SCAN_EN == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 3a3a383852..407f595408 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -94,9 +94,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { #endif // #if (CLASSIC_BT_INCLUDED == TRUE) bta_dm_acl_change, /* BTA_DM_ACL_CHANGE_EVT */ bta_dm_add_device, /* BTA_DM_API_ADD_DEVICE_EVT */ -#if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) - bta_dm_close_acl, /* BTA_DM_API_REMOVE_ACL_EVT */ -#endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) #if (SMP_INCLUDED == TRUE) /* security API events */ bta_dm_bond, /* BTA_DM_API_BOND_EVT */ diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index e53ddf4192..42760f79de 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -80,9 +80,6 @@ enum { BTA_DM_ACL_CHANGE_EVT, BTA_DM_API_ADD_DEVICE_EVT, -#if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) - BTA_DM_API_REMOVE_ACL_EVT, -#endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) #if (SMP_INCLUDED == TRUE) /* security API events */ BTA_DM_API_BOND_EVT, @@ -1215,17 +1212,6 @@ typedef struct { #endif /* BLE_INCLUDED */ -#if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) -/* data type for BTA_DM_API_REMOVE_ACL_EVT */ -typedef struct { - BT_HDR hdr; - BD_ADDR bd_addr; - BOOLEAN remove_dev; - tBTA_TRANSPORT transport; - -} tBTA_DM_API_REMOVE_ACL; -#endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) - typedef struct { BT_HDR hdr; BD_ADDR bd_addr; @@ -1798,10 +1784,6 @@ typedef union { tBTA_DM_API_BLE_SET_CSA_SUPPORT ble_set_csa_support; tBTA_DM_API_BLE_SET_VENDOR_EVT_MASK ble_set_vendor_evt_mask; #endif -#if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) - tBTA_DM_API_REMOVE_ACL remove_acl; -#endif // #if (BLE_HOST_REMOVE_AN_ACL_EN == TRUE) - #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) tBTA_DM_API_BIG_CREATE big_creat; 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 74c423686c..a901870fe2 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1612,10 +1612,6 @@ #define BLE_INCLUDED FALSE #endif -#ifndef BLE_HOST_REMOVE_AN_ACL_EN -#define BLE_HOST_REMOVE_AN_ACL_EN FALSE -#endif - #ifndef BLE_HOST_READ_TX_POWER_EN #define BLE_HOST_READ_TX_POWER_EN FALSE #endif From 70b0e41a0675b6f000494d0fb075fbc41445b37b Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:28 +0800 Subject: [PATCH 129/226] fix(ble/bluedroid): Delete BLE_HOST_READ_TX_POWER_EN (cherry picked from commit 1c0c48b81483b3f2cb341626d3a759dccc72635d) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 12 -- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 12 -- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 3 - .../bluedroid/bta/dm/include/bta_dm_int.h | 13 -- .../common/include/common/bt_target.h | 4 - .../bt/host/bluedroid/stack/btm/btm_acl.c | 161 ------------------ .../bluedroid/stack/btm/include/btm_int.h | 5 - .../bt/host/bluedroid/stack/btu/btu_hcif.c | 6 - .../bluedroid/stack/include/stack/btm_api.h | 22 --- 9 files changed, 238 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index c7cc7ed318..c0e75d95c1 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -998,18 +998,6 @@ void bta_dm_clear_white_list(tBTA_DM_MSG *p_data) BTM_BleClearWhitelist(p_data->white_list.update_wl_cb); #endif } -#if (BLE_HOST_READ_TX_POWER_EN == TRUE) -void bta_dm_ble_read_adv_tx_power(tBTA_DM_MSG *p_data) -{ -#if (BLE_INCLUDED == TRUE) - if (p_data->read_tx_power.read_tx_power_cb != NULL) { - BTM_BleReadAdvTxPower(p_data->read_tx_power.read_tx_power_cb); - } else { - APPL_TRACE_ERROR("%s(), the callback function can't be NULL.", __func__); - } -#endif ///BLE_INCLUDED == TRUE -} -#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) void bta_dm_read_rssi(tBTA_DM_MSG *p_data) { diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 68c3dfb059..850155de4a 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -493,18 +493,6 @@ void BTA_DmClearWhiteList(tBTA_UPDATE_WHITELIST_CBACK *update_wl_cb) } } -#if (BLE_HOST_READ_TX_POWER_EN == TRUE) -void BTA_DmBleReadAdvTxPower(tBTA_CMPL_CB *cmpl_cb) -{ - tBTA_DM_API_READ_ADV_TX_POWER *p_msg; - if ((p_msg = (tBTA_DM_API_READ_ADV_TX_POWER *)osi_malloc(sizeof(tBTA_DM_API_READ_ADV_TX_POWER))) != NULL) { - p_msg->hdr.event = BTA_DM_API_BLE_READ_ADV_TX_POWER_EVT; - p_msg->read_tx_power_cb = cmpl_cb; - bta_sys_sendmsg(p_msg); - } -} -#endif // BLE_HOST_READ_TX_POWER_EN - void BTA_DmBleReadChannelMap(BD_ADDR remote_device, tBTA_CMPL_CB *p_callback) { if (!remote_device || !p_callback) { diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 407f595408..6a2f9eabc6 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -184,9 +184,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_set_channels, /* BTA_DM_API_BLE_SET_CHANNELS_EVT */ bta_dm_update_white_list, /* BTA_DM_API_UPDATE_WHITE_LIST_EVT */ bta_dm_clear_white_list, /* BTA_DM_API_CLEAR_WHITE_LIST_EVT */ -#if (BLE_HOST_READ_TX_POWER_EN == TRUE) - bta_dm_ble_read_adv_tx_power, /* BTA_DM_API_BLE_READ_ADV_TX_POWER_EVT */ -#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) bta_dm_read_rssi, /* BTA_DM_API_READ_RSSI_EVT */ #if BLE_INCLUDED == TRUE bta_dm_ble_update_duplicate_exceptional_list,/* BTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_EVT */ diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 42760f79de..18607a16be 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -170,9 +170,6 @@ enum { BTA_DM_API_BLE_SET_CHANNELS_EVT, BTA_DM_API_UPDATE_WHITE_LIST_EVT, BTA_DM_API_CLEAR_WHITE_LIST_EVT, -#if (BLE_HOST_READ_TX_POWER_EN == TRUE) - BTA_DM_API_BLE_READ_ADV_TX_POWER_EVT, -#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) BTA_DM_API_READ_RSSI_EVT, #if BLE_INCLUDED == TRUE BTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_EVT, @@ -447,13 +444,6 @@ typedef struct { tBTA_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK *exceptional_list_cb; }tBTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST; -#if (BLE_HOST_READ_TX_POWER_EN == TRUE) -typedef struct { - BT_HDR hdr; - tBTA_CMPL_CB *read_tx_power_cb; -}tBTA_DM_API_READ_ADV_TX_POWER; -#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) - #endif ///BLE_INCLUDED == TRUE typedef struct { @@ -1645,9 +1635,6 @@ typedef union { #if (BLE_INCLUDED == TRUE) tBTA_DM_API_BLE_SET_CHANNELS ble_set_channels; tBTA_DM_API_UPDATE_WHITE_LIST white_list; -#if (BLE_HOST_READ_TX_POWER_EN == TRUE) - tBTA_DM_API_READ_ADV_TX_POWER read_tx_power; -#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) #endif ///BLE_INCLUDED == TRUE tBTA_DM_API_READ_RSSI rssi; 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 a901870fe2..a188de1a3d 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1612,10 +1612,6 @@ #define BLE_INCLUDED FALSE #endif -#ifndef BLE_HOST_READ_TX_POWER_EN -#define BLE_HOST_READ_TX_POWER_EN FALSE -#endif - #ifndef BLE_HOST_SETUP_STORAGE_EN #define BLE_HOST_SETUP_STORAGE_EN FALSE #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_acl.c b/components/bt/host/bluedroid/stack/btm/btm_acl.c index 24ffea9fa9..6c3f7e4c31 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_acl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_acl.c @@ -2092,65 +2092,6 @@ tBTM_STATUS BTM_ReadLinkQuality (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb) return (BTM_UNKNOWN_ADDR); } -#if (BLE_HOST_READ_TX_POWER_EN == TRUE) -/******************************************************************************* -** -** Function BTM_ReadTxPower -** -** Description This function is called to read the current -** TX power of the connection. The tx power level results -** are returned in the callback. -** (tBTM_RSSI_RESULTS) -** -** Returns BTM_CMD_STARTED if successfully initiated or error code -** -*******************************************************************************/ -tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb) -{ - tACL_CONN *p; - BOOLEAN ret; -#define BTM_READ_RSSI_TYPE_CUR 0x00 -#define BTM_READ_RSSI_TYPE_MAX 0X01 - - BTM_TRACE_API ("BTM_ReadTxPower: RemBdAddr: %02x%02x%02x%02x%02x%02x\n", - remote_bda[0], remote_bda[1], remote_bda[2], - remote_bda[3], remote_bda[4], remote_bda[5]); - - /* If someone already waiting on the version, do not allow another */ - if (btm_cb.devcb.p_tx_power_cmpl_cb) { - return (BTM_BUSY); - } - - p = btm_bda_to_acl(remote_bda, transport); - if (p != (tACL_CONN *)NULL) { - btu_start_timer (&btm_cb.devcb.tx_power_timer, BTU_TTYPE_BTM_ACL, - BTM_DEV_REPLY_TIMEOUT); - - btm_cb.devcb.p_tx_power_cmpl_cb = p_cb; - -#if BLE_INCLUDED == TRUE - if (p->transport == BT_TRANSPORT_LE) { - memcpy(btm_cb.devcb.read_tx_pwr_addr, remote_bda, BD_ADDR_LEN); - ret = btsnd_hcic_ble_read_adv_chnl_tx_power(); - } else -#endif - { - ret = btsnd_hcic_read_tx_power (p->hci_handle, BTM_READ_RSSI_TYPE_CUR); - } - if (!ret) { - btm_cb.devcb.p_tx_power_cmpl_cb = NULL; - btu_stop_timer (&btm_cb.devcb.tx_power_timer); - return (BTM_NO_RESOURCES); - } else { - return (BTM_CMD_STARTED); - } - } - - /* If here, no BD Addr found */ - return (BTM_UNKNOWN_ADDR); -} -#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) - tBTM_STATUS BTM_SetAclPktTypes(BD_ADDR remote_bda, UINT16 pkt_types, tBTM_CMPL_CB *p_cb) { #if CLASSIC_BT_INCLUDED == TRUE @@ -2264,35 +2205,6 @@ tBTM_STATUS BTM_ReadChannelMap(BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb) return BTM_UNKNOWN_ADDR; } -#if (BLE_HOST_READ_TX_POWER_EN == TRUE) -tBTM_STATUS BTM_BleReadAdvTxPower(tBTM_CMPL_CB *p_cb) -{ - BOOLEAN ret; - tBTM_TX_POWER_RESULTS result; - /* If someone already waiting on the version, do not allow another */ - if (btm_cb.devcb.p_tx_power_cmpl_cb) { - result.status = BTM_BUSY; - (*p_cb)(&result); - return (BTM_BUSY); - } - - btm_cb.devcb.p_tx_power_cmpl_cb = p_cb; - btu_start_timer (&btm_cb.devcb.tx_power_timer, BTU_TTYPE_BTM_ACL, - BTM_DEV_REPLY_TIMEOUT); - ret = btsnd_hcic_ble_read_adv_chnl_tx_power(); - - if(!ret) { - btm_cb.devcb.p_tx_power_cmpl_cb = NULL; - btu_stop_timer (&btm_cb.devcb.tx_power_timer); - result.status = BTM_NO_RESOURCES; - (*p_cb)(&result); - return (BTM_NO_RESOURCES); - } else { - return BTM_CMD_STARTED; - } -} -#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) - void BTM_BleGetWhiteListSize(uint16_t *length) { tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; @@ -2316,79 +2228,6 @@ void BTM_BleGetPeriodicAdvListSize(uint8_t *size) #endif ///BLE_INCLUDED == TRUE -#if (BLE_HOST_READ_TX_POWER_EN == TRUE) -/******************************************************************************* -** -** Function btm_read_tx_power_complete -** -** Description This function is called when the command complete message -** is received from the HCI for the read tx power request. -** -** Returns void -** -*******************************************************************************/ -void btm_read_tx_power_complete (UINT8 *p, UINT16 evt_len, BOOLEAN is_ble) -{ - tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_tx_power_cmpl_cb; - tBTM_TX_POWER_RESULTS results; - UINT16 handle; - tACL_CONN *p_acl_cb = NULL; - BTM_TRACE_DEBUG ("btm_read_tx_power_complete\n"); - btu_stop_timer (&btm_cb.devcb.tx_power_timer); - - /* If there was a callback registered for read rssi, call it */ - btm_cb.devcb.p_tx_power_cmpl_cb = NULL; - - if (p_cb) { - if (evt_len < 1) { - BTM_TRACE_ERROR("Bogus event packet, too short\n"); - results.status = BTM_ERR_PROCESSING; - goto err_out; - } - - STREAM_TO_UINT8 (results.hci_status, p); - - if (results.hci_status == HCI_SUCCESS) { - results.status = BTM_SUCCESS; - - if (!is_ble) { - if (evt_len < 1 + 3) { - BTM_TRACE_ERROR("Bogus event packet, too short\n"); - results.status = BTM_ERR_PROCESSING; - goto err_out; - } - STREAM_TO_UINT16 (handle, p); - STREAM_TO_UINT8 (results.tx_power, p); - - /* Search through the list of active channels for the correct BD Addr */ - p_acl_cb = btm_handle_to_acl(handle); - if (p_acl_cb) { - memcpy (results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN); - } - } -#if BLE_INCLUDED == TRUE - else { - if (evt_len < 1 + 1) { - BTM_TRACE_ERROR("Bogus event packet, too short\n"); - results.status = BTM_ERR_PROCESSING; - goto err_out; - } - STREAM_TO_UINT8 (results.tx_power, p); - memcpy(results.rem_bda, btm_cb.devcb.read_tx_pwr_addr, BD_ADDR_LEN); - } -#endif - BTM_TRACE_DEBUG ("BTM TX power Complete: tx_power %d, hci status 0x%02x\n", - results.tx_power, results.hci_status); - } else { - results.status = BTM_ERR_PROCESSING; - } - -err_out: - (*p_cb)(&results); - } -} -#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) - /******************************************************************************* ** ** Function btm_read_channel_map_complete diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index 57fa5f002d..e3cfbe396b 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -221,11 +221,6 @@ tBTM_CMPL_CB *p_switch_role_cb; /* Callback function to be called when /* requested switch role is completed */ #endif // (CLASSIC_BT_INCLUDED == TRUE) -#if (BLE_HOST_READ_TX_POWER_EN == TRUE) -TIMER_LIST_ENT tx_power_timer; -tBTM_CMPL_CB *p_tx_power_cmpl_cb;/* Callback function to be called */ -#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) - #if CLASSIC_BT_INCLUDED == TRUE TIMER_LIST_ENT afh_channels_timer; tBTM_CMPL_CB *p_afh_channels_cmpl_cb; /* Callback function to be called When */ diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index d018f6a83e..73dfb57fdb 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -1227,9 +1227,6 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l btm_read_channel_map_complete (p); break; case HCI_READ_TRANSMIT_POWER_LEVEL: -#if (BLE_HOST_READ_TX_POWER_EN == TRUE) - btm_read_tx_power_complete(p, evt_len, FALSE); -#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) break; #if (CLASSIC_BT_INCLUDED == TRUE) case HCI_CREATE_CONNECTION_CANCEL: @@ -1309,9 +1306,6 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l break; case HCI_BLE_READ_ADV_CHNL_TX_POWER: -#if (BLE_HOST_READ_TX_POWER_EN == TRUE) - btm_read_tx_power_complete(p, evt_len, TRUE); -#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) break; #if (BLE_42_ADV_EN == TRUE) case HCI_BLE_WRITE_ADV_ENABLE: diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_api.h index 74af148f03..3f932d087d 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_api.h @@ -3030,28 +3030,6 @@ tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL ** *******************************************************************************/ tBTM_STATUS BTM_ReadChannelMap(BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb); -#if (BLE_HOST_READ_TX_POWER_EN == TRUE) -/******************************************************************************* -** -** Function BTM_ReadTxPower -** -** Description This function is called to read the current connection -** TX power of the connection. The TX power level results -** are returned in the callback. -** (tBTM_RSSI_RESULTS) -** -** Returns BTM_CMD_STARTED if command issued to controller. -** BTM_NO_RESOURCES if couldn't allocate memory to issue command -** BTM_UNKNOWN_ADDR if no active link with bd addr specified -** BTM_BUSY if command is already in progress -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, - tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb); - -tBTM_STATUS BTM_BleReadAdvTxPower(tBTM_CMPL_CB *p_cb); -#endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) void BTM_BleGetWhiteListSize(uint16_t *length); From 4965bc14ee8d3b42d024294f6494ad95ea27df4c Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:28 +0800 Subject: [PATCH 130/226] fix(ble/bluedroid): Delete BLE_HOST_SETUP_STORAGE_EN (cherry picked from commit 08740df98867cac0af5e00a7ea3eef8f7f1bbe34) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 73 ------------------- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 42 ----------- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 3 - .../bluedroid/bta/dm/include/bta_dm_int.h | 25 ------- .../host/bluedroid/bta/include/bta/bta_api.h | 62 ---------------- .../common/include/common/bt_target.h | 4 - .../stack/include/stack/btm_ble_api.h | 14 ---- 7 files changed, 223 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index c0e75d95c1..4fd35c54df 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -6125,79 +6125,6 @@ void bta_dm_api_cs_procedure_enable(tBTA_DM_MSG *p_data) } #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) -#if (BLE_HOST_SETUP_STORAGE_EN == TRUE) -/******************************************************************************* -** -** Function bta_dm_ble_setup_storage -** -** Description This function configures up the storage parameters for ADV batch scanning -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_ble_setup_storage (tBTA_DM_MSG *p_data) -{ - tBTM_STATUS btm_status = 0; - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - - if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) { - btm_status = BTM_BleSetStorageConfig(p_data->ble_set_storage.batch_scan_full_max, - p_data->ble_set_storage.batch_scan_trunc_max, - p_data->ble_set_storage.batch_scan_notify_threshold, - p_data->ble_set_storage.p_setup_cback, - p_data->ble_set_storage.p_thres_cback, - p_data->ble_set_storage.p_read_rep_cback, - p_data->ble_set_storage.ref_value); - } - - if (BTM_CMD_STARTED != btm_status) { - bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_CFG_STRG_EVT, p_data->ble_set_storage.ref_value, - btm_status); - } -} -#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) - -/******************************************************************************* -** -** Function bta_ble_scan_setup_cb -** -** Description Handle the setup callback from BTM layer and forward it to app layer -** -** Parameters: -** -*******************************************************************************/ -void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_value, - tBTM_STATUS status) -{ - tBTA_BLE_BATCH_SCAN_EVT bta_evt = 0; - - APPL_TRACE_DEBUG("bta_ble_scan_setup_cb : evt: %d, ref_value: %d, status:%d", evt, - ref_value, status); - - switch (evt) { - case BTM_BLE_BATCH_SCAN_ENABLE_EVT: - bta_evt = BTA_BLE_BATCH_SCAN_ENB_EVT; - break; - case BTM_BLE_BATCH_SCAN_CFG_STRG_EVT: - bta_evt = BTA_BLE_BATCH_SCAN_CFG_STRG_EVT; - break; - case BTM_BLE_BATCH_SCAN_DISABLE_EVT: - bta_evt = BTA_BLE_BATCH_SCAN_DIS_EVT; - break; - case BTM_BLE_BATCH_SCAN_PARAM_EVT: - bta_evt = BTA_BLE_BATCH_SCAN_PARAM_EVT; - break; - default: - break; - } - - if (NULL != bta_dm_cb.p_setup_cback) { - bta_dm_cb.p_setup_cback(bta_evt, ref_value, status); - } -} - #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE) #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT #define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000 diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 850155de4a..ffd2872f85 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -1605,48 +1605,6 @@ void BTA_DmUpdateDuplicateExceptionalList(UINT8 subcode, UINT32 type, BD_ADDR de bta_sys_sendmsg(p_msg); } } -#if (BLE_HOST_SETUP_STORAGE_EN == TRUE) -/******************************************************************************* -** -** Function BTA_DmBleSetStorageParams -** -** Description This function is called to override the BTA scan response. -** -** Parameters batch_scan_full_max -Max storage space (in %) allocated to full scanning -** batch_scan_trunc_max -Max storage space (in %) allocated to truncated scanning -** batch_scan_notify_threshold -Setup notification level based on total space -** p_setup_cback - Setup callback pointer -** p_thres_cback - Threshold callback pointer -** p_rep_cback - Reports callback pointer -** ref_value - Ref value -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleSetStorageParams(UINT8 batch_scan_full_max, - UINT8 batch_scan_trunc_max, - UINT8 batch_scan_notify_threshold, - tBTA_BLE_SCAN_SETUP_CBACK *p_setup_cback, - tBTA_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback, - tBTA_BLE_SCAN_REP_CBACK *p_rep_cback, - tBTA_DM_BLE_REF_VALUE ref_value) -{ - tBTA_DM_API_SET_STORAGE_CONFIG *p_msg; - bta_dm_cb.p_setup_cback = p_setup_cback; - if ((p_msg = (tBTA_DM_API_SET_STORAGE_CONFIG *) - osi_malloc(sizeof(tBTA_DM_API_SET_STORAGE_CONFIG))) != NULL) { - p_msg->hdr.event = BTA_DM_API_BLE_SETUP_STORAGE_EVT; - p_msg->p_setup_cback = bta_ble_scan_setup_cb; - p_msg->p_thres_cback = p_thres_cback; - p_msg->p_read_rep_cback = p_rep_cback; - p_msg->ref_value = ref_value; - p_msg->batch_scan_full_max = batch_scan_full_max; - p_msg->batch_scan_trunc_max = batch_scan_trunc_max; - p_msg->batch_scan_notify_threshold = batch_scan_notify_threshold; - bta_sys_sendmsg(p_msg); - } -} -#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) #endif diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 6a2f9eabc6..377a2ac949 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -175,9 +175,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_broadcast, /* BTA_DM_API_BLE_BROADCAST_EVT */ #endif // #if (BLE_42_ADV_EN == TRUE) bta_dm_ble_set_data_length, /* BTA_DM_API_SET_DATA_LENGTH_EVT */ -#if (BLE_HOST_SETUP_STORAGE_EN == TRUE) - bta_dm_ble_setup_storage, /* BTA_DM_API_BLE_SETUP_STORAGE_EVT */ -#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) bta_dm_ble_disconnect, /* BTA_DM_API_BLE_DISCONNECT_EVT */ #endif bta_dm_remove_device, /* BTA_DM_API_REMOVE_DEVICE_EVT */ diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 18607a16be..a0c1fce523 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -159,9 +159,6 @@ enum { BTA_DM_API_BLE_BROADCAST_EVT, #endif // #if (BLE_42_ADV_EN == TRUE) BTA_DM_API_SET_DATA_LENGTH_EVT, -#if (BLE_HOST_SETUP_STORAGE_EN == TRUE) - BTA_DM_API_BLE_SETUP_STORAGE_EVT, -#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) BTA_DM_API_BLE_DISCONNECT_EVT, @@ -909,19 +906,6 @@ typedef struct { tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback; } tBTA_DM_API_SET_ADV_CONFIG_RAW; -#if (BLE_HOST_SETUP_STORAGE_EN == TRUE) -typedef struct { - BT_HDR hdr; - UINT8 batch_scan_full_max; - UINT8 batch_scan_trunc_max; - UINT8 batch_scan_notify_threshold; - tBTA_BLE_SCAN_SETUP_CBACK *p_setup_cback; - tBTA_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback; - tBTA_BLE_SCAN_REP_CBACK *p_read_rep_cback; - tBTA_DM_BLE_REF_VALUE ref_value; -} tBTA_DM_API_SET_STORAGE_CONFIG; -#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) - typedef struct { BT_HDR hdr; BD_ADDR remote_bda; @@ -1715,9 +1699,6 @@ typedef union { tBTA_DM_APT_CLEAR_ADDR clear_addr; tBTA_DM_API_SET_RPA_TIMEOUT set_rpa_timeout; tBTA_DM_API_ADD_DEV_TO_RESOLVING_LIST add_dev_to_resolving_list; -#if (BLE_HOST_SETUP_STORAGE_EN == TRUE) - tBTA_DM_API_SET_STORAGE_CONFIG ble_set_storage; -#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) tBTA_DM_API_BLE_DISCONNECT ble_disconnect; tBTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST ble_duplicate_exceptional_list; #if (BLE_50_FEATURE_SUPPORT == TRUE) @@ -1955,9 +1936,6 @@ typedef struct { BOOLEAN is_bta_dm_active; tBTA_DM_ACTIVE_LINK device_list; tBTA_DM_SEC_CBACK *p_sec_cback; -#if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) - tBTA_BLE_SCAN_SETUP_CBACK *p_setup_cback; -#endif UINT16 state; BOOLEAN disabling; TIMER_LIST_ENT disable_timer; @@ -2308,9 +2286,6 @@ extern void bta_dm_ble_gap_set_ext_scan_params(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_ext_scan(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_set_prefer_ext_conn_params(tBTA_DM_MSG *p_data); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) -#if (BLE_HOST_SETUP_STORAGE_EN == TRUE) -extern void bta_dm_ble_setup_storage(tBTA_DM_MSG *p_data); -#endif // #if (BLE_HOST_SETUP_STORAGE_EN == TRUE) extern void bta_dm_ble_enable_batch_scan(tBTA_DM_MSG *p_data); extern void bta_dm_ble_disable_batch_scan(tBTA_DM_MSG *p_data); extern void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data); diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 3f8c0524e4..1945148848 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -530,16 +530,6 @@ enum { }; typedef UINT8 tBTA_BLE_ADV_CHANGE_REASON; -enum { - BTA_BLE_BATCH_SCAN_ENB_EVT = 1, - BTA_BLE_BATCH_SCAN_CFG_STRG_EVT = 2, - BTA_BLE_BATCH_SCAN_DATA_EVT = 3, - BTA_BLE_BATCH_SCAN_THRES_EVT = 4, - BTA_BLE_BATCH_SCAN_PARAM_EVT = 5, - BTA_BLE_BATCH_SCAN_DIS_EVT = 6 -}; -typedef tBTM_BLE_BATCH_SCAN_EVT tBTA_BLE_BATCH_SCAN_EVT; - // #endif /* BLE customer specific feature function type definitions */ @@ -1218,10 +1208,6 @@ typedef void (tBTA_BLE_SCAN_REP_CBACK) (tBTA_DM_BLE_REF_VALUE ref_value, UINT8 r UINT8 num_records, UINT16 data_len, UINT8 *p_rep_data, tBTA_STATUS status); -typedef void (tBTA_BLE_SCAN_SETUP_CBACK) (tBTA_BLE_BATCH_SCAN_EVT evt, - tBTA_DM_BLE_REF_VALUE ref_value, - tBTA_STATUS status); - typedef void (tBTA_START_STOP_SCAN_CMPL_CBACK) (tBTA_STATUS status); typedef void (tBTA_START_STOP_ADV_CMPL_CBACK) (tBTA_STATUS status); @@ -3033,54 +3019,6 @@ void BTA_DmBleGapCsSetProcPatams(tBTA_DM_CS_SET_PROC_PARAMS *set_proc_params); void BTA_DmBleGapCsProcEnable(uint16_t conn_handle, uint8_t config_id, uint8_t enable); #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) -/******************************************************************************* -** -** Function BTA_DmBleSetStorageParams -** -** Description This function is called to set the storage parameters -** -** Parameters batch_scan_full_max -Max storage space (in %) allocated to full scanning -** batch_scan_trunc_max -Max storage space (in %) allocated to truncated scanning -** batch_scan_notify_threshold - Setup notification level based on total space -** consumed by both pools. Setting it to 0 will disable threshold notification -** p_setup_cback - Setup callback -** p_thres_cback - Threshold callback -** p_rep_cback - Reports callback -** ref_value - Reference value -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleSetStorageParams(UINT8 batch_scan_full_max, - UINT8 batch_scan_trunc_max, - UINT8 batch_scan_notify_threshold, - tBTA_BLE_SCAN_SETUP_CBACK *p_setup_cback, - tBTA_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback, - tBTA_BLE_SCAN_REP_CBACK *p_rep_cback, - tBTA_DM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTA_DmBleEnableBatchScan -** -** Description This function is called to enable the batch scan -** -** Parameters scan_mode -Batch scan mode -** scan_interval - Scan interval -** scan_window - Scan window -** discard_rule -Discard rules -** addr_type - Address type -** ref_value - Reference value -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleEnableBatchScan(tBTA_BLE_BATCH_SCAN_MODE scan_mode, - UINT32 scan_interval, UINT32 scan_window, - tBTA_BLE_DISCARD_RULE discard_rule, - tBLE_ADDR_TYPE addr_type, - tBTA_DM_BLE_REF_VALUE ref_value); - /******************************************************************************* ** ** Function BTA_DmBleReadScanReports 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 a188de1a3d..2ff4ba171a 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1612,10 +1612,6 @@ #define BLE_INCLUDED FALSE #endif -#ifndef BLE_HOST_SETUP_STORAGE_EN -#define BLE_HOST_SETUP_STORAGE_EN FALSE -#endif - #ifndef BLE_HOST_BG_CONNECT_EN #define BLE_HOST_BG_CONNECT_EN FALSE #endif 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 cda8df761c..f6902af8d8 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 @@ -913,18 +913,6 @@ typedef UINT8 tBTM_BLE_CONN_TYPE; #define ADV_INFO_PRESENT 0x00 #define NO_ADV_INFO_PRESENT 0x01 -#define BTM_BLE_MULTI_ADV_INVALID 0 - -#define BTM_BLE_BATCH_SCAN_ENABLE_EVT 1 -#define BTM_BLE_BATCH_SCAN_CFG_STRG_EVT 2 -#define BTM_BLE_BATCH_SCAN_READ_REPTS_EVT 3 -#define BTM_BLE_BATCH_SCAN_THR_EVT 4 -#define BTM_BLE_BATCH_SCAN_PARAM_EVT 5 -#define BTM_BLE_BATCH_SCAN_DISABLE_EVT 6 - -typedef UINT8 tBTM_BLE_BATCH_SCAN_EVT; - - typedef BOOLEAN (tBTM_BLE_SEL_CBACK)(BD_ADDR random_bda, UINT8 *p_remote_name); /* callback function for SMP signing algorithm, signed data in little endian order with tlen bits long */ @@ -936,8 +924,6 @@ typedef void (tBTM_BLE_RANDOM_SET_CBACK) (BD_ADDR random_bda); typedef void (tBTM_BLE_SCAN_REQ_CBACK)(BD_ADDR remote_bda, tBLE_ADDR_TYPE addr_type, UINT8 adv_evt); typedef void (*tBLE_SCAN_PARAM_SETUP_CBACK)(tGATT_IF client_if, tBTM_STATUS status); -tBTM_BLE_SCAN_SETUP_CBACK bta_ble_scan_setup_cb; - typedef void (tBTM_START_ADV_CMPL_CBACK) (UINT8 status); typedef void (tBTM_START_STOP_ADV_CMPL_CBACK) (UINT8 status); From 57f330727a6720ad7192112baf1e68eb557968b5 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:29 +0800 Subject: [PATCH 131/226] fix(ble/bluedroid): Delete batch_scan related code (cherry picked from commit a784adef004af9e325c7edd18132e8950bd6f09d) Co-authored-by: zhiweijian --- .../bluedroid/bta/dm/include/bta_dm_int.h | 2 - .../host/bluedroid/bta/include/bta/bta_api.h | 35 ----- .../common/include/common/bt_target.h | 5 - .../stack/include/stack/btm_ble_api.h | 124 ------------------ .../bluedroid/stack/include/stack/hcidefs.h | 10 +- 5 files changed, 1 insertion(+), 175 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index a0c1fce523..bf4a8bc6a9 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -2286,8 +2286,6 @@ extern void bta_dm_ble_gap_set_ext_scan_params(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_ext_scan(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_set_prefer_ext_conn_params(tBTA_DM_MSG *p_data); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) -extern void bta_dm_ble_enable_batch_scan(tBTA_DM_MSG *p_data); -extern void bta_dm_ble_disable_batch_scan(tBTA_DM_MSG *p_data); extern void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data); #endif diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 1945148848..a9d907b32e 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -511,13 +511,6 @@ typedef struct { tBTA_BLE_SERVICE service; } tBTA_BLE_INQ_DATA; -enum { - BTA_BLE_BATCH_SCAN_MODE_PASS = 1, - BTA_BLE_BATCH_SCAN_MODE_ACTI = 2, - BTA_BLE_BATCH_SCAN_MODE_PASS_ACTI = 3 -}; -typedef UINT8 tBTA_BLE_BATCH_SCAN_MODE; - enum { BTA_BLE_DISCARD_OLD_ITEMS = 0, BTA_BLE_DISCARD_LOWER_RSSI_ITEMS = 1 @@ -3019,34 +3012,6 @@ void BTA_DmBleGapCsSetProcPatams(tBTA_DM_CS_SET_PROC_PARAMS *set_proc_params); void BTA_DmBleGapCsProcEnable(uint16_t conn_handle, uint8_t config_id, uint8_t enable); #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) -/******************************************************************************* -** -** Function BTA_DmBleReadScanReports -** -** Description This function is called to read the batch scan reports -** -** Parameters scan_mode -Batch scan mode -** ref_value - Reference value -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleReadScanReports(tBTA_BLE_BATCH_SCAN_MODE scan_type, - tBTA_DM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTA_DmBleDisableBatchScan -** -** Description This function is called to disable the batch scanning -** -** Parameters ref_value - Reference value -** -** Returns None -** -*******************************************************************************/ -extern void BTA_DmBleDisableBatchScan(tBTA_DM_BLE_REF_VALUE ref_value); - /******************************************************************************* ** ** Function BTA_BrcmInit 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 2ff4ba171a..fe537a6361 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1659,11 +1659,6 @@ #endif #endif - -#ifndef BLE_BATCH_SCAN_INCLUDED -#define BLE_BATCH_SCAN_INCLUDED TRUE -#endif - /****************************************************************************** ** ** ATT/GATT Protocol/Profile Settings 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 f6902af8d8..125f9a971e 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 @@ -57,13 +57,6 @@ typedef UINT32 tBTM_BLE_REF_VALUE; #define BTM_BLE_SCAN_MODE_NONE 0xff typedef UINT8 tBLE_SCAN_MODE; -#define BTM_BLE_BATCH_SCAN_MODE_DISABLE 0 -#define BTM_BLE_BATCH_SCAN_MODE_PASS 1 -#define BTM_BLE_BATCH_SCAN_MODE_ACTI 2 -#define BTM_BLE_BATCH_SCAN_MODE_PASS_ACTI 3 - -typedef UINT8 tBTM_BLE_BATCH_SCAN_MODE; - /* advertising channel map */ #define BTM_BLE_ADV_CHNL_37 (0x01 << 0) #define BTM_BLE_ADV_CHNL_38 (0x01 << 1) @@ -496,60 +489,17 @@ typedef void (tBTM_BLE_SCAN_REP_CBACK)(tBTM_BLE_REF_VALUE ref_value, UINT8 repor UINT8 *p_rep_data, UINT8 status); typedef void (tBTM_BLE_SCAN_SETUP_CBACK)(UINT8 evt, tBTM_BLE_REF_VALUE ref_value, UINT8 status); -#ifndef BTM_BLE_BATCH_SCAN_MAX -#define BTM_BLE_BATCH_SCAN_MAX 5 -#endif #ifndef BTM_BLE_BATCH_REP_MAIN_Q_SIZE #define BTM_BLE_BATCH_REP_MAIN_Q_SIZE 2 #endif -typedef enum { - BTM_BLE_SCAN_INVALID_STATE = 0, - BTM_BLE_SCAN_ENABLE_CALLED = 1, - BTM_BLE_SCAN_ENABLED_STATE = 2, - BTM_BLE_SCAN_DISABLE_CALLED = 3, - BTM_BLE_SCAN_DISABLED_STATE = 4 -} tBTM_BLE_BATCH_SCAN_STATE; - enum { BTM_BLE_DISCARD_OLD_ITEMS, BTM_BLE_DISCARD_LOWER_RSSI_ITEMS }; typedef UINT8 tBTM_BLE_DISCARD_RULE; -typedef struct { - UINT8 sub_code[BTM_BLE_BATCH_SCAN_MAX]; - tBTM_BLE_BATCH_SCAN_STATE cur_state[BTM_BLE_BATCH_SCAN_MAX]; - tBTM_BLE_REF_VALUE ref_value[BTM_BLE_BATCH_SCAN_MAX]; - UINT8 pending_idx; - UINT8 next_idx; -} tBTM_BLE_BATCH_SCAN_OPQ; - -typedef struct { - UINT8 rep_mode[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; - tBTM_BLE_REF_VALUE ref_value[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; - UINT8 num_records[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; - UINT16 data_len[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; - UINT8 *p_data[BTM_BLE_BATCH_REP_MAIN_Q_SIZE]; - UINT8 pending_idx; - UINT8 next_idx; -} tBTM_BLE_BATCH_SCAN_REP_Q; - -typedef struct { - tBTM_BLE_BATCH_SCAN_STATE cur_state; - tBTM_BLE_BATCH_SCAN_MODE scan_mode; - UINT32 scan_interval; - UINT32 scan_window; - tBLE_ADDR_TYPE addr_type; - tBTM_BLE_DISCARD_RULE discard_rule; - tBTM_BLE_BATCH_SCAN_OPQ op_q; - tBTM_BLE_BATCH_SCAN_REP_Q main_rep_q; - tBTM_BLE_SCAN_SETUP_CBACK *p_setup_cback; - tBTM_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback; - tBTM_BLE_SCAN_REP_CBACK *p_scan_rep_cback; - tBTM_BLE_REF_VALUE ref_value; -} tBTM_BLE_BATCH_SCAN_CB; /// Ble scan duplicate type enum { @@ -2142,20 +2092,6 @@ void BTM_BleClearRandAddress(void); void BTM_BleReadAdvParams (UINT16 *adv_int_min, UINT16 *adv_int_max, tBLE_BD_ADDR *p_dir_bda, tBTM_BLE_ADV_CHNL_MAP *p_chnl_map); -/******************************************************************************* -** -** Function BTM_BleObtainVendorCapabilities -** -** Description This function is called to obtain vendor capabilities -** -** Parameters p_cmn_vsc_cb - Returns the vendor capabilities -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_BleObtainVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb); - /******************************************************************************* ** ** Function BTM_BleSetScanFilterParams @@ -2192,66 +2128,6 @@ tBTM_STATUS BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, *******************************************************************************/ //extern void BTM_BleGetVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb); -/******************************************************************************* -** -** Function BTM_BleSetStorageConfig -** -** Description This function is called to setup storage configuration and setup callbacks. -** -** Parameters UINT8 batch_scan_full_max -Batch scan full maximum - UINT8 batch_scan_trunc_max - Batch scan truncated value maximum - UINT8 batch_scan_notify_threshold - Threshold value - tBTM_BLE_SCAN_SETUP_CBACK *p_setup_cback - Setup callback - tBTM_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback -Threshold callback - void *p_ref - Reference value -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleSetStorageConfig(UINT8 batch_scan_full_max, - UINT8 batch_scan_trunc_max, - UINT8 batch_scan_notify_threshold, - tBTM_BLE_SCAN_SETUP_CBACK *p_setup_cback, - tBTM_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback, - tBTM_BLE_SCAN_REP_CBACK *p_cback, - tBTM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTM_BleEnableBatchScan -** -** Description This function is called to enable batch scan -** -** Parameters tBTM_BLE_BATCH_SCAN_MODE scan_mode - Batch scan mode - UINT32 scan_interval -Scan interval - UINT32 scan_window - Scan window value - tBLE_ADDR_TYPE addr_type - Address type - tBTM_BLE_DISCARD_RULE discard_rule - Data discard rules -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode, - UINT32 scan_interval, UINT32 scan_window, - tBTM_BLE_DISCARD_RULE discard_rule, - tBLE_ADDR_TYPE addr_type, - tBTM_BLE_REF_VALUE ref_value); - -/******************************************************************************* -** -** Function BTM_BleDisableBatchScan -** -** Description This function is called to disable batch scanning -** -** Parameters void -** -** Returns void -** -*******************************************************************************/ -//extern -tBTM_STATUS BTM_BleDisableBatchScan(tBTM_BLE_REF_VALUE ref_value); /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index afefed4680..ca6f901377 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -488,7 +488,6 @@ //ESP BLE subcode define #define HCI_SUBCODE_BLE_INIT 0x00 #define HCI_SUBCODE_BLE_MULTI_ADV 0x01 -#define HCI_SUBCODE_BLE_BATCH_SCAN 0x02 #define HCI_SUBCODE_BLE_ADV_FILTER 0x03 #define HCI_SUBCODE_BLE_TRACK_ADV 0x04 @@ -536,8 +535,7 @@ //ESP BLE HCI CMD /* Multi adv OCF */ #define HCI_BLE_MULTI_ADV_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_MULTI_ADV) -/* Batch scan OCF */ -#define HCI_BLE_BATCH_SCAN_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_BATCH_SCAN) + /* ADV filter OCF */ #define HCI_BLE_ADV_FILTER_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_ADV_FILTER) /* Tracking OCF */ @@ -574,12 +572,6 @@ /* multi adv VSE subcode */ #define HCI_VSE_SUBCODE_BLE_MULTI_ADV_ST_CHG 0x55 /* multi adv instance state change */ -/* subcode for batch scan feature */ -#define BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE 0x01 -#define BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM 0x02 -#define BTM_BLE_BATCH_SCAN_SET_PARAMS 0x03 -#define BTM_BLE_BATCH_SCAN_READ_RESULTS 0x04 - /* batch scan VSE subcode */ #define HCI_VSE_SUBCODE_BLE_THRESHOLD_SUB_EVT 0x54 /* Threshold event */ From dd898594b14033916464a17c1ccd475e956f82fb Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:29 +0800 Subject: [PATCH 132/226] fix(ble/bluedroid): delete bluedroid unused code (cherry picked from commit 5145b366f7274856fdfd78f16bfde7cf6a774b67) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 2 ++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 9 +----- .../bt/host/bluedroid/stack/btm/btm_acl.c | 6 ++-- .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 32 ------------------- .../bt/host/bluedroid/stack/btm/btm_inq.c | 2 ++ .../bluedroid/stack/btm/include/btm_int.h | 5 ++- .../bt/host/bluedroid/stack/btu/btu_hcif.c | 2 ++ .../stack/include/stack/btm_ble_api.h | 18 ----------- 8 files changed, 15 insertions(+), 61 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 4fd35c54df..3ab02358b8 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -3446,11 +3446,13 @@ static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data) p_msg->busy_level = p_data->update.busy_level; p_msg->busy_level_flags = p_data->update.busy_level_flags; break; +#if (CLASSIC_BT_INCLUDED == TRUE) case BTM_BL_ROLE_CHG_EVT: p_msg->new_role = p_data->role_chg.new_role; p_msg->hci_status = p_data->role_chg.hci_status; bdcpy(p_msg->bd_addr, p_data->role_chg.p_bda); break; +#endif // (CLASSIC_BT_INCLUDED == TRUE) case BTM_BL_COLLISION_EVT: bdcpy(p_msg->bd_addr, p_data->conn.p_bda); break; diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 377a2ac949..85de4aa5b5 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -135,7 +135,7 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_passkey_reply, /* BTA_DM_API_BLE_PASSKEY_REPLY_EVT */ bta_dm_ble_set_static_passkey, /* BTA_DM_API_BLE_SET_STATIC_PASSKEY_EVT */ bta_dm_ble_confirm_reply, /* BTA_DM_API_BLE_CONFIRM_REPLY_EVT */ - bta_dm_security_grant, + bta_dm_security_grant, /* BTA_DM_API_BLE_SEC_GRANT_EVT */ #endif ///SMP_INCLUDED == TRUE bta_dm_ble_set_bg_conn_type, bta_dm_ble_set_conn_params, /* BTA_DM_API_BLE_CONN_PARAM_EVT */ @@ -146,15 +146,8 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_scan, /* BTA_DM_API_BLE_SCAN_EVT */ #endif // #if (BLE_42_SCAN_EN == TRUE) bta_dm_ble_update_conn_params, /* BTA_DM_API_UPDATE_CONN_PARAM_EVT */ - /* This handler function added by - Yulong at 2016/9/9 to support the - random address setting for the APP */ bta_dm_ble_set_rand_address, /* BTA_DM_API_SET_RAND_ADDR_EVT*/ bta_dm_ble_clear_rand_address, /* BTA_DM_API_CLEAR_RAND_ADDR_EVT */ - /* This handler function added by - Yulong at 2016/10/19 to support - stop the ble advertising setting - by the APP */ #if BLE_PRIVACY_SPT == TRUE bta_dm_ble_config_local_privacy, /* BTA_DM_API_LOCAL_PRIVACY_EVT */ #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_acl.c b/components/bt/host/bluedroid/stack/btm/btm_acl.c index 6c3f7e4c31..cc77df53a7 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_acl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_acl.c @@ -2049,6 +2049,7 @@ tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL return (BTM_UNKNOWN_ADDR); } +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function BTM_ReadLinkQuality @@ -2132,7 +2133,6 @@ tBTM_STATUS BTM_SetAclPktTypes(BD_ADDR remote_bda, UINT16 pkt_types, tBTM_CMPL_C void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types) { -#if CLASSIC_BT_INCLUDED == TRUE BTM_TRACE_DEBUG ("btm_acl_pkt_types_changed\n"); tACL_CONN *conn = NULL; tBTM_SET_ACL_PKT_TYPES_RESULTS results; @@ -2153,8 +2153,8 @@ void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types) } btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb = NULL; } -#endif } +#endif // (CLASSIC_BT_INCLUDED == TRUE) #if (BLE_INCLUDED == TRUE) @@ -2342,6 +2342,7 @@ err_out: } } +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btm_read_link_quality_complete @@ -2388,6 +2389,7 @@ void btm_read_link_quality_complete (UINT8 *p) (*p_cb)(&results); } } +#endif // (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index 53adaa7bbc..6ea55dcba9 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -1482,38 +1482,6 @@ tBTM_STATUS BTM_BleStartAdv(void) return status; } #endif // #if (BLE_42_ADV_EN == TRUE) -/******************************************************************************* -** -** Function BTM_BleReadAdvParams -** -** Description This function is called to set advertising parameters. -** -** Parameters adv_int_min: minimum advertising interval -** adv_int_max: maximum advertising interval -** p_dir_bda: connectable direct initiator's LE device address -** chnl_map: advertising channel map. -** -** Returns void -** -*******************************************************************************/ -void BTM_BleReadAdvParams (UINT16 *adv_int_min, UINT16 *adv_int_max, - tBLE_BD_ADDR *p_dir_bda, tBTM_BLE_ADV_CHNL_MAP *p_chnl_map) -{ - tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; - - BTM_TRACE_EVENT ("BTM_BleReadAdvParams "); - if (!controller_get_interface()->supports_ble()) { - return ; - } - - *adv_int_min = p_cb->adv_interval_min; - *adv_int_max = p_cb->adv_interval_max; - *p_chnl_map = p_cb->adv_chnl_map; - - if (p_dir_bda != NULL) { - memcpy(p_dir_bda, &p_cb->direct_bda, sizeof(tBLE_BD_ADDR)); - } -} #if (BLE_42_SCAN_EN == TRUE) tBTM_STATUS BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, UINT32 scan_window, diff --git a/components/bt/host/bluedroid/stack/btm/btm_inq.c b/components/bt/host/bluedroid/stack/btm/btm_inq.c index b6b7c47205..43f7db43fe 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_inq.c +++ b/components/bt/host/bluedroid/stack/btm/btm_inq.c @@ -1124,6 +1124,7 @@ tBTM_STATUS BTM_ClearInqDb (BD_ADDR p_bda) return (BTM_SUCCESS); } +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function BTM_ReadInquiryRspTxPower @@ -1154,6 +1155,7 @@ tBTM_STATUS BTM_ReadInquiryRspTxPower (tBTM_CMPL_CB *p_cb) return (BTM_CMD_STARTED); } } +#endif // (CLASSIC_BT_INCLUDED == TRUE) /********************************************************************************* ********************************************************************************** diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index e3cfbe396b..42173e4e82 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -202,12 +202,15 @@ tBTM_CMPL_CB *p_rssi_cmpl_cb; /* Callback function to be called when tBTM_CMPL_CB *p_ble_ch_map_cmpl_cb; /* Callback function to be called when */ /* read channel map function completes */ - +#if (CLASSIC_BT_INCLUDED == TRUE) TIMER_LIST_ENT lnk_quality_timer; tBTM_CMPL_CB *p_lnk_qual_cmpl_cb;/* Callback function to be called when */ +#endif // (CLASSIC_BT_INCLUDED == TRUE) + /* read link quality function completes */ TIMER_LIST_ENT txpwer_timer; tBTM_CMPL_CB *p_txpwer_cmpl_cb; /* Callback function to be called when */ + /* read inq tx power function completes */ #if (CLASSIC_BT_INCLUDED == TRUE) TIMER_LIST_ENT qossu_timer; diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 73dfb57fdb..4d300f069c 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -1212,7 +1212,9 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l break; case HCI_GET_LINK_QUALITY: +#if (CLASSIC_BT_INCLUDED == TRUE) btm_read_link_quality_complete (p); +#endif // (CLASSIC_BT_INCLUDED == TRUE) break; #endif // #if (CLASSIC_BT_INCLUDED == TRUE) case HCI_READ_LOCAL_NAME: 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 125f9a971e..45017bb93a 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 @@ -2074,24 +2074,6 @@ tBTM_STATUS BTM_BleSetRandAddress(BD_ADDR rand_addr); void BTM_BleClearRandAddress(void); -/******************************************************************************* -** -** Function BTM_BleSetAdvParams -** -** Description This function is called to set advertising parameters. -** -** Parameters adv_int_min: minimum advertising interval -** adv_int_max: maximum advertising interval -** p_dir_bda: connectable direct initiator's LE device address -** chnl_map: advertising channel map. -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_BleReadAdvParams (UINT16 *adv_int_min, UINT16 *adv_int_max, - tBLE_BD_ADDR *p_dir_bda, tBTM_BLE_ADV_CHNL_MAP *p_chnl_map); - /******************************************************************************* ** ** Function BTM_BleSetScanFilterParams From edabdeecfc9ec51eaed2586e193e8e089216a40b Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:29 +0800 Subject: [PATCH 133/226] fix(ble/bluedroid): Delete observe and inquiry (cherry picked from commit 34448a74552ad5aca8e6008dad24bf9aa2b7f5e4) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 292 ------------------ .../bt/host/bluedroid/stack/btm/btm_inq.c | 52 ---- .../bluedroid/stack/btm/include/btm_ble_int.h | 7 +- .../bluedroid/stack/btm/include/btm_int.h | 2 - 4 files changed, 1 insertion(+), 352 deletions(-) diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index 6ea55dcba9..1dfe687ebb 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -59,12 +59,6 @@ #define BTM_BLE_GAP_ADV_RPT_BATCH_SIZE (10) -#if BTM_DYNAMIC_MEMORY == FALSE -static tBTM_BLE_VSC_CB cmn_ble_gap_vsc_cb; -#else -static tBTM_BLE_VSC_CB *cmn_ble_gap_vsc_cb_ptr; -#define cmn_ble_gap_vsc_cb (*cmn_ble_gap_vsc_cb_ptr) -#endif tBTM_CallbackFunc conn_callback_func; // BLE vendor HCI event callback @@ -84,7 +78,6 @@ static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb, BD_ADDR_PTR p_peer_addr_ptr, tBLE_ADDR_TYPE *p_peer_addr_type, tBLE_ADDR_TYPE *p_own_addr_type); -static void btm_ble_stop_observe(void); static void btm_ble_stop_discover(void); #if (BLE_42_SCAN_EN == TRUE) static void btm_adv_pkt_handler(void *arg); @@ -487,91 +480,6 @@ BOOLEAN btm_ble_send_extended_scan_params(UINT8 scan_type, UINT32 scan_int, return TRUE; } -/******************************************************************************* -** -** Function BTM_BleObserve -** -** Description This procedure keep the device listening for advertising -** events from a broadcast device. -** -** Parameters start: start or stop observe. -** white_list: use white list in observer mode or not. -** -** Returns void -** -*******************************************************************************/ -tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT32 duration, - tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb) -{ - tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var; - tBTM_STATUS status = BTM_WRONG_MODE; - - UINT32 scan_interval = !p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval; - UINT32 scan_window = !p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window; - - BTM_TRACE_EVENT ("%s : scan_type:%d, %d, %d\n", __func__, btm_cb.btm_inq_vars.scan_type, - p_inq->scan_interval, p_inq->scan_window); - - if (!controller_get_interface()->supports_ble()) { - return BTM_ILLEGAL_VALUE; - } - - if (start) { - /* shared inquiry database, do not allow observe if any inquiry is active */ - if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) { - BTM_TRACE_ERROR("%s Observe Already Active", __func__); - return status; - } - - btm_cb.ble_ctr_cb.p_obs_results_cb = p_results_cb; - btm_cb.ble_ctr_cb.p_obs_cmpl_cb = p_cmpl_cb; - status = BTM_CMD_STARTED; - - /* scan is not started */ - if (!BTM_BLE_IS_SCAN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) { - /* allow config of scan type */ - p_inq->scan_type = (p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) ? - BTM_BLE_SCAN_MODE_ACTI : p_inq->scan_type; - /* assume observe always not using white list */ -#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) - /* enable resolving list */ - //btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_SCAN); -#endif - - if (cmn_ble_gap_vsc_cb.extended_scan_support == 0) { - btsnd_hcic_ble_set_scan_params(p_inq->scan_type, (UINT16)scan_interval, - (UINT16)scan_window, - btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, - BTM_BLE_DEFAULT_SFP); - } else { - btm_ble_send_extended_scan_params(p_inq->scan_type, scan_interval, scan_window, - btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, - BTM_BLE_DEFAULT_SFP); - } -#if (BLE_42_SCAN_EN == TRUE) - status = btm_ble_start_scan(); -#endif // #if (BLE_42_SCAN_EN == TRUE) - } - - if (status == BTM_CMD_STARTED) { - btm_cb.ble_ctr_cb.scan_activity |= BTM_LE_OBSERVE_ACTIVE; - if (duration != 0) - /* start observer timer */ - { - btu_start_timer (&btm_cb.ble_ctr_cb.obs_timer_ent, BTU_TTYPE_BLE_OBSERVE, duration); - } - } - } else if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) { - status = BTM_CMD_STARTED; - btm_ble_stop_observe(); - } else { - BTM_TRACE_ERROR("%s Observe not active\n", __func__); - } - - return status; - -} - #if (BLE_42_SCAN_EN == TRUE) /******************************************************************************* ** @@ -2555,82 +2463,6 @@ tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode) return status; } - -/******************************************************************************* -** -** Function btm_ble_start_inquiry -** -** Description This function is called to start BLE inquiry procedure. -** If the duration is zero, the periodic inquiry mode is cancelled. -** -** Parameters: mode - GENERAL or LIMITED inquiry -** p_inq_params - pointer to the BLE inquiry parameter. -** p_results_cb - callback returning pointer to results (tBTM_INQ_RESULTS) -** p_cmpl_cb - callback indicating the end of an inquiry -** -** -** -** Returns BTM_CMD_STARTED if successfully started -** BTM_NO_RESOURCES if could not allocate a message buffer -** BTM_BUSY - if an inquiry is already active -** -*******************************************************************************/ -tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8 duration) -{ - tBTM_STATUS status = BTM_CMD_STARTED; - tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb; - tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; - - BTM_TRACE_DEBUG("btm_ble_start_inquiry: mode = %02x inq_active = 0x%02x", mode, btm_cb.btm_inq_vars.inq_active); - - /* if selective connection is active, or inquiry is already active, reject it */ - if (BTM_BLE_IS_INQ_ACTIVE(p_ble_cb->scan_activity) || - BTM_BLE_IS_SEL_CONN_ACTIVE (p_ble_cb->scan_activity)) { - BTM_TRACE_ERROR("LE Inquiry is active, can not start inquiry"); - return (BTM_BUSY); - } - - if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) { - btsnd_hcic_ble_set_scan_params(BTM_BLE_SCAN_MODE_ACTI, - BTM_BLE_LOW_LATENCY_SCAN_INT, - BTM_BLE_LOW_LATENCY_SCAN_WIN, - btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, - SP_ADV_ALL); -#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) - /* enable IRK list */ - //btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_SCAN); -#endif -#if (BLE_42_SCAN_EN == TRUE) - status = btm_ble_start_scan(); -#endif // #if (BLE_42_SCAN_EN == TRUE) - } else if ((p_ble_cb->inq_var.scan_interval != BTM_BLE_LOW_LATENCY_SCAN_INT) || - (p_ble_cb->inq_var.scan_window != BTM_BLE_LOW_LATENCY_SCAN_WIN)) { - BTM_TRACE_DEBUG("%s, restart LE scan with low latency scan params", __FUNCTION__); - btsnd_hcic_ble_set_scan_enable(BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE); - btsnd_hcic_ble_set_scan_params(BTM_BLE_SCAN_MODE_ACTI, - BTM_BLE_LOW_LATENCY_SCAN_INT, - BTM_BLE_LOW_LATENCY_SCAN_WIN, - btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, - SP_ADV_ALL); - btsnd_hcic_ble_set_scan_enable(BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE); - } - - if (status == BTM_CMD_STARTED) { - p_inq->inq_active |= mode; - p_ble_cb->scan_activity |= mode; - - BTM_TRACE_DEBUG("btm_ble_start_inquiry inq_active = 0x%02x", p_inq->inq_active); - - if (duration != 0) { - /* start inquiry timer */ - btu_start_timer (&p_ble_cb->inq_var.inq_timer_ent, BTU_TTYPE_BLE_INQUIRY, duration); - } - } - - return status; - -} - /******************************************************************************* ** ** Function btm_ble_read_remote_name_cmpl @@ -3456,9 +3288,6 @@ static void btm_ble_process_last_adv_pkt(void) { UINT8 result = 0; UINT8 null_bda[6] = {0}; - tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; - tBTM_INQ_RESULTS_CB *p_inq_results_cb = p_inq->p_inq_results_cb; - tBTM_INQ_RESULTS_CB *p_obs_results_cb = btm_cb.ble_ctr_cb.p_obs_results_cb; tBTM_INQ_RESULTS_CB *p_scan_results_cb = btm_cb.ble_ctr_cb.p_scan_results_cb; tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var; tINQ_DB_ENT *p_i = btm_inq_db_find (p_le_inq_cb->adv_addr); @@ -3481,20 +3310,6 @@ static void btm_ble_process_last_adv_pkt(void) if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE) { //do nothing } else { - if (p_inq_results_cb && (result & BTM_BLE_INQ_RESULT)) { - (p_inq_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache); - p_le_inq_cb->adv_len = 0; - memset(p_le_inq_cb->adv_addr, 0, BD_ADDR_LEN); - p_i->inq_info.results.adv_data_len = 0; - p_i->inq_info.results.scan_rsp_len = 0; - } - if (p_obs_results_cb && (result & BTM_BLE_OBS_RESULT)) { - (p_obs_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache); - p_le_inq_cb->adv_len = 0; - memset(p_le_inq_cb->adv_addr, 0, BD_ADDR_LEN); - p_i->inq_info.results.adv_data_len = 0; - p_i->inq_info.results.scan_rsp_len = 0; - } if (p_scan_results_cb && (result & BTM_BLE_DISCO_RESULT)) { (p_scan_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache); p_le_inq_cb->adv_len = 0; @@ -3522,8 +3337,6 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt tINQ_DB_ENT *p_i; tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; - tBTM_INQ_RESULTS_CB *p_inq_results_cb = p_inq->p_inq_results_cb; - tBTM_INQ_RESULTS_CB *p_obs_results_cb = btm_cb.ble_ctr_cb.p_obs_results_cb; tBTM_INQ_RESULTS_CB *p_scan_results_cb = btm_cb.ble_ctr_cb.p_scan_results_cb; tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var; BOOLEAN update = TRUE; @@ -3600,15 +3413,6 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt /* assume a DUMO device, BR/EDR inquiry is always active */ ((p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE && p_i->scan_rsp)) { - BTM_TRACE_WARNING("INQ RES: Extra Response Received...cancelling inquiry.."); - - /* if is non-periodic inquiry active, cancel now */ - if ((p_inq->inq_active & BTM_BR_INQ_ACTIVE_MASK) != 0 && - (p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) == 0) { - btsnd_hcic_inq_cancel(); - } - - btm_ble_stop_inquiry(); btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT); } @@ -3621,20 +3425,6 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt BTM_TRACE_DEBUG("None LE device, can not initiate selective connection\n"); } } else { - if (p_inq_results_cb && (result & BTM_BLE_INQ_RESULT)) { - (p_inq_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache); - p_le_inq_cb->adv_len = 0; - memset(p_le_inq_cb->adv_addr, 0, BD_ADDR_LEN); - p_i->inq_info.results.adv_data_len = 0; - p_i->inq_info.results.scan_rsp_len = 0; - } - if (p_obs_results_cb && (result & BTM_BLE_OBS_RESULT)) { - (p_obs_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache); - p_le_inq_cb->adv_len = 0; - memset(p_le_inq_cb->adv_addr, 0, BD_ADDR_LEN); - p_i->inq_info.results.adv_data_len = 0; - p_i->inq_info.results.scan_rsp_len = 0; - } if (p_scan_results_cb && (result & BTM_BLE_DISCO_RESULT)) { (p_scan_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache); p_le_inq_cb->adv_len = 0; @@ -3728,73 +3518,6 @@ void btm_ble_stop_scan(void) btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_SCAN; } -/******************************************************************************* -** -** Function btm_ble_stop_inquiry -** -** Description Stop the BLE Inquiry. -** -** Returns void -** -*******************************************************************************/ -void btm_ble_stop_inquiry(void) -{ - tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; - tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb; - - btu_stop_timer (&p_ble_cb->inq_var.inq_timer_ent); - - p_ble_cb->scan_activity &= ~BTM_BLE_INQUIRY_MASK; - - /* If no more scan activity, stop LE scan now */ - if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) { - btm_ble_stop_scan(); - } else if ((p_ble_cb->inq_var.scan_interval != BTM_BLE_LOW_LATENCY_SCAN_INT) || - (p_ble_cb->inq_var.scan_window != BTM_BLE_LOW_LATENCY_SCAN_WIN)) { - BTM_TRACE_DEBUG("%s: setting default params for ongoing observe", __FUNCTION__); -#if (BLE_42_SCAN_EN == TRUE) - btm_ble_stop_scan(); - btm_ble_start_scan(); -#endif // #if (BLE_42_SCAN_EN == TRUE) - } - - /* If we have a callback registered for inquiry complete, call it */ - BTM_TRACE_DEBUG ("BTM Inq Compl Callback: status 0x%02x, num results %d", - p_inq->inq_cmpl_info.status, p_inq->inq_cmpl_info.num_resp); - - btm_process_inq_complete(HCI_SUCCESS, (UINT8)(p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK)); -} - -/******************************************************************************* -** -** Function btm_ble_stop_observe -** -** Description Stop the BLE Observe. -** -** Returns void -** -*******************************************************************************/ -static void btm_ble_stop_observe(void) -{ - tBTM_BLE_CB *p_ble_cb = & btm_cb.ble_ctr_cb; - tBTM_CMPL_CB *p_obs_cb = p_ble_cb->p_obs_cmpl_cb; - - btu_stop_timer (&p_ble_cb->obs_timer_ent); - - p_ble_cb->scan_activity &= ~BTM_LE_OBSERVE_ACTIVE; - - p_ble_cb->p_obs_results_cb = NULL; - p_ble_cb->p_obs_cmpl_cb = NULL; - - if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) { - btm_ble_stop_scan(); - } - - if (p_obs_cb) { - (p_obs_cb)((tBTM_INQUIRY_CMPL *) &btm_cb.btm_inq_vars.inq_cmpl_info); - } -} - /******************************************************************************* ** ** Function btm_ble_stop_observe @@ -4110,13 +3833,11 @@ void btm_ble_timeout(TIMER_LIST_ENT *p_tle) switch (p_tle->event) { case BTU_TTYPE_BLE_OBSERVE: - btm_ble_stop_observe(); break; case BTU_TTYPE_BLE_SCAN: btm_ble_stop_discover(); break; case BTU_TTYPE_BLE_INQUIRY: - btm_ble_stop_inquiry(); break; case BTU_TTYPE_BLE_GAP_LIM_DISC: @@ -4396,17 +4117,8 @@ void btm_ble_init (void) { BTM_TRACE_DEBUG("%s", __func__); -#if BTM_DYNAMIC_MEMORY == TRUE - cmn_ble_gap_vsc_cb_ptr = (tBTM_BLE_VSC_CB *)osi_malloc(sizeof(tBTM_BLE_VSC_CB)); - if (cmn_ble_gap_vsc_cb_ptr == NULL) { - BTM_TRACE_ERROR("%s malloc failed", __func__); - return; - } -#endif - tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; - btu_free_timer(&p_cb->obs_timer_ent); btu_free_timer(&p_cb->scan_timer_ent); btu_free_timer(&p_cb->inq_var.fast_adv_timer); memset(p_cb, 0, sizeof(tBTM_BLE_CB)); @@ -4465,10 +4177,6 @@ void btm_ble_free (void) osi_event_delete(p_cb->adv_rpt_ready); p_cb->adv_rpt_ready = NULL; #endif // #if (BLE_42_SCAN_EN == TRUE) -#if BTM_DYNAMIC_MEMORY == TRUE - osi_free(cmn_ble_gap_vsc_cb_ptr); - cmn_ble_gap_vsc_cb_ptr = NULL; -#endif } static bool enable_topology_check_flag = true; diff --git a/components/bt/host/bluedroid/stack/btm/btm_inq.c b/components/bt/host/bluedroid/stack/btm/btm_inq.c index 43f7db43fe..34d2c56070 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_inq.c +++ b/components/bt/host/bluedroid/stack/btm/btm_inq.c @@ -747,12 +747,6 @@ tBTM_STATUS BTM_CancelInquiry(void) status = BTM_NO_RESOURCES; } } -#if BLE_INCLUDED == TRUE - if (((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0) - ) { - btm_ble_stop_inquiry(); - } -#endif } /* Do not send the BUSY_LEVEL event yet. Wait for the cancel_complete event @@ -810,16 +804,6 @@ tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p /* Only one active inquiry is allowed in this implementation. Also do not allow an inquiry if the inquiry filter is being updated */ if (p_inq->inq_active || p_inq->inqfilt_active) { -#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE) - /*check if LE observe is already running*/ - if (p_inq->scan_type == INQ_LE_OBSERVE && p_inq->p_inq_ble_results_cb != NULL) { - BTM_TRACE_API("BTM_StartInquiry: LE observe in progress"); - p_inq->scan_type = INQ_GENERAL; - p_inq->inq_active = BTM_INQUIRY_INACTIVE; - btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE; - btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE); - } else -#endif { return (BTM_BUSY); BTM_TRACE_API("BTM_StartInquiry: return BUSY\n"); @@ -854,28 +838,6 @@ tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p p_inq->inq_active = p_inqparms->mode; BTM_TRACE_DEBUG("BTM_StartInquiry: p_inq->inq_active = 0x%02x\n", p_inq->inq_active); - /* start LE inquiry here if requested */ -#if BLE_INCLUDED == TRUE - if ((p_inqparms->mode & BTM_BLE_INQUIRY_MASK) - ) - - { - if (!controller_get_interface()->supports_ble()) { - p_inq->inqparms.mode &= ~ BTM_BLE_INQUIRY_MASK; - status = BTM_ILLEGAL_VALUE; - } - /* BLE for now does not support filter condition for inquiry */ - else if ((status = btm_ble_start_inquiry((UINT8)(p_inqparms->mode & BTM_BLE_INQUIRY_MASK), - p_inqparms->duration)) != BTM_CMD_STARTED) { - BTM_TRACE_ERROR("Err Starting LE Inquiry.\n"); - p_inq->inqparms.mode &= ~ BTM_BLE_INQUIRY_MASK; - } - p_inqparms->mode &= ~BTM_BLE_INQUIRY_MASK; - - BTM_TRACE_DEBUG("BTM_StartInquiry: mode = %02x\n", p_inqparms->mode); - } -#endif /* end of BLE_INCLUDED */ - /* we're done with this routine if BR/EDR inquiry is not desired. */ if ((p_inqparms->mode & BTM_BR_INQUIRY_MASK) == BTM_INQUIRY_NONE) { return status; @@ -1884,11 +1846,6 @@ void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode) /* BTM_TRACE_DEBUG("BTMINQ: Found devices, cancelling inquiry..."); */ btsnd_hcic_inq_cancel(); -#if BLE_INCLUDED == TRUE - if ((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0) { - btm_ble_stop_inquiry(); - } -#endif btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT); } /* Initialize flag to FALSE. This flag is set/used by application */ @@ -1973,8 +1930,6 @@ void btm_process_inq_complete (UINT8 status, UINT8 mode) if (p_inq->scan_type == INQ_LE_OBSERVE && !p_inq->inq_active) { /*end of LE observe*/ - p_inq->p_inq_ble_results_cb = (tBTM_INQ_RESULTS_CB *) NULL; - p_inq->p_inq_ble_cmpl_cb = (tBTM_CMPL_CB *) NULL; p_inq->scan_type = INQ_NONE; } @@ -2021,13 +1976,6 @@ void btm_process_inq_complete (UINT8 status, UINT8 mode) } if (p_inq->inqparms.mode == 0 && p_inq->scan_type == INQ_GENERAL) { //this inquiry is complete p_inq->scan_type = INQ_NONE; -#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE) - /* check if the LE observe is pending */ - if (p_inq->p_inq_ble_results_cb != NULL) { - BTM_TRACE_DEBUG("BTM Inq Compl: resuming a pending LE scan"); - BTM_BleObserve(1, 0, p_inq->p_inq_ble_results_cb, p_inq->p_inq_ble_cmpl_cb); - } -#endif } #if (BTM_INQ_DEBUG == TRUE) BTM_TRACE_DEBUG ("inq_active:0x%x state:%d inqfilt_active:%d\n", diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index cbd0082991..5975063a61 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -332,11 +332,8 @@ typedef struct { *****************************************************/ tBTM_BLE_INQ_CB inq_var; - /* observer callback and timer */ - tBTM_INQ_RESULTS_CB *p_obs_results_cb; - tBTM_CMPL_CB *p_obs_cmpl_cb; + // /* observer callback and timer */ tBTM_INQ_DIS_CB *p_obs_discard_cb; - TIMER_LIST_ENT obs_timer_ent; /* scan callback and timer */ tBTM_INQ_RESULTS_CB *p_scan_results_cb; @@ -406,12 +403,10 @@ BOOLEAN btm_ble_cancel_remote_name(BD_ADDR remote_bda); tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode); tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode); -tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8 duration); void btm_ble_stop_scan(void); void btm_clear_all_pending_le_entry(void); BOOLEAN btm_ble_send_extended_scan_params(UINT8 scan_type, UINT32 scan_int, UINT32 scan_win, UINT8 addr_type_own, UINT8 scan_filter_policy); -void btm_ble_stop_inquiry(void); void btm_ble_init (void); void btm_ble_free (void); void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role, tBLE_ADDR_TYPE addr_type, BOOLEAN addr_matched); diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index 42173e4e82..9e9cebd513 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -356,8 +356,6 @@ typedef struct { tBTM_CMPL_CB *p_inq_cmpl_cb; tBTM_INQ_RESULTS_CB *p_inq_results_cb; - tBTM_CMPL_CB *p_inq_ble_cmpl_cb; /*completion callback exclusively for LE Observe*/ - tBTM_INQ_RESULTS_CB *p_inq_ble_results_cb;/*results callback exclusively for LE observe*/ tBTM_CMPL_CB *p_inqfilter_cmpl_cb; /* Called (if not NULL) after inquiry filter completed */ UINT32 inq_counter; /* Counter incremented each time an inquiry completes */ /* Used for determining whether or not duplicate devices */ From 1f297b4a3a3b3a7e6bf3614896689784b7f2e586 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:30 +0800 Subject: [PATCH 134/226] fix(bluedroid): delete bluedroid gatt_listen (cherry picked from commit db17c7cea3aafdbd93f2c27060e605194d2624b7) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 62 ------------------- .../bt/host/bluedroid/stack/gatt/gatt_api.c | 43 ------------- .../bt/host/bluedroid/stack/gatt/gatt_utils.c | 47 -------------- .../bluedroid/stack/gatt/include/gatt_int.h | 1 - .../stack/include/stack/btm_ble_api.h | 13 ---- .../bluedroid/stack/include/stack/gatt_api.h | 17 ----- 6 files changed, 183 deletions(-) diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index 1dfe687ebb..db05a3bbd3 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -379,68 +379,6 @@ void BTM_BleClearWhitelist(tBTM_UPDATE_WHITELIST_CBACK *update_wl_cb) btm_ble_clear_white_list(update_wl_cb); } -/******************************************************************************* -** -** Function BTM_BleUpdateAdvFilterPolicy -** -** Description This function update the filter policy of advertiser. -** -** Parameter adv_policy: advertising filter policy -** -** Return void -*******************************************************************************/ -void BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy) -{ - tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; - tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC; - BD_ADDR p_addr_ptr = {0}; - UINT8 adv_mode = p_cb->adv_mode; - - BTM_TRACE_EVENT ("BTM_BleUpdateAdvFilterPolicy\n"); - - if (!controller_get_interface()->supports_ble()) { - return; - } - - if (p_cb->afp != adv_policy) { - p_cb->afp = adv_policy; - -#if (BLE_42_ADV_EN == TRUE) - /* if adv active, stop and restart */ - btm_ble_stop_adv (); -#endif // #if (BLE_42_ADV_EN == TRUE) - - if (p_cb->connectable_mode & BTM_BLE_CONNECTABLE) { - p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, - &p_cb->adv_addr_type); - } - - uint8_t null_addr[BD_ADDR_LEN] = {0}; - if ((p_cb->evt_type == 0x01 || p_cb->evt_type == 0x04) && memcmp(p_addr_ptr, null_addr, BD_ADDR_LEN) == 0) { - /* directed advertising */ - return; - } - - btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : - BTM_BLE_GAP_ADV_SLOW_INT), - (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : - BTM_BLE_GAP_ADV_SLOW_INT), - p_cb->evt_type, - p_cb->adv_addr_type, - init_addr_type, - p_addr_ptr, - p_cb->adv_chnl_map, - p_cb->afp); - - if (adv_mode == BTM_BLE_ADV_ENABLE) { -#if (BLE_42_ADV_EN == TRUE) - btm_ble_start_adv (); -#endif // #if (BLE_42_ADV_EN == TRUE) - } - - } -} - /******************************************************************************* ** ** Function btm_ble_send_extended_scan_params diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_api.c b/components/bt/host/bluedroid/stack/gatt/gatt_api.c index e48d9d2289..621ab52cbc 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_api.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_api.c @@ -1394,10 +1394,6 @@ void GATT_Deregister (tGATT_IF gatt_if) #if (tGATT_BG_CONN_DEV == TRUE) gatt_deregister_bgdev_list(gatt_if); #endif // #if (tGATT_BG_CONN_DEV == TRUE) - /* update the listen mode */ -#if (defined(BLE_PERIPHERAL_MODE_SUPPORT) && (BLE_PERIPHERAL_MODE_SUPPORT == TRUE)) - GATT_Listen(gatt_if, FALSE, NULL); -#endif memset (p_reg, 0, sizeof(tGATT_REG)); } @@ -1703,45 +1699,6 @@ BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, UINT16 *p_c return status; } - -/******************************************************************************* -** -** Function GATT_Listen -** -** Description This function start or stop LE advertisement and listen for -** connection. -** -** Parameters gatt_if: application interface -** p_bd_addr: listen for specific address connection, or NULL for -** listen to all device connection. -** start: start or stop listening. -** -** Returns TRUE if advertisement is started; FALSE if adv start failure. -** -*******************************************************************************/ -BOOLEAN GATT_Listen (tGATT_IF gatt_if, BOOLEAN start, BD_ADDR_PTR bd_addr) -{ - tGATT_REG *p_reg; - - GATT_TRACE_API ("GATT_Listen gatt_if=%d", gatt_if); - - /* Make sure app is registered */ - if ((p_reg = gatt_get_regcb(gatt_if)) == NULL) { - GATT_TRACE_ERROR("GATT_Listen - gatt_if =%d is not registered", gatt_if); - return (FALSE); - } - - if (bd_addr != NULL) { -#if (tGATT_BG_CONN_DEV == TRUE) - gatt_update_auto_connect_dev(gatt_if, start, bd_addr, FALSE); -#endif // #if (tGATT_BG_CONN_DEV == TRUE) - } else { - p_reg->listening = start ? GATT_LISTEN_TO_ALL : GATT_LISTEN_TO_NONE; - } - - return gatt_update_listen_mode(); -} - #if (GATTS_INCLUDED == TRUE) tGATT_STATUS GATTS_SetServiceChangeMode(UINT8 mode) { diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c index 113f43952f..1bf819bc24 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c @@ -2830,53 +2830,6 @@ tGATT_PENDING_ENC_CLCB *gatt_add_pending_enc_channel_clcb(tGATT_TCB *p_tcb, tGAT return p_buf; } #endif // (SMP_INCLUDED == TRUE) -/******************************************************************************* -** -** Function gatt_update_listen_mode -** -** Description update peripheral role listening mode -** -** Returns Pointer to the new service start buffer, NULL no buffer available -** -*******************************************************************************/ -BOOLEAN gatt_update_listen_mode(void) -{ - UINT8 ii = 0; - tGATT_REG *p_reg = &gatt_cb.cl_rcb[0]; - UINT8 listening = 0; - UINT16 connectability, window, interval; - BOOLEAN rt = TRUE; - - for (; ii < GATT_MAX_APPS; ii ++, p_reg ++) { - if ( p_reg->in_use && p_reg->listening > listening) { - listening = p_reg->listening; - } - } - - if (listening == GATT_LISTEN_TO_ALL || - listening == GATT_LISTEN_TO_NONE) { - BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_ALL); - } else { - BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_WL); - } - - if (rt) { - connectability = BTM_ReadConnectability (&window, &interval); - - if (listening != GATT_LISTEN_TO_NONE) { - connectability |= BTM_BLE_CONNECTABLE; - } else { - if ((connectability & BTM_BLE_CONNECTABLE) == 0) { - connectability &= ~BTM_BLE_CONNECTABLE; - } - } - /* turning on the adv now */ - btm_ble_set_connectability(connectability); - } - - return rt; - -} char *gatt_uuid_to_str(const tBT_UUID *uuid) { diff --git a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h index dbb4582742..4fd74fba0e 100644 --- a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -665,7 +665,6 @@ extern void gatt_set_srv_chg(void); extern void gatt_delete_dev_from_srv_chg_clt_list(BD_ADDR bd_addr); extern tGATTS_PENDING_NEW_SRV_START *gatt_add_pending_new_srv_start( tGATTS_HNDL_RANGE *p_new_srv_start); extern void gatt_free_srvc_db_buffer_app_id(tBT_UUID *p_app_id); -extern BOOLEAN gatt_update_listen_mode(void); extern BOOLEAN gatt_cl_send_next_cmd_inq(tGATT_TCB *p_tcb); /* reserved handle list */ 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 45017bb93a..fd3c9e167d 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 @@ -2754,19 +2754,6 @@ BOOLEAN BTM_BleUpdateAdvWhitelist(BOOLEAN add_remove, BD_ADDR emote_bda, tBLE_AD *******************************************************************************/ void BTM_BleClearWhitelist(tBTM_UPDATE_WHITELIST_CBACK *update_wl_cb); -/******************************************************************************* -** -** Function BTM_BleUpdateAdvFilterPolicy -** -** Description This function update the filter policy of advertiser. -** -** Parameter adv_policy: advertising filter policy -** -** Return void -*******************************************************************************/ -//extern -void BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy); - /******************************************************************************* ** ** Function BTM_BleReceiverTest diff --git a/components/bt/host/bluedroid/stack/include/stack/gatt_api.h b/components/bt/host/bluedroid/stack/include/stack/gatt_api.h index 83667e7724..2e1d2d54c2 100644 --- a/components/bt/host/bluedroid/stack/include/stack/gatt_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/gatt_api.h @@ -1227,23 +1227,6 @@ extern BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, UINT16 *p_conn_id, tBT_TRANSPORT transport); -/******************************************************************************* -** -** Function GATT_Listen -** -** Description This function start or stop LE advertisement and listen for -** connection. -** -** Parameters gatt_if: application interface -** p_bd_addr: listen for specific address connection, or NULL for -** listen to all device connection. -** start: is a direct connection or a background auto connection -** -** Returns TRUE if advertisement is started; FALSE if adv start failure. -** -*******************************************************************************/ -extern BOOLEAN GATT_Listen (tGATT_IF gatt_if, BOOLEAN start, BD_ADDR_PTR bd_addr); - /******************************************************************************* ** ** Function GATT_ConfigServiceChangeCCC From 8bf14a7c86abc2ba2ce69e91aadaae74f200adda Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:30 +0800 Subject: [PATCH 135/226] fix(ble/bluedroid): change bluedroid scan callback name (cherry picked from commit b9440efbe9f395d78557de4925922baea0e694c0) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 30 ++++++++++--------- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 10 +++---- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 2 +- .../bluedroid/bta/dm/include/bta_dm_int.h | 4 +-- .../host/bluedroid/bta/include/bta/bta_api.h | 4 +-- .../btc/profile/std/gap/btc_gap_ble.c | 2 +- .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 3 ++ 7 files changed, 30 insertions(+), 25 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 3ab02358b8..cbccbc486c 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -133,9 +133,9 @@ extern tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void); static BOOLEAN bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr); #endif ///SMP_INCLUDED == TRUE #if (BLE_INCLUDED == TRUE) -static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir); -static void bta_dm_observe_cmpl_cb(void *p_result); -static void bta_dm_observe_discard_cb (uint32_t num_dis); +static void bta_dm_scan_results_cb(tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir); +static void bta_dm_scan_cmpl_cb(void *p_result); +static void bta_dm_scan_discard_cb (uint32_t num_dis); #endif ///BLE_INCLUDED == TRUE #if (CLASSIC_BT_INCLUDED == TRUE) @@ -4684,9 +4684,10 @@ BOOLEAN bta_dm_check_if_only_hd_connected(BD_ADDR peer_addr) #endif /* BTA_HD_INCLUDED == TRUE */ #if (BLE_INCLUDED == TRUE) +#if (BLE_42_SCAN_EN == TRUE) /******************************************************************************* ** -** Function bta_dm_observe_results_cb +** Function bta_dm_scan_results_cb ** ** Description Callback for BLE Observe result ** @@ -4694,7 +4695,7 @@ BOOLEAN bta_dm_check_if_only_hd_connected(BD_ADDR peer_addr) ** Returns void ** *******************************************************************************/ -static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir) +static void bta_dm_scan_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir) { tBTA_DM_SEARCH result; tBTM_INQ_INFO *p_inq_info; @@ -4734,7 +4735,7 @@ static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir) /******************************************************************************* ** -** Function bta_dm_observe_cmpl_cb +** Function bta_dm_scan_cmpl_cb ** ** Description Callback for BLE Observe complete ** @@ -4742,11 +4743,11 @@ static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir) ** Returns void ** *******************************************************************************/ -static void bta_dm_observe_cmpl_cb (void *p_result) +static void bta_dm_scan_cmpl_cb (void *p_result) { tBTA_DM_SEARCH data; - APPL_TRACE_DEBUG("bta_dm_observe_cmpl_cb"); + APPL_TRACE_DEBUG("bta_dm_scan_cmpl_cb"); data.inq_cmpl.num_resps = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp; if (bta_dm_search_cb.p_scan_cback) { @@ -4756,7 +4757,7 @@ static void bta_dm_observe_cmpl_cb (void *p_result) /******************************************************************************* ** -** Function bta_dm_observe_discard_cb +** Function bta_dm_scan_discard_cb ** ** Description Callback for BLE Observe lost ** @@ -4764,17 +4765,18 @@ static void bta_dm_observe_cmpl_cb (void *p_result) ** Returns void ** *******************************************************************************/ -static void bta_dm_observe_discard_cb (uint32_t num_dis) +static void bta_dm_scan_discard_cb (uint32_t num_dis) { tBTA_DM_SEARCH data; - APPL_TRACE_DEBUG("bta_dm_observe_discard_cb"); + APPL_TRACE_DEBUG("bta_dm_scan_discard_cb"); data.inq_dis.num_dis = num_dis; if (bta_dm_search_cb.p_scan_cback) { bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_DISCARD_NUM_EVT, &data); } } +#endif // (BLE_42_SCAN_EN == TRUE) #if (SMP_INCLUDED == TRUE) /******************************************************************************* @@ -5255,7 +5257,7 @@ void bta_dm_ble_scan (tBTA_DM_MSG *p_data) bta_dm_search_cb.p_scan_cback = p_data->ble_scan.p_cback; if ((status = BTM_BleScan(TRUE, p_data->ble_scan.duration, - bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb, bta_dm_observe_discard_cb)) != BTM_CMD_STARTED) { + bta_dm_scan_results_cb, bta_dm_scan_cmpl_cb, bta_dm_scan_discard_cb)) != BTM_CMD_STARTED) { APPL_TRACE_WARNING(" %s start scan failed. status=0x%x\n", __FUNCTION__, status); } @@ -5490,14 +5492,14 @@ void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data) #if (BLE_42_ADV_EN == TRUE) /******************************************************************************* ** -** Function bta_dm_ble_broadcast +** Function bta_dm_ble_advstop ** ** Description Starts or stops LE broadcasts ** ** Parameters: ** *******************************************************************************/ -void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data) +void bta_dm_ble_advstop (tBTA_DM_MSG *p_data) { tBTA_STATUS status = BTA_FAILURE; BOOLEAN start = p_data->ble_observe.start; diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index ffd2872f85..13484b01c0 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -1615,25 +1615,25 @@ void BTA_DmUpdateDuplicateExceptionalList(UINT8 subcode, UINT32 type, BD_ADDR de #if (BLE_42_ADV_EN == TRUE) /******************************************************************************* ** -** Function BTA_DmBleBroadcast +** Function BTA_DmBleAdvStop ** ** Description This function starts or stops LE broadcasting. ** -** Parameters start: start or stop broadcast. +** Parameters start: always be false. ** ** Returns None ** *******************************************************************************/ -extern void BTA_DmBleBroadcast (BOOLEAN start, tBTA_START_STOP_ADV_CMPL_CBACK *p_start_stop_adv_cb) +extern void BTA_DmBleAdvStop (BOOLEAN start, tBTA_START_STOP_ADV_CMPL_CBACK *p_start_stop_adv_cb) { tBTA_DM_API_BLE_OBSERVE *p_msg; - APPL_TRACE_API("BTA_DmBleBroadcast: start = %d \n", start); + APPL_TRACE_API("BTA_DmBleAdvStop: start = %d \n", start); if ((p_msg = (tBTA_DM_API_BLE_OBSERVE *) osi_malloc(sizeof(tBTA_DM_API_BLE_OBSERVE))) != NULL) { memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_OBSERVE)); - p_msg->hdr.event = BTA_DM_API_BLE_BROADCAST_EVT; + p_msg->hdr.event = BTA_DM_API_BLE_ADVSTOP_EVT; p_msg->start = start; if (start == FALSE){ p_msg->p_stop_adv_cback= p_start_stop_adv_cb; diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 85de4aa5b5..b9a57a45d5 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -165,7 +165,7 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { /* New function to allow set raw scan response data to HCI */ bta_dm_ble_set_scan_rsp_raw, /* BTA_DM_API_BLE_SET_SCAN_RSP_RAW_EVT */ - bta_dm_ble_broadcast, /* BTA_DM_API_BLE_BROADCAST_EVT */ + bta_dm_ble_advstop, /* BTA_DM_API_BLE_ADVSTOP_EVT */ #endif // #if (BLE_42_ADV_EN == TRUE) bta_dm_ble_set_data_length, /* BTA_DM_API_SET_DATA_LENGTH_EVT */ bta_dm_ble_disconnect, /* BTA_DM_API_BLE_DISCONNECT_EVT */ diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index bf4a8bc6a9..23ca27995f 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -156,7 +156,7 @@ enum { BTA_DM_API_BLE_SET_SCAN_RSP_EVT, /* Add for set raw scan response data */ BTA_DM_API_BLE_SET_SCAN_RSP_RAW_EVT, - BTA_DM_API_BLE_BROADCAST_EVT, + BTA_DM_API_BLE_ADVSTOP_EVT, #endif // #if (BLE_42_ADV_EN == TRUE) BTA_DM_API_SET_DATA_LENGTH_EVT, @@ -2250,7 +2250,7 @@ extern void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_adv_config_raw (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_scan_rsp_raw (tBTA_DM_MSG *p_data); -extern void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data); +extern void bta_dm_ble_advstop (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data); extern void bta_dm_ble_update_duplicate_exceptional_list(tBTA_DM_MSG *p_data); #if SMP_INCLUDED == TRUE diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index a9d907b32e..151ab14ac9 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -2907,7 +2907,7 @@ extern void BTA_DmUpdateDuplicateExceptionalList(UINT8 subcode, UINT32 type, /******************************************************************************* ** -** Function BTA_DmBleBroadcast +** Function BTA_DmBleAdvStop ** ** Description This function starts or stops LE broadcasting. ** @@ -2917,7 +2917,7 @@ extern void BTA_DmUpdateDuplicateExceptionalList(UINT8 subcode, UINT32 type, ** Returns None ** *******************************************************************************/ -extern void BTA_DmBleBroadcast (BOOLEAN start, tBTA_START_STOP_ADV_CMPL_CBACK *p_start_stop_adv_cb); +extern void BTA_DmBleAdvStop (BOOLEAN start, tBTA_START_STOP_ADV_CMPL_CBACK *p_start_stop_adv_cb); /******************************************************************************* ** 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 8d506d7110..44c6244445 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 @@ -1801,7 +1801,7 @@ static void btc_ble_stop_advertising(tBTA_START_STOP_ADV_CMPL_CBACK *stop_adv_cb { bool stop_adv = false; - BTA_DmBleBroadcast(stop_adv, stop_adv_cb); + BTA_DmBleAdvStop(stop_adv, stop_adv_cb); } #endif // #if (BLE_42_ADV_EN == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index db05a3bbd3..ba348730e1 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -528,6 +528,8 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_s #endif if (start) { +// "start" should not be ture +#if (0) /* update adv params */ if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT), @@ -547,6 +549,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_s } status = btm_ble_start_adv (); +#endif // } else { //save the stop adv callback to the BTM env. p_cb->p_stop_adv_cb = p_stop_adv_cback; From fcb4030e5758709e3a83706c4c0e4de72ef48372 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:30 +0800 Subject: [PATCH 136/226] fix(ble/bluedroid): Delete btm_ble_send_extended_scan_params (cherry picked from commit 1174ad41a5e53e38e6ae6a14fe9f6514c8bf6640) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 15 ---- .../host/bluedroid/bta/include/bta/bta_api.h | 11 --- components/bt/host/bluedroid/main/bte_main.c | 3 - .../host/bluedroid/stack/btm/btm_ble_bgconn.c | 39 +++------- .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 78 ++----------------- .../bluedroid/stack/btm/include/btm_ble_int.h | 1 - .../bluedroid/stack/btm/include/btm_int.h | 1 - .../stack/include/stack/btm_ble_api.h | 21 +---- 8 files changed, 19 insertions(+), 150 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 13484b01c0..5e19457ec3 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -2636,21 +2636,6 @@ void BTA_VendorInit (void) APPL_TRACE_API("BTA_VendorInit"); } -/******************************************************************************* -** -** Function BTA_VendorCleanup -** -** Description This function frees up Broadcom specific VS specific dynamic memory -** -** Returns void -** -*******************************************************************************/ -void BTA_VendorCleanup (void) -{ - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); -} - #if (BLE_50_FEATURE_SUPPORT == TRUE) void BTA_DmBleGapReadPHY(BD_ADDR addr) { diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 151ab14ac9..12e12be2c2 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -3023,17 +3023,6 @@ void BTA_DmBleGapCsProcEnable(uint16_t conn_handle, uint8_t config_id, uint8_t e *******************************************************************************/ extern void BTA_VendorInit (void); -/******************************************************************************* -** -** Function BTA_BrcmCleanup -** -** Description This function frees up Broadcom specific VS specific dynamic memory -** -** Returns void -** -*******************************************************************************/ -extern void BTA_VendorCleanup (void); - #if (BLE_50_FEATURE_SUPPORT == TRUE) extern void BTA_DmBleGapReadPHY(BD_ADDR addr); diff --git a/components/bt/host/bluedroid/main/bte_main.c b/components/bt/host/bluedroid/main/bte_main.c index c974037ef9..73cbafc644 100644 --- a/components/bt/host/bluedroid/main/bte_main.c +++ b/components/bt/host/bluedroid/main/bte_main.c @@ -105,9 +105,6 @@ int bte_main_boot_entry(bluedroid_init_done_cb_t cb) ******************************************************************************/ void bte_main_shutdown(void) { -#if (BLE_INCLUDED == TRUE) - BTA_VendorCleanup(); -#endif #if (BT_BLE_DYNAMIC_ENV_MEMORY == TRUE) free_controller_param(); diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c index b418bd70f7..23117acae3 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c @@ -137,16 +137,11 @@ void btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy) p_inq->sfp = scan_policy; p_inq->scan_type = p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE ? BTM_BLE_SCAN_MODE_ACTI : p_inq->scan_type; - if (btm_cb.cmn_ble_vsc_cb.extended_scan_support == 0) { - btsnd_hcic_ble_set_scan_params(p_inq->scan_type, (UINT16)scan_interval, - (UINT16)scan_window, - btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, - scan_policy); - } else { - btm_ble_send_extended_scan_params(p_inq->scan_type, scan_interval, scan_window, - btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, - scan_policy); - } + + btsnd_hcic_ble_set_scan_params(p_inq->scan_type, (UINT16)scan_interval, + (UINT16)scan_window, + btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, + scan_policy); } /******************************************************************************* ** @@ -604,23 +599,13 @@ BOOLEAN btm_ble_start_select_conn(BOOLEAN start, tBTM_BLE_SEL_CBACK *p_select_cb btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_PASS; /* Process advertising packets only from devices in the white list */ - if (btm_cb.cmn_ble_vsc_cb.extended_scan_support == 0) { - /* use passive scan by default */ - if (!btsnd_hcic_ble_set_scan_params(BTM_BLE_SCAN_MODE_PASS, - scan_int, - scan_win, - p_cb->addr_mgnt_cb.own_addr_type, - SP_ADV_WL)) { - return FALSE; - } - } else { - if (!btm_ble_send_extended_scan_params(BTM_BLE_SCAN_MODE_PASS, - scan_int, - scan_win, - p_cb->addr_mgnt_cb.own_addr_type, - SP_ADV_WL)) { - return FALSE; - } + /* use passive scan by default */ + if (!btsnd_hcic_ble_set_scan_params(BTM_BLE_SCAN_MODE_PASS, + scan_int, + scan_win, + p_cb->addr_mgnt_cb.own_addr_type, + SP_ADV_WL)) { + return FALSE; } if (!btm_ble_topology_check(BTM_BLE_STATE_PASSIVE_SCAN)) { diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index ba348730e1..bc6068ee06 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -379,45 +379,6 @@ void BTM_BleClearWhitelist(tBTM_UPDATE_WHITELIST_CBACK *update_wl_cb) btm_ble_clear_white_list(update_wl_cb); } -/******************************************************************************* -** -** Function btm_ble_send_extended_scan_params -** -** Description This function sends out the extended scan parameters command to the controller -** -** Parameters scan_type - Scan type -** scan_int - Scan interval -** scan_win - Scan window -** addr_type_own - Own address type -** scan_filter_policy - Scan filter policy -** -** Returns TRUE or FALSE -** -*******************************************************************************/ -BOOLEAN btm_ble_send_extended_scan_params(UINT8 scan_type, UINT32 scan_int, - UINT32 scan_win, UINT8 addr_type_own, - UINT8 scan_filter_policy) -{ - UINT8 scan_param[HCIC_PARAM_SIZE_BLE_WRITE_EXTENDED_SCAN_PARAM]; - UINT8 *pp_scan = scan_param; - - memset(scan_param, 0, HCIC_PARAM_SIZE_BLE_WRITE_EXTENDED_SCAN_PARAM); - - UINT8_TO_STREAM(pp_scan, scan_type); - UINT32_TO_STREAM(pp_scan, scan_int); - UINT32_TO_STREAM(pp_scan, scan_win); - UINT8_TO_STREAM(pp_scan, addr_type_own); - UINT8_TO_STREAM(pp_scan, scan_filter_policy); - - BTM_TRACE_DEBUG("%s, %d, %d", __func__, scan_int, scan_win); - if ((BTM_VendorSpecificCommand(HCI_BLE_EXTENDED_SCAN_PARAMS_OCF, - HCIC_PARAM_SIZE_BLE_WRITE_EXTENDED_SCAN_PARAM, scan_param, NULL)) != BTM_SUCCESS) { - BTM_TRACE_ERROR("%s error sending extended scan parameters", __func__); - return FALSE; - } - return TRUE; -} - #if (BLE_42_SCAN_EN == TRUE) /******************************************************************************* ** @@ -513,9 +474,9 @@ tBTM_STATUS BTM_BleScan(BOOLEAN start, UINT32 duration, tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_stop_adv_cback) { tBTM_STATUS status = BTM_NO_RESOURCES; - tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; + // tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; - UINT8 evt_type = p_cb->scan_rsp ? BTM_BLE_DISCOVER_EVT : BTM_BLE_NON_CONNECT_EVT; + //UINT8 evt_type = p_cb->scan_rsp ? BTM_BLE_DISCOVER_EVT : BTM_BLE_NON_CONNECT_EVT; if (!controller_get_interface()->supports_ble()) { return BTM_ILLEGAL_VALUE; @@ -562,26 +523,6 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_s } #endif // #if (BLE_42_ADV_EN == TRUE) -/******************************************************************************* -** -** Function BTM_BleGetVendorCapabilities -** -** Description This function reads local LE features -** -** Parameters p_cmn_vsc_cb : Locala LE capability structure -** -** Returns void -** -*******************************************************************************/ -extern void BTM_BleGetVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb) -{ - BTM_TRACE_DEBUG("BTM_BleGetVendorCapabilities"); - - if (NULL != p_cmn_vsc_cb) { - *p_cmn_vsc_cb = btm_cb.cmn_ble_vsc_cb; - } -} - void BTM_VendorHciEchoCmdCallback(tBTM_VSC_CMPL *p1) { #if (!CONFIG_BT_STACK_NO_LOG) @@ -1349,15 +1290,10 @@ tBTM_STATUS BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, if (BTM_BleUpdateOwnType(&addr_type_own, NULL) != 0) { return BTM_ILLEGAL_VALUE; } - /* If not supporting extended scan support, use the older range for checking */ - if (btm_cb.cmn_ble_vsc_cb.extended_scan_support == 0) { - max_scan_interval = BTM_BLE_SCAN_INT_MAX; - max_scan_window = BTM_BLE_SCAN_WIN_MAX; - } else { - /* If supporting extended scan support, use the new extended range for checking */ - max_scan_interval = BTM_BLE_EXT_SCAN_INT_MAX; - max_scan_window = BTM_BLE_EXT_SCAN_WIN_MAX; - } + + max_scan_interval = BTM_BLE_SCAN_INT_MAX; + max_scan_window = BTM_BLE_SCAN_WIN_MAX; + osi_mutex_lock(&scan_param_lock, OSI_MUTEX_MAX_TIMEOUT); @@ -4063,8 +3999,6 @@ void btm_ble_init (void) btu_free_timer(&p_cb->scan_timer_ent); btu_free_timer(&p_cb->inq_var.fast_adv_timer); memset(p_cb, 0, sizeof(tBTM_BLE_CB)); - memset(&(btm_cb.cmn_ble_vsc_cb), 0 , sizeof(tBTM_BLE_VSC_CB)); - btm_cb.cmn_ble_vsc_cb.values_read = FALSE; p_cb->cur_states = 0; p_cb->conn_pending_q = fixed_queue_new(QUEUE_SIZE_MAX); diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index 5975063a61..8580cb3c52 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -406,7 +406,6 @@ tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode); void btm_ble_stop_scan(void); void btm_clear_all_pending_le_entry(void); -BOOLEAN btm_ble_send_extended_scan_params(UINT8 scan_type, UINT32 scan_int, UINT32 scan_win, UINT8 addr_type_own, UINT8 scan_filter_policy); void btm_ble_init (void); void btm_ble_free (void); void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role, tBLE_ADDR_TYPE addr_type, BOOLEAN addr_matched); diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index 9e9cebd513..1c825bbefe 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -899,7 +899,6 @@ typedef struct { BT_OCTET8 enc_rand; /* received rand value from LTK request*/ UINT16 ediv; /* received ediv value from LTK request */ UINT8 key_size; - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; BOOLEAN addr_res_en; /* internal use for test: address resolution enable/disable */ #endif 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 fd3c9e167d..eaefaf6a79 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,8 +122,6 @@ 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 -#define BTM_BLE_EXT_SCAN_INT_MAX 0x00FFFFFF -#define BTM_BLE_EXT_SCAN_WIN_MAX 0xFFFF #define BTM_BLE_CONN_INT_MIN 0x0006 #define BTM_BLE_CONN_INT_MAX 0x0C80 #define BTM_BLE_CONN_LATENCY_MAX 499 @@ -386,10 +384,7 @@ typedef UINT8 tBTM_BLE_AD_TYPE; typedef UINT8 tBTM_BLE_ADV_TX_POWER; /* adv tx power in dBm */ -typedef struct { - BOOLEAN values_read; - UINT8 extended_scan_support; -} tBTM_BLE_VSC_CB; + /* slave preferred connection interval range */ typedef struct { @@ -2097,20 +2092,6 @@ tBTM_STATUS BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, tBLE_SCAN_PARAM_SETUP_CBACK scan_setup_status_cback); -/******************************************************************************* -** -** Function BTM_BleGetVendorCapabilities -** -** Description This function reads local LE features -** -** Parameters p_cmn_vsc_cb : Locala LE capability structure -** -** Returns void -** -*******************************************************************************/ -//extern -void BTM_BleGetVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb); - /******************************************************************************* ** ** Function BTM_BleWriteScanRsp From fb6c56d180a633b4682d97e365266b98539e1980 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:31 +0800 Subject: [PATCH 137/226] fix(ble/bluedroid): disable vendor hci function (cherry picked from commit 715184fa364fede121838e55722ca8cd536b7a22) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 2 ++ .../host/bluedroid/stack/btm/btm_ble_privacy.c | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index bc6068ee06..7ab8974e8b 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -523,6 +523,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_s } #endif // #if (BLE_42_ADV_EN == TRUE) +#if (BLE_VENDOR_HCI_EN == TRUE) void BTM_VendorHciEchoCmdCallback(tBTM_VSC_CMPL *p1) { #if (!CONFIG_BT_STACK_NO_LOG) @@ -555,6 +556,7 @@ void BTM_VendorHciEchoCmdTest(uint8_t echo) &echo, BTM_VendorHciEchoCmdCallback); } +#endif // (BLE_VENDOR_HCI_EN == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c index ccc7f6e0b7..0c22e965d5 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c @@ -499,6 +499,7 @@ void btm_ble_set_privacy_mode_complete(UINT8 *p, UINT16 evt_len) } } +#if (0) /******************************************************************************* VSC that implement controller based privacy ********************************************************************************/ @@ -534,7 +535,7 @@ void btm_ble_resolving_list_vsc_op_cmpl (tBTM_VSC_CMPL *p_params) /* RPA offloading enable/disabled */ } } - +#endif /******************************************************************************* ** ** Function btm_ble_remove_resolving_list_entry @@ -569,6 +570,7 @@ tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec) * send key to the controller, but to resolve the random address in host. */ #endif } else { +#if (0) UINT8 param[20] = {0}; UINT8 *p = param; @@ -580,6 +582,7 @@ tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec) BTM_BLE_META_REMOVE_IRK_LEN, param, btm_ble_resolving_list_vsc_op_cmpl); +#endif } if (st == BTM_CMD_STARTED) { @@ -609,6 +612,7 @@ tBTM_STATUS btm_ble_clear_resolving_list(void) st = BTM_SUCCESS; } } else { +#if (0) UINT8 param[20] = {0}; UINT8 *p = param; @@ -617,6 +621,7 @@ tBTM_STATUS btm_ble_clear_resolving_list(void) BTM_BLE_META_CLEAR_IRK_LEN, param, btm_ble_resolving_list_vsc_op_cmpl); +#endif } return st; @@ -647,6 +652,7 @@ tBTM_STATUS btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec) st = BTM_CMD_STARTED; } } else { +#if (0) UINT8 param[20] = {0}; UINT8 *p = param; @@ -657,6 +663,7 @@ tBTM_STATUS btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec) BTM_BLE_META_READ_IRK_LEN, param, btm_ble_resolving_list_vsc_op_cmpl); +#endif } if (st == BTM_CMD_STARTED) { @@ -751,6 +758,7 @@ void btm_ble_resume_resolving_list_activity(void) p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE; } +#if (0) /******************************************************************************* ** ** Function btm_ble_vendor_enable_irk_feature @@ -780,6 +788,7 @@ tBTM_STATUS btm_ble_vendor_enable_irk_feature(BOOLEAN enable) return st; } +#endif /******************************************************************************* ** @@ -797,7 +806,9 @@ BOOLEAN btm_ble_exe_disable_resolving_list(void) } if (!controller_get_interface()->supports_ble_privacy()) { +#if (0) btm_ble_vendor_enable_irk_feature(FALSE); +#endif } else { //btsnd_hcic_ble_set_addr_resolution_enable(FALSE); } @@ -821,7 +832,9 @@ void btm_ble_exe_enable_resolving_list(void) } if (!controller_get_interface()->supports_ble_privacy()) { +#if (0) btm_ble_vendor_enable_irk_feature(TRUE); +#endif } else { //btsnd_hcic_ble_set_addr_resolution_enable(TRUE); } @@ -930,6 +943,7 @@ BOOLEAN btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec) #endif } else { +#if (0) UINT8 param[40] = {0}; UINT8 *p = param; @@ -945,6 +959,7 @@ BOOLEAN btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec) == BTM_CMD_STARTED) { rt = TRUE; } +#endif } if (rt) { From a0b1b26efdcfd490a63c6d5e220dbc5b23308cb3 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:31 +0800 Subject: [PATCH 138/226] fix(ble/bluedroid): disable exception list if scan is not enabled (cherry picked from commit ec6809611a21274b29e44678ae694bf0b21cce02) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/api/esp_gap_ble_api.c | 49 ++++++++++--------- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 2 + .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 2 + .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 2 + .../bluedroid/bta/dm/include/bta_dm_int.h | 4 ++ .../btc/profile/std/gap/btc_gap_ble.c | 8 ++- .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 2 + 7 files changed, 45 insertions(+), 24 deletions(-) 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 aa6a979833..7dfe9dd3dd 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -524,6 +524,29 @@ esp_err_t esp_ble_gap_config_adv_data_raw(uint8_t *raw_data, uint32_t raw_data_l btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } + +esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_data_len) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if ((raw_data_len != 0 && raw_data == NULL) || raw_data_len > ESP_BLE_ADV_DATA_LEN_MAX) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW; + arg.cfg_scan_rsp_data_raw.raw_scan_rsp = raw_data; + arg.cfg_scan_rsp_data_raw.raw_scan_rsp_len = raw_data_len; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy, + btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + +} + #endif // #if (BLE_42_ADV_EN == TRUE) #endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) esp_err_t esp_ble_gap_read_rssi(esp_bd_addr_t remote_addr) @@ -547,28 +570,7 @@ esp_err_t esp_ble_gap_read_rssi(esp_bd_addr_t remote_addr) return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } -#if (BLE_42_FEATURE_SUPPORT == TRUE) -esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_data_len) -{ - btc_msg_t msg = {0}; - btc_ble_gap_args_t arg; - - ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); - - if ((raw_data_len != 0 && raw_data == NULL) || raw_data_len > ESP_BLE_ADV_DATA_LEN_MAX) { - return ESP_ERR_INVALID_ARG; - } - - msg.sig = BTC_SIG_API_CALL; - msg.pid = BTC_PID_GAP_BLE; - msg.act = BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW; - arg.cfg_scan_rsp_data_raw.raw_scan_rsp = raw_data; - arg.cfg_scan_rsp_data_raw.raw_scan_rsp_len = raw_data_len; - - return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy, - btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); - -} +#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) esp_err_t esp_ble_gap_add_duplicate_scan_exceptional_device(esp_ble_duplicate_exceptional_info_type_t type, esp_duplicate_info_t device_info) { @@ -636,7 +638,8 @@ esp_err_t esp_ble_gap_clean_duplicate_scan_exceptional_list(esp_duplicate_scan_e return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } -#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) +#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) + #if (SMP_INCLUDED == TRUE) esp_err_t esp_ble_gap_set_security_param(esp_ble_sm_param_t param_type, void *value, uint8_t len) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index cbccbc486c..3690d44db1 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -5324,6 +5324,7 @@ void bta_dm_ble_set_adv_params_all (tBTA_DM_MSG *p_data) } #endif // #if (BLE_42_ADV_EN == TRUE) +#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) /******************************************************************************* ** ** Function bta_dm_ble_update_duplicate_exceptional_list @@ -5339,6 +5340,7 @@ void bta_dm_ble_update_duplicate_exceptional_list(tBTA_DM_MSG *p_data) p_data->ble_duplicate_exceptional_list.device_info, p_data->ble_duplicate_exceptional_list.exceptional_list_cb); } +#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) #if (BLE_42_ADV_EN == TRUE) /******************************************************************************* diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 5e19457ec3..04a95edfa2 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -1578,6 +1578,7 @@ void BTA_DmBleSetScanRspRaw (UINT8 *p_raw_scan_rsp, UINT32 raw_scan_rsp_len, } #endif // #if (BLE_42_ADV_EN == TRUE) +#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) /******************************************************************************* ** ** Function BTA_DmUpdateDuplicateExceptionalList @@ -1605,6 +1606,7 @@ void BTA_DmUpdateDuplicateExceptionalList(UINT8 subcode, UINT32 type, BD_ADDR de bta_sys_sendmsg(p_msg); } } +#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) #endif diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index b9a57a45d5..9f031fe522 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -176,7 +176,9 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_clear_white_list, /* BTA_DM_API_CLEAR_WHITE_LIST_EVT */ bta_dm_read_rssi, /* BTA_DM_API_READ_RSSI_EVT */ #if BLE_INCLUDED == TRUE +#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) bta_dm_ble_update_duplicate_exceptional_list,/* BTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_EVT */ +#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) #endif #if (BLE_50_FEATURE_SUPPORT == TRUE) bta_dm_ble_gap_read_phy, /* BTA_DM_API_READ_PHY_EVT */ diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 23ca27995f..639e758802 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -169,7 +169,9 @@ enum { BTA_DM_API_CLEAR_WHITE_LIST_EVT, BTA_DM_API_READ_RSSI_EVT, #if BLE_INCLUDED == TRUE +#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) BTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_EVT, +#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) #endif #if (BLE_50_FEATURE_SUPPORT == TRUE) BTA_DM_API_READ_PHY_EVT, @@ -433,6 +435,7 @@ typedef struct { tBTA_UPDATE_WHITELIST_CBACK *update_wl_cb; }tBTA_DM_API_UPDATE_WHITE_LIST; +#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) typedef struct { BT_HDR hdr; UINT8 subcode; @@ -440,6 +443,7 @@ typedef struct { BD_ADDR device_info; tBTA_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK *exceptional_list_cb; }tBTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST; +#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) #endif ///BLE_INCLUDED == TRUE 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 44c6244445..5eb9ab6b07 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 @@ -470,6 +470,7 @@ static void btc_stop_adv_callback(uint8_t status) } #endif // #if (BLE_42_ADV_EN == TRUE) +#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) void btc_update_duplicate_exceptional_list_callback(tBTA_STATUS status, uint8_t subcode, uint32_t length, uint8_t *device_info) { esp_ble_gap_cb_param_t param; @@ -498,6 +499,7 @@ static void btc_ble_update_duplicate_exceptional_list(uint8_t subcode, uint32_t { BTA_DmUpdateDuplicateExceptionalList(subcode, info_type, device_info, p_update_duplicate_ignore_list_cback); } +#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) #if (BLE_42_ADV_EN == TRUE) static void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params, tBTA_START_ADV_CMPL_CBACK start_adv_cback) @@ -2695,13 +2697,17 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) btc_scan_rsp_data_raw_callback); break; #endif // #if (BLE_42_ADV_EN == TRUE) +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + +#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) case BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST: btc_ble_update_duplicate_exceptional_list(arg->update_duplicate_exceptional_list.subcode, arg->update_duplicate_exceptional_list.info_type, arg->update_duplicate_exceptional_list.device_info, btc_update_duplicate_exceptional_list_callback); break; -#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) +#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) + #if (SMP_INCLUDED == TRUE) case BTC_GAP_BLE_SET_ENCRYPTION_EVT: { BD_ADDR bd_addr; diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index 7ab8974e8b..3f93a42da3 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -1405,6 +1405,7 @@ tBTM_STATUS BTM_BleWriteScanRspRaw(UINT8 *p_raw_scan_rsp, UINT32 raw_scan_rsp_le } #endif // #if (BLE_42_ADV_EN == TRUE) +#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) /******************************************************************************* ** ** Function BTM_UpdateBleDuplicateExceptionalList @@ -1469,6 +1470,7 @@ tBTM_STATUS BTM_UpdateBleDuplicateExceptionalList(uint8_t subcode, uint32_t type return status; } +#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) #if (BLE_42_ADV_EN == TRUE) /******************************************************************************* From 27f9a8a3c9bf4c39e4c56a53625bb0180248b5e4 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:31 +0800 Subject: [PATCH 139/226] fix(ble/bluedroid): change tGATT_BG_CONN_DEV to GATT_BG_CONN_DEV (cherry picked from commit ac7812ef8d89feaba28014587c0fb1eac3ed991a) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/bta/dm/bta_dm_act.c | 2 ++ .../bt/host/bluedroid/stack/btm/btm_ble_bgconn.c | 12 ++++++------ components/bt/host/bluedroid/stack/btm/btm_ble_gap.c | 8 ++++---- .../bt/host/bluedroid/stack/btm/btm_ble_privacy.c | 8 ++++---- components/bt/host/bluedroid/stack/btm/btm_devctl.c | 4 ++-- .../host/bluedroid/stack/btm/include/btm_ble_int.h | 4 ++-- components/bt/host/bluedroid/stack/gatt/gatt_api.c | 12 ++++++------ components/bt/host/bluedroid/stack/gatt/gatt_main.c | 12 ++++++------ components/bt/host/bluedroid/stack/gatt/gatt_utils.c | 4 ++-- .../bt/host/bluedroid/stack/gatt/include/gatt_int.h | 12 ++++++------ components/bt/host/bluedroid/stack/l2cap/l2c_ble.c | 4 ++-- 11 files changed, 42 insertions(+), 40 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 3690d44db1..ce98b0a987 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -599,7 +599,9 @@ void bta_dm_disable (tBTA_DM_MSG *p_data) #endif #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE +#if (GATT_BG_CONN_DEV == TRUE) BTM_BleClearBgConnDev(); +#endif // (GATT_BG_CONN_DEV == TRUE) #endif if (BTM_GetNumAclLinks() == 0) { diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c index 23117acae3..c82179aa92 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c @@ -660,7 +660,7 @@ void btm_ble_initiate_select_conn(BD_ADDR bda) BTM_TRACE_ERROR("btm_ble_initiate_select_conn failed"); } } -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) /******************************************************************************* ** ** Function btm_ble_suspend_bg_conn @@ -685,7 +685,7 @@ BOOLEAN btm_ble_suspend_bg_conn(void) return FALSE; } -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) /******************************************************************************* ** @@ -721,9 +721,9 @@ static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state) *******************************************************************************/ void btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state) { -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) btm_ble_resume_bg_conn(); -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) if (wl_state & BTM_BLE_WL_ADV) { #if (BLE_42_ADV_EN == TRUE) btm_ble_start_adv(); @@ -750,7 +750,7 @@ static void btm_wl_update_to_controller(void) btm_execute_wl_dev_operation(); } -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) /******************************************************************************* ** ** Function btm_ble_resume_bg_conn @@ -780,7 +780,7 @@ BOOLEAN btm_ble_resume_bg_conn(void) return ret; } -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index 3f93a42da3..6667a9d96f 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -1015,6 +1015,7 @@ BOOLEAN BTM_BleSetBgConnType(tBTM_BLE_CONN_TYPE bg_conn_type, return started; } +#if (GATT_BG_CONN_DEV == TRUE) /******************************************************************************* ** ** Function BTM_BleClearBgConnDev @@ -1032,10 +1033,9 @@ void BTM_BleClearBgConnDev(void) { btm_ble_start_auto_conn(FALSE); btm_ble_clear_white_list(NULL); -#if (tGATT_BG_CONN_DEV == TRUE) gatt_reset_bgdev_list(); -#endif // #if (tGATT_BG_CONN_DEV == TRUE) } +#endif // #if (GATT_BG_CONN_DEV == TRUE) /******************************************************************************* ** @@ -3955,9 +3955,9 @@ BOOLEAN btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bd_addr, UINT8 st now in order */ if (btm_ble_get_conn_st() == BLE_CONN_IDLE && status != HCI_ERR_HOST_REJECT_RESOURCES && !btm_send_pending_direct_conn()) { -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) bg_con = btm_ble_resume_bg_conn(); -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) } return bg_con; diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c index 0c22e965d5..633d15e253 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c @@ -718,11 +718,11 @@ BOOLEAN btm_ble_suspend_resolving_list_activity(void) btm_ble_stop_scan(); p_ble_cb->suspended_rl_state |= BTM_BLE_RL_SCAN; } -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) if (btm_ble_suspend_bg_conn()) { p_ble_cb->suspended_rl_state |= BTM_BLE_RL_INIT; } -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) return TRUE; } @@ -750,11 +750,11 @@ void btm_ble_resume_resolving_list_activity(void) btm_ble_start_scan(); } #endif // #if (BLE_42_SCAN_EN == TRUE) -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_INIT) { btm_ble_resume_bg_conn(); } -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE; } diff --git a/components/bt/host/bluedroid/stack/btm/btm_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index 9698c439ab..d32030a84e 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -176,9 +176,9 @@ static void reset_complete(void) btm_cb.ble_ctr_cb.conn_state = BLE_CONN_IDLE; btm_cb.ble_ctr_cb.bg_conn_type = BTM_BLE_CONN_NONE; btm_cb.ble_ctr_cb.p_select_cback = NULL; -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) gatt_reset_bgdev_list(); -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) #endif diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index 8580cb3c52..cb0ff2a5b1 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -464,11 +464,11 @@ void btm_ble_remove_from_white_list_complete(UINT8 *p, UINT16 evt_len); void btm_ble_clear_white_list_complete(UINT8 *p, UINT16 evt_len); void btm_ble_white_list_init(UINT8 white_list_size); -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) /* background connection function */ BOOLEAN btm_ble_suspend_bg_conn(void); BOOLEAN btm_ble_resume_bg_conn(void); -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) void btm_ble_initiate_select_conn(BD_ADDR bda); BOOLEAN btm_ble_start_auto_conn(BOOLEAN start); diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_api.c b/components/bt/host/bluedroid/stack/gatt/gatt_api.c index 621ab52cbc..a245247d56 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_api.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_api.c @@ -1391,9 +1391,9 @@ void GATT_Deregister (tGATT_IF gatt_if) } } } -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) gatt_deregister_bgdev_list(gatt_if); -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) memset (p_reg, 0, sizeof(tGATT_REG)); } @@ -1469,11 +1469,11 @@ BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, tBLE_ADDR_TYPE bd_addr_ if (is_direct) { status = gatt_act_connect (p_reg, bd_addr, bd_addr_type, transport, is_aux, is_pawr_synced, adv_handle, subevent); } else { -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) if (transport == BT_TRANSPORT_LE) { status = gatt_update_auto_connect_dev(gatt_if, TRUE, bd_addr, TRUE); } else -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) { GATT_TRACE_ERROR("Unsupported transport for background connection"); } @@ -1531,7 +1531,7 @@ BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct status = gatt_cancel_open(gatt_if, bd_addr); } } else { -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) if (!gatt_if) { if (gatt_get_num_apps_for_bg_dev(bd_addr)) { while (gatt_find_app_for_bg_dev(bd_addr, &temp_gatt_if)) { @@ -1544,7 +1544,7 @@ BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct } else { status = gatt_remove_bg_dev_for_app(gatt_if, bd_addr); } -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) } return status; diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_main.c b/components/bt/host/bluedroid/stack/gatt/gatt_main.c index 15ea739ee6..93eb1bb194 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_main.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_main.c @@ -935,23 +935,23 @@ static void gatt_send_conn_cback(tGATT_TCB *p_tcb) { UINT8 i; tGATT_REG *p_reg; -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) tGATT_BG_CONN_DEV *p_bg_dev = NULL; -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) UINT16 conn_id; -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) p_bg_dev = gatt_find_bg_dev(p_tcb->peer_bda); -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) /* notifying all applications for the connection up event */ for (i = 0, p_reg = gatt_cb.cl_rcb ; i < GATT_MAX_APPS; i++, p_reg++) { if (p_reg->in_use) { -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) if (p_bg_dev && gatt_is_bg_dev_for_app(p_bg_dev, p_reg->gatt_if)) { gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, TRUE, TRUE); } -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) if (p_reg->app_cb.p_conn_cb) { conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if); (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id, diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c index 1bf819bc24..e950b67932 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c @@ -2424,7 +2424,7 @@ void gatt_dbg_display_uuid(tBT_UUID bt_uuid) } -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) /******************************************************************************* ** ** Function gatt_is_bg_dev_for_app @@ -2805,7 +2805,7 @@ BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_ } return ret; } -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) #if (SMP_INCLUDED == TRUE) /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h index 4fd74fba0e..b1337d5cfd 100644 --- a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -489,14 +489,14 @@ typedef struct { UINT32 service_change; } tGATT_SVC_CHG; -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) typedef struct { tGATT_IF gatt_if[GATT_MAX_APPS]; tGATT_IF listen_gif[GATT_MAX_APPS]; BD_ADDR remote_bda; BOOLEAN in_use; } tGATT_BG_CONN_DEV; -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) #define GATT_SVC_CHANGED_CONNECTING 1 /* wait for connection */ #define GATT_SVC_CHANGED_SERVICE 2 /* GATT service discovery */ @@ -565,9 +565,9 @@ typedef struct { #if (GATTS_INCLUDED == TRUE) tGATT_HDL_CFG hdl_cfg; #endif // (GATTS_INCLUDED == TRUE) -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) tGATT_BG_CONN_DEV bgconn_dev[GATT_MAX_BG_CONN_DEV]; -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) #if (GATTC_INCLUDED == TRUE) BOOLEAN auto_disc; /* internal use: true for auto discovering after connected */ #endif // (GATTC_INCLUDED == TRUE) @@ -682,7 +682,7 @@ extern BOOLEAN gatt_add_an_item_to_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_L extern BOOLEAN gatt_remove_an_item_from_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIST_ELEM *p_remove); extern tGATTS_SRV_CHG *gatt_add_srv_chg_clt(tGATTS_SRV_CHG *p_srv_chg); -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) /* for background connection */ extern BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_addr, BOOLEAN is_initiator); extern BOOLEAN gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV *p_dev, tGATT_IF gatt_if); @@ -692,7 +692,7 @@ extern BOOLEAN gatt_find_app_for_bg_dev(BD_ADDR bd_addr, tGATT_IF *p_gatt_if); extern tGATT_BG_CONN_DEV *gatt_find_bg_dev(BD_ADDR remote_bda); extern void gatt_deregister_bgdev_list(tGATT_IF gatt_if); extern void gatt_reset_bgdev_list(void); -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) /* server function */ extern UINT8 gatt_sr_find_i_rcb_by_handle(UINT16 handle); diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c index 39ba389451..b578a5640f 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c @@ -1079,11 +1079,11 @@ BOOLEAN l2cble_create_conn (tL2C_LCB *p_lcb) L2CAP_TRACE_WARNING ("L2CAP - LE - cannot start new connection at conn st: %d", conn_st); btm_ble_enqueue_direct_conn_req(p_lcb); -#if (tGATT_BG_CONN_DEV == TRUE) +#if (GATT_BG_CONN_DEV == TRUE) if (conn_st == BLE_BG_CONN) { btm_ble_suspend_bg_conn(); } -#endif // #if (tGATT_BG_CONN_DEV == TRUE) +#endif // #if (GATT_BG_CONN_DEV == TRUE) rt = TRUE; } return rt; From bd1c995c651d09fb30a4622cbd8e6a5fef63547a Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:32 +0800 Subject: [PATCH 140/226] fix(ble/bluedroid): disable bluedroid background connection (cherry picked from commit 1f5fa1e72b290b3471f90dfe695dca23f8825181) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/bta/dm/bta_dm_api.c | 3 +++ components/bt/host/bluedroid/bta/dm/bta_dm_main.c | 4 +++- .../bt/host/bluedroid/bta/dm/include/bta_dm_int.h | 2 ++ components/bt/host/bluedroid/bta/hh/bta_hh_le.c | 3 ++- .../bt/host/bluedroid/stack/btm/btm_ble_bgconn.c | 15 ++++++++++++++- .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 14 ++++++++++++-- .../bt/host/bluedroid/stack/btm/btm_devctl.c | 2 ++ .../bluedroid/stack/btm/include/btm_ble_int.h | 4 ++++ 8 files changed, 42 insertions(+), 5 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 04a95edfa2..8a6538bf0b 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -1647,6 +1647,8 @@ extern void BTA_DmBleAdvStop (BOOLEAN start, tBTA_START_STOP_ADV_CMPL_CBACK *p_s #endif // #if (BLE_42_ADV_EN == TRUE) #endif + +#if (BLE_GATT_BGCONN == TRUE) /******************************************************************************* ** ** Function BTA_DmBleSetBgConnType @@ -1677,6 +1679,7 @@ void BTA_DmBleSetBgConnType(tBTA_DM_BLE_CONN_TYPE bg_conn_type, tBTA_DM_BLE_SEL_ } #endif } +#endif// (BLE_GATT_BGCONN == TRUE) /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 9f031fe522..6d86d41be3 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -137,7 +137,9 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_confirm_reply, /* BTA_DM_API_BLE_CONFIRM_REPLY_EVT */ bta_dm_security_grant, /* BTA_DM_API_BLE_SEC_GRANT_EVT */ #endif ///SMP_INCLUDED == TRUE - bta_dm_ble_set_bg_conn_type, +#if (BLE_GATT_BGCONN == TRUE) + bta_dm_ble_set_bg_conn_type, /* BTA_DM_API_BLE_SET_BG_CONN_TYPE */ +#endif // (BLE_GATT_BGCONN == TRUE) bta_dm_ble_set_conn_params, /* BTA_DM_API_BLE_CONN_PARAM_EVT */ #if (BLE_42_SCAN_EN == TRUE) bta_dm_ble_set_scan_fil_params, /* BTA_DM_API_BLE_SCAN_FIL_PARAM_EVT */ diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 639e758802..d03825a5d6 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -123,7 +123,9 @@ enum { BTA_DM_API_BLE_CONFIRM_REPLY_EVT, BTA_DM_API_BLE_SEC_GRANT_EVT, #endif ///SMP_INCLUDED == TRUE +#if (BLE_GATT_BGCONN == TRUE) BTA_DM_API_BLE_SET_BG_CONN_TYPE, +#endif // (BLE_GATT_BGCONN == TRUE) BTA_DM_API_BLE_CONN_PARAM_EVT, /*******This event added by Yulong at 2016/10/25 to support the scan filter setting for the APP******/ diff --git a/components/bt/host/bluedroid/bta/hh/bta_hh_le.c b/components/bt/host/bluedroid/bta/hh/bta_hh_le.c index ae150a3c94..9bb7801a41 100644 --- a/components/bt/host/bluedroid/bta/hh/bta_hh_le.c +++ b/components/bt/host/bluedroid/bta/hh/bta_hh_le.c @@ -2605,8 +2605,9 @@ static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB *p_cb, BOOLEAN check_bond) BTA_GATTC_Enh_Open(bta_hh_cb.gatt_if, p_cb->addr, BLE_ADDR_UNKNOWN_TYPE, FALSE, BTA_GATT_TRANSPORT_LE, FALSE, BLE_ADDR_UNKNOWN_TYPE, false, 0xFF, 0xFF, 0, NULL, NULL); p_cb->in_bg_conn = TRUE; - +#if (BLE_GATT_BGCONN == TRUE) BTA_DmBleSetBgConnType(BTA_DM_BLE_CONN_AUTO, NULL); +#endif // (BLE_GATT_BGCONN == TRUE) } return; } diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c index c82179aa92..18cb93c125 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c @@ -39,10 +39,11 @@ #endif #if (BLE_INCLUDED == TRUE) - static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state); static void btm_wl_update_to_controller(void); +#if (BLE_GATT_BGCONN == TRUE) + // Unfortunately (for now?) we have to maintain a copy of the device whitelist // on the host to determine if a device is pending to be connected or not. This // controls whether the host should keep trying to scan for whitelisted @@ -118,6 +119,7 @@ static bool background_connections_pending(void) } return pending_connections; } +#endif // (BLE_GATT_BGCONN == TRUE) /******************************************************************************* ** @@ -335,6 +337,7 @@ BOOLEAN btm_update_dev_to_white_list(BOOLEAN to_add, BD_ADDR bd_addr, tBLE_ADDR_ return FALSE; } +#if (BLE_GATT_BGCONN == TRUE) if (to_add) { /* added the bd_addr to the connection hash map queue */ if(!background_connection_add((bt_bdaddr_t *)bd_addr)) { @@ -354,6 +357,7 @@ BOOLEAN btm_update_dev_to_white_list(BOOLEAN to_add, BD_ADDR bd_addr, tBLE_ADDR_ return TRUE; } } +#endif // (BLE_GATT_BGCONN == TRUE) if (update_wl_cb){ //save add whitelist complete callback @@ -381,7 +385,10 @@ void btm_ble_clear_white_list (tBTM_UPDATE_WHITELIST_CBACK *update_wl_cb) BTM_TRACE_EVENT ("btm_ble_clear_white_list"); btsnd_hcic_ble_clear_white_list(); + +#if (BLE_GATT_BGCONN == TRUE) background_connections_clear(); +#endif // (BLE_GATT_BGCONN == TRUE) if (update_wl_cb) { p_cb->update_wl_cb = update_wl_cb; @@ -488,6 +495,7 @@ void btm_ble_remove_from_white_list_complete(UINT8 *p, UINT16 evt_len) } } +#if (BLE_GATT_BGCONN == TRUE) /******************************************************************************* ** ** Function btm_ble_start_auto_conn @@ -660,6 +668,8 @@ void btm_ble_initiate_select_conn(BD_ADDR bda) BTM_TRACE_ERROR("btm_ble_initiate_select_conn failed"); } } +#endif // (BLE_GATT_BGCONN == TRUE) + #if (GATT_BG_CONN_DEV == TRUE) /******************************************************************************* ** @@ -698,12 +708,15 @@ BOOLEAN btm_ble_suspend_bg_conn(void) *******************************************************************************/ static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state) { +#if (BLE_GATT_BGCONN == TRUE) if (wl_state & BTM_BLE_WL_INIT) { btm_ble_start_auto_conn(FALSE); } if (wl_state & BTM_BLE_WL_SCAN) { btm_ble_start_select_conn(FALSE, NULL); } +#endif // (BLE_GATT_BGCONN == TRUE) + #if (BLE_42_ADV_EN == TRUE) if (wl_state & BTM_BLE_WL_ADV) { btm_ble_stop_adv(); diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index 6667a9d96f..f8699d6b0a 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -956,6 +956,7 @@ BOOLEAN BTM_BleLocalPrivacyEnabled(void) #endif } +#if (BLE_GATT_BGCONN == TRUE) /******************************************************************************* ** ** Function BTM_BleSetBgConnType @@ -1014,6 +1015,7 @@ BOOLEAN BTM_BleSetBgConnType(tBTM_BLE_CONN_TYPE bg_conn_type, } return started; } +#endif // (BLE_GATT_BGCONN == TRUE) #if (GATT_BG_CONN_DEV == TRUE) /******************************************************************************* @@ -2987,6 +2989,7 @@ void btm_clear_all_pending_le_entry(void) } } +#if (BLE_GATT_BGCONN == TRUE) /******************************************************************************* ** ** Function btm_send_sel_conn_callback @@ -3030,6 +3033,7 @@ void btm_send_sel_conn_callback(BD_ADDR remote_bda, UINT8 evt_type, UINT8 *p_dat btm_ble_initiate_select_conn(remote_bda); } } +#endif // #if (BLE_GATT_BGCONN == TRUE) #if (BLE_42_SCAN_EN == TRUE) static void btm_adv_pkt_handler(void *arg) @@ -3187,10 +3191,13 @@ static void btm_ble_process_last_adv_pkt(void) __func__); return; } +#if (BLE_GATT_BGCONN == TRUE) /* background connection in selective connection mode */ if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE) { //do nothing - } else { + } else +#endif // (BLE_GATT_BGCONN == TRUE) + { if (p_scan_results_cb && (result & BTM_BLE_DISCO_RESULT)) { (p_scan_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache); p_le_inq_cb->adv_len = 0; @@ -3298,6 +3305,7 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT); } } +#if (BLE_GATT_BGCONN == TRUE) /* background connection in selective connection mode */ if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE) { if (result & BTM_BLE_SEL_CONN_RESULT) { @@ -3305,7 +3313,9 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt } else { BTM_TRACE_DEBUG("None LE device, can not initiate selective connection\n"); } - } else { + } else +#endif // (BLE_GATT_BGCONN == TRUE) + { if (p_scan_results_cb && (result & BTM_BLE_DISCO_RESULT)) { (p_scan_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache); p_le_inq_cb->adv_len = 0; diff --git a/components/bt/host/bluedroid/stack/btm/btm_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index d32030a84e..54459b4d6b 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -174,8 +174,10 @@ static void reset_complete(void) #if (BLE_INCLUDED == TRUE) btm_cb.ble_ctr_cb.conn_state = BLE_CONN_IDLE; +#if (BLE_GATT_BGCONN == TRUE) btm_cb.ble_ctr_cb.bg_conn_type = BTM_BLE_CONN_NONE; btm_cb.ble_ctr_cb.p_select_cback = NULL; +#endif // (BLE_GATT_BGCONN == TRUE) #if (GATT_BG_CONN_DEV == TRUE) gatt_reset_bgdev_list(); #endif // #if (GATT_BG_CONN_DEV == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index cb0ff2a5b1..9be480869c 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -343,11 +343,15 @@ typedef struct { struct pkt_queue *adv_rpt_queue; struct osi_event *adv_rpt_ready; #endif // #if (BLE_42_SCAN_EN == TRUE) +#if (BLE_GATT_BGCONN == TRUE) /* background connection procedure cb value */ tBTM_BLE_CONN_TYPE bg_conn_type; +#endif // (BLE_GATT_BGCONN == TRUE) UINT32 scan_int; UINT32 scan_win; +#if (BLE_GATT_BGCONN == TRUE) tBTM_BLE_SEL_CBACK *p_select_cback; +#endif // (BLE_GATT_BGCONN == TRUE) /* white list information */ UINT8 white_list_avail_size; #if (BLE_50_EXTEND_SYNC_EN == TRUE) From e10bb32d8b3294decd41e94cb94816dfff839eaa Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:32 +0800 Subject: [PATCH 141/226] fix(ble/bluedroid): Fixed build error if scan is disabled (cherry picked from commit dd10e3220bfc919773c7e5b86a2ebb26e403c396) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/bta/dm/bta_dm_act.c | 4 ++++ components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index ce98b0a987..7cee634164 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -133,9 +133,11 @@ extern tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void); static BOOLEAN bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr); #endif ///SMP_INCLUDED == TRUE #if (BLE_INCLUDED == TRUE) +#if (BLE_42_SCAN_EN == TRUE) static void bta_dm_scan_results_cb(tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir); static void bta_dm_scan_cmpl_cb(void *p_result); static void bta_dm_scan_discard_cb (uint32_t num_dis); +#endif // (BLE_42_SCAN_EN == TRUE) #endif ///BLE_INCLUDED == TRUE #if (CLASSIC_BT_INCLUDED == TRUE) @@ -5242,6 +5244,7 @@ void bta_dm_ble_set_key_material (tBTA_DM_MSG *p_data) } #endif +#if (BLE_42_SCAN_EN == TRUE) /******************************************************************************* ** ** Function bta_dm_ble_scan @@ -5285,6 +5288,7 @@ void bta_dm_ble_scan (tBTA_DM_MSG *p_data) btm_ble_clear_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT); } } +#endif // (BLE_42_SCAN_EN == TRUE) #if (BLE_42_ADV_EN == TRUE) /******************************************************************************* diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index d03825a5d6..32eda4d51f 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -1706,7 +1706,9 @@ typedef union { tBTA_DM_API_SET_RPA_TIMEOUT set_rpa_timeout; tBTA_DM_API_ADD_DEV_TO_RESOLVING_LIST add_dev_to_resolving_list; tBTA_DM_API_BLE_DISCONNECT ble_disconnect; +#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) tBTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST ble_duplicate_exceptional_list; +#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) #if (BLE_50_FEATURE_SUPPORT == TRUE) tBTA_DM_API_READ_PHY ble_read_phy; tBTA_DM_API_SET_PER_DEF_PHY ble_set_per_def_phy; From 016cd78b3069c7c5cc7cf6cca9b3b3bdb81f1214 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:33 +0800 Subject: [PATCH 142/226] fix(ble/bluedroid): Add BLE_TOPOLOGY_CHECK (cherry picked from commit 728c4c8a1005161fec705dead1e6b493c912385d) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 3 +- .../host/bluedroid/stack/btm/btm_ble_bgconn.c | 13 +++++-- .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 38 +++++++++++++++---- .../bluedroid/stack/btm/include/btm_ble_int.h | 6 ++- .../bt/host/bluedroid/stack/l2cap/l2c_ble.c | 10 ++++- .../bt/host/bluedroid/stack/l2cap/l2c_link.c | 2 + 6 files changed, 59 insertions(+), 13 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 7cee634164..3498ce4300 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -5282,10 +5282,11 @@ void bta_dm_ble_scan (tBTA_DM_MSG *p_data) status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE); p_data->ble_scan.p_stop_scan_cback(status); } - +#if (BLE_TOPOLOGY_CHECK == TRUE) // reset BLE scan link state when stop scan btm_ble_clear_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT); btm_ble_clear_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT); +#endif // (BLE_TOPOLOGY_CHECK == TRUE) } } #endif // (BLE_42_SCAN_EN == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c index 18cb93c125..efff14dc82 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c @@ -519,7 +519,10 @@ BOOLEAN btm_ble_start_auto_conn(BOOLEAN start) if (start) { if (p_cb->conn_state == BLE_CONN_IDLE && background_connections_pending() - && btm_ble_topology_check(BTM_BLE_STATE_INIT)) { +#if (BLE_TOPOLOGY_CHECK == TRUE) + && btm_ble_topology_check(BTM_BLE_STATE_INIT) +#endif // (BLE_TOPOLOGY_CHECK == TRUE) + ) { p_cb->wl_state |= BTM_BLE_WL_INIT; btm_execute_wl_dev_operation(); @@ -615,11 +618,13 @@ BOOLEAN btm_ble_start_select_conn(BOOLEAN start, tBTM_BLE_SEL_CBACK *p_select_cb SP_ADV_WL)) { return FALSE; } - +#if (BLE_TOPOLOGY_CHECK == TRUE) if (!btm_ble_topology_check(BTM_BLE_STATE_PASSIVE_SCAN)) { BTM_TRACE_ERROR("peripheral device cannot initiate passive scan for a selective connection"); return FALSE; - } else if (background_connections_pending()) { + } +#endif // (BLE_TOPOLOGY_CHECK == TRUE) + if (background_connections_pending()) { #if BLE_PRIVACY_SPT == TRUE btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_SCAN); #endif @@ -822,11 +827,13 @@ void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st) BTM_TRACE_DEBUG("%s old=%u new=%u", __func__, btm_cb.ble_ctr_cb.conn_state, new_st); btm_cb.ble_ctr_cb.conn_state = new_st; +#if (BLE_TOPOLOGY_CHECK == TRUE) if (new_st == BLE_BG_CONN || new_st == BLE_DIR_CONN) { btm_ble_set_topology_mask(BTM_BLE_STATE_INIT_BIT); } else { btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT); } +#endif // (BLE_TOPOLOGY_CHECK == TRUE) } /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index f8699d6b0a..0c8918dd3d 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -101,6 +101,7 @@ bool btm_ble_inter_get(void) return is_ble50_inter; } +#if (BLE_TOPOLOGY_CHECK == TRUE) /* LE states combo bit to check */ const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] = { {/* single state support */ @@ -242,6 +243,7 @@ const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] = { }; /* check LE combo state supported */ #define BTM_LE_STATES_SUPPORTED(x, y, z) ((x)[(z)] & (y)) +#endif // (BLE_TOPOLOGY_CHECK == TRUE) #if (BLE_42_ADV_EN == TRUE) static osi_mutex_t adv_enable_lock; @@ -1219,6 +1221,7 @@ tBTM_STATUS BTM_BleSetAdvParamsAll(UINT16 adv_int_min, UINT16 adv_int_max, UINT8 btm_ble_stop_adv(); osi_mutex_lock(&adv_param_lock, OSI_MUTEX_MAX_TIMEOUT); +#if (BLE_TOPOLOGY_CHECK == TRUE) if(adv_type == BTM_BLE_CONNECT_DIR_EVT){ btm_ble_set_topology_mask(BTM_BLE_STATE_HI_DUTY_DIR_ADV_BIT); }else if(adv_type == BTM_BLE_CONNECT_LO_DUTY_DIR_EVT){ @@ -1226,7 +1229,7 @@ tBTM_STATUS BTM_BleSetAdvParamsAll(UINT16 adv_int_min, UINT16 adv_int_max, UINT8 }else if(adv_type == BTM_BLE_NON_CONNECT_EVT){ btm_ble_set_topology_mask(BTM_BLE_STATE_NON_CONN_ADV_BIT); } - +#endif // (BLE_TOPOLOGY_CHECK == TRUE) p_cb->adv_interval_min = adv_int_min; p_cb->adv_interval_max = adv_int_max; p_cb->adv_chnl_map = chnl_map; @@ -3374,11 +3377,13 @@ tBTM_STATUS btm_ble_start_scan(void) status = BTM_NO_RESOURCES; } btm_cb.ble_ctr_cb.inq_var.state |= BTM_BLE_SCANNING; +#if (BLE_TOPOLOGY_CHECK == TRUE) if (p_inq->scan_type == BTM_BLE_SCAN_MODE_ACTI) { btm_ble_set_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT); } else { btm_ble_set_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT); } +#endif // (BLE_TOPOLOGY_CHECK == TRUE) } osi_mutex_unlock(&scan_enable_lock); return status; @@ -3438,9 +3443,11 @@ static void btm_ble_stop_discover(void) if(btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE)) { osi_sem_take(&scan_enable_sem, OSI_SEM_MAX_TIMEOUT); } +#if (BLE_TOPOLOGY_CHECK == TRUE) /* reset status */ btm_ble_clear_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT); btm_ble_clear_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT); +#endif // (BLE_TOPOLOGY_CHECK == TRUE) } if (p_scan_cb) { @@ -3461,6 +3468,7 @@ static void btm_ble_stop_discover(void) *******************************************************************************/ typedef BOOLEAN (BTM_TOPOLOGY_FUNC_PTR)(tBTM_BLE_STATE_MASK); #if (BLE_42_ADV_EN == TRUE) +#if (BLE_TOPOLOGY_CHECK == TRUE) static BOOLEAN btm_ble_adv_states_operation(BTM_TOPOLOGY_FUNC_PTR *p_handler, UINT8 adv_evt) { BOOLEAN rt = FALSE; @@ -3492,6 +3500,7 @@ static BOOLEAN btm_ble_adv_states_operation(BTM_TOPOLOGY_FUNC_PTR *p_handler, UI return rt; } +#endif // (BLE_TOPOLOGY_CHECK == TRUE) /******************************************************************************* ** @@ -3508,10 +3517,11 @@ tBTM_STATUS btm_ble_start_adv(void) tBTM_STATUS rt = BTM_NO_RESOURCES; BTM_TRACE_EVENT ("btm_ble_start_adv\n"); - +#if (BLE_TOPOLOGY_CHECK == TRUE) if (!btm_ble_adv_states_operation (btm_ble_topology_check, p_cb->evt_type)) { return BTM_WRONG_MODE; } +#endif // (BLE_TOPOLOGY_CHECK == TRUE) osi_mutex_lock(&adv_enable_lock, OSI_MUTEX_MAX_TIMEOUT); @@ -3535,7 +3545,9 @@ tBTM_STATUS btm_ble_start_adv(void) UINT8 adv_mode = p_cb->adv_mode; p_cb->adv_mode = BTM_BLE_ADV_ENABLE; p_cb->state |= BTM_BLE_ADVERTISING; +#if (BLE_TOPOLOGY_CHECK == TRUE) btm_ble_adv_states_operation(btm_ble_set_topology_mask, p_cb->evt_type); +#endif // (BLE_TOPOLOGY_CHECK == TRUE) if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_ENABLE)) { osi_sem_take(&adv_enable_sem, OSI_SEM_MAX_TIMEOUT); rt = adv_enable_status; @@ -3544,7 +3556,9 @@ tBTM_STATUS btm_ble_start_adv(void) p_cb->adv_mode = BTM_BLE_ADV_DISABLE; p_cb->state = temp_state; p_cb->adv_mode = adv_mode; +#if (BLE_TOPOLOGY_CHECK == TRUE) btm_ble_adv_states_operation(btm_ble_clear_topology_mask, p_cb->evt_type); +#endif // (BLE_TOPOLOGY_CHECK == TRUE) btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV; } @@ -3574,16 +3588,18 @@ tBTM_STATUS btm_ble_stop_adv(void) BOOLEAN temp_fast_adv_on = p_cb->fast_adv_on; tBTM_BLE_GAP_STATE temp_state = p_cb->state; tBTM_BLE_WL_STATE temp_wl_state = btm_cb.ble_ctr_cb.wl_state; +#if (BLE_TOPOLOGY_CHECK == TRUE) tBTM_BLE_STATE_MASK temp_mask = btm_ble_get_topology_mask (); +#endif // (BLE_TOPOLOGY_CHECK == TRUE) p_cb->fast_adv_on = FALSE; p_cb->adv_mode = BTM_BLE_ADV_DISABLE; p_cb->state &= ~BTM_BLE_ADVERTISING; btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV; - +#if (BLE_TOPOLOGY_CHECK == TRUE) /* clear all adv states */ btm_ble_clear_topology_mask (BTM_BLE_STATE_ALL_ADV_MASK); - +#endif // (BLE_TOPOLOGY_CHECK == TRUE) if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE)) { osi_sem_take(&adv_enable_sem, OSI_SEM_MAX_TIMEOUT); rt = adv_enable_status; @@ -3593,8 +3609,9 @@ tBTM_STATUS btm_ble_stop_adv(void) p_cb->adv_mode = temp_adv_mode; p_cb->state = temp_state; btm_cb.ble_ctr_cb.wl_state = temp_wl_state; +#if (BLE_TOPOLOGY_CHECK == TRUE) btm_ble_set_topology_mask (temp_mask); - +#endif // (BLE_TOPOLOGY_CHECK == TRUE) rt = BTM_NO_RESOURCES; } if(adv_enable_status != HCI_SUCCESS) { @@ -3852,6 +3869,7 @@ void btm_ble_dir_adv_tout(void) btm_cb.ble_ctr_cb.inq_var.directed_conn = FALSE; } +#if (BLE_TOPOLOGY_CHECK == TRUE) /******************************************************************************* ** ** Function btm_ble_set_topology_mask @@ -3933,6 +3951,7 @@ void btm_ble_update_link_topology_mask(UINT8 link_role, BOOLEAN increase) btm_ble_clear_topology_mask(BTM_BLE_STATE_ALL_ADV_MASK); } } +#endif // (BLE_TOPOLOGY_CHECK == TRUE) /******************************************************************************* ** @@ -3951,8 +3970,10 @@ BOOLEAN btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bd_addr, UINT8 st btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE; /* make device fall back into undirected adv mode by default */ btm_cb.ble_ctr_cb.inq_var.directed_conn = BTM_BLE_CONNECT_EVT; +#if (BLE_TOPOLOGY_CHECK == TRUE) /* clear all adv states */ btm_ble_clear_topology_mask (BTM_BLE_STATE_ALL_ADV_MASK); +#endif // (BLE_TOPOLOGY_CHECK == TRUE) } if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE) { @@ -4013,8 +4034,9 @@ void btm_ble_init (void) btu_free_timer(&p_cb->scan_timer_ent); btu_free_timer(&p_cb->inq_var.fast_adv_timer); memset(p_cb, 0, sizeof(tBTM_BLE_CB)); +#if (BLE_TOPOLOGY_CHECK == TRUE) p_cb->cur_states = 0; - +#endif // (BLE_TOPOLOGY_CHECK == TRUE) p_cb->conn_pending_q = fixed_queue_new(QUEUE_SIZE_MAX); p_cb->inq_var.adv_mode = BTM_BLE_ADV_DISABLE; @@ -4074,6 +4096,8 @@ void esp_qa_enable_topology_check(bool enable) // This is a workaround: If the topology check is disabled, the 'Supported States' will not be checked. enable_topology_check_flag = enable; } + +#if (BLE_TOPOLOGY_CHECK == TRUE) /******************************************************************************* ** ** Function btm_ble_topology_check @@ -4138,7 +4162,7 @@ BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request_state_mask) } return rt; } - +#endif // (BLE_TOPOLOGY_CHECK == TRUE) /******************************************************************************* ** ** Function BTM_Ble_Authorization diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index 9be480869c..000b9a0b15 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -381,8 +381,10 @@ typedef struct { tBTM_BLE_WL_OP wl_op_q[BTM_BLE_MAX_BG_CONN_DEV_NUM]; +#if (BLE_TOPOLOGY_CHECK == TRUE) /* current BLE link state */ tBTM_BLE_STATE_MASK cur_states; /* bit mask of tBTM_BLE_STATE */ +#endif // (BLE_TOPOLOGY_CHECK == TRUE) UINT8 link_count[2]; /* total link count master and slave*/ tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK *update_exceptional_list_cmp_cb; tBTM_SET_CSA_SUPPORT_CMPL_CBACK *set_csa_support_cmpl_cb; @@ -516,11 +518,13 @@ void btm_ble_add_default_entry_to_resolving_list(void); void btm_ble_set_privacy_mode_complete(UINT8 *p, UINT16 evt_len); #endif -char btm_ble_map_adv_tx_power(int tx_power_index);; +char btm_ble_map_adv_tx_power(int tx_power_index); +#if (BLE_TOPOLOGY_CHECK == TRUE) BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request); BOOLEAN btm_ble_clear_topology_mask(tBTM_BLE_STATE_MASK request_state); BOOLEAN btm_ble_set_topology_mask(tBTM_BLE_STATE_MASK request_state); tBTM_BLE_STATE_MASK btm_ble_get_topology_mask(void); +#endif // (BLE_TOPOLOGY_CHECK == TRUE) #if BTM_BLE_CONFORMANCE_TESTING == TRUE void btm_ble_set_no_disc_if_pair_fail (BOOLEAN disble_disc); diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c index b578a5640f..511ed673fb 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c @@ -506,8 +506,13 @@ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE typ void l2cble_conn_comp(UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type, UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout) { +#if (BLE_TOPOLOGY_CHECK == TRUE) btm_ble_update_link_topology_mask(role, TRUE); - +#else + btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE; + /* make device fall back into undirected adv mode by default */ + btm_cb.ble_ctr_cb.inq_var.directed_conn = BTM_BLE_CONNECT_EVT; +#endif // (BLE_TOPOLOGY_CHECK == TRUE) if (role == HCI_ROLE_MASTER) { l2cble_scanner_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout); } else { @@ -945,11 +950,14 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) #endif // CONTROLLER_RPA_LIST_ENABLE #endif // (defined BLE_PRIVACY_SPT) && (BLE_PRIVACY_SPT == TRUE) +#if (BLE_TOPOLOGY_CHECK == TRUE) if (!btm_ble_topology_check(BTM_BLE_STATE_INIT)) { l2cu_release_lcb (p_lcb); L2CAP_TRACE_ERROR("initiate direct connection fail, topology limitation"); return FALSE; } +#endif // (BLE_TOPOLOGY_CHECK == TRUE) + uint32_t link_timeout = L2CAP_BLE_LINK_CONNECT_TOUT; if(GATTC_CONNECT_RETRY_COUNT) { if(!p_lcb->retry_create_con) { diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c index c151231bd9..1787828b77 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c @@ -392,10 +392,12 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) p_lcb->link_state = LST_DISCONNECTING; #if (BLE_INCLUDED == TRUE) +#if (BLE_TOPOLOGY_CHECK == TRUE) /* Check for BLE and handle that differently */ if (p_lcb->transport == BT_TRANSPORT_LE) { btm_ble_update_link_topology_mask(p_lcb->link_role, FALSE); } +#endif // (BLE_TOPOLOGY_CHECK == TRUE) #endif #if (CLASSIC_BT_INCLUDED == TRUE) /* Link is disconnected. For all channels, send the event through */ From 04f4602a6ae928e73960cd28d7c91e22de015279 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:33 +0800 Subject: [PATCH 143/226] fix(ble/bluedroid): optimize bluedroid host code (cherry picked from commit 3b18da2bdef039ca6643dd219ba84d4189c32d90) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/bta/dm/bta_dm_act.c | 8 +++++--- components/bt/host/bluedroid/stack/btm/btm_acl.c | 7 ++++++- components/bt/host/bluedroid/stack/btm/btm_ble_gap.c | 10 +++++++--- components/bt/host/bluedroid/stack/btm/btm_devctl.c | 10 ++++++---- components/bt/host/bluedroid/stack/btm/btm_main.c | 12 +++++++++--- .../host/bluedroid/stack/btm/include/btm_ble_int.h | 12 ++++++++---- .../bt/host/bluedroid/stack/btm/include/btm_int.h | 12 ++++++++++-- 7 files changed, 51 insertions(+), 20 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 3498ce4300..e5341d8cdf 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -78,9 +78,9 @@ static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data); static void bta_dm_acl_link_stat_cback(tBTM_ACL_LINK_STAT_EVENT_DATA *p_data); -static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr); #if (CLASSIC_BT_INCLUDED == TRUE) +static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr); static void bta_dm_encryption_change_cback(BD_ADDR bd_addr, UINT8 enc_mode); static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data); /* Extended Inquiry Response */ @@ -540,8 +540,9 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status ) /* initialize bluetooth low power manager */ bta_dm_init_pm(); #endif /* #if (BTA_DM_PM_INCLUDED == TRUE) */ - +#if (CLASSIC_BT_INCLUDED == TRUE) bta_sys_policy_register((tBTA_SYS_CONN_CBACK *)bta_dm_policy_cback); +#endif // (CLASSIC_BT_INCLUDED == TRUE) #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE) bta_dm_gattc_register(); @@ -1361,6 +1362,7 @@ void bta_dm_pin_reply (tBTA_DM_MSG *p_data) } #endif ///SMP_INCLUDED == TRUE +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function bta_dm_policy_cback @@ -1426,7 +1428,7 @@ static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app break; } } - +#endif // (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function bta_dm_confirm diff --git a/components/bt/host/bluedroid/stack/btm/btm_acl.c b/components/bt/host/bluedroid/stack/btm/btm_acl.c index cc77df53a7..b65d7b2745 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_acl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_acl.c @@ -257,7 +257,9 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, UINT8 bdn[BTM_MAX_REM_BD_NAME_L #endif BTM_TRACE_DEBUG ("Duplicate btm_acl_created: RemBdAddr: %02x%02x%02x%02x%02x%02x\n", bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); +#if (CLASSIC_BT_INCLUDED == TRUE) BTM_SetLinkPolicy(p->remote_addr, &btm_cb.btm_def_link_policy); +#endif // (CLASSIC_BT_INCLUDED == TRUE) return; } @@ -871,6 +873,7 @@ void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable) } } #endif // (CLASSIC_BT_INCLUDED == TRUE) +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function BTM_SetLinkPolicy @@ -954,7 +957,7 @@ void BTM_SetDefaultLinkPolicy (UINT16 settings) /* Set the default Link Policy of the controller */ btsnd_hcic_write_def_policy_set(settings); } - +#endif // (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btm_read_remote_version_complete @@ -1260,6 +1263,7 @@ void btm_establish_continue (tACL_CONN *p_acl_cb) tBTM_BL_EVENT_DATA evt_data; BTM_TRACE_DEBUG ("btm_establish_continue\n"); #if (!defined(BTM_BYPASS_EXTRA_ACL_SETUP) || BTM_BYPASS_EXTRA_ACL_SETUP == FALSE) +#if (CLASSIC_BT_INCLUDED == TRUE) #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE) if (p_acl_cb->transport == BT_TRANSPORT_BR_EDR) #endif @@ -1273,6 +1277,7 @@ void btm_establish_continue (tACL_CONN *p_acl_cb) BTM_SetLinkPolicy (p_acl_cb->remote_addr, &btm_cb.btm_def_link_policy); } } +#endif // (CLASSIC_BT_INCLUDED == TRUE) #endif p_acl_cb->link_up_issued = TRUE; diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index 0c8918dd3d..136f1fb393 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -69,7 +69,9 @@ static tBTM_BLE_VENDOR_HCI_EVT_CBACK *ble_vs_evt_callback = NULL; ** Local functions *******************************************************************************/ static void btm_ble_update_adv_flag(UINT8 flag); +#if (BLE_42_SCAN_EN == TRUE) static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt_type, UINT8 *p); +#endif // (BLE_42_SCAN_EN == TRUE) UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst, tBTM_BLE_ADV_DATA *p_data); @@ -414,7 +416,9 @@ tBTM_STATUS BTM_BleScan(BOOLEAN start, UINT32 duration, btm_cb.ble_ctr_cb.p_scan_results_cb = p_results_cb; btm_cb.ble_ctr_cb.p_scan_cmpl_cb = p_cmpl_cb; +#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) btm_cb.ble_ctr_cb.p_obs_discard_cb = p_discard_cb; +#endif // (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) status = BTM_CMD_STARTED; /* scan is not started */ @@ -3081,7 +3085,6 @@ static void btm_adv_pkt_handler(void *arg) UNUSED(hci_evt_code); UNUSED(hci_evt_len); } -#endif // #if (BLE_42_SCAN_EN == TRUE) /******************************************************************************* ** @@ -3348,7 +3351,7 @@ void btm_ble_process_direct_adv_pkt(UINT8 *p) // TODO } -#if (BLE_42_SCAN_EN == TRUE) + /******************************************************************************* ** ** Function btm_ble_start_scan @@ -4030,8 +4033,9 @@ void btm_ble_init (void) BTM_TRACE_DEBUG("%s", __func__); tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; - +#if (BLE_42_SCAN_EN == TRUE) btu_free_timer(&p_cb->scan_timer_ent); +#endif // (BLE_42_SCAN_EN == TRUE) btu_free_timer(&p_cb->inq_var.fast_adv_timer); memset(p_cb, 0, sizeof(tBTM_BLE_CB)); #if (BLE_TOPOLOGY_CHECK == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/btm_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index 54459b4d6b..39aec56e73 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -393,7 +393,7 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p BTM_TRACE_DEBUG("Local supported SCO packet types: 0x%04x", btm_cb.btm_sco_pkt_types_supported); -#endif // #if (CLASSIC_BT_INCLUDED == TRUE) + /* Create Default Policy Settings */ if (HCI_SWITCH_SUPPORTED(p_features)) { btm_cb.btm_def_link_policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH; @@ -418,9 +418,9 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p } else { btm_cb.btm_def_link_policy &= ~HCI_ENABLE_PARK_MODE; } - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) btm_sec_dev_reset (); - +#if (CLASSIC_BT_INCLUDED == TRUE) if (HCI_LMP_INQ_RSSI_SUPPORTED(p_features)) { if (HCI_EXT_INQ_RSP_SUPPORTED(p_features)) { BTM_SetInquiryMode (BTM_INQ_RESULT_EXTENDED); @@ -428,7 +428,7 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p BTM_SetInquiryMode (BTM_INQ_RESULT_WITH_RSSI); } } - +#endif // (CLASSIC_BT_INCLUDED == TRUE) #if L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE if ( HCI_NON_FLUSHABLE_PB_SUPPORTED(p_features)) { l2cu_set_non_flushable_pbf(TRUE); @@ -771,6 +771,7 @@ void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len, tBTM_BLE_CB *ble_cb = &btm_cb.ble_ctr_cb; switch(opcode) { case HCI_VENDOR_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST: { +#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) uint8_t subcode, status; uint32_t length; STREAM_TO_UINT8(status, p); STREAM_TO_UINT8(subcode, p); @@ -779,6 +780,7 @@ void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len, (*ble_cb->update_exceptional_list_cmp_cb)(status, subcode, length, p); } break; +#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) } case HCI_VENDOR_BLE_CLEAR_ADV: { uint8_t status; diff --git a/components/bt/host/bluedroid/stack/btm/btm_main.c b/components/bt/host/bluedroid/stack/btm/btm_main.c index 49447f00f6..5543047786 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_main.c +++ b/components/bt/host/bluedroid/stack/btm/btm_main.c @@ -67,8 +67,9 @@ void btm_init (void) #if (CLASSIC_BT_INCLUDED == TRUE) btm_cb.page_queue = fixed_queue_new(QUEUE_SIZE_MAX); #endif // #if (CLASSIC_BT_INCLUDED == TRUE) +#if (SMP_INCLUDED == TRUE) btm_cb.sec_pending_q = fixed_queue_new(QUEUE_SIZE_MAX); - +#endif // (SMP_INCLUDED == TRUE) #if defined(BTM_INITIAL_TRACE_LEVEL) btm_cb.trace_level = BTM_INITIAL_TRACE_LEVEL; #else @@ -88,7 +89,9 @@ void btm_init (void) #if BLE_INCLUDED == TRUE btm_ble_lock_init(); btm_ble_sem_init(); +#if ((SMP_INCLUDED == TRUE) || (BLE_PRIVACY_SPT == TRUE)) btm_cb.addr_res_en = TRUE; +#endif // ((SMP_INCLUDED == TRUE) || (BLE_PRIVACY_SPT == TRUE)) #endif btm_sec_dev_init(); #if (BLE_50_FEATURE_SUPPORT == TRUE) @@ -114,8 +117,10 @@ void btm_free(void) { #if (CLASSIC_BT_INCLUDED == TRUE) fixed_queue_free(btm_cb.page_queue, osi_free_func); - fixed_queue_free(btm_cb.sec_pending_q, osi_free_func); #endif // #if (CLASSIC_BT_INCLUDED == TRUE) +#if (SMP_INCLUDED == TRUE) + fixed_queue_free(btm_cb.sec_pending_q, osi_free_func); +#endif // (SMP_INCLUDED == TRUE) btm_acl_free(); btm_sec_dev_free(); #if BTM_SCO_INCLUDED == TRUE @@ -155,7 +160,7 @@ uint8_t btm_ble_acl_active_count(void) return count; } - +#if ((SMP_INCLUDED == TRUE) || (BLE_PRIVACY_SPT == TRUE)) // Address resolution status uint8_t btm_get_ble_addr_resolve_disable_status(void) { @@ -167,4 +172,5 @@ void btm_ble_addr_resolve_enable(bool enable) { btm_cb.addr_res_en = enable; } +#endif // ((SMP_INCLUDED == TRUE) || (BLE_PRIVACY_SPT == TRUE)) #endif /*BLE_INCLUDED*/ diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index 000b9a0b15..76b34bcefe 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -331,15 +331,15 @@ typedef struct { ** BLE Inquiry *****************************************************/ tBTM_BLE_INQ_CB inq_var; - +#if (BLE_42_SCAN_EN == TRUE) +#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) // /* observer callback and timer */ tBTM_INQ_DIS_CB *p_obs_discard_cb; - +#endif // (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) /* scan callback and timer */ tBTM_INQ_RESULTS_CB *p_scan_results_cb; tBTM_CMPL_CB *p_scan_cmpl_cb; TIMER_LIST_ENT scan_timer_ent; -#if (BLE_42_SCAN_EN == TRUE) struct pkt_queue *adv_rpt_queue; struct osi_event *adv_rpt_ready; #endif // #if (BLE_42_SCAN_EN == TRUE) @@ -384,11 +384,15 @@ typedef struct { #if (BLE_TOPOLOGY_CHECK == TRUE) /* current BLE link state */ tBTM_BLE_STATE_MASK cur_states; /* bit mask of tBTM_BLE_STATE */ -#endif // (BLE_TOPOLOGY_CHECK == TRUE) UINT8 link_count[2]; /* total link count master and slave*/ +#endif // (BLE_TOPOLOGY_CHECK == TRUE) +#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK *update_exceptional_list_cmp_cb; +#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) +#if (BLE_VENDOR_HCI_EN == TRUE) tBTM_SET_CSA_SUPPORT_CMPL_CBACK *set_csa_support_cmpl_cb; tBTM_SET_VENDOR_EVT_MASK_CBACK *set_vendor_evt_mask_cmpl_cb; +#endif // (BLE_VENDOR_HCI_EN == TRUE) } tBTM_BLE_CB; #ifdef __cplusplus diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index 1c825bbefe..45dfe0b3ea 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -867,8 +867,9 @@ typedef struct { list_t *p_acl_db_list; #if (CLASSIC_BT_INCLUDED == TRUE) UINT8 btm_scn[BTM_MAX_SCN]; /* current SCNs: TRUE if SCN is in use */ -#endif ///CLASSIC_BT_INCLUDED == TRUE + UINT16 btm_def_link_policy; +#endif ///CLASSIC_BT_INCLUDED == TRUE UINT16 btm_def_link_super_tout; tBTM_ACL_LINK_STAT_CB *p_acl_link_stat_cb; /* Callback for when ACL link related events came */ @@ -894,12 +895,15 @@ typedef struct { *****************************************************/ #if (BLE_INCLUDED == TRUE) tBTM_BLE_CB ble_ctr_cb; - +#if (SMP_INCLUDED == TRUE) UINT16 enc_handle; BT_OCTET8 enc_rand; /* received rand value from LTK request*/ UINT16 ediv; /* received ediv value from LTK request */ UINT8 key_size; +#endif // (SMP_INCLUDED == TRUE) +#if ((SMP_INCLUDED == TRUE) || (BLE_PRIVACY_SPT == TRUE)) BOOLEAN addr_res_en; /* internal use for test: address resolution enable/disable */ +#endif // ((SMP_INCLUDED == TRUE) || (BLE_PRIVACY_SPT == TRUE)) #endif /* Packet types supported by the local device */ @@ -982,8 +986,12 @@ typedef struct { fixed_queue_t *page_queue; BOOLEAN paging; #endif // #if (CLASSIC_BT_INCLUDED == TRUE) +#if (SMP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == TRUE) BOOLEAN discing; +#endif // (SMP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == TRUE) +#if (SMP_INCLUDED == TRUE) fixed_queue_t *sec_pending_q; /* pending sequrity requests in tBTM_SEC_QUEUE_ENTRY format */ +#endif // (SMP_INCLUDED == TRUE) #if (!defined(BT_TRACE_VERBOSE) || (BT_TRACE_VERBOSE == FALSE)) char state_temp_buffer[BTM_STATE_BUFFER_SIZE]; #endif From 8e361fc5bbf89f9f005280bdb664085755112202 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:33 +0800 Subject: [PATCH 144/226] fix(ble/bluedroid): disable some member in tBTA_SYS_CB (cherry picked from commit 280385acf4d0d97407b072dcc3002936b4dca475) Co-authored-by: zhiweijian --- components/bt/host/bluedroid/bta/dm/bta_dm_act.c | 14 ++++++++------ components/bt/host/bluedroid/bta/dm/bta_dm_api.c | 2 ++ .../bt/host/bluedroid/bta/gatt/bta_gattc_act.c | 12 ++++++++---- .../bt/host/bluedroid/bta/gatt/bta_gatts_act.c | 11 ++++++++--- .../bt/host/bluedroid/bta/include/bta/bta_sys.h | 2 +- .../bt/host/bluedroid/bta/sys/bta_sys_conn.c | 4 ++++ .../bt/host/bluedroid/bta/sys/bta_sys_main.c | 3 ++- .../host/bluedroid/bta/sys/include/bta_sys_int.h | 3 ++- 8 files changed, 35 insertions(+), 16 deletions(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index e5341d8cdf..aa40ae8a25 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -93,7 +93,9 @@ static void bta_dm_eir_search_services( tBTM_INQ_RESULTS *p_result, #endif ///SDP_INCLUDED == TRUE static void bta_dm_search_timer_cback (TIMER_LIST_ENT *p_tle); static void bta_dm_disable_conn_down_timer_cback (TIMER_LIST_ENT *p_tle); +#if (CLASSIC_BT_INCLUDED == TRUE) static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #if (CLASSIC_BT_INCLUDED == TRUE) static void bta_dm_adjust_roles(BOOLEAN delay_role_switch); #endif // #if (CLASSIC_BT_INCLUDED == TRUE) @@ -532,10 +534,9 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status ) the DM_ENABLE_EVT to be sent only after all the init steps are complete */ #if (CLASSIC_BT_INCLUDED == TRUE) BTM_ReadLocalDeviceNameFromController((tBTM_CMPL_CB *)bta_dm_local_name_cback); -#endif // (CLASSIC_BT_INCLUDED == TRUE) bta_sys_rm_register((tBTA_SYS_CONN_CBACK *)bta_dm_rm_cback); - +#endif // (CLASSIC_BT_INCLUDED == TRUE) #if (BTA_DM_PM_INCLUDED == TRUE) /* initialize bluetooth low power manager */ bta_dm_init_pm(); @@ -672,8 +673,9 @@ static void bta_dm_disable_timer_cback (TIMER_LIST_ENT *p_tle) } } else { bta_dm_cb.disabling = FALSE; - +#if (CLASSIC_BT_INCLUDED == TRUE) bta_sys_remove_uuid(UUID_SERVCLASS_PNP_INFORMATION); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) bta_dm_cb.p_sec_cback(BTA_DM_DISABLE_EVT, NULL); } } @@ -3652,13 +3654,13 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data) return; #endif // #if (CLASSIC_BT_INCLUDED == TRUE) } - +#if (CLASSIC_BT_INCLUDED == TRUE) /* Collision report from Stack: Notify profiles */ if (p_data->acl_change.event == BTM_BL_COLLISION_EVT) { bta_sys_notify_collision (p_bda); return; } - +#endif // (CLASSIC_BT_INCLUDED == TRUE) if (is_new) { for (i = 0; i < bta_dm_cb.device_list.count; i++) { if (!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda) @@ -3827,6 +3829,7 @@ static void bta_dm_disable_conn_down_timer_cback (TIMER_LIST_ENT *p_tle) } +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function bta_dm_rm_cback @@ -3899,7 +3902,6 @@ static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, #endif // #if (CLASSIC_BT_INCLUDED == TRUE) } -#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function bta_dm_delay_role_switch_cback diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 8a6538bf0b..aaf0d8864f 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -73,8 +73,10 @@ tBTA_STATUS BTA_EnableBluetooth(tBTA_DM_SEC_CBACK *p_cback) bta_sys_register (BTA_ID_DM, &bta_dm_reg ); bta_sys_register (BTA_ID_DM_SEARCH, &bta_dm_search_reg ); +#if (CLASSIC_BT_INCLUDED == TRUE) /* if UUID list is not provided as static data */ bta_sys_eir_register(bta_dm_eir_update_uuid); +#endif // (CLASSIC_BT_INCLUDED == TRUE) if ((p_msg = (tBTA_DM_API_ENABLE *) osi_malloc(sizeof(tBTA_DM_API_ENABLE))) != NULL) { p_msg->hdr.event = BTA_DM_API_ENABLE_EVT; diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c index 07ebff2877..e808dc9f54 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c @@ -764,10 +764,12 @@ void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) } if (p_clcb->p_rcb) { +#if (CLASSIC_BT_INCLUDED == TRUE) /* there is no RM for GATT */ if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) { bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) tBTA_GATT_STATUS status = BTA_GATT_OK; if (p_data && p_data->int_conn.already_connect) { //clear already_connect @@ -870,11 +872,11 @@ void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) cb_data.close.reason = p_clcb->reason; cb_data.close.status = p_clcb->status; bdcpy(cb_data.close.remote_bda, p_clcb->bda); - +#if (CLASSIC_BT_INCLUDED == TRUE) if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) { bta_sys_conn_close( BTA_ID_GATTC , BTA_ALL_APP_ID, p_clcb->bda); } - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT) { cb_data.close.status = GATT_Disconnect(p_data->hdr.layer_specific); } else if (p_data->hdr.event == BTA_GATTC_INT_DISCONN_EVT) { @@ -1338,11 +1340,13 @@ void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) != GATT_SUCCESS) { APPL_TRACE_ERROR("bta_gattc_confirm to handle [0x%04x] failed", handle); } else { +#if (CLASSIC_BT_INCLUDED == TRUE) /* if over BR_EDR, inform PM for mode change */ if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) { bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } } /******************************************************************************* @@ -2202,13 +2206,13 @@ static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS APPL_TRACE_ERROR("bta_gattc_cmpl_cback unknown conn_id = %d, ignore data", conn_id); return; } - +#if (CLASSIC_BT_INCLUDED == TRUE) /* if over BR_EDR, inform PM for mode change */ if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) { bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); } - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) bta_gattc_cmpl_sendmsg(conn_id, op, status, p_data); } diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c index 37c9a67527..4e786bc8a1 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c @@ -695,12 +695,13 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg) p_msg->api_indicate.len, p_msg->api_indicate.value); } - +#if (CLASSIC_BT_INCLUDED == TRUE) /* if over BR_EDR, inform PM for mode change */ if (transport == BTA_TRANSPORT_BR_EDR) { bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda); bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda); } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } else { APPL_TRACE_ERROR("Unknown connection ID: %d fail sending notification", p_msg->api_indicate.hdr.layer_specific); @@ -839,10 +840,11 @@ void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg) p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if); if (p_rcb && p_rcb->p_cback) { +#if (CLASSIC_BT_INCLUDED == TRUE) if (transport == BTA_TRANSPORT_BR_EDR) { bta_sys_conn_close( BTA_ID_GATTS , BTA_ALL_APP_ID, remote_bda); } - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) close.status = status; close.conn_id = p_msg->hdr.layer_specific; (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT, (tBTA_GATTS *)&close); @@ -925,12 +927,13 @@ static void bta_gatts_send_request_cback (UINT16 conn_id, conn_id, trans_id, req_type); if (p_rcb && p_rcb->p_cback) { +#if (CLASSIC_BT_INCLUDED == TRUE) /* if over BR_EDR, inform PM for mode change */ if (transport == BTA_TRANSPORT_BR_EDR) { bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda); bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda); } - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) cb_data.req_data.conn_id = conn_id; cb_data.req_data.trans_id = trans_id; cb_data.req_data.p_data = (tBTA_GATTS_REQ_DATA *)p_data; @@ -980,6 +983,7 @@ static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if); if (p_reg && p_reg->p_cback) { +#if (CLASSIC_BT_INCLUDED == TRUE) /* there is no RM for GATT */ if (transport == BTA_TRANSPORT_BR_EDR) { if (connected) { @@ -988,6 +992,7 @@ static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, bta_sys_conn_close( BTA_ID_GATTS , BTA_ALL_APP_ID, bda); } } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) if(evt == BTA_GATTS_CONNECT_EVT) { tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE); if(p_lcb != NULL) { diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_sys.h b/components/bt/host/bluedroid/bta/include/bta/bta_sys.h index ecf4791995..07cd39d24c 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_sys.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_sys.h @@ -44,7 +44,7 @@ typedef void (tBTA_SYS_DISABLE)(void); /* HW modules */ enum { BTA_SYS_HW_BLUETOOTH, - BTA_SYS_HW_RT, + // BTA_SYS_HW_RT, BTA_SYS_MAX_HW_MODULES }; diff --git a/components/bt/host/bluedroid/bta/sys/bta_sys_conn.c b/components/bt/host/bluedroid/bta/sys/bta_sys_conn.c index 914df55d9c..b251a38694 100644 --- a/components/bt/host/bluedroid/bta/sys/bta_sys_conn.c +++ b/components/bt/host/bluedroid/bta/sys/bta_sys_conn.c @@ -28,6 +28,8 @@ #include "bta_sys_int.h" #include "bta/utl.h" +#if (CLASSIC_BT_INCLUDED == TRUE) + /******************************************************************************* ** ** Function bta_sys_rm_register @@ -661,3 +663,5 @@ BOOLEAN bta_sys_vs_hdl(UINT16 evt, void *p) return FALSE; } + +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) diff --git a/components/bt/host/bluedroid/bta/sys/bta_sys_main.c b/components/bt/host/bluedroid/bta/sys/bta_sys_main.c index db6ee48972..62eb274391 100644 --- a/components/bt/host/bluedroid/bta/sys/bta_sys_main.c +++ b/components/bt/host/bluedroid/bta/sys/bta_sys_main.c @@ -750,7 +750,7 @@ void bta_sys_set_trace_level(UINT8 level) { appl_trace_level = level; } - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function bta_sys_get_sys_features @@ -764,3 +764,4 @@ UINT16 bta_sys_get_sys_features (void) { return bta_sys_cb.sys_features; } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) \ No newline at end of file diff --git a/components/bt/host/bluedroid/bta/sys/include/bta_sys_int.h b/components/bt/host/bluedroid/bta/sys/include/bta_sys_int.h index aa2596d96c..5cff706b56 100644 --- a/components/bt/host/bluedroid/bta/sys/include/bta_sys_int.h +++ b/components/bt/host/bluedroid/bta/sys/include/bta_sys_int.h @@ -56,8 +56,8 @@ typedef struct { tBTA_SYS_HW_STATE state; tBTA_SYS_HW_CBACK *sys_hw_cback[BTA_SYS_MAX_HW_MODULES]; /* enable callback for each HW modules */ UINT32 sys_hw_module_active; /* bitmask of all active modules */ +#if (CLASSIC_BT_INCLUDED == TRUE) UINT16 sys_features; /* Bitmask of sys features */ - tBTA_SYS_CONN_CBACK *prm_cb; /* role management callback registered by DM */ tBTA_SYS_CONN_CBACK *ppm_cb; /* low power management callback registered by DM */ tBTA_SYS_CONN_CBACK *p_policy_cb; /* link policy change callback registered by DM */ @@ -72,6 +72,7 @@ typedef struct { #endif /* VS event handler */ tBTA_SYS_VS_EVT_HDLR *p_vs_evt_hdlr; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } tBTA_SYS_CB; From cbf4640668e2a553fb56313d72c7ad5ce33fe4a0 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:34 +0800 Subject: [PATCH 145/226] fix(ble/bluedroid): Fixed bt buuld error fix(ble/bluedroid): disable power management if bt is disabled (cherry picked from commit 6f27074c1ee4486cedf8adeb1a57e67b9cb6a525) Co-authored-by: zhiweijian --- .../api/include/api/esp_gap_ble_api.h | 5 +- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 2 + .../bt/host/bluedroid/bta/dm/bta_dm_pm.c | 4 ++ .../bluedroid/bta/dm/include/bta_dm_int.h | 2 + .../host/bluedroid/bta/include/bta/bta_api.h | 5 ++ .../bt/host/bluedroid/bta/sys/bta_sys_main.c | 6 +- .../bt/host/bluedroid/btc/core/btc_main.c | 2 + .../btc/profile/std/gap/btc_gap_ble.c | 63 ++++++++++--------- .../btc/profile/std/include/btc_gap_ble.h | 4 +- components/bt/host/bluedroid/main/bte_init.c | 6 ++ .../bt/host/bluedroid/stack/btm/btm_acl.c | 14 ++++- .../host/bluedroid/stack/btm/btm_ble_bgconn.c | 2 +- .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 8 ++- .../bt/host/bluedroid/stack/btm/btm_devctl.c | 3 +- .../bt/host/bluedroid/stack/btm/btm_inq.c | 3 + .../bt/host/bluedroid/stack/btm/btm_pm.c | 4 ++ .../bt/host/bluedroid/stack/btm/btm_sec.c | 13 +++- .../bluedroid/stack/btm/include/btm_int.h | 23 +++++-- .../bt/host/bluedroid/stack/btu/btu_hcif.c | 2 + .../bluedroid/stack/gatt/include/gatt_int.h | 2 +- .../bluedroid/stack/l2cap/include/l2c_int.h | 11 +++- .../bt/host/bluedroid/stack/l2cap/l2c_ble.c | 2 + .../bt/host/bluedroid/stack/l2cap/l2c_link.c | 8 ++- .../bt/host/bluedroid/stack/l2cap/l2c_main.c | 2 + .../bt/host/bluedroid/stack/l2cap/l2c_utils.c | 9 ++- 25 files changed, 144 insertions(+), 61 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 704e2c1086..ea39a5d730 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -823,9 +823,10 @@ typedef enum { ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ALL_LIST = 0xFFFF, /*!< duplicate scan exceptional all list */ } esp_duplicate_scan_exceptional_list_type_t; +#endif //#if (BLE_42_FEATURE_SUPPORT == TRUE) + typedef uint8_t esp_duplicate_info_t[ESP_BD_ADDR_LEN]; -#endif //#if (BLE_42_FEATURE_SUPPORT == TRUE) #if (BLE_50_FEATURE_SUPPORT == TRUE) #define ESP_BLE_GAP_SET_EXT_ADV_PROP_NONCONN_NONSCANNABLE_UNDIRECTED (0 << 0) /*!< Non-Connectable and Non-Scannable Undirected advertising */ @@ -1894,7 +1895,6 @@ typedef union { esp_bt_status_t status; /*!< Indicate the add or remove whitelist operation success status */ esp_ble_wl_operation_t wl_operation; /*!< The value is ESP_BLE_WHITELIST_ADD if add address to whitelist operation success, ESP_BLE_WHITELIST_REMOVE if remove address from the whitelist operation success */ } update_whitelist_cmpl; /*!< Event parameter of ESP_GAP_BLE_UPDATE_WHITELIST_COMPLETE_EVT */ -#if (BLE_42_FEATURE_SUPPORT == TRUE) /** * @brief ESP_GAP_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_COMPLETE_EVT */ @@ -1904,7 +1904,6 @@ typedef union { uint16_t length; /*!< The length of device_info */ esp_duplicate_info_t device_info; /*!< device information, when subcode is ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_CLEAN, the value is invalid */ } update_duplicate_exceptional_list_cmpl; /*!< Event parameter of ESP_GAP_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_COMPLETE_EVT */ -#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) /** * @brief ESP_GAP_BLE_SET_CHANNELS_EVT */ diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index aa40ae8a25..4f6f496a52 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -488,7 +488,9 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status ) #endif /* hw is ready, go on with BTA DM initialization */ memset(&bta_dm_search_cb, 0x00, sizeof(bta_dm_search_cb)); +#if (CLASSIC_BT_INCLUDED == TRUE) memset(&bta_dm_conn_srvcs, 0x00, sizeof(bta_dm_conn_srvcs)); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #if (CLASSIC_BT_INCLUDED == TRUE) memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB)); #endif // #if (CLASSIC_BT_INCLUDED == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_pm.c b/components/bt/host/bluedroid/bta/dm/bta_dm_pm.c index 8167ddf9a6..35727779ee 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_pm.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_pm.c @@ -32,6 +32,8 @@ #include "stack/btm_api.h" #include "osi/allocator.h" +#if (CLASSIC_BT_INCLUDED == TRUE) + #if BTA_DYNAMIC_MEMORY == FALSE tBTA_DM_CONNECTED_SRVCS bta_dm_conn_srvcs; #else @@ -1171,3 +1173,5 @@ tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void) } #endif + +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 32eda4d51f..f4498b54da 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -1609,12 +1609,14 @@ typedef union { tBTA_DM_API_CFG_COEX_STATUS cfg_coex_status; #endif tBTA_DM_API_SEND_VENDOR_HCI_CMD vendor_hci_cmd; +#if CLASSIC_BT_INCLUDED tBTA_DM_API_CONFIG_EIR config_eir; tBTA_DM_API_SET_AFH_CHANNELS set_afh_channels; tBTA_DM_API_PAGE_TO_SET set_page_timeout; tBTA_DM_API_PAGE_TO_GET get_page_timeout; tBTA_DM_API_SET_ACL_PKT_TYPES set_acl_pkt_types; +#endif /* CLASSIC_BT_INCLUDED */ #if (ENC_KEY_SIZE_CTRL_MODE != ENC_KEY_SIZE_CTRL_MODE_NONE) tBTA_DM_API_SET_MIN_ENC_KEY_SIZE set_min_enc_key_size; #endif diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 12e12be2c2..d8918fccff 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1188,6 +1188,11 @@ typedef void (tBTA_DM_ENCRYPT_CBACK) (BD_ADDR bd_addr, tBTA_TRANSPORT transport, #define BTA_DM_BLE_SEC_MITM BTM_BLE_SEC_ENCRYPT_MITM typedef tBTM_BLE_SEC_ACT tBTA_DM_BLE_SEC_ACT; +#define BTA_DM_CONTRL_UNKNOWN 0 /* Unknown state */ +#define BTA_DM_CONTRL_ACTIVE 1 /* ACL link on, SCO link ongoing, sniff mode */ +#define BTA_DM_CONTRL_SCAN 2 /* Scan state - paging/inquiry/trying to connect*/ +#define BTA_DM_CONTRL_IDLE 3 /* Idle state - page scan, LE advt, inquiry scan */ + typedef UINT8 tBTA_DM_CONTRL_STATE; typedef UINT8 tBTA_DM_BLE_ADV_STATE; diff --git a/components/bt/host/bluedroid/bta/sys/bta_sys_main.c b/components/bt/host/bluedroid/bta/sys/bta_sys_main.c index 62eb274391..ea1bc5a854 100644 --- a/components/bt/host/bluedroid/bta/sys/bta_sys_main.c +++ b/components/bt/host/bluedroid/bta/sys/bta_sys_main.c @@ -543,7 +543,7 @@ void bta_sys_deregister(UINT8 id) ** ** Function bta_sys_is_register ** -** Description Called by other BTA subsystems to get registeration +** Description Called by other BTA subsystems to get registration ** status. ** ** @@ -724,7 +724,7 @@ void bta_sys_disable(tBTA_SYS_HW_MODULE module) bta_id_max = BTA_ID_BLUETOOTH_MAX; break; default: - APPL_TRACE_WARNING("bta_sys_disable: unkown module"); + APPL_TRACE_WARNING("bta_sys_disable: unknown module"); return; } @@ -764,4 +764,4 @@ UINT16 bta_sys_get_sys_features (void) { return bta_sys_cb.sys_features; } -#endif // #if (CLASSIC_BT_INCLUDED == TRUE) \ No newline at end of file +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) diff --git a/components/bt/host/bluedroid/btc/core/btc_main.c b/components/bt/host/bluedroid/btc/core/btc_main.c index e05e7db020..0802202797 100644 --- a/components/bt/host/bluedroid/btc/core/btc_main.c +++ b/components/bt/host/bluedroid/btc/core/btc_main.c @@ -168,6 +168,7 @@ uint32_t btc_get_ble_status(void) status |= BIT(BTC_BLE_STATUS_CONN); } +#if ((SMP_INCLUDED == TRUE) || (BLE_PRIVACY_SPT == TRUE)) // Address resolve status extern uint8_t btm_get_ble_addr_resolve_disable_status(void); uint8_t addr_resolve_disable = btm_get_ble_addr_resolve_disable_status(); @@ -175,6 +176,7 @@ uint32_t btc_get_ble_status(void) BTC_TRACE_WARNING("%s address resolve disabled", __func__); status |= BIT(BTC_BLE_STATUS_ADDR_RESOLVE_DISABLE); } +#endif // #if ((SMP_INCLUDED == TRUE) || (BLE_PRIVACY_SPT == TRUE)) #if (SMP_INCLUDED == TRUE) // Number of recorded devices 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 5eb9ab6b07..a550b5c28a 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 @@ -470,37 +470,6 @@ static void btc_stop_adv_callback(uint8_t status) } #endif // #if (BLE_42_ADV_EN == TRUE) -#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) -void btc_update_duplicate_exceptional_list_callback(tBTA_STATUS status, uint8_t subcode, uint32_t length, uint8_t *device_info) -{ - esp_ble_gap_cb_param_t param; - bt_status_t ret; - btc_msg_t msg = {0}; - - msg.sig = BTC_SIG_API_CB; - msg.pid = BTC_PID_GAP_BLE; - msg.act = ESP_GAP_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_COMPLETE_EVT; - param.update_duplicate_exceptional_list_cmpl.status = status; - param.update_duplicate_exceptional_list_cmpl.subcode = subcode; - if(length > sizeof(param.update_duplicate_exceptional_list_cmpl.device_info)) { - length = sizeof(param.update_duplicate_exceptional_list_cmpl.device_info); - } - param.update_duplicate_exceptional_list_cmpl.length = length; - memcpy(param.update_duplicate_exceptional_list_cmpl.device_info, device_info, length); - ret = btc_transfer_context(&msg, ¶m, sizeof(esp_ble_gap_cb_param_t), NULL, NULL); - - if (ret != BT_STATUS_SUCCESS) { - BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__); - } -} - -static void btc_ble_update_duplicate_exceptional_list(uint8_t subcode, uint32_t info_type, BD_ADDR device_info, - tBTA_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK p_update_duplicate_ignore_list_cback) -{ - BTA_DmUpdateDuplicateExceptionalList(subcode, info_type, device_info, p_update_duplicate_ignore_list_cback); -} -#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) - #if (BLE_42_ADV_EN == TRUE) static void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params, tBTA_START_ADV_CMPL_CBACK start_adv_cback) { @@ -737,6 +706,38 @@ static void btc_stop_scan_callback(tBTA_STATUS status) } #endif // #if (BLE_42_SCAN_EN == TRUE) #endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + +#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) +void btc_update_duplicate_exceptional_list_callback(tBTA_STATUS status, uint8_t subcode, uint32_t length, uint8_t *device_info) +{ + esp_ble_gap_cb_param_t param; + bt_status_t ret; + btc_msg_t msg = {0}; + + msg.sig = BTC_SIG_API_CB; + msg.pid = BTC_PID_GAP_BLE; + msg.act = ESP_GAP_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_COMPLETE_EVT; + param.update_duplicate_exceptional_list_cmpl.status = status; + param.update_duplicate_exceptional_list_cmpl.subcode = subcode; + if(length > sizeof(param.update_duplicate_exceptional_list_cmpl.device_info)) { + length = sizeof(param.update_duplicate_exceptional_list_cmpl.device_info); + } + param.update_duplicate_exceptional_list_cmpl.length = length; + memcpy(param.update_duplicate_exceptional_list_cmpl.device_info, device_info, length); + ret = btc_transfer_context(&msg, ¶m, sizeof(esp_ble_gap_cb_param_t), NULL, NULL); + + if (ret != BT_STATUS_SUCCESS) { + BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__); + } +} + +static void btc_ble_update_duplicate_exceptional_list(uint8_t subcode, uint32_t info_type, BD_ADDR device_info, + tBTA_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK p_update_duplicate_ignore_list_cback) +{ + BTA_DmUpdateDuplicateExceptionalList(subcode, info_type, device_info, p_update_duplicate_ignore_list_cback); +} +#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) + void btc_update_conn_param_callback (UINT8 status, BD_ADDR bd_addr, tBTM_LE_UPDATE_CONN_PRAMS *update_conn_params) { esp_ble_gap_cb_param_t param; diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index 9784dbf126..a429751293 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -231,13 +231,15 @@ typedef union { esp_bd_addr_t remote_bda; esp_ble_wl_addr_type_t wl_addr_type; } update_white_list; -#if (BLE_42_FEATURE_SUPPORT == TRUE) +#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) //BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST struct update_duplicate_exceptional_list_args { uint8_t subcode; uint32_t info_type; esp_duplicate_info_t device_info; } update_duplicate_exceptional_list; +#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE)) +#if (BLE_42_FEATURE_SUPPORT == TRUE) //BTC_GAP_BLE_ACT_SET_CONN_PARAMS struct set_conn_params_args { esp_bd_addr_t bd_addr; diff --git a/components/bt/host/bluedroid/main/bte_init.c b/components/bt/host/bluedroid/main/bte_init.c index f556cd6a0c..c19b50b6aa 100644 --- a/components/bt/host/bluedroid/main/bte_init.c +++ b/components/bt/host/bluedroid/main/bte_init.c @@ -264,10 +264,12 @@ void BTE_DeinitStack(void) bta_ag_cb_ptr = NULL; } #endif +#if (CLASSIC_BT_INCLUDED == TRUE) if (bta_dm_conn_srvcs_ptr){ osi_free(bta_dm_conn_srvcs_ptr); bta_dm_conn_srvcs_ptr = NULL; } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #if (CLASSIC_BT_INCLUDED == TRUE) if (bta_dm_di_cb_ptr){ osi_free(bta_dm_di_cb_ptr); @@ -445,16 +447,20 @@ bt_status_t BTE_InitStack(void) goto error_exit; } #endif // #if (CLASSIC_BT_INCLUDED == TRUE) +#if (CLASSIC_BT_INCLUDED == TRUE) if ((bta_dm_conn_srvcs_ptr = (tBTA_DM_CONNECTED_SRVCS *)osi_malloc(sizeof(tBTA_DM_CONNECTED_SRVCS))) == NULL) { goto error_exit; } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) memset((void *)bta_sys_cb_ptr, 0, sizeof(tBTA_SYS_CB)); memset((void *)bta_dm_cb_ptr, 0, sizeof(tBTA_DM_CB)); memset((void *)bta_dm_search_cb_ptr, 0, sizeof(tBTA_DM_SEARCH_CB)); #if (CLASSIC_BT_INCLUDED == TRUE) memset((void *)bta_dm_di_cb_ptr, 0, sizeof(tBTA_DM_DI_CB)); #endif // #if (CLASSIC_BT_INCLUDED == TRUE) +#if (CLASSIC_BT_INCLUDED == TRUE) memset((void *)bta_dm_conn_srvcs_ptr, 0, sizeof(tBTA_DM_CONNECTED_SRVCS)); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) //memset((void *)bta_prm_cb_ptr, 0, sizeof(tBTA_PRM_CB)); #if (defined BTA_HF_INCLUDED && BTA_HF_INCLUDED == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/btm_acl.c b/components/bt/host/bluedroid/stack/btm/btm_acl.c index b65d7b2745..a5aed0a91b 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_acl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_acl.c @@ -75,7 +75,9 @@ void btm_acl_init (void) btm_cb.p_bl_changed_cb = NULL; #endif btm_cb.p_acl_db_list = list_new(osi_free_func); +#if (CLASSIC_BT_INCLUDED == TRUE) btm_cb.p_pm_mode_db_list = list_new(osi_free_func); +#endif// #if (CLASSIC_BT_INCLUDED == TRUE) /* Initialize nonzero defaults */ btm_cb.btm_def_link_super_tout = HCI_DEFAULT_INACT_TOUT; @@ -296,12 +298,14 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, UINT8 bdn[BTM_MAX_REM_BD_NAME_L #endif #if (CLASSIC_BT_INCLUDED == TRUE) p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE; -#endif // (CLASSIC_BT_INCLUDED == TRUE) + p->p_pm_mode_db = btm_pm_sm_alloc(); + #if BTM_PM_DEBUG == TRUE BTM_TRACE_DEBUG( "btm_pm_sm_alloc handle:%d st:%d", hci_handle, p->p_pm_mode_db->state); #endif // BTM_PM_DEBUG +#endif // (CLASSIC_BT_INCLUDED == TRUE) #if (CLASSIC_BT_INCLUDED == TRUE) btm_sec_update_legacy_auth_state(p, BTM_ACL_LEGACY_AUTH_NONE); @@ -491,8 +495,9 @@ void btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport) } #endif - +#if (CLASSIC_BT_INCLUDED == TRUE) list_remove(btm_cb.p_pm_mode_db_list, p->p_pm_mode_db); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /* Clear the ACL connection data */ memset(p, 0, sizeof(tACL_CONN)); if (list_remove(btm_cb.p_acl_db_list, p)) { @@ -2233,6 +2238,7 @@ void BTM_BleGetPeriodicAdvListSize(uint8_t *size) #endif ///BLE_INCLUDED == TRUE +#if BLE_INCLUDED == TRUE /******************************************************************************* ** ** Function btm_read_channel_map_complete @@ -2287,7 +2293,7 @@ void btm_read_channel_map_complete(UINT8 *p) (*p_cb)(&results); } } - +#endif // #if BLE_INCLUDED == TRUE /******************************************************************************* ** @@ -2702,7 +2708,9 @@ void btm_acl_chk_peer_pkt_type_support (tACL_CONN *p, UINT16 *p_pkt_type) void btm_acl_free(void) { list_free(btm_cb.p_acl_db_list); +#if (CLASSIC_BT_INCLUDED == TRUE) list_free(btm_cb.p_pm_mode_db_list); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c index efff14dc82..82bbcf1c3b 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c @@ -139,7 +139,7 @@ void btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy) p_inq->sfp = scan_policy; p_inq->scan_type = p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE ? BTM_BLE_SCAN_MODE_ACTI : p_inq->scan_type; - + btsnd_hcic_ble_set_scan_params(p_inq->scan_type, (UINT16)scan_interval, (UINT16)scan_window, btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index 136f1fb393..831dbf7c0a 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -495,7 +495,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_s #endif if (start) { -// "start" should not be ture +// "start" should not be true #if (0) /* update adv params */ if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : @@ -902,6 +902,7 @@ void BTM_BleConfigConnParams(uint16_t int_min, uint16_t int_max, uint16_t latenc } #if BLE_PRIVACY_SPT == TRUE +#if (BLE_42_SCAN_EN == TRUE) /******************************************************************************* ** ** Function btm_ble_resolve_random_addr_on_adv @@ -942,6 +943,7 @@ static void btm_ble_resolve_random_addr_on_adv(void *p_rec, void *p) return; } +#endif // #if (BLE_42_SCAN_EN == TRUE) #endif /******************************************************************************* @@ -1301,10 +1303,10 @@ tBTM_STATUS BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, if (BTM_BleUpdateOwnType(&addr_type_own, NULL) != 0) { return BTM_ILLEGAL_VALUE; } - + max_scan_interval = BTM_BLE_SCAN_INT_MAX; max_scan_window = BTM_BLE_SCAN_WIN_MAX; - + osi_mutex_lock(&scan_param_lock, OSI_MUTEX_MAX_TIMEOUT); diff --git a/components/bt/host/bluedroid/stack/btm/btm_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index 39aec56e73..057eba2dbb 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -183,8 +183,9 @@ static void reset_complete(void) #endif // #if (GATT_BG_CONN_DEV == TRUE) #endif - +#if (CLASSIC_BT_INCLUDED == TRUE) btm_pm_reset(); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) l2c_link_processs_num_bufs(controller->get_acl_buffer_count_classic()); #if BTM_SCO_HCI_INCLUDED == TRUE diff --git a/components/bt/host/bluedroid/stack/btm/btm_inq.c b/components/bt/host/bluedroid/stack/btm/btm_inq.c index 34d2c56070..db93304a4e 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_inq.c +++ b/components/bt/host/bluedroid/stack/btm/btm_inq.c @@ -2183,6 +2183,8 @@ void btm_inq_rmt_name_failed (void) btm_sec_rmt_name_request_complete (NULL, NULL, HCI_ERR_UNSPECIFIED); #endif ///SMP_INCLUDED == TRUE } + +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function btm_read_linq_tx_power_complete @@ -2218,6 +2220,7 @@ void btm_read_linq_tx_power_complete(UINT8 *p) } } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function BTM_WriteEIR diff --git a/components/bt/host/bluedroid/stack/btm/btm_pm.c b/components/bt/host/bluedroid/stack/btm/btm_pm.c index aa94c88c90..9391976a4e 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_pm.c +++ b/components/bt/host/bluedroid/stack/btm/btm_pm.c @@ -45,6 +45,8 @@ //#include "bt_utils.h" //#include "osi/include/log.h" #include "osi/allocator.h" + +#if (CLASSIC_BT_INCLUDED == TRUE) /*****************************************************************************/ /* to handle different modes */ /*****************************************************************************/ @@ -968,3 +970,5 @@ static const char *mode_to_string(tBTM_PM_MODE mode) } } #endif + +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/btm_sec.c b/components/bt/host/bluedroid/stack/btm/btm_sec.c index 2a04bb38ee..4dcfaffe52 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_sec.c +++ b/components/bt/host/bluedroid/stack/btm/btm_sec.c @@ -211,7 +211,7 @@ static BOOLEAN btm_serv_trusted(tBTM_SEC_DEV_REC *p_dev_rec, tBTM_SEC_SERV_REC * } return (FALSE); } -#endif ///SMP_INCLUDED == TRUE + /******************************************************************************* ** ** Function BTM_SecRegister @@ -274,6 +274,7 @@ BOOLEAN BTM_SecRegisterLinkKeyNotificationCallback (tBTM_LINK_KEY_CALLBACK *p_ca btm_cb.api.p_link_key_callback = p_callback; return TRUE; } +#endif ///SMP_INCLUDED == TRUE /******************************************************************************* ** @@ -410,6 +411,7 @@ void BTM_SetPinType (UINT8 pin_type, PIN_CODE pin_code, UINT8 pin_code_len) } #endif ///CLASSIC_BT_INCLUDED == TRUE +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function BTM_SetPairableMode @@ -455,6 +457,8 @@ void BTM_SetSecureConnectionsOnly (BOOLEAN secure_connections_only_mode) btm_cb.devcb.secure_connections_only = secure_connections_only_mode; btm_cb.security_mode = BTM_SEC_MODE_SC; } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) + #define BTM_NO_AVAIL_SEC_SERVICES ((UINT16) 0xffff) /******************************************************************************* @@ -2779,10 +2783,12 @@ void btm_create_conn_cancel_complete (UINT8 *p, UINT16 evt_len) case HCI_ERR_CONNECTION_EXISTS: case HCI_ERR_NO_CONNECTION: default: +#if (SMP_INCLUDED == TRUE) /* Notify application of the error */ if (btm_cb.api.p_bond_cancel_cmpl_callback) { btm_cb.api.p_bond_cancel_cmpl_callback(BTM_ERR_PROCESSING); } +#endif // #if (SMP_INCLUDED == TRUE) break; } } @@ -4549,10 +4555,11 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) /* commands events and data at the same time. */ /* Set the packet types to the default allowed by the device */ btm_set_packet_types (p_acl_cb, btm_cb.btm_acl_pkt_types_supported); - +#if (CLASSIC_BT_INCLUDED == TRUE) if (btm_cb.btm_def_link_policy) { BTM_SetLinkPolicy (p_acl_cb->remote_addr, &btm_cb.btm_def_link_policy); } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #endif } btm_acl_created (bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name, handle, HCI_ROLE_SLAVE, BT_TRANSPORT_BR_EDR); @@ -4639,10 +4646,10 @@ BOOLEAN btm_sec_disconnected (UINT16 handle, UINT8 reason) tBTM_SEC_CALLBACK *p_callback = NULL; tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; +#if (CLASSIC_BT_INCLUDED == TRUE) /* If page was delayed for disc complete, can do it now */ btm_cb.discing = FALSE; -#if (CLASSIC_BT_INCLUDED == TRUE) btm_acl_resubmit_page(); #endif diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index 45dfe0b3ea..25a45d2e88 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -199,17 +199,20 @@ tBTM_CMPL_CB *p_rln_cmpl_cb; /* Callback function to be called when TIMER_LIST_ENT rssi_timer; tBTM_CMPL_CB *p_rssi_cmpl_cb; /* Callback function to be called when */ /* read rssi function completes */ - +#if BLE_INCLUDED == TRUE tBTM_CMPL_CB *p_ble_ch_map_cmpl_cb; /* Callback function to be called when */ +#endif // #if BLE_INCLUDED == TRUE /* read channel map function completes */ #if (CLASSIC_BT_INCLUDED == TRUE) TIMER_LIST_ENT lnk_quality_timer; tBTM_CMPL_CB *p_lnk_qual_cmpl_cb;/* Callback function to be called when */ #endif // (CLASSIC_BT_INCLUDED == TRUE) +#if (CLASSIC_BT_INCLUDED == TRUE) /* read link quality function completes */ TIMER_LIST_ENT txpwer_timer; tBTM_CMPL_CB *p_txpwer_cmpl_cb; /* Callback function to be called when */ +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /* read inq tx power function completes */ #if (CLASSIC_BT_INCLUDED == TRUE) @@ -274,10 +277,11 @@ UINT32 test_local_sign_cntr; #endif #endif /* BLE_INCLUDED */ - tBTM_IO_CAP loc_io_caps; /* IO capability of the local device */ +#if (SMP_INCLUDED == TRUE) tBTM_AUTH_REQ loc_auth_req; /* the auth_req flag */ BOOLEAN secure_connections_only; /* Rejects service level 0 connections if */ +#endif // #if (SMP_INCLUDED == TRUE) /* itself or peer device doesn't support */ /* secure connections */ } tBTM_DEVCB; @@ -880,11 +884,12 @@ typedef struct { /**************************************************** ** Power Management ****************************************************/ +#if (CLASSIC_BT_INCLUDED == TRUE) list_t *p_pm_mode_db_list; tBTM_PM_RCB pm_reg_db[BTM_MAX_PM_RECORDS + 1]; /* per application/module */ UINT16 pm_pend_link_hdl; /* the index of acl_db, which has a pending PM cmd */ UINT8 pm_pend_id; /* the id pf the module, which has a pending PM cmd */ - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /***************************************************** ** Device control *****************************************************/ @@ -924,7 +929,7 @@ typedef struct { #if BTM_SCO_INCLUDED == TRUE tSCO_CB sco_cb; #endif - +#if (SMP_INCLUDED == TRUE) /***************************************************** ** Security Management *****************************************************/ @@ -933,18 +938,22 @@ typedef struct { #define BTM_SEC_MAX_RMT_NAME_CALLBACKS 2 tBTM_RMT_NAME_CALLBACK *p_rmt_name_callback[BTM_SEC_MAX_RMT_NAME_CALLBACKS]; +#endif // #if (SMP_INCLUDED == TRUE) #if (SMP_INCLUDED == TRUE) tBTM_SEC_DEV_REC *p_collided_dev_rec; #endif ///SMP_INCLUDED == TRUE + UINT8 security_mode; + UINT32 dev_rec_count; /* Counter used for device record timestamp */ +#if (SMP_INCLUDED == TRUE) TIMER_LIST_ENT sec_collision_tle; UINT32 collision_start_time; UINT32 max_collision_delay; - UINT32 dev_rec_count; /* Counter used for device record timestamp */ - UINT8 security_mode; BOOLEAN pairing_disabled; BOOLEAN connect_only_paired; BOOLEAN security_mode_changed; /* mode changed during bonding */ BOOLEAN sec_req_pending; /* TRUE if a request is pending */ +#endif // #if (SMP_INCLUDED == TRUE) + #if (CLASSIC_BT_INCLUDED == TRUE) BOOLEAN pin_type_changed; /* pin type changed during bonding */ #endif ///CLASSIC_BT_INCLUDED == TRUE @@ -961,10 +970,12 @@ typedef struct { UINT8 disc_reason; /* for legacy devices */ UINT16 disc_handle; /* for legacy devices */ #endif ///CLASSIC_BT_INCLUDED == TRUE +#if (SMP_INCLUDED == TRUE) tBTM_PAIRING_STATE pairing_state; /* The current pairing state */ UINT8 pairing_flags; /* The current pairing flags */ BD_ADDR pairing_bda; /* The device currently pairing */ TIMER_LIST_ENT pairing_tle; /* Timer for pairing process */ +#endif // #if (SMP_INCLUDED == TRUE) #endif ///SMP_INCLUDED == TRUE #if SMP_INCLUDED == TRUE || CLASSIC_BT_INCLUDED == TRUE diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 4d300f069c..75b62e5b59 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -1226,7 +1226,9 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l btm_read_rssi_complete (p, evt_len); break; case HCI_BLE_READ_CHNL_MAP: +#if BLE_INCLUDED == TRUE btm_read_channel_map_complete (p); +#endif // #if BLE_INCLUDED == TRUE break; case HCI_READ_TRANSMIT_POWER_LEVEL: break; diff --git a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h index b1337d5cfd..933312a46e 100644 --- a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -573,8 +573,8 @@ typedef struct { #endif // (GATTC_INCLUDED == TRUE) #if (GATTS_INCLUDED == TRUE) UINT8 srv_chg_mode; /* internal use: service change mode */ -#endif // (GATTS_INCLUDED == TRUE) tGATTS_RSP rsp; /* use to read internal service attribute */ +#endif // (GATTS_INCLUDED == TRUE) } tGATT_CB; typedef struct{ diff --git a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h index abe75c18f4..df956dc442 100644 --- a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h +++ b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h @@ -488,7 +488,9 @@ typedef struct { list_t *p_lcb_pool; /* Link Control Block pool */ list_t *p_ccb_pool; /* Channel Control Block pool */ +#if (CLASSIC_BT_INCLUDED == TRUE) tL2C_RCB rcb_pool[MAX_L2CAP_CLIENTS]; /* Registration info pool */ +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #if (CLASSIC_BT_INCLUDED == TRUE) UINT8 desire_role; /* desire to be master/slave when accepting a connection */ @@ -500,8 +502,10 @@ typedef struct { list_t *rcv_pending_q; /* Recv pending queue */ TIMER_LIST_ENT rcv_hold_tle; /* Timer list entry for rcv hold */ - tL2C_LCB *p_cur_hcit_lcb; /* Current HCI Transport buffer */ + // tL2C_LCB *p_cur_hcit_lcb; /* Current HCI Transport buffer */ +#if (CLASSIC_BT_INCLUDED == TRUE) UINT16 num_links_active; /* Number of links active */ +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) UINT16 non_flushable_pbf; /* L2CAP_PKT_START_NON_FLUSHABLE if controller supports */ @@ -530,13 +534,16 @@ typedef struct { tL2C_RCB ble_rcb_pool[BLE_MAX_L2CAP_CLIENTS]; /* Registration info pool */ #endif +#if (CLASSIC_BT_INCLUDED == TRUE) tL2CA_ECHO_DATA_CB *p_echo_data_cb; /* Echo data callback */ +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #if (defined(L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE) && (L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE == TRUE)) UINT16 high_pri_min_xmit_quota; /* Minimum number of ACL credit for high priority link */ #endif /* (L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE == TRUE) */ - +#if (CLASSIC_BT_INCLUDED == TRUE) UINT16 dyn_psm; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } tL2C_CB; diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c index 511ed673fb..e41174695e 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c @@ -1118,6 +1118,7 @@ void l2c_link_processs_ble_num_bufs (UINT16 num_lm_ble_bufs) l2cb.num_lm_ble_bufs = l2cb.controller_le_xmit_window = num_lm_ble_bufs; } +#if (BLE_INCLUDED == TRUE) /******************************************************************************* ** ** Function l2c_ble_link_adjust_allocation @@ -1237,6 +1238,7 @@ void l2c_ble_link_adjust_allocation (void) } } } +#endif // #if (BLE_INCLUDED == TRUE) #if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c index 1787828b77..a51c4e8427 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c @@ -736,7 +736,7 @@ void l2c_info_timeout (tL2C_LCB *p_lcb) #endif ///CLASSIC_BT_INCLUDED == TRUE } } - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function l2c_link_adjust_allocation @@ -857,7 +857,7 @@ void l2c_link_adjust_allocation (void) } } - +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function l2c_link_adjust_chnl_allocation @@ -1013,7 +1013,9 @@ void l2c_pin_code_request (BD_ADDR bd_addr) *******************************************************************************/ BOOLEAN l2c_link_check_power_mode (tL2C_LCB *p_lcb) { +#if (CLASSIC_BT_INCLUDED == TRUE) tBTM_PM_MODE mode; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) tL2C_CCB *p_ccb; BOOLEAN need_to_active = FALSE; @@ -1033,6 +1035,7 @@ BOOLEAN l2c_link_check_power_mode (tL2C_LCB *p_lcb) /* if we have packets to send */ if ( need_to_active ) { +#if (CLASSIC_BT_INCLUDED == TRUE) /* check power mode */ if (BTM_ReadPowerMode(p_lcb->remote_bd_addr, &mode) == BTM_SUCCESS) { if ( mode == BTM_PM_STS_PENDING ) { @@ -1041,6 +1044,7 @@ BOOLEAN l2c_link_check_power_mode (tL2C_LCB *p_lcb) return TRUE; } } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } return FALSE; } diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c index 3e911bdec7..d5d6b91dbb 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c @@ -859,8 +859,10 @@ void l2c_init (void) l2c_cb_ptr = (tL2C_CB *)osi_malloc(sizeof(tL2C_CB)); #endif /* #if L2C_DYNAMIC_MEMORY */ memset (&l2cb, 0, sizeof (tL2C_CB)); +#if (CLASSIC_BT_INCLUDED == TRUE) /* the psm is increased by 2 before being used */ l2cb.dyn_psm = 0xFFF; +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) l2cb.p_ccb_pool = list_new(osi_free_func); if (l2cb.p_ccb_pool == NULL) { diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c index 52c1713cfc..de1faec749 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c @@ -113,8 +113,10 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPOR } else #endif { +#if (CLASSIC_BT_INCLUDED == TRUE) l2cb.num_links_active++; l2c_link_adjust_allocation(); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } p_lcb->link_xmit_data_q = list_new(NULL); return (p_lcb); @@ -261,11 +263,13 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb) } else #endif { +#if (CLASSIC_BT_INCLUDED == TRUE) if (l2cb.num_links_active >= 1) { l2cb.num_links_active--; } l2c_link_adjust_allocation(); +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) } /* Check for ping outstanding */ @@ -1799,6 +1803,7 @@ tL2C_CCB *l2cu_find_ccb_by_remote_cid (tL2C_LCB *p_lcb, UINT16 remote_cid) return (NULL); } +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function l2cu_allocate_rcb @@ -1828,6 +1833,7 @@ tL2C_RCB *l2cu_allocate_rcb (UINT16 psm) /* If here, no free RCB found */ return (NULL); } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #if (BLE_INCLUDED == TRUE) /******************************************************************************* @@ -1907,7 +1913,7 @@ void l2cu_disconnect_chnl (tL2C_CCB *p_ccb) } } - +#if (CLASSIC_BT_INCLUDED == TRUE) /******************************************************************************* ** ** Function l2cu_find_rcb_by_psm @@ -1932,6 +1938,7 @@ tL2C_RCB *l2cu_find_rcb_by_psm (UINT16 psm) /* If here, no match found */ return (NULL); } +#endif // #if (CLASSIC_BT_INCLUDED == TRUE) #if (BLE_INCLUDED == TRUE) /******************************************************************************* From e5619686eb078738741b38122061ce18079b09bf Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 7 Jan 2026 17:24:35 +0800 Subject: [PATCH 146/226] fix(ble/bluedroid): Fixed bluedroid host get white list size error (cherry picked from commit f4dfd427250f45e42d7922f4270c4ba96c9fc879) Co-authored-by: zhiweijian --- .../host/bluedroid/api/include/api/esp_gap_ble_api.h | 1 + .../bt/host/bluedroid/stack/btm/btm_ble_bgconn.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index ea39a5d730..25149955cf 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -3067,6 +3067,7 @@ esp_err_t esp_ble_gap_clear_whitelist(void); /** * @brief Get the whitelist size in the controller +* Note: This API returns a constant value indicating the maximum number of whitelists supported by the controller * * @param[out] length: the white list length. * @return diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c index 82bbcf1c3b..452d3b3a1a 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c @@ -464,7 +464,15 @@ void btm_ble_add_2_white_list_complete(UINT8 status) BTM_TRACE_EVENT("%s status=%d", __func__, status); tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; if (status == HCI_SUCCESS) { - --btm_cb.ble_ctr_cb.white_list_avail_size; + // --btm_cb.ble_ctr_cb.white_list_avail_size; + /* + According to the latest Bluetooth spec: + If the device is already in the Filter Accept List, the Controller should not add the device + to the Filter Accept List again and should return success. + The host cannot obtain the controller as the actual remaining white list size unless the host + also maintains a white list + Keep consistent behavior with the NimBLE host stack + */ } // add whitelist complete callback if (p_cb->update_wl_cb) @@ -487,7 +495,7 @@ void btm_ble_remove_from_white_list_complete(UINT8 *p, UINT16 evt_len) UNUSED(evt_len); BTM_TRACE_EVENT ("%s status=%d", __func__, *p); if (*p == HCI_SUCCESS) { - ++btm_cb.ble_ctr_cb.white_list_avail_size; + // ++btm_cb.ble_ctr_cb.white_list_avail_size; } if (p_cb->update_wl_cb) { From a012fee0beaba99ecd3ec35c7bcb559f76dbce3b Mon Sep 17 00:00:00 2001 From: Zhang Hai Peng Date: Tue, 30 Dec 2025 11:53:39 +0800 Subject: [PATCH 147/226] fix(ble/bluedroid): Added security check in example Bluedroid_GATT_Server (cherry picked from commit a36bf7fe14305b643baa4c97306274b592d2329d) Co-authored-by: zhanghaipeng --- .../bluedroid/Bluedroid_GATT_Server/main/main.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/examples/bluetooth/ble_get_started/bluedroid/Bluedroid_GATT_Server/main/main.c b/examples/bluetooth/ble_get_started/bluedroid/Bluedroid_GATT_Server/main/main.c index 07e19e6b24..d464c583a5 100644 --- a/examples/bluetooth/ble_get_started/bluedroid/Bluedroid_GATT_Server/main/main.c +++ b/examples/bluetooth/ble_get_started/bluedroid/Bluedroid_GATT_Server/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -362,12 +362,16 @@ static void auto_io_gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_ case ESP_GATTS_WRITE_EVT: ESP_LOGI(GATTS_TAG, "Characteristic write, value len %u, value ", param->write.len); ESP_LOG_BUFFER_HEX(GATTS_TAG, param->write.value, param->write.len); - if (param->write.value[0]) { - ESP_LOGI(GATTS_TAG, "LED ON!"); - led_on(); + if (param->write.len > 0) { + if (param->write.value[0]) { + ESP_LOGI(GATTS_TAG, "LED ON!"); + led_on(); + } else { + ESP_LOGI(GATTS_TAG, "LED OFF!"); + led_off(); + } } else { - ESP_LOGI(GATTS_TAG, "LED OFF!"); - led_off(); + ESP_LOGW(GATTS_TAG, "Empty write data received"); } example_write_event_env(gatts_if, param); break; From 9ad2dd11adae02037f6500eecdbdb28d423f5f30 Mon Sep 17 00:00:00 2001 From: Zhang Hai Peng Date: Tue, 30 Dec 2025 11:53:40 +0800 Subject: [PATCH 148/226] fix(ble/hci): Fix OOB read in ble_adv_scan_combined example (cherry picked from commit c76283260003781735618a827418dfed9f481cba) Co-authored-by: zhanghaipeng --- .../hci/ble_adv_scan_combined/main/app_bt.c | 64 ++++++++++++++----- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/examples/bluetooth/hci/ble_adv_scan_combined/main/app_bt.c b/examples/bluetooth/hci/ble_adv_scan_combined/main/app_bt.c index 1f2a6a8399..c8fc988fcb 100644 --- a/examples/bluetooth/hci/ble_adv_scan_combined/main/app_bt.c +++ b/examples/bluetooth/hci/ble_adv_scan_combined/main/app_bt.c @@ -1,7 +1,7 @@ /* * BLE Combined Advertising and Scanning Example. * - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -18,8 +18,10 @@ static const char *TAG = "BLE_ADV_SCAN"; +#define SCAN_LOCAL_NAME_MAX_LEN 32 + typedef struct { - char scan_local_name[32]; + char scan_local_name[SCAN_LOCAL_NAME_MAX_LEN]; uint8_t name_len; } ble_scan_local_name_t; @@ -187,28 +189,58 @@ static void hci_cmd_send_ble_set_adv_data(void) ESP_LOGI(TAG, "Starting BLE advertising with name \"%s\"", adv_name); } -static esp_err_t get_local_name (uint8_t *data_msg, uint8_t data_len, ble_scan_local_name_t *scanned_packet) +static esp_err_t get_local_name(uint8_t *data_msg, uint8_t data_len, ble_scan_local_name_t *scanned_packet) { - uint8_t curr_ptr = 0, curr_len, curr_type; + uint8_t curr_ptr = 0; + + /* Initialize output structure */ + scanned_packet->name_len = 0; + scanned_packet->scan_local_name[0] = '\0'; + while (curr_ptr < data_len) { - curr_len = data_msg[curr_ptr++]; - curr_type = data_msg[curr_ptr++]; + /* Ensure there is at least 1 byte for length field */ + if (curr_ptr >= data_len) { + return ESP_FAIL; + } + uint8_t curr_len = data_msg[curr_ptr++]; + + /* Length of 0 indicates end of AD structures or invalid data */ if (curr_len == 0) { return ESP_FAIL; } - /* Search for current data type and see if it contains name as data (0x08 or 0x09). */ - if (curr_type == 0x08 || curr_type == 0x09) { - for (uint8_t i = 0; i < curr_len - 1; i += 1) { - scanned_packet->scan_local_name[i] = data_msg[curr_ptr + i]; - } - scanned_packet->name_len = curr_len - 1; - return ESP_OK; - } else { - /* Search for next data. Current length includes 1 octate for AD Type (2nd octate). */ - curr_ptr += curr_len - 1; + /* Ensure there is at least 1 byte for type field */ + if (curr_ptr >= data_len) { + return ESP_FAIL; } + uint8_t curr_type = data_msg[curr_ptr++]; + + /* Calculate data field length (curr_len includes type byte) */ + uint8_t data_field_len = curr_len - 1; + + /* Verify remaining buffer has enough data */ + if (curr_ptr + data_field_len > data_len) { + return ESP_FAIL; + } + + /* Check for Local Name type (0x08: Shortened, 0x09: Complete) */ + if (curr_type == 0x08 || curr_type == 0x09) { + /* Limit copy length to prevent buffer overflow */ + uint8_t copy_len = data_field_len; + if (copy_len > SCAN_LOCAL_NAME_MAX_LEN - 1) { + copy_len = SCAN_LOCAL_NAME_MAX_LEN - 1; + } + + memcpy(scanned_packet->scan_local_name, &data_msg[curr_ptr], copy_len); + scanned_packet->scan_local_name[copy_len] = '\0'; /* Ensure null termination */ + scanned_packet->name_len = copy_len; + return ESP_OK; + } + + /* Move to next AD structure */ + curr_ptr += data_field_len; } + return ESP_FAIL; } From a805e4e6e88af6aacc136cc03f3353d781e83eac Mon Sep 17 00:00:00 2001 From: Zhang Hai Peng Date: Tue, 30 Dec 2025 11:53:40 +0800 Subject: [PATCH 149/226] fix(bt): fix BLE security issue in controller and HCI packet parser (cherry picked from commit a721e94a0fc78c61f6690126a982ac2966ff400b) Co-authored-by: zhanghaipeng --- components/bt/host/bluedroid/device/controller.c | 2 +- components/bt/host/bluedroid/hci/hci_packet_parser.c | 6 +++--- .../bt/host/bluedroid/hci/include/hci/hci_packet_parser.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/components/bt/host/bluedroid/device/controller.c b/components/bt/host/bluedroid/device/controller.c index 0364ba2ca9..d471c8be9e 100644 --- a/components/bt/host/bluedroid/device/controller.c +++ b/components/bt/host/bluedroid/device/controller.c @@ -87,7 +87,7 @@ typedef struct { uint16_t ble_ext_adv_data_max_len; #endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) #if (BLE_50_EXTEND_SYNC_EN == TRUE) - uint16_t get_ble_periodic_advertiser_list_size; + uint8_t get_ble_periodic_advertiser_list_size; #endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) } controller_local_param_t; diff --git a/components/bt/host/bluedroid/hci/hci_packet_parser.c b/components/bt/host/bluedroid/hci/hci_packet_parser.c index 560ee7b4a1..87c8499f8e 100644 --- a/components/bt/host/bluedroid/hci/hci_packet_parser.c +++ b/components/bt/host/bluedroid/hci/hci_packet_parser.c @@ -219,7 +219,7 @@ static void parse_ble_read_suggested_default_data_length_response( uint16_t *ble_default_packet_txtime_ptr) { - uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_DEFAULT_DATA_LENGTH, 2 /* bytes after */); + uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_DEFAULT_DATA_LENGTH, 4 /* bytes after: 2+2 */); if (stream) { STREAM_TO_UINT16(*ble_default_packet_length_ptr, stream); STREAM_TO_UINT16(*ble_default_packet_txtime_ptr, stream); @@ -235,7 +235,7 @@ static void parse_ble_read_adv_max_len_response( uint16_t *adv_max_len_ptr) { - uint8_t *stream = read_command_complete_header(response, HCI_BLE_RD_MAX_ADV_DATA_LEN, 1 /* bytes after */); + uint8_t *stream = read_command_complete_header(response, HCI_BLE_RD_MAX_ADV_DATA_LEN, 2 /* bytes after */); if (stream) { // Size: 2 Octets ; Value: 0x001F – 0x0672 ; Maximum supported advertising data length STREAM_TO_UINT16(*adv_max_len_ptr, stream); @@ -246,7 +246,7 @@ static void parse_ble_read_adv_max_len_response( #if (BLE_50_EXTEND_SYNC_EN == TRUE) static void parse_ble_read_periodic_adv_list_size_response( BT_HDR *response, - uint16_t *periodic_adv_list_size_ptr) + uint8_t *periodic_adv_list_size_ptr) { uint8_t *stream = read_command_complete_header(response, HCI_BLE_RD_PERIOD_ADV_LIST_SIZE, 1 /* bytes after */); diff --git a/components/bt/host/bluedroid/hci/include/hci/hci_packet_parser.h b/components/bt/host/bluedroid/hci/include/hci/hci_packet_parser.h index c40ffef94c..d926dd67ad 100644 --- a/components/bt/host/bluedroid/hci/include/hci/hci_packet_parser.h +++ b/components/bt/host/bluedroid/hci/include/hci/hci_packet_parser.h @@ -114,7 +114,7 @@ typedef struct { #if (BLE_50_EXTEND_SYNC_EN == TRUE) void (*parse_ble_read_periodic_adv_list_size_response) ( BT_HDR *response, - uint16_t *periodic_advertiser_list_size + uint8_t *periodic_advertiser_list_size ); #endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) From 00e6211ff8fa6849b8cd47c190b7aa6d37ca7c7e Mon Sep 17 00:00:00 2001 From: Zhang Hai Peng Date: Tue, 30 Dec 2025 11:53:41 +0800 Subject: [PATCH 150/226] fix(ble/bluedroid): Fix integer underflow in gatt_process_read_by_type_rsp (cherry picked from commit 597fc6e5c1b4a0448ad3d43185d9d48624085a0c) Co-authored-by: zhanghaipeng --- components/bt/host/bluedroid/stack/gatt/gatt_cl.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_cl.c b/components/bt/host/bluedroid/stack/gatt/gatt_cl.c index ddd089f4e0..1cc9aefb47 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_cl.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_cl.c @@ -800,6 +800,14 @@ void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 handle_len = 4; } + /* Check value_len is sufficient before subtraction to prevent underflow */ + if (value_len < handle_len) { + GATT_TRACE_ERROR("gatt_process_read_by_type_rsp: value_len(%d) < handle_len(%d), invalid response", + value_len, handle_len); + gatt_end_operation(p_clcb, GATT_INVALID_PDU, NULL); + return; + } + value_len -= handle_len; /* subtract the handle pairs bytes */ len -= 1; From fa99ba7f7283dc8b7f97fd39f6b4cf58e5a1046a Mon Sep 17 00:00:00 2001 From: Zhang Hai Peng Date: Tue, 30 Dec 2025 11:53:41 +0800 Subject: [PATCH 151/226] fix(ble/bluedroid): Fix out-of-bounds read in l2cble_process_sig_cmd (cherry picked from commit 93cfbb8522c8e4cf3c56378fe97f2a7d10a2e5e3) Co-authored-by: zhanghaipeng --- .../bt/host/bluedroid/stack/l2cap/l2c_ble.c | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c index 39ba389451..d21ce831cc 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c @@ -710,6 +710,11 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) UINT16 cmd_len; UINT16 min_interval, max_interval, latency, timeout; + if (pkt_len < L2CAP_CMD_OVERHEAD) { + L2CAP_TRACE_WARNING ("L2CAP - LE - pkt too short: %d", pkt_len); + return; + } + p_pkt_end = p + pkt_len; STREAM_TO_UINT8 (cmd_code, p); @@ -726,6 +731,10 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) case L2CAP_CMD_REJECT: case L2CAP_CMD_ECHO_RSP: case L2CAP_CMD_INFO_RSP: + if (cmd_len < 2) { + L2CAP_TRACE_WARNING ("L2CAP - LE - short cmd: %d", cmd_len); + return; + } p += 2; break; case L2CAP_CMD_ECHO_REQ: @@ -734,6 +743,10 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) break; case L2CAP_CMD_BLE_UPDATE_REQ: + if (cmd_len < 8) { + L2CAP_TRACE_WARNING ("L2CAP - LE - short cmd: %d", cmd_len); + return; + } STREAM_TO_UINT16 (min_interval, p); /* 0x0006 - 0x0C80 */ STREAM_TO_UINT16 (max_interval, p); /* 0x0006 - 0x0C80 */ STREAM_TO_UINT16 (latency, p); /* 0x0000 - 0x03E8 */ @@ -776,6 +789,10 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) break; case L2CAP_CMD_BLE_UPDATE_RSP: { + if (cmd_len < 2) { + L2CAP_TRACE_WARNING ("L2CAP - LE - short cmd: %d", cmd_len); + return; + } UINT16 result = 0; STREAM_TO_UINT16(result, p); //result = 0 connection param accepted, result = 1 connection param rejected. UINT8 status = (result == 0) ? HCI_SUCCESS : HCI_ERR_PARAM_OUT_OF_RANGE; @@ -788,6 +805,10 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) break; } case L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ: { + if (cmd_len < 10) { + L2CAP_TRACE_WARNING ("L2CAP - LE - short cmd: %d", cmd_len); + return; + } tL2C_CCB *p_ccb = NULL; tL2C_RCB *p_rcb = NULL; UINT16 spsm; @@ -836,6 +857,10 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) break; } case L2CAP_CMD_DISC_REQ: { + if (cmd_len < 4) { + L2CAP_TRACE_WARNING ("L2CAP - LE - short cmd: %d", cmd_len); + return; + } tL2C_CCB *p_ccb = NULL; UINT16 lcid; UINT16 rcid; From 2cf13e5c6dc3cb41f73a6f313bfbbf150e07cfd2 Mon Sep 17 00:00:00 2001 From: Zhang Hai Peng Date: Tue, 30 Dec 2025 11:53:41 +0800 Subject: [PATCH 152/226] fix(ble/bluedroid): Fix multiple out-of-bounds read vulnerabilities in GATT PDU handlers (cherry picked from commit 643d9c2387f9fc677025e66faf714667a7e75f85) Co-authored-by: zhanghaipeng --- .../bt/host/bluedroid/stack/gatt/gatt_cl.c | 8 +++++- .../bt/host/bluedroid/stack/gatt/gatt_sr.c | 25 +++++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_cl.c b/components/bt/host/bluedroid/stack/gatt/gatt_cl.c index 1cc9aefb47..1bdbfaec08 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_cl.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_cl.c @@ -554,7 +554,13 @@ void gatt_process_error_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code, tGATT_VALUE *p_attr = (tGATT_VALUE *)p_clcb->p_attr_buf; UNUSED(op_code); - UNUSED(len); + + /* Fix: Validate minimum length (opcode:1 + handle:2 + reason:1 = 4 bytes) */ + if (len < 4) { + GATT_TRACE_ERROR("invalid error rsp len: %d", len); + gatt_end_operation(p_clcb, GATT_INVALID_PDU, NULL); + return; + } GATT_TRACE_DEBUG("%s", __func__); STREAM_TO_UINT8(opcode, p); diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c index 585a4c921a..2a7e9fb35c 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c @@ -479,7 +479,13 @@ void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U BOOLEAN is_need_dequeue_sr_cmd = FALSE; tGATT_PREPARE_WRITE_RECORD *prepare_record = NULL; tGATT_PREPARE_WRITE_QUEUE_DATA * queue_data = NULL; - UNUSED(len); + + /* Fix: Validate minimum length (flags: 1 byte) */ + if (len < 1) { + GATT_TRACE_ERROR("invalid exec write req len: %d", len); + gatt_send_error_rsp(p_tcb, GATT_INVALID_PDU, op_code, 0, FALSE); + return; + } #if GATT_CONFORMANCE_TESTING == TRUE if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) { @@ -1234,10 +1240,13 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle, switch (op_code) { case GATT_SIGN_CMD_WRITE: - if (op_code == GATT_SIGN_CMD_WRITE) { - GATT_TRACE_DEBUG("Write CMD with data signing" ); - len -= GATT_AUTH_SIGN_LEN; + /* Fix: Validate length before subtraction to prevent underflow */ + if (len < GATT_AUTH_SIGN_LEN) { + GATT_TRACE_ERROR("signed write len too short: %d", len); + return; /* GATT_SIGN_CMD_WRITE has no response */ } + GATT_TRACE_DEBUG("Write CMD with data signing" ); + len -= GATT_AUTH_SIGN_LEN; /* fall through */ case GATT_CMD_WRITE: case GATT_REQ_WRITE: @@ -1473,7 +1482,13 @@ static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8 UINT8 sec_flag, key_size, *p; UINT16 offset = 0, value_len = 0; - UNUSED (len); + /* Fix: Validate length for GATT_REQ_READ_BLOB (needs offset: 2 bytes) */ + if (op_code == GATT_REQ_READ_BLOB && len < 2) { + GATT_TRACE_ERROR("invalid read blob req len: %d", len); + gatt_send_error_rsp(p_tcb, GATT_INVALID_PDU, op_code, handle, FALSE); + return; + } + if ((p_msg = (BT_HDR *)osi_calloc(buf_len)) == NULL) { GATT_TRACE_ERROR("gatts_process_find_info failed. no resources.\n"); From 3c3cfb7eaa98bf75b2d678ccd763e7458fcebd34 Mon Sep 17 00:00:00 2001 From: Zhang Hai Peng Date: Tue, 30 Dec 2025 11:53:42 +0800 Subject: [PATCH 153/226] feat(ble/bluedroid): Increase maximum notify/indication registration count (cherry picked from commit b6aed7e1c8b22a3813eda17f9436706b725e1de5) Co-authored-by: zhanghaipeng --- components/bt/host/bluedroid/Kconfig.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 892ac18306..5447060f8e 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -405,7 +405,7 @@ config BT_GATTC_MAX_CACHE_CHAR config BT_GATTC_NOTIF_REG_MAX int "Max gattc notify(indication) register number" depends on BT_GATTC_ENABLE - range 1 64 + range 1 255 default 5 help Maximum GATTC notify(indication) register number From 622990b70ef2759810f85b92b436a79af9e2e8e7 Mon Sep 17 00:00:00 2001 From: Zhang Hai Peng Date: Tue, 30 Dec 2025 11:53:43 +0800 Subject: [PATCH 154/226] feat(examples/bluedroid): Add BLE time interval conversion macros for better readability Add macros to convert time values from milliseconds to BLE interval units: - ESP_BLE_GAP_ADV_ITVL_MS: Convert advertising interval (0.625ms unit) - ESP_BLE_GAP_SCAN_ITVL_MS: Convert scan interval (0.625ms unit) - ESP_BLE_GAP_SCAN_WIN_MS: Convert scan window (0.625ms unit) - ESP_BLE_GAP_CONN_ITVL_MS: Convert connection interval (1.25ms unit) - ESP_BLE_GAP_PERIODIC_ADV_ITVL_MS: Convert periodic adv interval (1.25ms unit) - ESP_BLE_GAP_SUPERVISION_TIMEOUT_MS: Convert supervision timeout (10ms unit) (cherry picked from commit 7cd2f7b34d925f6b4ebcbecf320c2d5a1b2e7036) Co-authored-by: zhanghaipeng --- .../api/include/api/esp_gap_ble_api.h | 21 +++++++++++++++++++ .../ble/ble_ancs/main/ble_ancs_demo.c | 8 +++---- .../main/ble_compatibility_test.c | 14 ++++++------- .../main/esp_eddystone_demo.c | 4 ++-- .../main/esp_eddystone_demo.c | 4 ++-- .../main/ble_hidd_demo_main.c | 8 +++---- .../ble/ble_ibeacon/main/ibeacon_demo.c | 10 ++++----- .../main/ble_multiconn_cent_demo.c | 14 ++++++------- .../main/ble_multiconn_prph_demo.c | 8 +++---- .../ble/ble_spp_client/main/spp_client_demo.c | 6 +++--- .../ble_spp_server/main/ble_spp_server_demo.c | 4 ++-- .../main/example_ble_client_throughput.c | 8 +++---- .../main/example_ble_server_throughput.c | 14 ++++++------- .../ble/gatt_client/main/gattc_demo.c | 4 ++-- .../main/example_ble_sec_gattc_demo.c | 4 ++-- .../main/example_ble_sec_gatts_demo.c | 10 ++++----- .../ble/gatt_server/main/gatts_demo.c | 8 +++---- .../main/gatts_table_creat_demo.c | 14 ++++++------- .../main/gattc_multi_connect.c | 4 ++-- .../main/ble50_sec_gattc_demo.c | 20 +++++++++--------- .../main/ble50_sec_gatts_demo.c | 4 ++-- .../main/example_ble_client_throughput.c | 20 +++++++++--------- .../main/example_ble_server_throughput.c | 4 ++-- .../ble_50/multi-adv/main/multi_adv_demo.c | 16 +++++++------- .../periodic_adv/main/periodic_adv_demo.c | 10 ++++----- .../coex/a2dp_gatts_coex/main/main.c | 4 ++-- .../gattc_gatts_coex/main/gattc_gatts_coex.c | 18 ++++++++-------- 27 files changed, 142 insertions(+), 121 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 704e2c1086..382ebf5f9c 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -283,6 +283,27 @@ typedef uint8_t esp_gap_ble_channels[ESP_GAP_BLE_CHANNELS_LEN]; #define VENDOR_HCI_CMD_MASK (0x3F << 10) /**!< 0xFC00 */ +/** + * @brief BLE time interval conversion macros + * + * These macros convert time values in milliseconds to BLE interval units. + * + * - Advertising interval: unit is 0.625ms (range: 20ms to 10240ms) + * - Connection interval: unit is 1.25ms (range: 7.5ms to 4000ms) + * - Scan interval/window: unit is 0.625ms + * - Periodic advertising interval: unit is 1.25ms + * - Supervision timeout: unit is 10ms (range: 100ms to 32000ms) + * + * @note If the input value is not an exact multiple of the unit, the result will be rounded to the nearest value. + * For example, ESP_BLE_GAP_ADV_ITVL_MS(25) = 40 (25ms / 0.625ms = 40), but ESP_BLE_GAP_ADV_ITVL_MS(25.5) = 40 (rounded). + */ +#define ESP_BLE_GAP_ADV_ITVL_MS(t) ((uint16_t)((t) * 1000 / 625)) /*!< Convert advertising interval from ms to 0.625ms units. If input is not a multiple of 0.625ms, it will be rounded to the nearest value. */ +#define ESP_BLE_GAP_SCAN_ITVL_MS(t) ((uint16_t)((t) * 1000 / 625)) /*!< Convert scan interval from ms to 0.625ms units. If input is not a multiple of 0.625ms, it will be rounded to the nearest value. */ +#define ESP_BLE_GAP_SCAN_WIN_MS(t) ((uint16_t)((t) * 1000 / 625)) /*!< Convert scan window from ms to 0.625ms units. If input is not a multiple of 0.625ms, it will be rounded to the nearest value. */ +#define ESP_BLE_GAP_CONN_ITVL_MS(t) ((uint16_t)((t) * 1000 / 1250)) /*!< Convert connection interval from ms to 1.25ms units. If input is not a multiple of 1.25ms, it will be rounded to the nearest value. */ +#define ESP_BLE_GAP_PERIODIC_ADV_ITVL_MS(t) ((uint16_t)((t) * 1000 / 1250)) /*!< Convert periodic advertising interval from ms to 1.25ms units. If input is not a multiple of 1.25ms, it will be rounded to the nearest value. */ +#define ESP_BLE_GAP_SUPERVISION_TIMEOUT_MS(t) ((uint16_t)((t) / 10)) /*!< Convert supervision timeout from ms to 10ms units. If input is not a multiple of 10ms, it will be rounded to the nearest value. */ + /* relate to BTM_BLE_AD_TYPE_xxx in stack/btm_ble_api.h */ /// The type of advertising data(not adv_type) typedef enum { diff --git a/examples/bluetooth/bluedroid/ble/ble_ancs/main/ble_ancs_demo.c b/examples/bluetooth/bluedroid/ble/ble_ancs/main/ble_ancs_demo.c index 4dfb0bd4b1..70d6f822b2 100644 --- a/examples/bluetooth/bluedroid/ble/ble_ancs/main/ble_ancs_demo.c +++ b/examples/bluetooth/bluedroid/ble/ble_ancs/main/ble_ancs_demo.c @@ -83,8 +83,8 @@ static uint8_t hidd_service_uuid128[] = { static esp_ble_adv_data_t adv_config = { .set_scan_rsp = false, .include_txpower = false, - .min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec - .max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec + .min_interval = ESP_BLE_GAP_CONN_ITVL_MS(7.5), //slave connection min interval + .max_interval = ESP_BLE_GAP_CONN_ITVL_MS(20), //slave connection max interval .appearance = ESP_BLE_APPEARANCE_GENERIC_HID, .service_uuid_len = sizeof(hidd_service_uuid128), .p_service_uuid = hidd_service_uuid128, @@ -99,8 +99,8 @@ static esp_ble_adv_data_t scan_rsp_config = { }; static esp_ble_adv_params_t adv_params = { - .adv_int_min = 0x100, - .adv_int_max = 0x100, + .adv_int_min = ESP_BLE_GAP_ADV_ITVL_MS(160), + .adv_int_max = ESP_BLE_GAP_ADV_ITVL_MS(160), .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_RPA_PUBLIC, .channel_map = ADV_CHNL_ALL, diff --git a/examples/bluetooth/bluedroid/ble/ble_compatibility_test/main/ble_compatibility_test.c b/examples/bluetooth/bluedroid/ble/ble_compatibility_test/main/ble_compatibility_test.c index 171289a8a9..27457f8b4c 100644 --- a/examples/bluetooth/bluedroid/ble/ble_compatibility_test/main/ble_compatibility_test.c +++ b/examples/bluetooth/bluedroid/ble/ble_compatibility_test/main/ble_compatibility_test.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -101,8 +101,8 @@ static esp_ble_adv_data_t adv_data = { .set_scan_rsp = false, .include_name = true, .include_txpower = true, - .min_interval = 0x20, - .max_interval = 0x40, + .min_interval = ESP_BLE_GAP_CONN_ITVL_MS(40), + .max_interval = ESP_BLE_GAP_CONN_ITVL_MS(80), .appearance = 0x00, .manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN, .p_manufacturer_data = NULL, //test_manufacturer, @@ -118,8 +118,8 @@ static esp_ble_adv_data_t scan_rsp_data = { .set_scan_rsp = true, .include_name = true, .include_txpower = true, - .min_interval = 0x20, - .max_interval = 0x40, + .min_interval = ESP_BLE_GAP_CONN_ITVL_MS(40), + .max_interval = ESP_BLE_GAP_CONN_ITVL_MS(80), .appearance = 0x00, .manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN, .p_manufacturer_data = NULL, //&test_manufacturer[0], @@ -132,8 +132,8 @@ static esp_ble_adv_data_t scan_rsp_data = { #endif /* CONFIG_SET_RAW_ADV_DATA */ static esp_ble_adv_params_t adv_params = { - .adv_int_min = 0x40, - .adv_int_max = 0x40, + .adv_int_min = ESP_BLE_GAP_ADV_ITVL_MS(40), + .adv_int_max = ESP_BLE_GAP_ADV_ITVL_MS(40), .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .channel_map = ADV_CHNL_ALL, diff --git a/examples/bluetooth/bluedroid/ble/ble_eddystone_receiver/main/esp_eddystone_demo.c b/examples/bluetooth/bluedroid/ble/ble_eddystone_receiver/main/esp_eddystone_demo.c index f4849f8b7b..14602043b4 100644 --- a/examples/bluetooth/bluedroid/ble/ble_eddystone_receiver/main/esp_eddystone_demo.c +++ b/examples/bluetooth/bluedroid/ble/ble_eddystone_receiver/main/esp_eddystone_demo.c @@ -39,8 +39,8 @@ static esp_ble_scan_params_t ble_scan_params = { .scan_type = BLE_SCAN_TYPE_ACTIVE, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, - .scan_interval = 0x50, - .scan_window = 0x30, + .scan_interval = ESP_BLE_GAP_SCAN_ITVL_MS(50), + .scan_window = ESP_BLE_GAP_SCAN_WIN_MS(30), .scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE }; diff --git a/examples/bluetooth/bluedroid/ble/ble_eddystone_sender/main/esp_eddystone_demo.c b/examples/bluetooth/bluedroid/ble/ble_eddystone_sender/main/esp_eddystone_demo.c index 8b62d61d93..9ca3559682 100644 --- a/examples/bluetooth/bluedroid/ble/ble_eddystone_sender/main/esp_eddystone_demo.c +++ b/examples/bluetooth/bluedroid/ble/ble_eddystone_sender/main/esp_eddystone_demo.c @@ -36,8 +36,8 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t* par static void eddystone_send_raw(const esp_eddystone_result_t *res); static esp_ble_adv_params_t adv_params = { - .adv_int_min = 0x20, - .adv_int_max = 0x40, + .adv_int_min = ESP_BLE_GAP_ADV_ITVL_MS(20), + .adv_int_max = ESP_BLE_GAP_ADV_ITVL_MS(40), .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .channel_map = ADV_CHNL_ALL, diff --git a/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/main/ble_hidd_demo_main.c b/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/main/ble_hidd_demo_main.c index 0a9240fb92..9922033966 100644 --- a/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/main/ble_hidd_demo_main.c +++ b/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/main/ble_hidd_demo_main.c @@ -67,8 +67,8 @@ static esp_ble_adv_data_t hidd_adv_data = { .set_scan_rsp = false, .include_name = true, .include_txpower = true, - .min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec - .max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec + .min_interval = ESP_BLE_GAP_CONN_ITVL_MS(7.5), //slave connection min interval + .max_interval = ESP_BLE_GAP_CONN_ITVL_MS(20), //slave connection max interval .appearance = 0x03c0, //HID Generic, .manufacturer_len = 0, .p_manufacturer_data = NULL, @@ -80,8 +80,8 @@ static esp_ble_adv_data_t hidd_adv_data = { }; static esp_ble_adv_params_t hidd_adv_params = { - .adv_int_min = 0x20, - .adv_int_max = 0x30, + .adv_int_min = ESP_BLE_GAP_ADV_ITVL_MS(20), + .adv_int_max = ESP_BLE_GAP_ADV_ITVL_MS(30), .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, //.peer_addr = diff --git a/examples/bluetooth/bluedroid/ble/ble_ibeacon/main/ibeacon_demo.c b/examples/bluetooth/bluedroid/ble/ble_ibeacon/main/ibeacon_demo.c index 846f7fea31..beaabe96f5 100644 --- a/examples/bluetooth/bluedroid/ble/ble_ibeacon/main/ibeacon_demo.c +++ b/examples/bluetooth/bluedroid/ble/ble_ibeacon/main/ibeacon_demo.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -43,15 +43,15 @@ static esp_ble_scan_params_t ble_scan_params = { .scan_type = BLE_SCAN_TYPE_ACTIVE, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, - .scan_interval = 0x50, - .scan_window = 0x30, + .scan_interval = ESP_BLE_GAP_SCAN_ITVL_MS(50), + .scan_window = ESP_BLE_GAP_SCAN_WIN_MS(30), .scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE }; #elif (IBEACON_MODE == IBEACON_SENDER) static esp_ble_adv_params_t ble_adv_params = { - .adv_int_min = 0x20, - .adv_int_max = 0x40, + .adv_int_min = ESP_BLE_GAP_ADV_ITVL_MS(20), + .adv_int_max = ESP_BLE_GAP_ADV_ITVL_MS(40), .adv_type = ADV_TYPE_NONCONN_IND, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .channel_map = ADV_CHNL_ALL, diff --git a/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_cent/main/ble_multiconn_cent_demo.c b/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_cent/main/ble_multiconn_cent_demo.c index 49bf214bcf..c61853bb8b 100644 --- a/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_cent/main/ble_multiconn_cent_demo.c +++ b/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_cent/main/ble_multiconn_cent_demo.c @@ -101,7 +101,7 @@ const static esp_ble_conn_params_t phy_1m_conn_params = { .interval_min = BLE_PREF_CONN_ITVL_MS * 1000 / 1250, .interval_max = BLE_PREF_CONN_ITVL_MS * 1000 / 1250, .latency = 0, - .supervision_timeout = 600, + .supervision_timeout = ESP_BLE_GAP_SUPERVISION_TIMEOUT_MS(6000), .min_ce_len = BLE_PREF_CE_LEN, .max_ce_len = BLE_PREF_CE_LEN, }; @@ -113,7 +113,7 @@ const static esp_ble_conn_params_t phy_2m_conn_params = { .interval_min = BLE_PREF_CONN_ITVL_MS * 1000 / 1250, .interval_max = BLE_PREF_CONN_ITVL_MS * 1000 / 1250, .latency = 0, - .supervision_timeout = 600, + .supervision_timeout = ESP_BLE_GAP_SUPERVISION_TIMEOUT_MS(6000), .min_ce_len = BLE_PREF_CE_LEN, .max_ce_len = BLE_PREF_CE_LEN, }; @@ -124,7 +124,7 @@ const static esp_ble_conn_params_t phy_coded_conn_params = { .interval_min = BLE_PREF_CONN_ITVL_MS * 1000 / 1250, .interval_max = BLE_PREF_CONN_ITVL_MS * 1000 / 1250, .latency = 0, - .supervision_timeout = 600, + .supervision_timeout = ESP_BLE_GAP_SUPERVISION_TIMEOUT_MS(6000), .min_ce_len = BLE_PREF_CE_LEN, .max_ce_len = BLE_PREF_CE_LEN, }; @@ -160,8 +160,8 @@ struct gatts_profile_inst #if (BLE50_SUPPORTED == 0) esp_ble_adv_params_t legacy_adv_params = { - .adv_int_min = 0x20, - .adv_int_max = 0x20, + .adv_int_min = ESP_BLE_GAP_ADV_ITVL_MS(20), + .adv_int_max = ESP_BLE_GAP_ADV_ITVL_MS(20), .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_RANDOM, .channel_map = ADV_CHNL_ALL, @@ -171,8 +171,8 @@ esp_ble_adv_params_t legacy_adv_params = { #else esp_ble_gap_ext_adv_params_t ext_adv_params = { .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE, - .interval_min = 0x20, - .interval_max = 0x20, + .interval_min = ESP_BLE_GAP_ADV_ITVL_MS(20), + .interval_max = ESP_BLE_GAP_ADV_ITVL_MS(20), .channel_map = ADV_CHNL_ALL, .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, .primary_phy = ESP_BLE_GAP_PHY_1M, diff --git a/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_prph/main/ble_multiconn_prph_demo.c b/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_prph/main/ble_multiconn_prph_demo.c index 43e6a34a21..91513af992 100644 --- a/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_prph/main/ble_multiconn_prph_demo.c +++ b/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_prph/main/ble_multiconn_prph_demo.c @@ -68,8 +68,8 @@ static esp_ble_gap_ext_adv_t ext_adv[1] = { esp_ble_gap_ext_adv_params_t ext_adv_params = { .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE, - .interval_min = 0x20, - .interval_max = 0x20, + .interval_min = ESP_BLE_GAP_ADV_ITVL_MS(20), + .interval_max = ESP_BLE_GAP_ADV_ITVL_MS(20), .channel_map = ADV_CHNL_ALL, .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, .primary_phy = ESP_BLE_GAP_PHY_1M, @@ -82,8 +82,8 @@ esp_ble_gap_ext_adv_params_t ext_adv_params = { }; #else static esp_ble_adv_params_t legacy_adv_params = { - .adv_int_min = 0x20, - .adv_int_max = 0x40, + .adv_int_min = ESP_BLE_GAP_ADV_ITVL_MS(20), + .adv_int_max = ESP_BLE_GAP_ADV_ITVL_MS(40), .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_RANDOM, .channel_map = ADV_CHNL_ALL, diff --git a/examples/bluetooth/bluedroid/ble/ble_spp_client/main/spp_client_demo.c b/examples/bluetooth/bluedroid/ble/ble_spp_client/main/spp_client_demo.c index f38d4beff8..9c1b7cf761 100644 --- a/examples/bluetooth/bluedroid/ble/ble_spp_client/main/spp_client_demo.c +++ b/examples/bluetooth/bluedroid/ble/ble_spp_client/main/spp_client_demo.c @@ -89,8 +89,8 @@ static esp_ble_scan_params_t ble_scan_params = { .scan_type = BLE_SCAN_TYPE_ACTIVE, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, - .scan_interval = 0x50, - .scan_window = 0x30, + .scan_interval = ESP_BLE_GAP_SCAN_ITVL_MS(50), + .scan_window = ESP_BLE_GAP_SCAN_WIN_MS(30), .scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE }; @@ -255,7 +255,7 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par phy_1m_conn_params.interval_max = 32; phy_1m_conn_params.interval_min = 32; phy_1m_conn_params.latency = 0; - phy_1m_conn_params.supervision_timeout = 600; + phy_1m_conn_params.supervision_timeout = ESP_BLE_GAP_SUPERVISION_TIMEOUT_MS(6000); esp_ble_gatt_creat_conn_params_t creat_conn_params = {0}; memcpy(&creat_conn_params.remote_bda, scan_result->scan_rst.bda,ESP_BD_ADDR_LEN); creat_conn_params.remote_addr_type = scan_result->scan_rst.ble_addr_type; diff --git a/examples/bluetooth/bluedroid/ble/ble_spp_server/main/ble_spp_server_demo.c b/examples/bluetooth/bluedroid/ble/ble_spp_server/main/ble_spp_server_demo.c index 8e4351231e..f61cbddc73 100644 --- a/examples/bluetooth/bluedroid/ble/ble_spp_server/main/ble_spp_server_demo.c +++ b/examples/bluetooth/bluedroid/ble/ble_spp_server/main/ble_spp_server_demo.c @@ -79,8 +79,8 @@ static esp_bd_addr_t spp_remote_bda = {0x0,}; static uint16_t spp_handle_table[SPP_IDX_NB]; static esp_ble_adv_params_t spp_adv_params = { - .adv_int_min = 0x20, - .adv_int_max = 0x40, + .adv_int_min = ESP_BLE_GAP_ADV_ITVL_MS(20), + .adv_int_max = ESP_BLE_GAP_ADV_ITVL_MS(40), .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .channel_map = ADV_CHNL_ALL, diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/main/example_ble_client_throughput.c b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/main/example_ble_client_throughput.c index 8759479bbe..adcdde612e 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/main/example_ble_client_throughput.c +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/main/example_ble_client_throughput.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -95,8 +95,8 @@ static esp_ble_scan_params_t ble_scan_params = { .scan_type = BLE_SCAN_TYPE_ACTIVE, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, - .scan_interval = 0x50, - .scan_window = 0x30, + .scan_interval = ESP_BLE_GAP_SCAN_ITVL_MS(50), + .scan_window = ESP_BLE_GAP_SCAN_WIN_MS(30), .scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE }; @@ -412,7 +412,7 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par phy_1m_conn_params.interval_min = 32; #endif phy_1m_conn_params.latency = 0; - phy_1m_conn_params.supervision_timeout = 600; + phy_1m_conn_params.supervision_timeout = ESP_BLE_GAP_SUPERVISION_TIMEOUT_MS(6000); esp_ble_gatt_creat_conn_params_t creat_conn_params = {0}; memcpy(&creat_conn_params.remote_bda, scan_result->scan_rst.bda, ESP_BD_ADDR_LEN); diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c index 9569d04c73..8d5492d23c 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -127,8 +127,8 @@ static esp_ble_adv_data_t adv_data = { .set_scan_rsp = false, .include_name = true, .include_txpower = true, - .min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec - .max_interval = 0x000C, //slave connection max interval, Time = max_interval * 1.25 msec + .min_interval = ESP_BLE_GAP_CONN_ITVL_MS(7.5), //slave connection min interval + .max_interval = ESP_BLE_GAP_CONN_ITVL_MS(15), //slave connection max interval .appearance = 0x00, .manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN, .p_manufacturer_data = NULL, //&test_manufacturer[0], @@ -143,8 +143,8 @@ static esp_ble_adv_data_t scan_rsp_data = { .set_scan_rsp = true, .include_name = true, .include_txpower = true, - .min_interval = 0x0006, - .max_interval = 0x000C, + .min_interval = ESP_BLE_GAP_CONN_ITVL_MS(7.5), + .max_interval = ESP_BLE_GAP_CONN_ITVL_MS(15), .appearance = 0x00, .manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN, .p_manufacturer_data = NULL, //&test_manufacturer[0], @@ -158,8 +158,8 @@ static esp_ble_adv_data_t scan_rsp_data = { #endif /* CONFIG_EXAMPLE_SET_RAW_ADV_DATA */ static esp_ble_adv_params_t adv_params = { - .adv_int_min = 0x20, - .adv_int_max = 0x40, + .adv_int_min = ESP_BLE_GAP_ADV_ITVL_MS(20), + .adv_int_max = ESP_BLE_GAP_ADV_ITVL_MS(40), .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, //.peer_addr = diff --git a/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c b/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c index 8c628b685a..481b671df2 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c @@ -72,8 +72,8 @@ static esp_ble_scan_params_t ble_scan_params = { .scan_type = BLE_SCAN_TYPE_ACTIVE, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, - .scan_interval = 0x50, - .scan_window = 0x30, + .scan_interval = ESP_BLE_GAP_SCAN_ITVL_MS(50), + .scan_window = ESP_BLE_GAP_SCAN_WIN_MS(30), .scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE }; diff --git a/examples/bluetooth/bluedroid/ble/gatt_security_client/main/example_ble_sec_gattc_demo.c b/examples/bluetooth/bluedroid/ble/gatt_security_client/main/example_ble_sec_gattc_demo.c index 7955da0c71..38fe1f50ce 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_security_client/main/example_ble_sec_gattc_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_security_client/main/example_ble_sec_gattc_demo.c @@ -57,8 +57,8 @@ static esp_ble_scan_params_t ble_scan_params = { .scan_type = BLE_SCAN_TYPE_ACTIVE, .own_addr_type = BLE_ADDR_TYPE_RPA_PUBLIC, .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, - .scan_interval = 0x50, - .scan_window = 0x30, + .scan_interval = ESP_BLE_GAP_SCAN_ITVL_MS(50), + .scan_window = ESP_BLE_GAP_SCAN_WIN_MS(30), .scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE }; diff --git a/examples/bluetooth/bluedroid/ble/gatt_security_server/main/example_ble_sec_gatts_demo.c b/examples/bluetooth/bluedroid/ble/gatt_security_server/main/example_ble_sec_gatts_demo.c index 35def35da8..9679350b49 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_security_server/main/example_ble_sec_gatts_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_security_server/main/example_ble_sec_gatts_demo.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -49,8 +49,8 @@ static uint8_t sec_service_uuid[16] = { static esp_ble_adv_data_t heart_rate_adv_config = { .set_scan_rsp = false, .include_txpower = true, - .min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec - .max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec + .min_interval = ESP_BLE_GAP_CONN_ITVL_MS(7.5), //slave connection min interval + .max_interval = ESP_BLE_GAP_CONN_ITVL_MS(20), //slave connection max interval .appearance = 0x00, .manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN, .p_manufacturer_data = NULL, //&test_manufacturer[0], @@ -69,8 +69,8 @@ static esp_ble_adv_data_t heart_rate_scan_rsp_config = { }; static esp_ble_adv_params_t heart_rate_adv_params = { - .adv_int_min = 0x100, - .adv_int_max = 0x100, + .adv_int_min = ESP_BLE_GAP_ADV_ITVL_MS(160), + .adv_int_max = ESP_BLE_GAP_ADV_ITVL_MS(160), .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_RPA_PUBLIC, .channel_map = ADV_CHNL_ALL, diff --git a/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c b/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c index a8b8254bc4..6acc6ff1c3 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c @@ -118,8 +118,8 @@ static esp_ble_adv_data_t adv_data = { .set_scan_rsp = false, .include_name = true, .include_txpower = false, - .min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec - .max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec + .min_interval = ESP_BLE_GAP_CONN_ITVL_MS(7.5), //slave connection min interval + .max_interval = ESP_BLE_GAP_CONN_ITVL_MS(20), //slave connection max interval .appearance = 0x00, .manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN, .p_manufacturer_data = NULL, //&test_manufacturer[0], @@ -149,8 +149,8 @@ static esp_ble_adv_data_t scan_rsp_data = { #endif /* CONFIG_SET_RAW_ADV_DATA */ static esp_ble_adv_params_t adv_params = { - .adv_int_min = 0x20, - .adv_int_max = 0x40, + .adv_int_min = ESP_BLE_GAP_ADV_ITVL_MS(20), + .adv_int_max = ESP_BLE_GAP_ADV_ITVL_MS(40), .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, //.peer_addr = diff --git a/examples/bluetooth/bluedroid/ble/gatt_server_service_table/main/gatts_table_creat_demo.c b/examples/bluetooth/bluedroid/ble/gatt_server_service_table/main/gatts_table_creat_demo.c index 9c468cd351..bc088bcc29 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server_service_table/main/gatts_table_creat_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_server_service_table/main/gatts_table_creat_demo.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -94,8 +94,8 @@ static esp_ble_adv_data_t adv_data = { .set_scan_rsp = false, .include_name = true, .include_txpower = true, - .min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec - .max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec + .min_interval = ESP_BLE_GAP_CONN_ITVL_MS(7.5), //slave connection min interval + .max_interval = ESP_BLE_GAP_CONN_ITVL_MS(20), //slave connection max interval .appearance = 0x00, .manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN, .p_manufacturer_data = NULL, //test_manufacturer, @@ -111,8 +111,8 @@ static esp_ble_adv_data_t scan_rsp_data = { .set_scan_rsp = true, .include_name = true, .include_txpower = true, - .min_interval = 0x0006, - .max_interval = 0x0010, + .min_interval = ESP_BLE_GAP_CONN_ITVL_MS(7.5), + .max_interval = ESP_BLE_GAP_CONN_ITVL_MS(20), .appearance = 0x00, .manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN, .p_manufacturer_data = NULL, //&test_manufacturer[0], @@ -125,8 +125,8 @@ static esp_ble_adv_data_t scan_rsp_data = { #endif /* CONFIG_SET_RAW_ADV_DATA */ static esp_ble_adv_params_t adv_params = { - .adv_int_min = 0x20, - .adv_int_max = 0x40, + .adv_int_min = ESP_BLE_GAP_ADV_ITVL_MS(20), + .adv_int_max = ESP_BLE_GAP_ADV_ITVL_MS(40), .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .channel_map = ADV_CHNL_ALL, diff --git a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/main/gattc_multi_connect.c b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/main/gattc_multi_connect.c index 0908e5e4ee..213523d05c 100644 --- a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/main/gattc_multi_connect.c +++ b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/main/gattc_multi_connect.c @@ -92,8 +92,8 @@ static esp_ble_scan_params_t ble_scan_params = { .scan_type = BLE_SCAN_TYPE_ACTIVE, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, - .scan_interval = 0x50, - .scan_window = 0x30, + .scan_interval = ESP_BLE_GAP_SCAN_ITVL_MS(50), + .scan_window = ESP_BLE_GAP_SCAN_WIN_MS(30), .scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE }; diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_security_client/main/ble50_sec_gattc_demo.c b/examples/bluetooth/bluedroid/ble_50/ble50_security_client/main/ble50_sec_gattc_demo.c index 720fd61924..06c1274953 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_security_client/main/ble50_sec_gattc_demo.c +++ b/examples/bluetooth/bluedroid/ble_50/ble50_security_client/main/ble50_sec_gattc_demo.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -66,32 +66,32 @@ static esp_ble_ext_scan_params_t ext_scan_params = { }; const esp_ble_conn_params_t phy_1m_conn_params = { - .scan_interval = 0x40, - .scan_window = 0x40, + .scan_interval = ESP_BLE_GAP_SCAN_ITVL_MS(40), + .scan_window = ESP_BLE_GAP_SCAN_WIN_MS(40), .interval_min = 320, .interval_max = 320, .latency = 0, - .supervision_timeout = 600, + .supervision_timeout = ESP_BLE_GAP_SUPERVISION_TIMEOUT_MS(6000), .min_ce_len = 0, .max_ce_len = 0, }; const esp_ble_conn_params_t phy_2m_conn_params = { - .scan_interval = 0x40, - .scan_window = 0x40, + .scan_interval = ESP_BLE_GAP_SCAN_ITVL_MS(40), + .scan_window = ESP_BLE_GAP_SCAN_WIN_MS(40), .interval_min = 320, .interval_max = 320, .latency = 0, - .supervision_timeout = 600, + .supervision_timeout = ESP_BLE_GAP_SUPERVISION_TIMEOUT_MS(6000), .min_ce_len = 0, .max_ce_len = 0, }; const esp_ble_conn_params_t phy_coded_conn_params = { - .scan_interval = 0x40, - .scan_window = 0x40, + .scan_interval = ESP_BLE_GAP_SCAN_ITVL_MS(40), + .scan_window = ESP_BLE_GAP_SCAN_WIN_MS(40), .interval_min = 320, // 306-> 362Kbps .interval_max = 320, .latency = 0, - .supervision_timeout = 600, + .supervision_timeout = ESP_BLE_GAP_SUPERVISION_TIMEOUT_MS(6000), .min_ce_len = 0, .max_ce_len = 0, }; diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_security_server/main/ble50_sec_gatts_demo.c b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/main/ble50_sec_gatts_demo.c index e5727564e4..506567ca29 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_security_server/main/ble50_sec_gatts_demo.c +++ b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/main/ble50_sec_gatts_demo.c @@ -52,8 +52,8 @@ static esp_ble_gap_ext_adv_t ext_adv[1] = { esp_ble_gap_ext_adv_params_t ext_adv_params_2M = { .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE, - .interval_min = 0x20, - .interval_max = 0x20, + .interval_min = ESP_BLE_GAP_ADV_ITVL_MS(20), + .interval_max = ESP_BLE_GAP_ADV_ITVL_MS(20), .channel_map = ADV_CHNL_ALL, .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, .primary_phy = ESP_BLE_GAP_PHY_1M, diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_throughput/throughput_client/main/example_ble_client_throughput.c b/examples/bluetooth/bluedroid/ble_50/ble50_throughput/throughput_client/main/example_ble_client_throughput.c index 17c9a99d82..fb002f1e7e 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_throughput/throughput_client/main/example_ble_client_throughput.c +++ b/examples/bluetooth/bluedroid/ble_50/ble50_throughput/throughput_client/main/example_ble_client_throughput.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -110,9 +110,9 @@ const esp_ble_conn_params_t phy_1m_conn_params = { .latency = 0, .max_ce_len = 0, .min_ce_len = 0, - .scan_interval = 0x40, - .scan_window = 0x40, - .supervision_timeout = 600, + .scan_interval = ESP_BLE_GAP_SCAN_ITVL_MS(40), + .scan_window = ESP_BLE_GAP_SCAN_WIN_MS(40), + .supervision_timeout = ESP_BLE_GAP_SUPERVISION_TIMEOUT_MS(6000), }; const esp_ble_conn_params_t phy_2m_conn_params = { @@ -121,9 +121,9 @@ const esp_ble_conn_params_t phy_2m_conn_params = { .latency = 0, .max_ce_len = 0, .min_ce_len = 0, - .scan_interval = 0x40, - .scan_window = 0x40, - .supervision_timeout = 600, + .scan_interval = ESP_BLE_GAP_SCAN_ITVL_MS(40), + .scan_window = ESP_BLE_GAP_SCAN_WIN_MS(40), + .supervision_timeout = ESP_BLE_GAP_SUPERVISION_TIMEOUT_MS(6000), }; const esp_ble_conn_params_t phy_coded_conn_params = { @@ -132,9 +132,9 @@ const esp_ble_conn_params_t phy_coded_conn_params = { .latency = 0, .max_ce_len = 0, .min_ce_len = 0, - .scan_interval = 0x40, - .scan_window = 0x40, - .supervision_timeout = 600, + .scan_interval = ESP_BLE_GAP_SCAN_ITVL_MS(40), + .scan_window = ESP_BLE_GAP_SCAN_WIN_MS(40), + .supervision_timeout = ESP_BLE_GAP_SUPERVISION_TIMEOUT_MS(6000), }; struct gattc_profile_inst { diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_throughput/throughput_server/main/example_ble_server_throughput.c b/examples/bluetooth/bluedroid/ble_50/ble50_throughput/throughput_server/main/example_ble_server_throughput.c index d7d00133ed..5818bab655 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_throughput/throughput_server/main/example_ble_server_throughput.c +++ b/examples/bluetooth/bluedroid/ble_50/ble50_throughput/throughput_server/main/example_ble_server_throughput.c @@ -112,8 +112,8 @@ static esp_ble_gap_ext_adv_t ext_adv[1] = { esp_ble_gap_ext_adv_params_t ext_adv_params = { .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE, - .interval_min = 0x20, - .interval_max = 0x20, + .interval_min = ESP_BLE_GAP_ADV_ITVL_MS(20), + .interval_max = ESP_BLE_GAP_ADV_ITVL_MS(20), .channel_map = ADV_CHNL_ALL, .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, .primary_phy = ESP_BLE_GAP_PHY_1M, diff --git a/examples/bluetooth/bluedroid/ble_50/multi-adv/main/multi_adv_demo.c b/examples/bluetooth/bluedroid/ble_50/multi-adv/main/multi_adv_demo.c index db750ce70b..5f4a27fd84 100644 --- a/examples/bluetooth/bluedroid/ble_50/multi-adv/main/multi_adv_demo.c +++ b/examples/bluetooth/bluedroid/ble_50/multi-adv/main/multi_adv_demo.c @@ -49,8 +49,8 @@ static SemaphoreHandle_t test_sem = NULL; esp_ble_gap_ext_adv_params_t ext_adv_params_1M = { .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE, - .interval_min = 0x30, - .interval_max = 0x30, + .interval_min = ESP_BLE_GAP_ADV_ITVL_MS(30), + .interval_max = ESP_BLE_GAP_ADV_ITVL_MS(30), .channel_map = ADV_CHNL_ALL, .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, .primary_phy = ESP_BLE_GAP_PHY_1M, @@ -64,8 +64,8 @@ esp_ble_gap_ext_adv_params_t ext_adv_params_1M = { esp_ble_gap_ext_adv_params_t ext_adv_params_2M = { .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE, - .interval_min = 0x40, - .interval_max = 0x40, + .interval_min = ESP_BLE_GAP_ADV_ITVL_MS(40), + .interval_max = ESP_BLE_GAP_ADV_ITVL_MS(40), .channel_map = ADV_CHNL_ALL, .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, .primary_phy = ESP_BLE_GAP_PHY_1M, @@ -79,8 +79,8 @@ esp_ble_gap_ext_adv_params_t ext_adv_params_2M = { esp_ble_gap_ext_adv_params_t legacy_adv_params = { .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_IND, - .interval_min = 0x45, - .interval_max = 0x45, + .interval_min = ESP_BLE_GAP_ADV_ITVL_MS(43), + .interval_max = ESP_BLE_GAP_ADV_ITVL_MS(43), .channel_map = ADV_CHNL_ALL, .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, .primary_phy = ESP_BLE_GAP_PHY_1M, @@ -94,8 +94,8 @@ esp_ble_gap_ext_adv_params_t legacy_adv_params = { esp_ble_gap_ext_adv_params_t ext_adv_params_coded = { .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE, - .interval_min = 0x50, - .interval_max = 0x50, + .interval_min = ESP_BLE_GAP_ADV_ITVL_MS(50), + .interval_max = ESP_BLE_GAP_ADV_ITVL_MS(50), .channel_map = ADV_CHNL_ALL, .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, .primary_phy = ESP_BLE_GAP_PHY_1M, diff --git a/examples/bluetooth/bluedroid/ble_50/periodic_adv/main/periodic_adv_demo.c b/examples/bluetooth/bluedroid/ble_50/periodic_adv/main/periodic_adv_demo.c index aa7ffdac2a..517c301e45 100644 --- a/examples/bluetooth/bluedroid/ble_50/periodic_adv/main/periodic_adv_demo.c +++ b/examples/bluetooth/bluedroid/ble_50/periodic_adv/main/periodic_adv_demo.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -58,8 +58,8 @@ static SemaphoreHandle_t test_sem = NULL; esp_ble_gap_ext_adv_params_t ext_adv_params_2M = { .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_NONCONN_NONSCANNABLE_UNDIRECTED, - .interval_min = 0x30, - .interval_max = 0x30, + .interval_min = ESP_BLE_GAP_ADV_ITVL_MS(30), + .interval_max = ESP_BLE_GAP_ADV_ITVL_MS(30), .channel_map = ADV_CHNL_ALL, .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, .primary_phy = ESP_BLE_GAP_PHY_1M, @@ -72,8 +72,8 @@ esp_ble_gap_ext_adv_params_t ext_adv_params_2M = { }; static esp_ble_gap_periodic_adv_params_t periodic_adv_params = { - .interval_min = 0x40, // 80 ms interval - .interval_max = 0x40, + .interval_min = ESP_BLE_GAP_PERIODIC_ADV_ITVL_MS(80), + .interval_max = ESP_BLE_GAP_PERIODIC_ADV_ITVL_MS(80), .properties = 0, // Do not include TX power }; diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c index 348f429af8..4b9288eedb 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c @@ -98,8 +98,8 @@ esp_attr_value_t gatts_initial_char_val = { }; static esp_ble_adv_params_t adv_params = { - .adv_int_min = 0x060, - .adv_int_max = 0x060, + .adv_int_min = ESP_BLE_GAP_ADV_ITVL_MS(60), + .adv_int_max = ESP_BLE_GAP_ADV_ITVL_MS(60), .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_RPA_PUBLIC, .channel_map = ADV_CHNL_ALL, diff --git a/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c index 6d9627337b..eeacbfb6d1 100644 --- a/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c +++ b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -145,8 +145,8 @@ static esp_ble_adv_data_t adv_data = { .set_scan_rsp = false, .include_name = true, .include_txpower = true, - .min_interval = 0x20, - .max_interval = 0x40, + .min_interval = ESP_BLE_GAP_CONN_ITVL_MS(40), + .max_interval = ESP_BLE_GAP_CONN_ITVL_MS(80), .appearance = 0x00, .manufacturer_len = 0, .p_manufacturer_data = NULL, @@ -162,8 +162,8 @@ static esp_ble_adv_data_t scan_rsp_data = { .set_scan_rsp = true, .include_name = true, .include_txpower = true, - .min_interval = 0x0006, - .max_interval = 0x0010, + .min_interval = ESP_BLE_GAP_CONN_ITVL_MS(7.5), + .max_interval = ESP_BLE_GAP_CONN_ITVL_MS(20), .appearance = 0x00, .manufacturer_len = 0, .p_manufacturer_data = NULL, @@ -176,8 +176,8 @@ static esp_ble_adv_data_t scan_rsp_data = { #endif /* CONFIG_SET_RAW_ADV_DATA */ static esp_ble_adv_params_t adv_params = { - .adv_int_min = 0x20, - .adv_int_max = 0x40, + .adv_int_min = ESP_BLE_GAP_ADV_ITVL_MS(20), + .adv_int_max = ESP_BLE_GAP_ADV_ITVL_MS(40), .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .channel_map = ADV_CHNL_ALL, @@ -215,8 +215,8 @@ static esp_ble_scan_params_t ble_scan_params = { .scan_type = BLE_SCAN_TYPE_ACTIVE, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, - .scan_interval = 0x50, - .scan_window = 0x30, + .scan_interval = ESP_BLE_GAP_SCAN_ITVL_MS(50), + .scan_window = ESP_BLE_GAP_SCAN_WIN_MS(30), .scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE }; From 07ed373646ed5e0f4806daf1db55bab7e1af39f7 Mon Sep 17 00:00:00 2001 From: Zhang Hai Peng Date: Tue, 30 Dec 2025 11:53:43 +0800 Subject: [PATCH 155/226] fix(bt/bluedroid): fix UAF in bta_gattc_enqueue for search service command (cherry picked from commit 61962987501dbc778d474dc7d6e065211cea557b) Co-authored-by: zhanghaipeng --- .../host/bluedroid/bta/gatt/bta_gattc_utils.c | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c index 4b2d019252..6f3f3c0a4c 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c @@ -528,6 +528,79 @@ BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memory.", __func__, __LINE__); return FALSE; } + } else if (p_data->hdr.event == BTA_GATTC_API_SEARCH_EVT) { + /* + * Fix for Use-After-Free (UAF) bug in service search with filter_uuid. + * + * Problem Description: + * ==================== + * In BTA_GATTC_ServiceSearchRequest(), memory is allocated as: + * [tBTA_GATTC_API_SEARCH structure][tBT_UUID data] + * + * The p_srvc_uuid pointer points to the tBT_UUID data located right after + * the structure: + * p_buf->p_srvc_uuid = (tBT_UUID *)(p_buf + 1); + * + * When this command is enqueued (e.g., during DISCOVER_ST state), the original + * code only performed a shallow copy: + * - Only sizeof(tBTA_GATTC_DATA) was allocated for cmd_data + * - memcpy copied the pointer VALUE (not the pointed data) + * - After the original message is freed by bta_sys_event(), the p_srvc_uuid + * pointer becomes a dangling pointer pointing to freed memory + * + * Memory layout before fix: + * + * Original (p_data): Copy (cmd_data): + * +------------------+----------+ +------------------+ + * | API_SEARCH | tBT_UUID | | API_SEARCH | + * | p_srvc_uuid: --------► | | p_srvc_uuid: --------► (dangling!) + * +------------------+----------+ +------------------+ + * ↑ + * After free(), this memory may be + * overwritten by other allocations + * + * Solution: + * ========= + * For BTA_GATTC_API_SEARCH_EVT with non-NULL p_srvc_uuid, we need to: + * 1. Allocate extra space for tBT_UUID + * 2. Copy the structure + * 3. Update p_srvc_uuid to point to the new location + * 4. Copy the tBT_UUID data + * + * Memory layout after fix: + * + * Copy (cmd_data): + * +------------------+----------+ + * | API_SEARCH | tBT_UUID | + * | p_srvc_uuid: --------► | (points to its own copy) + * +------------------+----------+ + */ + if (p_data->api_search.p_srvc_uuid != NULL) { + /* Allocate space for structure + UUID data (deep copy) */ + len = sizeof(tBTA_GATTC_DATA) + sizeof(tBT_UUID); + if ((cmd_data = (tBTA_GATTC_DATA *)osi_malloc(len)) != NULL) { + memset(cmd_data, 0, len); + /* Copy the structure */ + memcpy(cmd_data, p_data, sizeof(tBTA_GATTC_DATA)); + /* Update pointer to point to the space after the structure */ + cmd_data->api_search.p_srvc_uuid = (tBT_UUID *)(cmd_data + 1); + /* Copy the UUID data */ + memcpy(cmd_data->api_search.p_srvc_uuid, + p_data->api_search.p_srvc_uuid, sizeof(tBT_UUID)); + } else { + APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memory.", __func__, __LINE__); + return FALSE; + } + } else { + /* p_srvc_uuid is NULL, no extra space needed (search all services) */ + if ((cmd_data = (tBTA_GATTC_DATA *)osi_malloc(sizeof(tBTA_GATTC_DATA))) != NULL) { + memset(cmd_data, 0, sizeof(tBTA_GATTC_DATA)); + memcpy(cmd_data, p_data, sizeof(tBTA_GATTC_DATA)); + } else { + APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memory.", __func__, __LINE__); + return FALSE; + } + } } else { if ((cmd_data = (tBTA_GATTC_DATA *)osi_malloc(sizeof(tBTA_GATTC_DATA))) != NULL) { memset(cmd_data, 0, sizeof(tBTA_GATTC_DATA)); From c92bd4679c2ef74fb0776495859f51596578c6e8 Mon Sep 17 00:00:00 2001 From: Zhang Hai Peng Date: Tue, 30 Dec 2025 11:53:44 +0800 Subject: [PATCH 156/226] fix(bt/osi): add NULL check in osi_mutex_free and osi_sem_free (IDFGH-16853) (cherry picked from commit 863004060215b4730aafa15914729175a2f0f173) Co-authored-by: zhanghaipeng --- components/bt/common/osi/mutex.c | 9 +++++++-- components/bt/common/osi/semaphore.c | 8 +++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/components/bt/common/osi/mutex.c b/components/bt/common/osi/mutex.c index b7fe38a1ee..5a4de81ee5 100644 --- a/components/bt/common/osi/mutex.c +++ b/components/bt/common/osi/mutex.c @@ -65,10 +65,15 @@ void osi_mutex_unlock(osi_mutex_t *mutex) xSemaphoreGive(*mutex); } -/** Delete a semaphore - * @param mutex the mutex to delete */ +/** Delete a mutex + * @param mutex the mutex to delete + * Note: Safe to call with NULL or uninitialized mutex (IDFGH-16853) + */ void osi_mutex_free(osi_mutex_t *mutex) { + if (mutex == NULL || *mutex == NULL) { + return; + } vSemaphoreDelete(*mutex); *mutex = NULL; } diff --git a/components/bt/common/osi/semaphore.c b/components/bt/common/osi/semaphore.c index 14823160e3..5acbb67b8f 100644 --- a/components/bt/common/osi/semaphore.c +++ b/components/bt/common/osi/semaphore.c @@ -69,9 +69,15 @@ osi_sem_take(osi_sem_t *sem, uint32_t timeout) return ret; } -// Deallocates a semaphore +/** Deallocates a semaphore + * @param sem the semaphore to delete + * Note: Safe to call with NULL or uninitialized semaphore (IDFGH-16853) + */ void osi_sem_free(osi_sem_t *sem) { + if (sem == NULL || *sem == NULL) { + return; + } vSemaphoreDelete(*sem); *sem = NULL; } From a40ac062f4c0d7acec95494b6816d06a69f3f990 Mon Sep 17 00:00:00 2001 From: Zhang Hai Peng Date: Tue, 30 Dec 2025 11:53:44 +0800 Subject: [PATCH 157/226] refactor(examples/bluedroid): Replace hardcoded ADV type values with macros (cherry picked from commit fdeb5ad87abb328a8d0a69787e324e69972bca2a) Co-authored-by: zhanghaipeng --- .../ble_spp_server/main/ble_spp_server_demo.c | 6 ++-- .../main/ble50_sec_gatts_demo.c | 8 ++--- .../main/example_ble_server_throughput.c | 14 ++++---- .../ble_50/multi-adv/main/multi_adv_demo.c | 32 +++++++++---------- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/examples/bluetooth/bluedroid/ble/ble_spp_server/main/ble_spp_server_demo.c b/examples/bluetooth/bluedroid/ble/ble_spp_server/main/ble_spp_server_demo.c index f61cbddc73..e588c790e1 100644 --- a/examples/bluetooth/bluedroid/ble/ble_spp_server/main/ble_spp_server_demo.c +++ b/examples/bluetooth/bluedroid/ble/ble_spp_server/main/ble_spp_server_demo.c @@ -52,11 +52,11 @@ static const uint16_t spp_service_uuid = 0xABF0; static const uint8_t spp_adv_data[23] = { /* Flags */ - 0x02,0x01,0x06, + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, /* Complete List of 16-bit Service Class UUIDs */ - 0x03,0x03,0xF0,0xAB, + 0x03, ESP_BLE_AD_TYPE_16SRV_CMPL, 0xF0, 0xAB, /* Complete Local Name in advertising */ - 0x0F,0x09, 'E', 'S', 'P', '_', 'S', 'P', 'P', '_', 'S', 'E', 'R','V', 'E', 'R' + 0x0F, ESP_BLE_AD_TYPE_NAME_CMPL, 'E', 'S', 'P', '_', 'S', 'P', 'P', '_', 'S', 'E', 'R','V', 'E', 'R' }; static uint16_t spp_mtu_size = SPP_GATT_MTU_SIZE; diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_security_server/main/ble50_sec_gatts_demo.c b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/main/ble50_sec_gatts_demo.c index 506567ca29..4fc1019724 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_security_server/main/ble50_sec_gatts_demo.c +++ b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/main/ble50_sec_gatts_demo.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -41,9 +41,9 @@ static uint16_t profile_handle_table[HRS_IDX_NB]; static uint8_t ext_adv_raw_data[] = { - 0x02, 0x01, 0x06, - 0x02, 0x0a, 0xeb, 0x03, 0x03, 0xab, 0xcd, - 0x11, 0X09, 'E', 'S', 'P', '_', 'B', 'L', 'E', '5', '0', '_', 'S', 'E', 'R', 'V', 'E', 'R', + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, + 0x02, ESP_BLE_AD_TYPE_TX_PWR, 0xeb, 0x03, ESP_BLE_AD_TYPE_16SRV_CMPL, 0xab, 0xcd, + 0x11, ESP_BLE_AD_TYPE_NAME_CMPL, 'E', 'S', 'P', '_', 'B', 'L', 'E', '5', '0', '_', 'S', 'E', 'R', 'V', 'E', 'R', }; static esp_ble_gap_ext_adv_t ext_adv[1] = { diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_throughput/throughput_server/main/example_ble_server_throughput.c b/examples/bluetooth/bluedroid/ble_50/ble50_throughput/throughput_server/main/example_ble_server_throughput.c index 5818bab655..b0174955ca 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_throughput/throughput_server/main/example_ble_server_throughput.c +++ b/examples/bluetooth/bluedroid/ble_50/ble50_throughput/throughput_server/main/example_ble_server_throughput.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -98,12 +98,12 @@ static esp_attr_value_t gatts_demo_char1_val = }; static uint8_t ext_adv_raw_data[] = { - 0x02, 0x01, 0x06, - 0x02, 0x0a, 0xeb, - 0x03, 0x03, 0xab, 0xcd, - 0x11, 0x07, 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xEE, 0x00, 0x00, 0x00, - 0x11, 0x07, 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x14, 0X09, 'T', 'H', 'R', 'O', 'U', 'G', 'H', 'P', 'U', 'T', '_', 'P', 'H', 'Y', '_', 'D', 'E', 'M', 'O', + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, + 0x02, ESP_BLE_AD_TYPE_TX_PWR, 0xeb, + 0x03, ESP_BLE_AD_TYPE_16SRV_CMPL, 0xab, 0xcd, + 0x11, ESP_BLE_AD_TYPE_128SRV_CMPL, 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xEE, 0x00, 0x00, 0x00, + 0x11, ESP_BLE_AD_TYPE_128SRV_CMPL, 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x14, ESP_BLE_AD_TYPE_NAME_CMPL, 'T', 'H', 'R', 'O', 'U', 'G', 'H', 'P', 'U', 'T', '_', 'P', 'H', 'Y', '_', 'D', 'E', 'M', 'O', }; static esp_ble_gap_ext_adv_t ext_adv[1] = { diff --git a/examples/bluetooth/bluedroid/ble_50/multi-adv/main/multi_adv_demo.c b/examples/bluetooth/bluedroid/ble_50/multi-adv/main/multi_adv_demo.c index 5f4a27fd84..0addc23bec 100644 --- a/examples/bluetooth/bluedroid/ble_50/multi-adv/main/multi_adv_demo.c +++ b/examples/bluetooth/bluedroid/ble_50/multi-adv/main/multi_adv_demo.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -108,37 +108,37 @@ esp_ble_gap_ext_adv_params_t ext_adv_params_coded = { }; static uint8_t raw_adv_data_1m[] = { - 0x02, 0x01, 0x06, - 0x02, 0x0a, 0xeb, - 0x11, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A', + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, + 0x02, ESP_BLE_AD_TYPE_TX_PWR, 0xeb, + 0x11, ESP_BLE_AD_TYPE_NAME_CMPL, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A', 'D', 'V', '_', '1', 'M' }; static uint8_t raw_scan_rsp_data_2m[] = { - 0x02, 0x01, 0x06, - 0x02, 0x0a, 0xeb, - 0x11, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A', + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, + 0x02, ESP_BLE_AD_TYPE_TX_PWR, 0xeb, + 0x11, ESP_BLE_AD_TYPE_NAME_CMPL, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A', 'D', 'V', '_', '2', 'M' }; static uint8_t legacy_adv_data[] = { - 0x02, 0x01, 0x06, - 0x02, 0x0a, 0xeb, - 0x14, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A', + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, + 0x02, ESP_BLE_AD_TYPE_TX_PWR, 0xeb, + 0x14, ESP_BLE_AD_TYPE_NAME_CMPL, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A', 'D', 'V', '_', 'C', 'O', 'D', 'E', 'D' }; static uint8_t legacy_scan_rsp_data[] = { - 0x02, 0x01, 0x06, - 0x02, 0x0a, 0xeb, - 0x15, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A', + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, + 0x02, ESP_BLE_AD_TYPE_TX_PWR, 0xeb, + 0x15, ESP_BLE_AD_TYPE_NAME_CMPL, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A', 'D', 'V', '_', 'L', 'E', 'G', 'A', 'C', 'Y' }; static uint8_t raw_scan_rsp_data_coded[] = { - 0x02, 0x01, 0x06, - 0x02, 0x0a, 0xeb, - 0x14, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A', + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, + 0x02, ESP_BLE_AD_TYPE_TX_PWR, 0xeb, + 0x14, ESP_BLE_AD_TYPE_NAME_CMPL, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A', 'D', 'V', '_', 'C', 'O', 'D', 'E', 'D' }; From 1af43047f6bce531896a844c5f218c3afd641ab3 Mon Sep 17 00:00:00 2001 From: Zhang Hai Peng Date: Tue, 30 Dec 2025 11:53:45 +0800 Subject: [PATCH 158/226] docs(ble): add flow diagrams to bluedroid BLE examples (cherry picked from commit 051077835cea876f316d73f869e8c49a47e64b64) Co-authored-by: zhanghaipeng --- .../bluedroid/ble/ble_ancs/README.md | 49 ++++++ .../ble/ble_compatibility_test/README.md | 46 +++++ .../ble/ble_eddystone_receiver/README.md | 34 +++- .../ble/ble_eddystone_sender/README.md | 34 +++- .../ble/ble_hid_device_demo/README.md | 48 ++++++ .../bluedroid/ble/ble_ibeacon/README.md | 55 ++++++ .../ble_multi_conn_cent/README.md | 46 +++++ .../ble_multi_conn_prph/README.md | 39 +++++ .../bluedroid/ble/ble_spp_client/README.md | 65 ++++++++ .../bluedroid/ble/ble_spp_server/README.md | 36 ++++ .../throughput_client/README.md | 43 +++++ .../throughput_server/README.md | 42 +++++ .../bluedroid/ble/gatt_client/README.md | 59 +++++++ .../ble/gatt_security_client/README.md | 53 ++++++ .../ble/gatt_security_server/README.md | 50 ++++++ .../bluedroid/ble/gatt_server/README.md | 56 +++++++ .../ble/gatt_server_service_table/README.md | 50 ++++++ .../ble/gattc_multi_connect/README.md | 157 ++++++++++++++++-- 18 files changed, 949 insertions(+), 13 deletions(-) diff --git a/examples/bluetooth/bluedroid/ble/ble_ancs/README.md b/examples/bluetooth/bluedroid/ble/ble_ancs/README.md index a839e400f8..da4d0ab4d0 100644 --- a/examples/bluetooth/bluedroid/ble/ble_ancs/README.md +++ b/examples/bluetooth/bluedroid/ble/ble_ancs/README.md @@ -5,6 +5,55 @@ The purpose of the Apple Notification Center Service (ANCS) is to give Bluetooth accessories (that connect to iOS devices through a Bluetooth low-energy link) a simple and convenient way to access many kinds of notifications that are generated on iOS devices. +## Flow Diagram + +``` + ┌──────────────┐ ┌──────────────┐ + │ ESP32 │ │ iOS Device │ + │ (ANCS Client)│ │ (ANCS Server)│ + └──────┬───────┘ └──────┬───────┘ + │ │ + │ ─────────── Connection ─────────── │ + │ │ + │ 1. Start Advertising │ + │ ───────────────────────────────────────────────> │ + │ │ + │ 2. iOS connects & pairs │ + │ <─────────────────────────────────────────────── │ + │ │ + │ ─────────── Service Discovery ─────────── │ + │ │ + │ 3. Discover ANCS Service │ + │ (UUID: 7905F431-B5CE-4E99-A40F-4B1E122D00D0) │ + │ ───────────────────────────────────────────────> │ + │ │ + │ 4. Subscribe to Notification Source │ + │ (UUID: 9FBF120D-6301-42D9-8C58-25E699A21DBD) │ + │ ───────────────────────────────────────────────> │ + │ │ + │ 5. Subscribe to Data Source │ + │ (UUID: 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB) │ + │ ───────────────────────────────────────────────> │ + │ │ + │ ─────────── Notification Flow ─────────── │ + │ │ + │ 6. New notification on iOS │ + │ (Call, SMS, Email, App, etc.) │ + │ <─────────────────────────────────────────────── │ + │ │ + │ 7. Request notification details │ + │ (Write to Control Point) │ + │ ───────────────────────────────────────────────> │ + │ │ + │ 8. Receive notification attributes │ + │ (Title, Message, App, etc.) │ + │ <─────────────────────────────────────────────── │ + │ │ + ┌──────┴───────┐ ┌──────┴───────┐ + │ ESP32 │ │ iOS Device │ + └──────────────┘ └──────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/ble_compatibility_test/README.md b/examples/bluetooth/bluedroid/ble/ble_compatibility_test/README.md index acbae4e97e..4a886f60f0 100644 --- a/examples/bluetooth/bluedroid/ble/ble_compatibility_test/README.md +++ b/examples/bluetooth/bluedroid/ble/ble_compatibility_test/README.md @@ -5,6 +5,52 @@ This example is to test the Bluetooth compatibility and mobile phones. +## Flow Diagram + +``` + ┌──────────────────┐ ┌──────────────────┐ + │ ESP32 BLE │ │ Mobile Phone │ + │ (Compatibility) │ │ (LightBlue App) │ + └────────┬─────────┘ └────────┬─────────┘ + │ │ + │ 1. Initialize BLE │ + │ 2. Create GATT Services │ + │ 3. Start Advertising │ + │ │ + │ ─────────── Test Scenarios ─────────── │ + │ │ + │ Scan & Discover │ + │ <════════════════════════════════════════════│ + │ │ + │ Connection Request │ + │ <════════════════════════════════════════════│ + │ │ + │ Service Discovery │ + │ <════════════════════════════════════════════│ + │ │ + │ Read Characteristic │ + │ <════════════════════════════════════════════│ + │ Read Response │ + │ ════════════════════════════════════════════>│ + │ │ + │ Write Characteristic │ + │ <════════════════════════════════════════════│ + │ Write Confirmation │ + │ ════════════════════════════════════════════>│ + │ │ + │ Enable Notification │ + │ <════════════════════════════════════════════│ + │ Notification Data │ + │ ════════════════════════════════════════════>│ + │ │ + │ Disconnection │ + │ <═══════════════════════════════════════════>│ + │ │ + ┌────────┴─────────┐ ┌────────┴─────────┐ + │ ESP32 BLE │ │ Mobile Phone │ + └──────────────────┘ └──────────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/ble_eddystone_receiver/README.md b/examples/bluetooth/bluedroid/ble/ble_eddystone_receiver/README.md index 3ec829bee2..918968fafe 100644 --- a/examples/bluetooth/bluedroid/ble/ble_eddystone_receiver/README.md +++ b/examples/bluetooth/bluedroid/ble/ble_eddystone_receiver/README.md @@ -5,11 +5,43 @@ This example demonstrates Eddystone-compatible BLE scanning of eddystone frame, including UID and URL. -Eddystone is an open beacon protocol specification from Google aimed at improving “proximity-based experiences” +Eddystone is an open beacon protocol specification from Google aimed at improving "proximity-based experiences" with support for both Android and iOS smart device platforms. Learn more on [Beacons](https://developers.google.com/nearby/notifications/get-started) and [Eddystone](https://github.com/google/eddystone). +## Flow Diagram + +``` + ┌──────────────────┐ ┌──────────────────┐ + │ Eddystone Sender │ │Eddystone Receiver│ + │ (Advertiser) │ │ (this example) │ + └────────┬─────────┘ └────────┬─────────┘ + │ │ + │ Broadcasting Eddystone Frames │ 1. Initialize BLE + │ │ 2. Start Scanning + │ │ + │ ─────────── Scanning ─────────── │ + │ │ + │ Eddystone UID Frame │ + │ ═══════════════════════════════════════════>│ + │ │ 3. Detect Eddystone + │ │ 4. Parse UID Frame: + │ │ - Namespace ID + │ │ - Instance ID + │ │ - RSSI + │ │ + │ Eddystone URL Frame │ + │ ═══════════════════════════════════════════>│ + │ │ 5. Parse URL Frame: + │ │ - Decode URL + │ │ - TX Power + │ │ + ┌────────┴─────────┐ ┌────────┴─────────┐ + │ Eddystone Sender │ │Eddystone Receiver│ + └──────────────────┘ └──────────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/ble_eddystone_sender/README.md b/examples/bluetooth/bluedroid/ble/ble_eddystone_sender/README.md index 7cb1a69290..f0251f4412 100644 --- a/examples/bluetooth/bluedroid/ble/ble_eddystone_sender/README.md +++ b/examples/bluetooth/bluedroid/ble/ble_eddystone_sender/README.md @@ -5,11 +5,43 @@ This example demonstrates Eddystone-compatible BLE sending of eddystone frame, including UID and URL and TLM. -Eddystone is an open beacon protocol specification from Google aimed at improving “proximity-based experiences” +Eddystone is an open beacon protocol specification from Google aimed at improving "proximity-based experiences" with support for both Android and iOS smart device platforms. Learn more on [Beacons](https://developers.google.com/nearby/notifications/get-started) and [Eddystone](https://github.com/google/eddystone). +## Flow Diagram + +``` + ┌──────────────────┐ ┌──────────────────┐ + │ Eddystone Sender │ │ Eddystone Receiver│ + │ (Advertiser) │ │ (Scanner) │ + └────────┬─────────┘ └────────┬─────────┘ + │ │ + │ 1. Initialize BLE │ + │ 2. Configure Eddystone Frame: │ + │ - UID Frame (Namespace + Instance) │ + │ - URL Frame (Encoded URL) │ + │ - TLM Frame (Telemetry Data) │ + │ 3. Set Raw Advertising Data │ + │ 4. Start Advertising │ + │ │ + │ ─────────── Broadcasting ─────────── │ + │ │ + │ Eddystone Advertisement Packet │ + │ ═══════════════════════════════════════════>│ + │ (Broadcast periodically) │ + │ │ + │ │ Parse Frame: + │ │ - UID: Namespace ID + │ │ - URL: Decoded URL + │ │ - TLM: Battery, Temp + │ │ + ┌────────┴─────────┐ ┌────────┴─────────┐ + │ Eddystone Sender │ │ Eddystone Receiver│ + └──────────────────┘ └──────────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/README.md b/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/README.md index 95fcaf166a..0bb49a7da4 100644 --- a/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/README.md +++ b/examples/bluetooth/bluedroid/ble/ble_hid_device_demo/README.md @@ -13,6 +13,54 @@ This example implement a BLE HID device profile related functions, in which the Users can choose different reports according to their own application scenarios. BLE HID profile inheritance and USB HID class. +## Flow Diagram + +``` + ┌──────────────┐ ┌──────────────┐ + │ BLE HID │ │ Host │ + │ Device │ │ (PC/Phone) │ + └──────┬───────┘ └──────┬───────┘ + │ │ + │ ─────────── Initialization ─────────── │ + │ │ + │ 1. Create HID Service │ + │ - HID Information Char │ + │ - Report Map Char │ + │ - Report Chars (Mouse/Keyboard/Consumer) │ + │ - HID Control Point Char │ + │ 2. Start Advertising │ + │ │ + │ ─────────── Connection & Pairing ─────────── │ + │ │ + │ Scan & Connect │ + │ <─────────────────────────────────────────────── │ + │ │ + │ Pairing (Bonding) │ + │ <────────────────────────────────────────────────>│ + │ │ + │ Enable Report Notification │ + │ <─────────────────────────────────────────────── │ + │ │ + │ ─────────── HID Data Transfer ─────────── │ + │ │ + │ Send Keyboard Report │ + │ (Key Press/Release) │ + │ ───────────────────────────────────────────────> │ + │ │ + │ Send Mouse Report │ + │ (X/Y Movement, Buttons) │ + │ ───────────────────────────────────────────────> │ + │ │ + │ Send Consumer Report │ + │ (Volume +/-, Media Control) │ + │ ───────────────────────────────────────────────> │ + │ │ + ┌──────┴───────┐ ┌──────┴───────┐ + │ BLE HID │ │ Host │ + │ Device │ │ (PC/Phone) │ + └──────────────┘ └──────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/ble_ibeacon/README.md b/examples/bluetooth/bluedroid/ble/ble_ibeacon/README.md index b375876e87..065a2efe83 100644 --- a/examples/bluetooth/bluedroid/ble/ble_ibeacon/README.md +++ b/examples/bluetooth/bluedroid/ble/ble_ibeacon/README.md @@ -5,6 +5,61 @@ From welcoming people as they arrive at a sporting event to providing information about a nearby museum exhibit, iBeacon opens a new world of possibilities for location awareness, and countless opportunities for interactivity between iOS devices and iBeacon hardware. +## Flow Diagram + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ iBeacon System │ +└─────────────────────────────────────────────────────────────────────────────┘ + + ┌──────────────────┐ ┌──────────────────┐ + │ iBeacon Sender │ │ iBeacon Receiver │ + │ (Advertiser) │ │ (Scanner) │ + └────────┬─────────┘ └────────┬─────────┘ + │ │ + │ ─────────── Sender Operation ─────────── │ + │ │ + │ 1. Initialize BLE │ + │ 2. Configure iBeacon Data: │ + │ - Proximity UUID (16 bytes) │ + │ - Major ID (2 bytes) │ + │ - Minor ID (2 bytes) │ + │ - TX Power (1 byte) │ + │ 3. Start Advertising │ + │ │ + │ ─────────── Broadcasting ─────────── │ + │ │ + │ iBeacon Advertisement Packet │ + │ ═══════════════════════════════════════════>│ + │ (Broadcast every ~100ms) │ + │ │ + │ │ ─── Receiver ─── + │ │ + │ │ 1. Start Scan + │ │ 2. Receive Adv + │ │ 3. Parse iBeacon: + │ │ - UUID + │ │ - Major/Minor + │ │ - RSSI + │ │ 4. Calculate + │ │ Distance + │ │ + ┌────────┴─────────┐ ┌────────┴─────────┐ + │ iBeacon Sender │ │ iBeacon Receiver │ + └──────────────────┘ └──────────────────┘ + + + ┌─────────────────────────────────┐ + │ iBeacon Packet Structure │ + ├─────────────────────────────────┤ + │ Prefix: 9 bytes │ + │ UUID: 16 bytes │ + │ Major: 2 bytes │ + │ Minor: 2 bytes │ + │ TX Power: 1 byte │ + └─────────────────────────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_cent/README.md b/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_cent/README.md index 8e86afbdbe..51c95b7401 100644 --- a/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_cent/README.md +++ b/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_cent/README.md @@ -7,6 +7,52 @@ **This example relies on the BLE controller. please use the chip modules listed under Supported Targets.** +## Flow Diagram + +``` + ┌──────────────────────────────────────────────────────────────────────────┐ + │ BLE Multi-Connection Central │ + └──────────────────────────────────────────────────────────────────────────┘ + + ┌───────────────────┐ + │ Multi-Conn Cent │ + │ (GATTC + GATTS) │ + └─────────┬─────────┘ + │ + │ 1. Initialize GATT Client & Server + │ 2. Set Random Address + │ 3. Start Scanning + │ + ▼ + ┌───────────────────────────────────────────────────────────────────────┐ + │ Scan for Peripherals │ + └───────────────────────────────────────────────────────────────────────┘ + │ + │ Found peripheral? + │ + ├───────────────────┬───────────────────┬───────────────────┐ + ▼ ▼ ▼ ▼ + ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ... + │ Peripheral 1 │ │ Peripheral 2 │ │ Peripheral 3 │ + └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ + │ │ │ + │ ─────────── For Each Peripheral ─────────── + │ + │ 4. Stop Scanning + │ 5. Create Connection + │ 6. Update Scheduling Length + │ 7. Connection Established + │ 8. Add to Peer List + │ 9. Change Random Address + │ 10. Resume Scanning + │ + ▼ + ┌───────────────────────────────────────────────────────────────────────┐ + │ All peripherals connected (up to CONFIG limit) │ + │ Maintain multiple connections │ + └───────────────────────────────────────────────────────────────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_prph/README.md b/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_prph/README.md index 01cf4ff01c..2eb99a15f5 100644 --- a/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_prph/README.md +++ b/examples/bluetooth/bluedroid/ble/ble_multi_conn/ble_multi_conn_prph/README.md @@ -7,6 +7,45 @@ **This example relies on the BLE controller. Please use the chip modules listed under Supported Targets.** +## Flow Diagram + +``` + ┌──────────────────────────────────────────────────────────────────────────┐ + │ BLE Multi-Connection Peripheral │ + └──────────────────────────────────────────────────────────────────────────┘ + + ┌───────────────────┐ ┌───────────────────┐ + │ Multi-Conn Prph │ │ Centrals │ + │ (GATT Server) │ │ (1, 2, 3, ...) │ + └─────────┬─────────┘ └─────────┬─────────┘ + │ │ + │ 1. Initialize GATT Server │ + │ 2. Create Service │ + │ 3. Set Random Address │ + │ 4. Start Advertising │ + │ │ + │ ─────────── Connection Loop ─────────── + │ │ + │ Central 1 connects │ + │ <───────────────────────────│ + │ │ + │ 5. Stop Advertising │ + │ 6. Connection Established │ + │ 7. Change Random Address │ + │ 8. Restart Advertising │ + │ │ + │ Central 2 connects │ + │ <───────────────────────────│ + │ │ + │ ... Repeat for each Central ... + │ │ + ▼ │ + ┌───────────────────────────────────────────────────────────────────────┐ + │ Maintain multiple connections simultaneously │ + │ (Limited by CONFIG_BT_ACL_CONNECTIONS) │ + └───────────────────────────────────────────────────────────────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/ble_spp_client/README.md b/examples/bluetooth/bluedroid/ble/ble_spp_client/README.md index e0ca60fd04..72ad1f99b1 100644 --- a/examples/bluetooth/bluedroid/ble/ble_spp_client/README.md +++ b/examples/bluetooth/bluedroid/ble/ble_spp_client/README.md @@ -9,6 +9,71 @@ This vendor-specific custom profile is implemented in [spp_client_demo.c](../ble_spp_client/main/spp_client_demo.c) and [spp_server_demo.c](../ble_spp_server/main/ble_spp_server_demo.c). +## Flow Diagram + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ BLE SPP Data Flow │ +└─────────────────────────────────────────────────────────────────────────────┘ + + SPP Client SPP Server + ┌───────────┐ ┌───────────┐ + │ UART │ │ UART │ + │ Terminal │ │ Terminal │ + └─────┬─────┘ └─────┬─────┘ + │ │ + ▼ ▼ + ┌───────────┐ ┌───────────┐ + │ uart_task │ │ uart_task │ + └─────┬─────┘ └─────┬─────┘ + │ │ + │ ─────────── Connection Phase ─────────── │ + │ │ + │ 1. Scan for SPP Server │ Advertising + │ ───────────────────────────────────────────────────> │ + │ │ + │ 2. Connect │ + │ ───────────────────────────────────────────────────> │ + │ │ + │ 3. MTU Exchange (200 bytes) │ + │ <────────────────────────────────────────────────────>│ + │ │ + │ 4. Service Discovery │ + │ ───────────────────────────────────────────────────> │ + │ │ + │ 5. Enable Notification (CCCD) │ + │ ───────────────────────────────────────────────────> │ + │ │ + │ ─────────── Data Exchange ─────────── │ + │ │ + │ UART Input ──> WriteNoRsp (SPP_DATA_RECV_CHAR) │ + │ ───────────────────────────────────────────────────> │──> UART Output + │ │ + │ UART Output <── Notification (SPP_DATA_NOTIFY_CHAR) │ + │ <─────────────────────────────────────────────────── │<── UART Input + │ │ + ┌─────┴─────┐ ┌─────┴─────┐ + │ SPP Client│ │SPP Server │ + └───────────┘ └───────────┘ + + + ┌─────────────────────────────────┐ + │ SPP Characteristics │ + ├─────────────────────────────────┤ + │ SPP_DATA_RECV (0xABF1) │ + │ - Client writes data here │ + │ │ + │ SPP_DATA_NOTIFY (0xABF2) │ + │ - Server sends data here │ + │ │ + │ SPP_COMMAND (0xABF3) │ + │ - Command channel │ + │ │ + │ SPP_STATUS (0xABF4) │ + │ - Status notification │ + └─────────────────────────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/ble_spp_server/README.md b/examples/bluetooth/bluedroid/ble/ble_spp_server/README.md index 9f570d67c9..d9b16345ab 100644 --- a/examples/bluetooth/bluedroid/ble/ble_spp_server/README.md +++ b/examples/bluetooth/bluedroid/ble/ble_spp_server/README.md @@ -5,6 +5,42 @@ For description of this application please refer to [ESP-IDF GATT CLIENT SPP Example](../ble_spp_client/README.md) +## Flow Diagram + +``` + SPP Server SPP Client + ┌───────────┐ ┌───────────┐ + │ UART │ │ UART │ + │ Terminal │ │ Terminal │ + └─────┬─────┘ └─────┬─────┘ + │ │ + │ ─────────── Initialization ─────────── │ + │ │ + │ 1. Create SPP Service (UUID: 0xABF0) │ + │ 2. Add Characteristics │ + │ 3. Start Advertising │ + │ │ + │ ─────────── Connection ─────────── │ + │ │ + │ Scan & Connect │ + │ <─────────────────────────────────────────────────── │ + │ │ + │ Connection Established │ + │ ─────────────────────────────────────────────────────>│ + │ │ + │ ─────────── Data Exchange ─────────── │ + │ │ + │ UART Input ──> Notification (SPP_DATA_NOTIFY_CHAR) │ + │ ─────────────────────────────────────────────────────>│──> UART Output + │ │ + │ UART Output <── WriteNoRsp (SPP_DATA_RECV_CHAR) │ + │ <─────────────────────────────────────────────────── │<── UART Input + │ │ + ┌─────┴─────┐ ┌─────┴─────┐ + │SPP Server │ │ SPP Client│ + └───────────┘ └───────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/README.md b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/README.md index 6b90e7a23e..f7a5b0375d 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/README.md +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/README.md @@ -6,6 +6,49 @@ This is the demo used to test the BLE throughput, this demo should used with throughput server demo together. The throughput of BLE can up to 720-767 Kbps between to ESP32 board. +## Flow Diagram + +``` + ┌──────────────┐ ┌──────────────┐ + │ Throughput │ │ Throughput │ + │ Client │ │ Server │ + └──────┬───────┘ └──────┬───────┘ + │ │ + │ ─────────── Connection Setup ─────────── │ + │ │ + │ 1. Scan for "THROUGHPUT_DEMO" │ Advertising + │ ───────────────────────────────────────────────> │ + │ │ + │ 2. Connect │ + │ ───────────────────────────────────────────────> │ + │ │ + │ 3. MTU Exchange (517 bytes) │ + │ <────────────────────────────────────────────────>│ + │ │ + │ 4. Enable Notification │ + │ ───────────────────────────────────────────────> │ + │ │ + │ ─────────── Throughput Test ─────────── │ + │ │ + │ Mode 1: Notify Test (Server → Client) │ + │ <═══════════════════════════════════════════════ │ + │ Continuous notifications (514 bytes/packet) │ + │ │ + │ Mode 2: Write Test (Client → Server) │ + │ ═══════════════════════════════════════════════> │ + │ Continuous writes (514 bytes/packet) │ + │ │ + │ ─────────── Statistics ─────────── │ + │ │ + │ Calculate: Bytes/s, bits/s │ + │ Expected: 600-767 Kbps │ + │ │ + ┌──────┴───────┐ ┌──────┴───────┐ + │ Throughput │ │ Throughput │ + │ Client │ │ Server │ + └──────────────┘ └──────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/README.md b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/README.md index 18851f22ea..c540c43760 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/README.md +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/README.md @@ -6,6 +6,48 @@ This is the demo used to test the BLE throughput, this demo should used with throughput client demo together. The throughput of BLE can up to 720-767 Kbps between to ESP32 board. +## Flow Diagram + +``` + ┌──────────────────┐ ┌──────────────────┐ + │ Throughput Server│ │ Throughput Client│ + │ (this example) │ │ │ + └────────┬─────────┘ └────────┬─────────┘ + │ │ + │ 1. Initialize BLE │ + │ 2. Create GATT Service │ + │ 3. Add Characteristic (Notify) │ + │ 4. Start Advertising │ + │ │ + │ ─────────── Connection Setup ─────────── │ + │ │ + │ Connection Request │ + │ <════════════════════════════════════════════│ + │ │ + │ 5. Accept Connection │ + │ │ + │ MTU Exchange (517 bytes) │ + │ <═══════════════════════════════════════════>│ + │ │ + │ Enable Notification │ + │ <════════════════════════════════════════════│ + │ │ + │ ─────────── Throughput Test ─────────── │ + │ │ + │ Notification Data (large packets) │ + │ ════════════════════════════════════════════>│ + │ Notification Data (large packets) │ + │ ════════════════════════════════════════════>│ + │ ... (continuous data stream) ... │ + │ ════════════════════════════════════════════>│ + │ │ Calculate + │ │ Throughput + │ │ + ┌────────┴─────────┐ ┌────────┴─────────┐ + │ Throughput Server│ │ Throughput Client│ + └──────────────────┘ └──────────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/gatt_client/README.md b/examples/bluetooth/bluedroid/ble/gatt_client/README.md index df97a162c5..d7348f8ed1 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_client/README.md +++ b/examples/bluetooth/bluedroid/ble/gatt_client/README.md @@ -5,6 +5,65 @@ This example shows how to use ESP APIs to create a GATT Client. +## Flow Diagram + +``` + ┌──────────────┐ ┌──────────────┐ + │ GATT Client │ │ GATT Server │ + │ (this example)│ │(gatt_server) │ + └──────┬───────┘ └──────┬───────┘ + │ │ + │ ─────────── Scanning Phase ─────────── │ + │ │ + │ 1. Start Scan │ Advertising + │ ───────────────────────────────────────────────> │ "ESP_GATTS_DEMO" + │ │ + │ 2. Found "ESP_GATTS_DEMO" │ + │ <─────────────────────────────────────────────── │ + │ │ + │ ─────────── Connection Phase ─────────── │ + │ │ + │ 3. Connect │ + │ ───────────────────────────────────────────────> │ + │ │ + │ 4. Connection Established │ + │ <─────────────────────────────────────────────────│ + │ │ + │ 5. MTU Exchange │ + │ <────────────────────────────────────────────────>│ + │ │ + │ ─────────── Service Discovery ─────────── │ + │ │ + │ 6. Discover Service (UUID: 0x00FF) │ + │ ───────────────────────────────────────────────> │ + │ │ + │ 7. Service Found │ + │ <─────────────────────────────────────────────── │ + │ │ + │ 8. Get Characteristic (UUID: 0xFF01) │ + │ ───────────────────────────────────────────────> │ + │ │ + │ ─────────── Enable Notification ─────────── │ + │ │ + │ 9. Register for Notify │ + │ ───────────────────────────────────────────────> │ + │ │ + │ 10. Write CCCD (Enable Notify) │ + │ ───────────────────────────────────────────────> │ + │ │ + │ ─────────── Data Exchange ─────────── │ + │ │ + │ 11. Write Characteristic │ + │ ───────────────────────────────────────────────> │ + │ │ + │ 12. Receive Notification │ + │ <─────────────────────────────────────────────── │ + │ │ + ┌──────┴───────┐ ┌──────┴───────┐ + │ GATT Client │ │ GATT Server │ + └──────────────┘ └──────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/gatt_security_client/README.md b/examples/bluetooth/bluedroid/ble/gatt_security_client/README.md index 2fe96fc901..f6ab4b81a2 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_security_client/README.md +++ b/examples/bluetooth/bluedroid/ble/gatt_security_client/README.md @@ -5,6 +5,59 @@ This example shows how to use the ESP BLE security APIs to secure connect to and encrypt with peer devices. +## Flow Diagram + +``` + ┌──────────────┐ ┌──────────────┐ + │ Security │ │ Security │ + │ Client │ │ Server │ + └──────┬───────┘ └──────┬───────┘ + │ │ + │ ─────────── Security Parameters Setup ───────── │ + │ │ + │ 1. Set IO Capability │ + │ 2. Set Auth Mode (Bonding, MITM, SC) │ + │ 3. Set Key Distribution │ + │ │ + │ ─────────── Connection Phase ─────────── │ + │ │ + │ 4. Scan for Server │ Advertising + │ ───────────────────────────────────────────────> │ + │ │ + │ 5. Connect │ + │ ───────────────────────────────────────────────> │ + │ │ + │ Connection Established │ + │ <─────────────────────────────────────────────────│ + │ │ + │ ─────────── Pairing & Encryption ─────────── │ + │ │ + │ 6. Start Encryption (esp_ble_set_encryption) │ + │ ───────────────────────────────────────────────> │ + │ │ + │ 7. Exchange Pairing Features │ + │ <────────────────────────────────────────────────>│ + │ │ + │ 8. Generate Keys (LTK, IRK, CSRK) │ + │ <────────────────────────────────────────────────>│ + │ │ + │ 9. Encrypt Link │ + │ <────────────────────────────────────────────────>│ + │ │ + │ 10. ESP_GAP_BLE_AUTH_CMPL_EVT │ + │ <─────────────────────────────────────────────── │ + │ │ + │ ─────────── Secure Data Exchange ─────────── │ + │ │ + │ Encrypted GATT Operations │ + │ <────────────────────────────────────────────────>│ + │ │ + ┌──────┴───────┐ ┌──────┴───────┐ + │ Security │ │ Security │ + │ Client │ │ Server │ + └──────────────┘ └──────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/gatt_security_server/README.md b/examples/bluetooth/bluedroid/ble/gatt_security_server/README.md index 36b1d60d27..337689ebc7 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_security_server/README.md +++ b/examples/bluetooth/bluedroid/ble/gatt_security_server/README.md @@ -9,6 +9,56 @@ To test this example, you can run [gatt_security_client_demo](../gatt_security_c Please, check this [tutorial](tutorial/Gatt_Security_Server_Example_Walkthrough.md) for more information about this example. +## Flow Diagram + +``` + ┌──────────────┐ ┌──────────────┐ + │ Security │ │ Security │ + │ Server │ │ Client │ + └──────┬───────┘ └──────┬───────┘ + │ │ + │ ─────────── Initialization ─────────── │ + │ │ + │ 1. Set Security Parameters │ + │ - IO Capability │ + │ - Auth Requirements │ + │ - Key Size │ + │ 2. Create GATT Service │ + │ 3. Start Advertising │ + │ │ + │ ─────────── Connection ─────────── │ + │ │ + │ Scan & Connect │ + │ <─────────────────────────────────────────────── │ + │ │ + │ ─────────── Security Request ─────────── │ + │ │ + │ ESP_GAP_BLE_SEC_REQ_EVT │ + │ <─────────────────────────────────────────────── │ + │ │ + │ Send Security Response │ + │ ───────────────────────────────────────────────> │ + │ │ + │ ─────────── Pairing Process ─────────── │ + │ │ + │ Exchange Pairing Features │ + │ <────────────────────────────────────────────────>│ + │ │ + │ Key Generation & Distribution │ + │ <────────────────────────────────────────────────>│ + │ │ + │ Link Encrypted │ + │ <────────────────────────────────────────────────>│ + │ │ + │ ESP_GAP_BLE_AUTH_CMPL_EVT │ + │ ───────────────────────────────────────────────> │ + │ │ + ┌──────┴───────┐ ┌──────┴───────┐ + │ Security │ │ Security │ + │ Server │ │ Client │ + └──────────────┘ └──────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/gatt_server/README.md b/examples/bluetooth/bluedroid/ble/gatt_server/README.md index fe79948f1c..07c4481b61 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server/README.md +++ b/examples/bluetooth/bluedroid/ble/gatt_server/README.md @@ -13,6 +13,62 @@ To test this demo, we can run the [gatt_client_demo](../gatt_client), which can Please, check this [tutorial](tutorial/Gatt_Server_Example_Walkthrough.md) for more information about this example. +## Flow Diagram + +``` + ┌──────────────┐ ┌──────────────┐ + │ GATT Server │ │ GATT Client │ + │(this example)│ │(gatt_client) │ + └──────┬───────┘ └──────┬───────┘ + │ │ + │ ─────────── Initialization ─────────── │ + │ │ + │ 1. Register GATT Server App │ + │ 2. Create Service (UUID: 0x00FF) │ + │ 3. Add Characteristic (UUID: 0xFF01) │ + │ 4. Add Descriptor (CCCD) │ + │ 5. Start Service │ + │ 6. Start Advertising "ESP_GATTS_DEMO" │ + │ │ + │ ─────────── Connection Phase ─────────── │ + │ │ + │ Scan & Connect │ + │ <─────────────────────────────────────────────── │ + │ │ + │ Connection Established │ + │ ─────────────────────────────────────────────────>│ + │ │ + │ MTU Exchange │ + │ <────────────────────────────────────────────────>│ + │ │ + │ ─────────── Service Discovery ─────────── │ + │ │ + │ Service Discovery │ + │ <─────────────────────────────────────────────── │ + │ │ + │ Return Service Info │ + │ ─────────────────────────────────────────────────>│ + │ │ + │ ─────────── Enable Notification ─────────── │ + │ │ + │ Write CCCD (0x0001) │ + │ <─────────────────────────────────────────────── │ + │ │ + │ Notification Enabled │ + │ │ + │ ─────────── Data Exchange ─────────── │ + │ │ + │ Write Request │ + │ <─────────────────────────────────────────────── │ + │ │ + │ Send Notification │ + │ ─────────────────────────────────────────────────>│ + │ │ + ┌──────┴───────┐ ┌──────┴───────┐ + │ GATT Server │ │ GATT Client │ + └──────────────┘ └──────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/gatt_server_service_table/README.md b/examples/bluetooth/bluedroid/ble/gatt_server_service_table/README.md index 4edb06cf0c..6296ff6ad3 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server_service_table/README.md +++ b/examples/bluetooth/bluedroid/ble/gatt_server_service_table/README.md @@ -7,6 +7,56 @@ This example shows how to create a GATT service with an attribute table defined Please, check this [tutorial](tutorial/Gatt_Server_Service_Table_Example_Walkthrough.md) for more information about this example. +## Flow Diagram + +``` + ┌──────────────────────────────────────────────────────────────────────────┐ + │ GATT Server Initialization Flow │ + └──────────────────────────────────────────────────────────────────────────┘ + + ┌───────────────────┐ + │ GATT Server │ + └─────────┬─────────┘ + │ + │ 1. Define Attribute Table (gatt_db[]) + │ ┌─────────────────────────────────────┐ + │ │ [0] Service Declaration │ + │ │ [1] Char Declaration │ + │ │ [2] Char Value │ + │ │ [3] CCCD (Notify Enable) │ + │ │ ... │ + │ └─────────────────────────────────────┘ + │ + │ 2. esp_ble_gatts_create_attr_tab() + │ - Create all attributes at once + │ + │ 3. ESP_GATTS_CREAT_ATTR_TAB_EVT + │ - Receive handle table + │ + │ 4. esp_ble_gatts_start_service() + │ + │ 5. Start Advertising + │ + ▼ + ┌───────────────────┐ ┌───────────────────┐ + │ GATT Server │ │ GATT Client │ + │ (Advertising) │ │ │ + └─────────┬─────────┘ └─────────┬─────────┘ + │ │ + │ Scan & Connect │ + │ <───────────────────────────────────────────│ + │ │ + │ Service Discovery │ + │ ───────────────────────────────────────────>│ + │ │ + │ Read/Write/Notify Operations │ + │ <──────────────────────────────────────────>│ + │ │ + ┌─────────┴─────────┐ ┌─────────┴─────────┐ + │ GATT Server │ │ GATT Client │ + └───────────────────┘ └───────────────────┘ +``` + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/README.md b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/README.md index 889efc13fe..af422337b0 100644 --- a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/README.md +++ b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/README.md @@ -3,34 +3,169 @@ # ESP-IDF Gatt Client Multi Connection Example -This example shows the usage of APIs to create a GATT multi-connection client. It can be used to connect to three GATT servers at the same time. +This example demonstrates how to use the BLE GATT client APIs to create a multi-connection client that can connect to multiple GATT servers simultaneously. By default, it supports connecting to up to 3 GATT servers at the same time. -To test this example, please run [gatt_server_demo](../gatt_server) to create three GATT server devices, namely ESP_GATTS_DEMO_a, ESP_GATTS_DEMO_b and ESP_GATTS_DEMO_c, `Gatt_client_multi_connection_demo` will connect to these three gatt server demos, and then exchange data. +## How It Works -Please, check this [tutorial](tutorial/Gatt_Client_Multi_Connection_Example_Walkthrough.md) for more information about this example. +The example creates three GATT client profiles (A, B, C), each corresponding to one connection. It scans for devices with specific names, connects to them, discovers services, registers for notifications, and exchanges data with each server. + +### Target Devices + +The example searches for three GATT servers with the following names: +- `ESP_GATTS_DEMO_a` → Profile A +- `ESP_GATTS_DEMO_b` → Profile B +- `ESP_GATTS_DEMO_c` → Profile C + +You can use the [gatt_server](../gatt_server) example to create these server devices by modifying the device name. + +## Flow Diagram + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ GATT Client Multi-Connection │ +└─────────────────────────────────────────────────────────────────────────────┘ + + ┌──────────────────┐ + │ GATTC Client │ + │ (Multi-Connect) │ + └────────┬─────────┘ + │ + │ 1. Start Scanning + │ + ▼ + ┌────────────────────────────────────────────────────────────────────────┐ + │ Scan for BLE Devices │ + │ Looking for: ESP_GATTS_DEMO_a, _b, _c │ + └────────────────────────────────────────────────────────────────────────┘ + │ + │ Found device matching name? + │ + ├─────────────────────┬─────────────────────┐ + ▼ ▼ ▼ + ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ + │ ESP_GATTS_DEMO_a│ │ ESP_GATTS_DEMO_b│ │ ESP_GATTS_DEMO_c│ + │ (Server A) │ │ (Server B) │ │ (Server C) │ + └───────┬────────┘ └───────┬────────┘ └───────┬────────┘ + │ │ │ + ▼ ▼ ▼ + ┌───────────────────────────────────────────────────────────────────────┐ + │ For Each Connected Device: │ + ├───────────────────────────────────────────────────────────────────────┤ + │ 2. Stop Scanning │ + │ 3. Connect (esp_ble_gattc_enh_open) │ + │ 4. MTU Exchange │ + │ 5. Service Discovery (UUID: 0x00FF) │ + │ 6. Find Characteristic (UUID: 0xFF01) │ + │ 7. Register for Notification │ + │ 8. Write CCCD (Enable Notification) │ + │ 9. Write Test Data (35 bytes) │ + │ 10. Resume Scanning for remaining devices │ + └───────────────────────────────────────────────────────────────────────┘ + │ + │ All 3 devices connected? + ▼ + ┌────────────────────────────────────────────────────────────────────────┐ + │ Stop Scanning │ + │ Continue receiving notifications from all devices │ + └────────────────────────────────────────────────────────────────────────┘ + + + ┌────────────────────────────────────┐ + │ Connection Sequence Detail │ + └────────────────────────────────────┘ + + Client Server + │ │ + │ ─────────── Connection Phase ─────────── │ + │ │ + │ Connect Request │ + │ ────────────────────────────────────────────────> │ + │ │ + │ Connection Established │ + │ <────────────────────────────────────────────────>│ + │ │ + │ MTU Exchange Request │ + │ ────────────────────────────────────────────────> │ + │ │ + │ MTU Exchange Response │ + │ <──────────────────────────────────────────────── │ + │ │ + │ ─────────── Service Discovery ─────────── │ + │ │ + │ Discover Services (UUID: 0x00FF) │ + │ ────────────────────────────────────────────────> │ + │ │ + │ Service Found │ + │ <──────────────────────────────────────────────── │ + │ │ + │ Get Characteristic (UUID: 0xFF01) │ + │ ────────────────────────────────────────────────> │ + │ │ + │ Characteristic Found │ + │ <──────────────────────────────────────────────── │ + │ │ + │ ─────────── Enable Notification ─────────── │ + │ │ + │ Register for Notify │ + │ ────────────────────────────────────────────────> │ + │ │ + │ Write CCCD (0x0001 = Enable Notify) │ + │ ────────────────────────────────────────────────> │ + │ │ + │ ─────────── Data Exchange ─────────── │ + │ │ + │ Write Characteristic (35 bytes test data) │ + │ ────────────────────────────────────────────────> │ + │ │ + │ Notification (data from server) │ + │ <──────────────────────────────────────────────── │ + │ │ +``` ## How to Use Example -Before project configuration and build, be sure to set the correct chip target using: +### Hardware Required + +* Four development boards with supported SoC: + - One board for the GATT Client (this example) + - Three boards for GATT Servers (using [gatt_server](../gatt_server) example) +* Four USB cables for power supply and programming + +See [Development Boards](https://www.espressif.com/en/products/devkits) for more information. + +### Setup GATT Servers + +1. Flash the [gatt_server](../gatt_server) example to three separate boards +2. Modify each server's device name before flashing: + - Server 1: Change `ESP_GATT_DEMO` to `ESP_GATTS_DEMO_a` + - Server 2: Change `ESP_GATT_DEMO` to `ESP_GATTS_DEMO_b` + - Server 3: Change `ESP_GATT_DEMO` to `ESP_GATTS_DEMO_c` + +### Configure the Project + +Set the correct chip target: ```bash idf.py set-target ``` -The code can be modified to connect to more devices (up to 4 devices by default). If you need to connect to more devices (more than 4 devices), you need to change `BT/BLE MAX ACL CONNECTIONS` in menuconfig. +**Connecting More Than 4 Devices:** -### Hardware Required +The default maximum number of ACL connections is 4. To connect more devices: -* A development board with ESP32/ESP32-C3/ESP32-C2/ESP32-H2/ESP32-S3 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.) -* A USB cable for Power supply and programming +```bash +idf.py menuconfig +``` -See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it. +Navigate to: `Component config` → `Bluetooth` → `Bluedroid Options` → `BT/BLE MAX ACL CONNECTIONS` ### Build and Flash -Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. +```bash +idf.py -p PORT flash monitor +``` -(To exit the serial monitor, type ``Ctrl-]``.) +(To exit the serial monitor, type `Ctrl-]`.) See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. From 9ef7842daa36baf289f70e6074793607355bf9b3 Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Mon, 1 Dec 2025 10:48:13 +0800 Subject: [PATCH 159/226] feat(ble/bluedroid): add periodic advertising create sync retry mechanism --- components/bt/host/bluedroid/Kconfig.in | 10 +++ .../include/common/bluedroid_user_config.h | 6 ++ .../common/include/common/bt_target.h | 6 ++ .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 70 ++++++++++++++++++- 4 files changed, 91 insertions(+), 1 deletion(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 5447060f8e..9dfef03026 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1410,6 +1410,16 @@ config BT_BLE_FEAT_CREATE_SYNC_ENH help Enable the create sync enhancements +config BT_BLE_FEAT_CREATE_SYNC_RETRY_MAX + int "Maximum retry count for periodic advertising create sync" + depends on BT_BLE_50_EXTEND_SYNC_EN + default 3 + range 0 16 + help + Set the maximum retry count when periodic advertising create sync fails + with error code 0x3E (Connection Failed to be Established). + Set to 0 to disable retry. Default is 3. + menuconfig BT_BLE_FEAT_ISO_EN bool "Enable BLE 5.2 iso feature" depends on (BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_BLE_AUDIO_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR 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 97bd25404f..d82ec6b547 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 @@ -278,6 +278,12 @@ #define UC_BT_BLE_FEAT_CREATE_SYNC_ENH FALSE #endif +#ifdef CONFIG_BT_BLE_FEAT_CREATE_SYNC_RETRY_MAX +#define UC_BT_BLE_FEAT_CREATE_SYNC_RETRY_MAX CONFIG_BT_BLE_FEAT_CREATE_SYNC_RETRY_MAX +#else +#define UC_BT_BLE_FEAT_CREATE_SYNC_RETRY_MAX 3 +#endif + #ifdef CONFIG_BT_BLE_FEAT_ISO_EN #define UC_BT_BLE_FEAT_ISO_EN CONFIG_BT_BLE_FEAT_ISO_EN #else 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 9ef207ebef..56d61fe6d4 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -319,6 +319,12 @@ #define BLE_FEAT_CREATE_SYNC_ENH FALSE #endif +#ifdef UC_BT_BLE_FEAT_CREATE_SYNC_RETRY_MAX +#define BLE_FEAT_CREATE_SYNC_RETRY_MAX UC_BT_BLE_FEAT_CREATE_SYNC_RETRY_MAX +#else +#define BLE_FEAT_CREATE_SYNC_RETRY_MAX 3 +#endif + #if (UC_BT_BLE_FEAT_ISO_EN == TRUE) #define BLE_FEAT_ISO_EN TRUE #else diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 81eb92414b..7ecde99cee 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -39,6 +39,19 @@ typedef struct { tBTM_EXT_ADV_RECORD adv_record[MAX_BLE_ADV_INSTANCE] = {0}; #endif // #if (BLE_50_EXTEND_ADV_EN == TRUE) +#if (BLE_50_EXTEND_SYNC_EN == TRUE) +#if (BLE_FEAT_CREATE_SYNC_RETRY_MAX > 0) +/* Create sync retry control block */ +typedef struct { + bool in_use; /* Whether sync creation is in progress */ + uint8_t retry_count; /* Current retry count */ + tBTM_BLE_Periodic_Sync_Params params; /* Saved sync parameters for retry */ +} tBTM_BLE_SYNC_RETRY_CB; + +static tBTM_BLE_SYNC_RETRY_CB sync_retry_cb = {0}; +#endif // #if (BLE_FEAT_CREATE_SYNC_RETRY_MAX > 0) +#endif // #if (BLE_50_EXTEND_SYNC_EN == TRUE) + extern void btm_ble_inter_set(bool extble_inter); #if !UC_BT_STACK_NO_LOG @@ -880,11 +893,19 @@ tBTM_STATUS BTM_BlePeriodicAdvCreateSync(tBTM_BLE_Periodic_Sync_Params *params) SET_BIT(option, 2); } #endif // (BLE_FEAT_CREATE_SYNC_ENH == TRUE) - +#if (BLE_FEAT_CREATE_SYNC_RETRY_MAX > 0) + /* Save parameters for potential retry */ + memcpy(&sync_retry_cb.params, params, sizeof(tBTM_BLE_Periodic_Sync_Params)); + sync_retry_cb.retry_count = 0; + sync_retry_cb.in_use = true; +#endif // #if (BLE_FEAT_CREATE_SYNC_RETRY_MAX > 0) if (!btsnd_hcic_ble_periodic_adv_create_sync(option, params->sid, params->addr_type, params->addr, params->sync_timeout, params->sync_cte_type)) { BTM_TRACE_ERROR("LE PA CreateSync cmd failed"); status = BTM_ILLEGAL_VALUE; +#if (BLE_FEAT_CREATE_SYNC_RETRY_MAX > 0) + sync_retry_cb.in_use = false; +#endif // #if (BLE_FEAT_CREATE_SYNC_RETRY_MAX > 0) } end: @@ -942,6 +963,11 @@ tBTM_STATUS BTM_BlePeriodicAdvSyncCancel(void) tBTM_STATUS status = BTM_SUCCESS; tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; +#if (BLE_FEAT_CREATE_SYNC_RETRY_MAX > 0) + /* Clear retry state when sync is cancelled */ + sync_retry_cb.in_use = false; + sync_retry_cb.retry_count = 0; +#endif // #if (BLE_FEAT_CREATE_SYNC_RETRY_MAX > 0) if ((err = btsnd_hcic_ble_periodic_adv_create_sync_cancel()) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA SyncCancel, cmd err=0x%x", err); status = BTM_HCI_ERROR | err; @@ -1399,6 +1425,48 @@ void btm_ble_periodic_adv_sync_establish_evt(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB *par return; } +#if (BLE_FEAT_CREATE_SYNC_RETRY_MAX > 0) + /* Check if retry is needed for error 0x3E (Connection Failed to be Established) */ + if (params->status == HCI_ERR_CONN_FAILED_ESTABLISHMENT && + sync_retry_cb.in_use && + sync_retry_cb.retry_count < BLE_FEAT_CREATE_SYNC_RETRY_MAX) { + + sync_retry_cb.retry_count++; + BTM_TRACE_WARNING("%s, Create sync failed with 0x3E, retry %d/%d", + __func__, sync_retry_cb.retry_count, BLE_FEAT_CREATE_SYNC_RETRY_MAX); + + /* Build option from saved parameters */ + uint8_t option = 0x00; + if (sync_retry_cb.params.filter_policy) { + SET_BIT(option, 0); + } +#if (BLE_FEAT_CREATE_SYNC_ENH == TRUE) + if (sync_retry_cb.params.reports_disabled) { + SET_BIT(option, 1); + } + if (sync_retry_cb.params.filter_duplicates) { + SET_BIT(option, 2); + } +#endif // (BLE_FEAT_CREATE_SYNC_ENH == TRUE) + + /* Retry create sync with saved parameters */ + if (btsnd_hcic_ble_periodic_adv_create_sync(option, + sync_retry_cb.params.sid, + sync_retry_cb.params.addr_type, + sync_retry_cb.params.addr, + sync_retry_cb.params.sync_timeout, + sync_retry_cb.params.sync_cte_type)) { + /* Retry command sent successfully, wait for next event */ + return; + } + /* If retry command failed, fall through to report failure */ + BTM_TRACE_ERROR("%s, Retry create sync command failed", __func__); + } + + /* Clear retry state */ + sync_retry_cb.in_use = false; + sync_retry_cb.retry_count = 0; +#endif // #if (BLE_FEAT_CREATE_SYNC_RETRY_MAX > 0) memcpy(&cb_params.sync_estab, params, sizeof(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB)); // If the user has register the callback function, should callback it to the application. From 086ebb7ccb2e62a60b3ec3d84dd39f2f14b98661 Mon Sep 17 00:00:00 2001 From: Zhang Hai Peng Date: Tue, 30 Dec 2025 11:53:38 +0800 Subject: [PATCH 160/226] feat(examples/bluedroid): add BLE ACL latency measurement example (cherry picked from commit 934970a06fc12973e2a1ec6381c9f78e5da6dbbb) Co-authored-by: zhanghaipeng --- examples/bluetooth/.build-test-rules.yml | 18 + .../ble/ble_acl_latency/cent/CMakeLists.txt | 6 + .../ble/ble_acl_latency/cent/README.md | 190 +++++++ .../ble_acl_latency/cent/main/CMakeLists.txt | 2 + .../ble_acl_latency/cent/main/gattc_latency.h | 56 ++ .../cent/main/gattc_latency_demo.c | 480 ++++++++++++++++++ .../ble_acl_latency/cent/main/latency_test.c | 261 ++++++++++ .../ble_acl_latency/cent/sdkconfig.defaults | 7 + .../cent/sdkconfig.defaults.esp32c2 | 13 + .../ble/ble_acl_latency/periph/CMakeLists.txt | 6 + .../ble/ble_acl_latency/periph/README.md | 124 +++++ .../periph/main/CMakeLists.txt | 2 + .../periph/main/gatts_latency.h | 37 ++ .../periph/main/gatts_latency_demo.c | 360 +++++++++++++ .../ble_acl_latency/periph/sdkconfig.defaults | 7 + .../periph/sdkconfig.defaults.esp32c2 | 13 + 16 files changed, 1582 insertions(+) create mode 100644 examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/README.md create mode 100644 examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/gattc_latency.h create mode 100644 examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/gattc_latency_demo.c create mode 100644 examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/latency_test.c create mode 100644 examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/sdkconfig.defaults create mode 100644 examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/sdkconfig.defaults.esp32c2 create mode 100644 examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/README.md create mode 100644 examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/main/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/main/gatts_latency.h create mode 100644 examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/main/gatts_latency_demo.c create mode 100644 examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/sdkconfig.defaults create mode 100644 examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/sdkconfig.defaults.esp32c2 diff --git a/examples/bluetooth/.build-test-rules.yml b/examples/bluetooth/.build-test-rules.yml index d0e2fdb7fe..89a6d427b9 100644 --- a/examples/bluetooth/.build-test-rules.yml +++ b/examples/bluetooth/.build-test-rules.yml @@ -27,6 +27,24 @@ examples/bluetooth/bluedroid/ble: depends_filepatterns: - examples/bluetooth/bluedroid/ble/pytest_ble_test.py +examples/bluetooth/bluedroid/ble/ble_acl_latency/cent: + <<: *bt_default_depends + disable: + - if: SOC_BLE_SUPPORTED != 1 + enable: + - if: IDF_TARGET in ["esp32", "esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32s3"] + temporary: true + reason: only enable build jobs for tested targets + +examples/bluetooth/bluedroid/ble/ble_acl_latency/periph: + <<: *bt_default_depends + disable: + - if: SOC_BLE_SUPPORTED != 1 + enable: + - if: IDF_TARGET in ["esp32", "esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32s3"] + temporary: true + reason: only enable build jobs for tested targets + examples/bluetooth/bluedroid/ble/ble_hid_device_demo: <<: *bt_default_depends disable: diff --git a/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/CMakeLists.txt b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/CMakeLists.txt new file mode 100644 index 0000000000..ea7d4a20a9 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/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(ble_acl_latency_cent) diff --git a/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/README.md b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/README.md new file mode 100644 index 0000000000..4cb1e830c3 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/README.md @@ -0,0 +1,190 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | + +# ESP-IDF BLE ACL Latency Test - Central + +This example demonstrates how to measure BLE ACL (Asynchronous Connection-Less) link latency. The central device scans for the peripheral, connects to it, and then performs a latency test by sending packets and measuring the round-trip time (RTT). + +This demo should be used together with the `periph` (peripheral) example. + +## How It Works + +1. The central scans for a device named `ESP_ACL_LATENCY` +2. Upon finding the peripheral, it connects and performs MTU exchange +3. After enabling notifications, the central sends 100 test packets (242 bytes each) +4. For each packet, the central records the send time +5. When the echoed packet is received via notification, it calculates RTT +6. Finally, statistics (average, min, max latency, packet loss) are printed + +## Test Flow Diagram + +``` + ┌──────────────┐ ┌──────────────┐ + │ Central │ │ Peripheral │ + │ (GATT Client)│ │ (GATT Server)│ + └──────┬───────┘ └──────┬───────┘ + │ │ + │ ──────────── Connection Setup ─────────── │ + │ │ + │ 1. Scan for "ESP_ACL_LATENCY" │ + │ ─────────────────────────────────────────> │ Advertising + │ │ + │ 2. Connect Request │ + │ ─────────────────────────────────────────> │ + │ │ + │ 3. Connection Established │ + │ <─────────────────────────────────────────> │ + │ │ + │ 4. MTU Exchange (517 bytes) │ + │ <─────────────────────────────────────────> │ + │ │ + │ 5. Connection Parameter Update (7.5ms) │ + │ <─────────────────────────────────────────> │ + │ │ + │ 6. Service Discovery │ + │ ─────────────────────────────────────────> │ + │ │ + │ 7. Enable Notification (CCCD) │ + │ ─────────────────────────────────────────> │ + │ │ + │ ──────────── Latency Test ───────────── │ + │ │ + │ 8. Write Test Packet [SEQ=0] ──┐ │ + │ Record send_time t1│ │ + │ ─────────────────────────────────────────> │ + │ │ │ Echo back + │ 9. Notification [SEQ=0] │ │ via Notify + │ Record recv_time t2│ │ + │ <───────────────────────────────────────── │ + │ │ │ + │ RTT = t2 - t1 ──┘ │ + │ Latency = RTT / 2 │ + │ │ + │ ... Repeat for SEQ 1-99 ... │ + │ │ + │ 10. Print Statistics │ + │ - Average/Min/Max Latency │ + │ - Packet Loss Rate │ + │ │ + ┌──────┴───────┐ ┌──────┴───────┐ + │ Central │ │ Peripheral │ + └──────────────┘ └──────────────┘ +``` + +## Test Configuration + +The following parameters can be modified in `gattc_latency.h`: + +| Parameter | Default Value | Description | +|------------------------|---------------|------------------------------------| +| TEST_PACKET_COUNT | 100 | Number of test packets to send | +| TEST_PACKET_INTERVAL_MS| 20 | Interval between packets (ms) | + +## How to Use Example + +### Hardware Required + +* Two development boards with supported SoC (e.g., ESP32-C3-DevKitC, ESP32-DevKitC, etc.) +* Two USB cables for power supply and programming + +See [Development Boards](https://www.espressif.com/en/products/devkits) for more information. + +### Configure the Project + +Before project configuration and build, be sure to set the correct chip target using: + +```bash +idf.py set-target +``` + +### Build and Flash + +1. First, flash the `periph` example to one board: + +```bash +cd ../periph +idf.py -p PORT1 flash +``` + +2. Then, flash this `cent` example to another board: + +```bash +cd ../cent +idf.py -p PORT2 flash +``` + +### Monitor + +Run `idf.py -p PORT monitor` to view the serial output of the central device. + +(To exit the serial monitor, type `Ctrl-]`.) + +See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +``` +I (362) BLE_ACL_LATENCY_CENT: BLE ACL Latency Test - Central +I (372) phy_init: phy_version 310,dde1ba9,Jun 4 2024,16:38:11 +I (432) BLE_ACL_LATENCY_CENT: REG_EVT +I (442) BLE_ACL_LATENCY_CENT: scan start success +I (442) BLE_ACL_LATENCY_CENT: Central initialized, scanning for peripheral... +I (622) BLE_ACL_LATENCY_CENT: searched device ESP_ACL_LATENCY +I (622) BLE_ACL_LATENCY_CENT: connect to the remote device. +I (622) BLE_ACL_LATENCY_CENT: stop scan successfully +I (892) BLE_ACL_LATENCY_CENT: ESP_GATTC_CONNECT_EVT conn_id 0, if 4 +I (892) BLE_ACL_LATENCY_CENT: REMOTE BDA: 58:cf:79:ea:77:30 +I (892) BLE_ACL_LATENCY_CENT: open success +I (1042) BLE_ACL_LATENCY_CENT: update connection params status = 0, min_int = 6, max_int = 6,conn_int = 6,latency = 0, timeout = 500 +I (1112) BLE_ACL_LATENCY_CENT: discover service complete conn_id 0 +I (1112) BLE_ACL_LATENCY_CENT: service found +I (1122) BLE_ACL_LATENCY_CENT: ESP_GATTC_CFG_MTU_EVT, Status 0, MTU 517, conn_id 0 +I (1132) BLE_ACL_LATENCY_CENT: ESP_GATTC_REG_FOR_NOTIFY_EVT +I (1172) BLE_ACL_LATENCY_CENT: write descr success +I (1172) BLE_ACL_LATENCY_CENT: Initializing latency test... +I (1172) LATENCY_TEST: Latency test initialized, conn_id=0, handle=42 +I (2182) BLE_ACL_LATENCY_CENT: Starting latency test... +I (2182) LATENCY_TEST: ==================================== +I (2182) LATENCY_TEST: Starting latency test... +I (2182) LATENCY_TEST: Packets: 100, Interval: 20 ms +I (2182) LATENCY_TEST: ==================================== +SEQ= 0, RTT= 20040 us, Latency= 10020 us (10.02 ms) +SEQ= 1, RTT= 18341 us, Latency= 9170 us (9.17 ms) +SEQ= 2, RTT= 13339 us, Latency= 6669 us (6.67 ms) +... +SEQ= 99, RTT= 15835 us, Latency= 7917 us (7.92 ms) +I (4192) LATENCY_TEST: All packets sent, waiting for responses... +I (6192) LATENCY_TEST: +I (6192) LATENCY_TEST: ======================================== +I (6192) LATENCY_TEST: Test Results Summary +I (6192) LATENCY_TEST: ======================================== +I (6192) LATENCY_TEST: Total packets: 100 +I (6202) LATENCY_TEST: Received: 100 +I (6202) LATENCY_TEST: Lost: 0 (0.0%) +I (6202) LATENCY_TEST: ---------------------------------------- +I (6212) LATENCY_TEST: Average latency: 7929 us (7.93 ms) +I (6222) LATENCY_TEST: Min latency: 6667 us (6.67 ms) +I (6222) LATENCY_TEST: Max latency: 10020 us (10.02 ms) +I (6232) LATENCY_TEST: ======================================== +``` + +## Connection Parameters + +The example uses optimized connection parameters for low latency: + +| Parameter | Value | Description | +|---------------------|----------|--------------------------------| +| Connection Interval | 7.5 ms | Minimum allowed by BLE spec | +| Slave Latency | 0 | No skipped connection events | +| Supervision Timeout | 4000 ms | Connection timeout | +| MTU | 517 | Maximum ATT MTU | + +## Understanding the Results + +- **RTT (Round-Trip Time)**: Time from sending a packet until receiving the echo +- **Latency**: Estimated one-way delay (RTT / 2) +- **Expected Results**: With 7.5ms connection interval, typical latency is 6-10ms + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/CMakeLists.txt b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/CMakeLists.txt new file mode 100644 index 0000000000..3b695c9c7e --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "gattc_latency_demo.c" "latency_test.c" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/gattc_latency.h b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/gattc_latency.h new file mode 100644 index 0000000000..ddd9c5409a --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/gattc_latency.h @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef H_GATTC_LATENCY_ +#define H_GATTC_LATENCY_ + +#include "esp_gattc_api.h" +#include "esp_gap_ble_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Service and Characteristic UUIDs - must match peripheral */ +#define REMOTE_SERVICE_UUID 0x1234 +#define REMOTE_CHAR_UUID 0x5678 + +/* Profile ID */ +#define PROFILE_APP_ID 0 +#define INVALID_HANDLE 0 + +/* Remote device name */ +#define REMOTE_DEVICE_NAME "ESP_ACL_LATENCY" + +/* Test configuration */ +#define TEST_PACKET_COUNT 100 +#define TEST_PACKET_INTERVAL_MS 20 + +/* Test packet structure */ +typedef struct { + uint16_t seq_num; + uint8_t payload[240]; +} __attribute__((packed)) test_packet_t; + +/* Latency record */ +typedef struct { + uint16_t seq; + int64_t send_time_us; + int64_t recv_time_us; + bool received; +} latency_record_t; + +/* Latency test functions */ +void latency_test_init(uint16_t conn_id, uint16_t char_handle); +void latency_test_start(void); +void latency_test_handle_notify(uint8_t *data, uint16_t len); +void latency_test_print_results(void); + +#ifdef __cplusplus +} +#endif + +#endif /* H_GATTC_LATENCY_ */ diff --git a/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/gattc_latency_demo.c b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/gattc_latency_demo.c new file mode 100644 index 0000000000..09bd9ee5ee --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/gattc_latency_demo.c @@ -0,0 +1,480 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include +#include "nvs.h" +#include "nvs_flash.h" + +#include "esp_bt.h" +#include "esp_gap_ble_api.h" +#include "esp_gattc_api.h" +#include "esp_gatt_defs.h" +#include "esp_bt_main.h" +#include "esp_gatt_common_api.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "gattc_latency.h" + +#define GATTC_TAG "BLE_ACL_LATENCY_CENT" + +#define PROFILE_NUM 1 +#define PROFILE_APP_ID 0 + +static bool connect = false; +static bool get_server = false; +static esp_gattc_char_elem_t *char_elem_result = NULL; +static esp_gattc_descr_elem_t *descr_elem_result = NULL; + +/* Declare static functions */ +static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param); +static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param); +static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param); + +/* Extern function */ +extern void latency_test_set_gattc_if(esp_gatt_if_t gattc_if); + +static esp_bt_uuid_t remote_filter_service_uuid = { + .len = ESP_UUID_LEN_16, + .uuid = {.uuid16 = REMOTE_SERVICE_UUID,}, +}; + +static esp_bt_uuid_t remote_filter_char_uuid = { + .len = ESP_UUID_LEN_16, + .uuid = {.uuid16 = REMOTE_CHAR_UUID,}, +}; + +static esp_bt_uuid_t notify_descr_uuid = { + .len = ESP_UUID_LEN_16, + .uuid = {.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG,}, +}; + +static esp_ble_scan_params_t ble_scan_params = { + .scan_type = BLE_SCAN_TYPE_ACTIVE, + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, + .scan_interval = ESP_BLE_GAP_SCAN_ITVL_MS(50), // 50ms + .scan_window = ESP_BLE_GAP_SCAN_WIN_MS(30), // 30ms + .scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE +}; + +struct gattc_profile_inst { + esp_gattc_cb_t gattc_cb; + uint16_t gattc_if; + uint16_t app_id; + uint16_t conn_id; + uint16_t service_start_handle; + uint16_t service_end_handle; + uint16_t char_handle; + esp_bd_addr_t remote_bda; +}; + +static struct gattc_profile_inst gl_profile_tab[PROFILE_NUM] = { + [PROFILE_APP_ID] = { + .gattc_cb = gattc_profile_event_handler, + .gattc_if = ESP_GATT_IF_NONE, + }, +}; + +static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) +{ + esp_ble_gattc_cb_param_t *p_data = (esp_ble_gattc_cb_param_t *)param; + + switch (event) { + case ESP_GATTC_REG_EVT: + ESP_LOGI(GATTC_TAG, "REG_EVT"); + gl_profile_tab[PROFILE_APP_ID].gattc_if = gattc_if; + esp_err_t scan_ret = esp_ble_gap_set_scan_params(&ble_scan_params); + if (scan_ret){ + ESP_LOGE(GATTC_TAG, "set scan params error, error code = %x", scan_ret); + } + break; + case ESP_GATTC_CONNECT_EVT:{ + ESP_LOGI(GATTC_TAG, "ESP_GATTC_CONNECT_EVT conn_id %d, if %d", p_data->connect.conn_id, gattc_if); + gl_profile_tab[PROFILE_APP_ID].conn_id = p_data->connect.conn_id; + memcpy(gl_profile_tab[PROFILE_APP_ID].remote_bda, p_data->connect.remote_bda, sizeof(esp_bd_addr_t)); + ESP_LOGI(GATTC_TAG, "REMOTE BDA: %02x:%02x:%02x:%02x:%02x:%02x", + p_data->connect.remote_bda[0], p_data->connect.remote_bda[1], + p_data->connect.remote_bda[2], p_data->connect.remote_bda[3], + p_data->connect.remote_bda[4], p_data->connect.remote_bda[5]); + + /* Update connection parameters to minimum interval (7.5ms) for lower latency */ + esp_ble_conn_update_params_t conn_params = {0}; + memcpy(conn_params.bda, p_data->connect.remote_bda, sizeof(esp_bd_addr_t)); + conn_params.min_int = ESP_BLE_GAP_CONN_ITVL_MS(7.5); // 7.5ms - minimum allowed + conn_params.max_int = ESP_BLE_GAP_CONN_ITVL_MS(7.5); // 7.5ms - minimum allowed + conn_params.latency = 0; + conn_params.timeout = ESP_BLE_GAP_SUPERVISION_TIMEOUT_MS(4000); // 4s + esp_ble_gap_update_conn_params(&conn_params); + + esp_err_t mtu_ret = esp_ble_gattc_send_mtu_req (gattc_if, p_data->connect.conn_id); + if (mtu_ret){ + ESP_LOGE(GATTC_TAG, "config MTU error, error code = %x", mtu_ret); + } + break; + } + case ESP_GATTC_OPEN_EVT: + if (param->open.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "open failed, status %d", p_data->open.status); + break; + } + ESP_LOGI(GATTC_TAG, "open success"); + break; + case ESP_GATTC_DIS_SRVC_CMPL_EVT: + if (param->dis_srvc_cmpl.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "discover service failed, status %d", param->dis_srvc_cmpl.status); + break; + } + ESP_LOGI(GATTC_TAG, "discover service complete conn_id %d", param->dis_srvc_cmpl.conn_id); + esp_ble_gattc_search_service(gattc_if, param->cfg_mtu.conn_id, &remote_filter_service_uuid); + break; + case ESP_GATTC_CFG_MTU_EVT: + if (param->cfg_mtu.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG,"config mtu failed, error status = %x", param->cfg_mtu.status); + } + ESP_LOGI(GATTC_TAG, "ESP_GATTC_CFG_MTU_EVT, Status %d, MTU %d, conn_id %d", param->cfg_mtu.status, param->cfg_mtu.mtu, param->cfg_mtu.conn_id); + break; + case ESP_GATTC_SEARCH_RES_EVT: { + ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x is primary service %d", p_data->search_res.conn_id, p_data->search_res.is_primary); + ESP_LOGI(GATTC_TAG, "start handle %d end handle %d current handle value %d", p_data->search_res.start_handle, p_data->search_res.end_handle, p_data->search_res.srvc_id.inst_id); + if (p_data->search_res.srvc_id.uuid.len == ESP_UUID_LEN_16 && p_data->search_res.srvc_id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) { + ESP_LOGI(GATTC_TAG, "service found"); + get_server = true; + gl_profile_tab[PROFILE_APP_ID].service_start_handle = p_data->search_res.start_handle; + gl_profile_tab[PROFILE_APP_ID].service_end_handle = p_data->search_res.end_handle; + ESP_LOGI(GATTC_TAG, "UUID16: %x", p_data->search_res.srvc_id.uuid.uuid.uuid16); + } + break; + } + case ESP_GATTC_SEARCH_CMPL_EVT: + if (p_data->search_cmpl.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "search service failed, error status = %x", p_data->search_cmpl.status); + break; + } + if(p_data->search_cmpl.searched_service_source == ESP_GATT_SERVICE_FROM_REMOTE_DEVICE) { + ESP_LOGI(GATTC_TAG, "Get service information from remote device"); + } else if (p_data->search_cmpl.searched_service_source == ESP_GATT_SERVICE_FROM_NVS_FLASH) { + ESP_LOGI(GATTC_TAG, "Get service information from flash"); + } else { + ESP_LOGI(GATTC_TAG, "unknown service source"); + } + ESP_LOGI(GATTC_TAG, "ESP_GATTC_SEARCH_CMPL_EVT"); + if (get_server){ + uint16_t count = 0; + esp_gatt_status_t status = esp_ble_gattc_get_attr_count( gattc_if, + p_data->search_cmpl.conn_id, + ESP_GATT_DB_CHARACTERISTIC, + gl_profile_tab[PROFILE_APP_ID].service_start_handle, + gl_profile_tab[PROFILE_APP_ID].service_end_handle, + INVALID_HANDLE, + &count); + if (status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error"); + break; + } + + if (count > 0){ + char_elem_result = (esp_gattc_char_elem_t *)malloc(sizeof(esp_gattc_char_elem_t) * count); + if (!char_elem_result){ + ESP_LOGE(GATTC_TAG, "gattc no mem"); + break; + }else{ + status = esp_ble_gattc_get_char_by_uuid( gattc_if, + p_data->search_cmpl.conn_id, + gl_profile_tab[PROFILE_APP_ID].service_start_handle, + gl_profile_tab[PROFILE_APP_ID].service_end_handle, + remote_filter_char_uuid, + char_elem_result, + &count); + if (status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_char_by_uuid error"); + free(char_elem_result); + char_elem_result = NULL; + break; + } + + if (count > 0 && (char_elem_result[0].properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY)){ + gl_profile_tab[PROFILE_APP_ID].char_handle = char_elem_result[0].char_handle; + esp_ble_gattc_register_for_notify (gattc_if, gl_profile_tab[PROFILE_APP_ID].remote_bda, char_elem_result[0].char_handle); + } + } + free(char_elem_result); + char_elem_result = NULL; + }else{ + ESP_LOGE(GATTC_TAG, "no char found"); + } + } + break; + case ESP_GATTC_REG_FOR_NOTIFY_EVT: { + ESP_LOGI(GATTC_TAG, "ESP_GATTC_REG_FOR_NOTIFY_EVT"); + if (p_data->reg_for_notify.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "REG FOR NOTIFY failed: error status = %d", p_data->reg_for_notify.status); + }else{ + uint16_t count = 0; + uint16_t notify_en = 1; + esp_gatt_status_t ret_status = esp_ble_gattc_get_attr_count( gattc_if, + gl_profile_tab[PROFILE_APP_ID].conn_id, + ESP_GATT_DB_DESCRIPTOR, + gl_profile_tab[PROFILE_APP_ID].service_start_handle, + gl_profile_tab[PROFILE_APP_ID].service_end_handle, + gl_profile_tab[PROFILE_APP_ID].char_handle, + &count); + if (ret_status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error"); + } + if (count > 0){ + descr_elem_result = malloc(sizeof(esp_gattc_descr_elem_t) * count); + if (!descr_elem_result){ + ESP_LOGE(GATTC_TAG, "malloc error, gattc no mem"); + }else{ + ret_status = esp_ble_gattc_get_descr_by_char_handle( gattc_if, + gl_profile_tab[PROFILE_APP_ID].conn_id, + p_data->reg_for_notify.handle, + notify_descr_uuid, + descr_elem_result, + &count); + if (ret_status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_descr_by_char_handle error"); + } + if (count > 0 && descr_elem_result[0].uuid.len == ESP_UUID_LEN_16 && descr_elem_result[0].uuid.uuid.uuid16 == ESP_GATT_UUID_CHAR_CLIENT_CONFIG){ + ret_status = esp_ble_gattc_write_char_descr( gattc_if, + gl_profile_tab[PROFILE_APP_ID].conn_id, + descr_elem_result[0].handle, + sizeof(notify_en), + (uint8_t *)¬ify_en, + ESP_GATT_WRITE_TYPE_RSP, + ESP_GATT_AUTH_REQ_NONE); + } + + if (ret_status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "esp_ble_gattc_write_char_descr error"); + } + + free(descr_elem_result); + descr_elem_result = NULL; + } + } + else{ + ESP_LOGE(GATTC_TAG, "decsr not found"); + } + + } + break; + } + case ESP_GATTC_NOTIFY_EVT: + if (p_data->notify.is_notify){ + ESP_LOGD(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, receive notify value:"); + }else{ + ESP_LOGD(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, receive indicate value:"); + } + ESP_LOGD(GATTC_TAG, "Received %d bytes of data", p_data->notify.value_len); + + /* Handle latency test notification */ + latency_test_handle_notify(p_data->notify.value, p_data->notify.value_len); + break; + case ESP_GATTC_WRITE_DESCR_EVT: + if (p_data->write.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "write descr failed, error status = %x", p_data->write.status); + break; + } + ESP_LOGI(GATTC_TAG, "write descr success "); + + /* After enabling notification, initialize and start latency test */ + ESP_LOGI(GATTC_TAG, "Initializing latency test..."); + latency_test_init(gl_profile_tab[PROFILE_APP_ID].conn_id, gl_profile_tab[PROFILE_APP_ID].char_handle); + latency_test_set_gattc_if(gl_profile_tab[PROFILE_APP_ID].gattc_if); + + vTaskDelay(pdMS_TO_TICKS(1000)); + ESP_LOGI(GATTC_TAG, "Starting latency test..."); + latency_test_start(); + break; + case ESP_GATTC_SRVC_CHG_EVT: { + esp_bd_addr_t bda; + memcpy(bda, p_data->srvc_chg.remote_bda, sizeof(esp_bd_addr_t)); + ESP_LOGI(GATTC_TAG, "ESP_GATTC_SRVC_CHG_EVT, bd_addr: %02x:%02x:%02x:%02x:%02x:%02x", + bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); + break; + } + case ESP_GATTC_WRITE_CHAR_EVT: + if (p_data->write.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "write char failed, error status = %x", p_data->write.status); + break; + } + ESP_LOGD(GATTC_TAG, "write char success "); + break; + case ESP_GATTC_DISCONNECT_EVT: + connect = false; + get_server = false; + ESP_LOGI(GATTC_TAG, "ESP_GATTC_DISCONNECT_EVT, reason = %d", p_data->disconnect.reason); + break; + default: + break; + } +} + +static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) +{ + uint8_t *adv_name = NULL; + uint8_t adv_name_len = 0; + switch (event) { + case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: { + uint32_t duration = 30; + esp_ble_gap_start_scanning(duration); + break; + } + case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: + if (param->scan_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { + ESP_LOGE(GATTC_TAG, "scan start failed, error status = %x", param->scan_start_cmpl.status); + break; + } + ESP_LOGI(GATTC_TAG, "scan start success"); + + break; + case ESP_GAP_BLE_SCAN_RESULT_EVT: { + esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; + switch (scan_result->scan_rst.search_evt) { + case ESP_GAP_SEARCH_INQ_RES_EVT: + adv_name = esp_ble_resolve_adv_data_by_type(scan_result->scan_rst.ble_adv, + scan_result->scan_rst.adv_data_len, + ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); + if (adv_name != NULL) { + if (strlen(REMOTE_DEVICE_NAME) == adv_name_len && strncmp((char *)adv_name, REMOTE_DEVICE_NAME, adv_name_len) == 0) { + ESP_LOGI(GATTC_TAG, "searched device %s", REMOTE_DEVICE_NAME); + if (connect == false) { + connect = true; + ESP_LOGI(GATTC_TAG, "connect to the remote device."); + esp_ble_gap_stop_scanning(); + esp_ble_gattc_open(gl_profile_tab[PROFILE_APP_ID].gattc_if, scan_result->scan_rst.bda, scan_result->scan_rst.ble_addr_type, true); + } + } + } + break; + case ESP_GAP_SEARCH_INQ_CMPL_EVT: + break; + default: + break; + } + break; + } + + case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: + if (param->scan_stop_cmpl.status != ESP_BT_STATUS_SUCCESS){ + ESP_LOGE(GATTC_TAG, "scan stop failed, error status = %x", param->scan_stop_cmpl.status); + break; + } + ESP_LOGI(GATTC_TAG, "stop scan successfully"); + break; + + case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: + if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS){ + ESP_LOGE(GATTC_TAG, "adv stop failed, error status = %x", param->adv_stop_cmpl.status); + break; + } + ESP_LOGI(GATTC_TAG, "stop adv successfully"); + break; + case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: + ESP_LOGI(GATTC_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d", + param->update_conn_params.status, + param->update_conn_params.min_int, + param->update_conn_params.max_int, + param->update_conn_params.conn_int, + param->update_conn_params.latency, + param->update_conn_params.timeout); + break; + default: + break; + } +} + +static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) +{ + if (event == ESP_GATTC_REG_EVT) { + if (param->reg.status == ESP_GATT_OK) { + gl_profile_tab[PROFILE_APP_ID].gattc_if = gattc_if; + } else { + ESP_LOGI(GATTC_TAG, "reg app failed, app_id %04x, status %d", + param->reg.app_id, + param->reg.status); + return; + } + } + + do { + int idx; + for (idx = 0; idx < PROFILE_NUM; idx++) { + if (gattc_if == ESP_GATT_IF_NONE || gattc_if == gl_profile_tab[idx].gattc_if) { + if (gl_profile_tab[idx].gattc_cb) { + gl_profile_tab[idx].gattc_cb(event, gattc_if, param); + } + } + } + } while (0); +} + +void app_main(void) +{ + ESP_LOGI(GATTC_TAG, "BLE ACL Latency Test - Central"); + + 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 ); + + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(GATTC_TAG, "%s initialize controller failed: %s", __func__, esp_err_to_name(ret)); + return; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (ret) { + ESP_LOGE(GATTC_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret)); + return; + } + + ret = esp_bluedroid_init(); + if (ret) { + ESP_LOGE(GATTC_TAG, "%s init bluetooth failed: %s", __func__, esp_err_to_name(ret)); + return; + } + + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(GATTC_TAG, "%s enable bluetooth failed: %s", __func__, esp_err_to_name(ret)); + return; + } + + ret = esp_ble_gattc_register_callback(esp_gattc_cb); + if(ret){ + ESP_LOGE(GATTC_TAG, "%s gattc register failed, error code = %x", __func__, ret); + return; + } + + ret = esp_ble_gap_register_callback(esp_gap_cb); + if(ret){ + ESP_LOGE(GATTC_TAG, "%s gap register failed, error code = %x", __func__, ret); + return; + } + + ret = esp_ble_gattc_app_register(PROFILE_APP_ID); + if (ret){ + ESP_LOGE(GATTC_TAG, "%s gattc app register failed, error code = %x", __func__, ret); + } + esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(517); + if (local_mtu_ret){ + ESP_LOGE(GATTC_TAG, "set local MTU failed, error code = %x", local_mtu_ret); + } + + ESP_LOGI(GATTC_TAG, "Central initialized, scanning for peripheral..."); +} diff --git a/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/latency_test.c b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/latency_test.c new file mode 100644 index 0000000000..23743d9482 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/main/latency_test.c @@ -0,0 +1,261 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include "esp_log.h" +#include "esp_timer.h" +#include "esp_random.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_gattc_api.h" +#include "gattc_latency.h" + +static const char *TAG = "LATENCY_TEST"; + +/* Global variables */ +static latency_record_t records[TEST_PACKET_COUNT]; +static uint16_t test_conn_id = 0; +static uint16_t char_handle = 0; +static test_packet_t send_packets[TEST_PACKET_COUNT]; +static bool test_running = false; +static bool test_initialized = false; +static esp_gatt_if_t test_gattc_if = 0; + +/** + * Fill random data + */ +static void +fill_random_data(uint8_t *data, uint16_t len) +{ + for (int i = 0; i < len; i++) { + data[i] = esp_random() & 0xFF; + } +} + +/** + * Initialize latency test + */ +void +latency_test_init(uint16_t conn_id, uint16_t handle) +{ + test_conn_id = conn_id; + char_handle = handle; + test_running = false; + test_initialized = true; + + memset(records, 0, sizeof(records)); + memset(send_packets, 0, sizeof(send_packets)); + + ESP_LOGI(TAG, "Latency test initialized, conn_id=%d, handle=%d", conn_id, handle); +} + +/** + * Set GATT interface + */ +void +latency_test_set_gattc_if(esp_gatt_if_t gattc_if) +{ + test_gattc_if = gattc_if; +} + +/** + * Send single test packet + */ +static int +send_test_packet(uint16_t seq) +{ + if (char_handle == 0 || test_gattc_if == 0) { + ESP_LOGE(TAG, "Test not initialized"); + return -1; + } + + /* Prepare packet */ + test_packet_t *pkt = &send_packets[seq]; + pkt->seq_num = seq; + fill_random_data(pkt->payload, sizeof(pkt->payload)); + + /* Record send time */ + records[seq].seq = seq; + records[seq].send_time_us = esp_timer_get_time(); + records[seq].received = false; + + /* Send write command (write without response) */ + esp_err_t ret = esp_ble_gattc_write_char(test_gattc_if, + test_conn_id, + char_handle, + sizeof(test_packet_t), + (uint8_t *)pkt, + ESP_GATT_WRITE_TYPE_NO_RSP, + ESP_GATT_AUTH_REQ_NONE); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Write failed: %s", esp_err_to_name(ret)); + return -1; + } + + return 0; +} + +/** + * Test task + */ +static void +latency_test_task(void *arg) +{ + ESP_LOGI(TAG, "===================================="); + ESP_LOGI(TAG, "Starting latency test..."); + ESP_LOGI(TAG, "Packets: %d, Interval: %d ms", TEST_PACKET_COUNT, TEST_PACKET_INTERVAL_MS); + ESP_LOGI(TAG, "===================================="); + + test_running = true; + + /* Send all test packets */ + for (int i = 0; i < TEST_PACKET_COUNT; i++) { + int rc = send_test_packet(i); + if (rc != 0) { + ESP_LOGW(TAG, "Send failed for seq=%d", i); + } + + /* Wait interval */ + vTaskDelay(pdMS_TO_TICKS(TEST_PACKET_INTERVAL_MS)); + } + + ESP_LOGI(TAG, "All packets sent, waiting for responses..."); + + /* Wait for all responses */ + vTaskDelay(pdMS_TO_TICKS(2000)); + + /* Print results */ + latency_test_print_results(); + + test_running = false; + vTaskDelete(NULL); +} + +/** + * Start latency test + */ +void +latency_test_start(void) +{ + if (test_running) { + ESP_LOGW(TAG, "Test already running"); + return; + } + + if (!test_initialized || char_handle == 0) { + ESP_LOGE(TAG, "Test not initialized"); + return; + } + + xTaskCreate(latency_test_task, "latency_test", 4096, NULL, 5, NULL); +} + +/** + * Handle notification + */ +void +latency_test_handle_notify(uint8_t *data, uint16_t len) +{ + if (!test_running) { + return; + } + + /* Record receive time */ + int64_t recv_time = esp_timer_get_time(); + + /* Parse packet */ + if (len < sizeof(test_packet_t)) { + ESP_LOGW(TAG, "Invalid packet size: %d", len); + return; + } + + test_packet_t *recv_pkt = (test_packet_t *)data; + uint16_t seq = recv_pkt->seq_num; + + /* Validate sequence number */ + if (seq >= TEST_PACKET_COUNT) { + ESP_LOGW(TAG, "Invalid seq number: %d", seq); + return; + } + + /* Verify data consistency */ + if (memcmp(recv_pkt, &send_packets[seq], sizeof(test_packet_t)) != 0) { + ESP_LOGW(TAG, "Data mismatch for seq=%d", seq); + return; + } + + /* Record receive time */ + records[seq].recv_time_us = recv_time; + records[seq].received = true; + + /* Calculate latency */ + int64_t rtt_us = recv_time - records[seq].send_time_us; + int64_t latency_us = rtt_us / 2; + + /* Print real-time result */ + printf("SEQ=%3d, RTT=%6lld us, Latency=%6lld us (%.2f ms)\n", + seq, rtt_us, latency_us, (float)latency_us / 1000.0); +} + +/** + * Print statistics + */ +void +latency_test_print_results(void) +{ + int64_t total_latency = 0; + int64_t min_latency = INT64_MAX; + int64_t max_latency = 0; + int valid_count = 0; + int lost_count = 0; + + /* Collect statistics */ + for (int i = 0; i < TEST_PACKET_COUNT; i++) { + if (records[i].received) { + int64_t rtt = records[i].recv_time_us - records[i].send_time_us; + int64_t latency = rtt / 2; + + total_latency += latency; + valid_count++; + + if (latency < min_latency) { + min_latency = latency; + } + if (latency > max_latency) { + max_latency = latency; + } + } else { + lost_count++; + } + } + + /* Print results */ + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========================================"); + ESP_LOGI(TAG, " Test Results Summary"); + ESP_LOGI(TAG, "========================================"); + ESP_LOGI(TAG, "Total packets: %d", TEST_PACKET_COUNT); + ESP_LOGI(TAG, "Received: %d", valid_count); + ESP_LOGI(TAG, "Lost: %d (%.1f%%)", lost_count, + (float)lost_count * 100.0 / TEST_PACKET_COUNT); + + if (valid_count > 0) { + int64_t avg_latency = total_latency / valid_count; + + ESP_LOGI(TAG, "----------------------------------------"); + ESP_LOGI(TAG, "Average latency: %lld us (%.2f ms)", avg_latency, + (float)avg_latency / 1000.0); + ESP_LOGI(TAG, "Min latency: %lld us (%.2f ms)", min_latency, + (float)min_latency / 1000.0); + ESP_LOGI(TAG, "Max latency: %lld us (%.2f ms)", max_latency, + (float)max_latency / 1000.0); + } + + ESP_LOGI(TAG, "========================================"); + ESP_LOGI(TAG, ""); +} diff --git a/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/sdkconfig.defaults b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/sdkconfig.defaults new file mode 100644 index 0000000000..a218a4da6a --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/sdkconfig.defaults @@ -0,0 +1,7 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_BT_ENABLED=y +# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set +CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y +# CONFIG_BT_LE_50_FEATURE_SUPPORT is not set diff --git a/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/sdkconfig.defaults.esp32c2 b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/sdkconfig.defaults.esp32c2 new file mode 100644 index 0000000000..9759e23400 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_acl_latency/cent/sdkconfig.defaults.esp32c2 @@ -0,0 +1,13 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_IDF_TARGET="esp32c2" +CONFIG_BT_ENABLED=y +# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set +CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y +# CONFIG_BT_LE_50_FEATURE_SUPPORT is not set +CONFIG_BT_LE_HCI_EVT_BUF_SIZE=257 + +# XTAL Freq Config +CONFIG_XTAL_FREQ_26=y +CONFIG_XTAL_FREQ=26 diff --git a/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/CMakeLists.txt b/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/CMakeLists.txt new file mode 100644 index 0000000000..333d1e60c4 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/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(ble_acl_latency_periph) diff --git a/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/README.md b/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/README.md new file mode 100644 index 0000000000..3c5f102352 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/README.md @@ -0,0 +1,124 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | + +# ESP-IDF BLE ACL Latency Test - Peripheral + +This example demonstrates how to measure BLE ACL (Asynchronous Connection-Less) link latency. The peripheral acts as a GATT server that echoes back any data written to it, allowing the central device to measure round-trip time (RTT) and calculate one-way latency. + +This demo should be used together with the `cent` (central) example. + +## How It Works + +1. The peripheral advertises with the device name `ESP_ACL_LATENCY` +2. When a central device connects, the peripheral accepts the connection +3. The peripheral provides a GATT service with a characteristic that supports both write and notify +4. When data is written to the characteristic, the peripheral immediately echoes it back via notification +5. The central measures the time between sending and receiving to calculate RTT and latency + +## Test Flow Diagram + +``` + ┌──────────────┐ ┌──────────────┐ + │ Central │ │ Peripheral │ + │ (GATT Client)│ │ (GATT Server)│ + └──────┬───────┘ └──────┬───────┘ + │ │ + │ │ Advertising + │ │ "ESP_ACL_LATENCY" + │ Scan & Connect │ + │ ─────────────────────────────────────────> │ + │ │ + │ Connection Established │ + │ <─────────────────────────────────────────> │ + │ │ + │ MTU Exchange, Service Discovery │ + │ <─────────────────────────────────────────> │ + │ │ + │ ──────────── Latency Test ───────────── │ + │ │ + │ Write [SEQ=N, 242 bytes] │ + │ ─────────────────────────────────────────> │ + │ ┌───────┴───────┐ + │ │ Echo the same │ + │ │ data back via │ + │ │ Notification │ + │ └───────┬───────┘ + │ Notification [SEQ=N, 242 bytes] │ + │ <───────────────────────────────────────── │ + │ │ + │ ... Repeat for 100 packets ... │ + │ │ + ┌──────┴───────┐ ┌──────┴───────┐ + │ Central │ │ Peripheral │ + └──────────────┘ └──────────────┘ + + ┌─────────────────────────────────┐ + │ Latency Calculation │ + ├─────────────────────────────────┤ + │ RTT = recv_time - send_time │ + │ One-way Latency = RTT / 2 │ + │ Typical Result: 6-10 ms │ + └─────────────────────────────────┘ +``` + +## How to Use Example + +### Hardware Required + +* Two development boards with supported SoC (e.g., ESP32-C3-DevKitC, ESP32-DevKitC, etc.) +* Two USB cables for power supply and programming + +See [Development Boards](https://www.espressif.com/en/products/devkits) for more information. + +### Configure the Project + +Before project configuration and build, be sure to set the correct chip target using: + +```bash +idf.py set-target +``` + +### Build and Flash + +Build the project and flash it to the board: + +```bash +idf.py -p PORT flash +``` + +(Replace PORT with the serial port name, e.g., `/dev/ttyUSB0` on Linux or `COM3` on Windows) + +### Monitor + +Run `idf.py -p PORT monitor` to view the serial output. + +(To exit the serial monitor, type `Ctrl-]`.) + +See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +``` +I (362) BLE_ACL_LATENCY_PERIPH: BLE ACL Latency Test - Peripheral +I (372) phy_init: phy_version 310,dde1ba9,Jun 4 2024,16:38:11 +I (432) BLE_ACL_LATENCY_PERIPH: GATT server register, status=0, app_id=0 +I (442) BLE_ACL_LATENCY_PERIPH: Create attribute table successfully, the number handle=4 +I (442) BLE_ACL_LATENCY_PERIPH: SERVICE_START_EVT, status=0, service_handle=40 +I (452) BLE_ACL_LATENCY_PERIPH: Advertising started +I (462) BLE_ACL_LATENCY_PERIPH: Peripheral ready, waiting for connection... +I (5532) BLE_ACL_LATENCY_PERIPH: ESP_GATTS_CONNECT_EVT, conn_id=0, remote 7c:df:a1:66:a6:00 +I (5892) BLE_ACL_LATENCY_PERIPH: MTU exchange, MTU=517 +I (5912) BLE_ACL_LATENCY_PERIPH: Connection params updated: status=0, conn_int=6, latency=0, timeout=500 +``` + +## GATT Service Structure + +| Attribute | UUID | Properties | Description | +|-----------|--------|-------------------|---------------------------------| +| Service | 0x1234 | - | Latency test service | +| Char | 0x5678 | Write, Notify | Write data, receive echo back | +| CCCD | 0x2902 | Read, Write | Client Characteristic Config | + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/main/CMakeLists.txt b/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/main/CMakeLists.txt new file mode 100644 index 0000000000..5c6ae4829f --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "gatts_latency_demo.c" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/main/gatts_latency.h b/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/main/gatts_latency.h new file mode 100644 index 0000000000..be0ca817aa --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/main/gatts_latency.h @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef H_GATTS_LATENCY_ +#define H_GATTS_LATENCY_ + +#include "esp_gatts_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Service UUID */ +#define LATENCY_SERVICE_UUID 0x1234 +#define LATENCY_CHAR_UUID 0x5678 + +/* Profile ID */ +#define PROFILE_APP_ID 0 + +/* Handle table */ +enum { + LATENCY_IDX_SVC, + LATENCY_IDX_CHAR, + LATENCY_IDX_CHAR_VAL, + LATENCY_IDX_CHAR_CFG, + + LATENCY_IDX_NB, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* H_GATTS_LATENCY_ */ diff --git a/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/main/gatts_latency_demo.c b/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/main/gatts_latency_demo.c new file mode 100644 index 0000000000..c0e9cab82c --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/main/gatts_latency_demo.c @@ -0,0 +1,360 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "esp_bt.h" + +#include "esp_gap_ble_api.h" +#include "esp_gatts_api.h" +#include "esp_bt_main.h" +#include "esp_gatt_common_api.h" +#include "gatts_latency.h" + +#define GATTS_TAG "BLE_ACL_LATENCY_PERIPH" + +#define DEVICE_NAME "ESP_ACL_LATENCY" +#define GATTS_NUM_HANDLE 4 + +static uint8_t adv_config_done = 0; +#define adv_config_flag (1 << 0) +#define scan_rsp_config_flag (1 << 1) + +/* Advertisement data */ +static esp_ble_adv_data_t adv_data = { + .set_scan_rsp = false, + .include_name = true, + .include_txpower = false, + .min_interval = ESP_BLE_GAP_CONN_ITVL_MS(7.5), // 7.5ms (minimum) + .max_interval = ESP_BLE_GAP_CONN_ITVL_MS(20), // 20ms + .appearance = 0x00, + .manufacturer_len = 0, + .p_manufacturer_data = NULL, + .service_data_len = 0, + .p_service_data = NULL, + .service_uuid_len = 0, + .p_service_uuid = NULL, + .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT), +}; + +/* Scan response data */ +static esp_ble_adv_data_t scan_rsp_data = { + .set_scan_rsp = true, + .include_name = true, + .include_txpower = true, + .appearance = 0x00, + .manufacturer_len = 0, + .p_manufacturer_data = NULL, + .service_data_len = 0, + .p_service_data = NULL, + .service_uuid_len = 0, + .p_service_uuid = NULL, + .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT), +}; + +static esp_ble_adv_params_t adv_params = { + .adv_int_min = ESP_BLE_GAP_ADV_ITVL_MS(20), // 20ms + .adv_int_max = ESP_BLE_GAP_ADV_ITVL_MS(40), // 40ms + .adv_type = ADV_TYPE_IND, + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .channel_map = ADV_CHNL_ALL, + .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, +}; + +struct gatts_profile_inst { + esp_gatts_cb_t gatts_cb; + uint16_t gatts_if; + uint16_t app_id; + uint16_t conn_id; + uint16_t service_handle; + esp_gatt_srvc_id_t service_id; + uint16_t char_handle; + esp_bt_uuid_t char_uuid; + esp_gatt_perm_t perm; + esp_gatt_char_prop_t property; + uint16_t descr_handle; + esp_bt_uuid_t descr_uuid; +}; + +static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); + +/* One gatt-based profile one app_id and one gatts_if, this array will store the gatts_if returned by ESP_GATTS_REG_EVT */ +#define PROFILE_NUM 1 +#define PROFILE_APP_IDX 0 + +static struct gatts_profile_inst gl_profile_tab[PROFILE_NUM] = { + [PROFILE_APP_IDX] = { + .gatts_cb = gatts_profile_event_handler, + .gatts_if = ESP_GATT_IF_NONE, + }, +}; + +/* Service */ +static const uint16_t GATTS_SERVICE_UUID = LATENCY_SERVICE_UUID; +static const uint16_t GATTS_CHAR_UUID = LATENCY_CHAR_UUID; + +static const uint16_t primary_service_uuid = ESP_GATT_UUID_PRI_SERVICE; +static const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE; +static const uint16_t character_client_config_uuid = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; +static const uint8_t char_prop_write_notify = ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY; +static uint8_t char_ccc[2] = {0x00, 0x00}; + +/* Full Database Description - Used to add attributes into the database */ +static const esp_gatts_attr_db_t gatt_db[LATENCY_IDX_NB] = +{ + /* Service Declaration */ + [LATENCY_IDX_SVC] = + {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ, + sizeof(uint16_t), sizeof(GATTS_SERVICE_UUID), (uint8_t *)&GATTS_SERVICE_UUID}}, + + /* Characteristic Declaration */ + [LATENCY_IDX_CHAR] = + {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, + sizeof(uint8_t), sizeof(uint8_t), (uint8_t *)&char_prop_write_notify}}, + + /* Characteristic Value */ + [LATENCY_IDX_CHAR_VAL] = + {{ESP_GATT_RSP_BY_APP}, {ESP_UUID_LEN_16, (uint8_t *)&GATTS_CHAR_UUID, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, + 512, 0, NULL}}, + + /* Client Characteristic Configuration Descriptor */ + [LATENCY_IDX_CHAR_CFG] = + {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, + sizeof(uint16_t), sizeof(char_ccc), (uint8_t *)char_ccc}}, +}; + +static uint16_t handle_table[LATENCY_IDX_NB]; + +static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) +{ + switch (event) { + case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: + adv_config_done &= (~adv_config_flag); + if (adv_config_done == 0){ + esp_ble_gap_start_advertising(&adv_params); + } + break; + case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT: + adv_config_done &= (~scan_rsp_config_flag); + if (adv_config_done == 0){ + esp_ble_gap_start_advertising(&adv_params); + } + break; + case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: + if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { + ESP_LOGE(GATTS_TAG, "Advertising start failed"); + } else { + ESP_LOGI(GATTS_TAG, "Advertising started"); + } + break; + case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: + if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) { + ESP_LOGE(GATTS_TAG, "Advertising stop failed"); + } else { + ESP_LOGI(GATTS_TAG, "Advertising stopped"); + } + break; + case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: + ESP_LOGI(GATTS_TAG, "Connection params updated: status=%d, conn_int=%d, latency=%d, timeout=%d", + param->update_conn_params.status, + param->update_conn_params.conn_int, + param->update_conn_params.latency, + param->update_conn_params.timeout); + break; + default: + break; + } +} + +static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) +{ + switch (event) { + case ESP_GATTS_REG_EVT:{ + ESP_LOGI(GATTS_TAG, "GATT server register, status=%d, app_id=%d", param->reg.status, param->reg.app_id); + gl_profile_tab[PROFILE_APP_IDX].service_id.is_primary = true; + gl_profile_tab[PROFILE_APP_IDX].service_id.id.inst_id = 0x00; + gl_profile_tab[PROFILE_APP_IDX].service_id.id.uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_APP_IDX].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID; + + esp_err_t set_dev_name_ret = esp_ble_gap_set_device_name(DEVICE_NAME); + if (set_dev_name_ret){ + ESP_LOGE(GATTS_TAG, "Set device name failed, error code = %x", set_dev_name_ret); + } + + esp_err_t ret = esp_ble_gap_config_adv_data(&adv_data); + if (ret){ + ESP_LOGE(GATTS_TAG, "Config adv data failed, error code = %x", ret); + } + adv_config_done |= adv_config_flag; + + ret = esp_ble_gap_config_adv_data(&scan_rsp_data); + if (ret){ + ESP_LOGE(GATTS_TAG, "Config scan response data failed, error code = %x", ret); + } + adv_config_done |= scan_rsp_config_flag; + + esp_err_t create_attr_ret = esp_ble_gatts_create_attr_tab(gatt_db, gatts_if, LATENCY_IDX_NB, 0); + if (create_attr_ret){ + ESP_LOGE(GATTS_TAG, "Create attr table failed, error code = %x", create_attr_ret); + } + } + break; + case ESP_GATTS_READ_EVT: + ESP_LOGD(GATTS_TAG, "ESP_GATTS_READ_EVT"); + break; + case ESP_GATTS_WRITE_EVT: + if (!param->write.is_prep){ + ESP_LOGD(GATTS_TAG, "GATT_WRITE_EVT, handle=%d, value len=%d", param->write.handle, param->write.len); + + if (handle_table[LATENCY_IDX_CHAR_VAL] == param->write.handle) { + /* Echo the data back via notification */ + esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, handle_table[LATENCY_IDX_CHAR_VAL], + param->write.len, param->write.value, false); + } + } + break; + case ESP_GATTS_EXEC_WRITE_EVT: + case ESP_GATTS_MTU_EVT: + ESP_LOGI(GATTS_TAG, "MTU exchange, MTU=%d", param->mtu.mtu); + break; + case ESP_GATTS_CONF_EVT: + break; + case ESP_GATTS_START_EVT: + ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status=%d, service_handle=%d", param->start.status, param->start.service_handle); + break; + case ESP_GATTS_CONNECT_EVT: + ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONNECT_EVT, conn_id=%d, remote "ESP_BD_ADDR_STR"", + param->connect.conn_id, ESP_BD_ADDR_HEX(param->connect.remote_bda)); + gl_profile_tab[PROFILE_APP_IDX].conn_id = param->connect.conn_id; + break; + case ESP_GATTS_DISCONNECT_EVT: + ESP_LOGI(GATTS_TAG, "ESP_GATTS_DISCONNECT_EVT, reason=0x%x", param->disconnect.reason); + esp_ble_gap_start_advertising(&adv_params); + break; + case ESP_GATTS_CREAT_ATTR_TAB_EVT:{ + if (param->add_attr_tab.status != ESP_GATT_OK){ + ESP_LOGE(GATTS_TAG, "Create attribute table failed, error code=0x%x", param->add_attr_tab.status); + } + else if (param->add_attr_tab.num_handle != LATENCY_IDX_NB){ + ESP_LOGE(GATTS_TAG, "Create attribute table abnormally, num_handle (%d) \ + doesn't equal to LATENCY_IDX_NB(%d)", param->add_attr_tab.num_handle, LATENCY_IDX_NB); + } + else { + ESP_LOGI(GATTS_TAG, "Create attribute table successfully, the number handle=%d",param->add_attr_tab.num_handle); + memcpy(handle_table, param->add_attr_tab.handles, sizeof(handle_table)); + esp_ble_gatts_start_service(handle_table[LATENCY_IDX_SVC]); + } + break; + } + case ESP_GATTS_STOP_EVT: + case ESP_GATTS_OPEN_EVT: + case ESP_GATTS_CANCEL_OPEN_EVT: + case ESP_GATTS_CLOSE_EVT: + case ESP_GATTS_LISTEN_EVT: + case ESP_GATTS_CONGEST_EVT: + case ESP_GATTS_UNREG_EVT: + case ESP_GATTS_DELETE_EVT: + default: + break; + } +} + +static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) +{ + if (event == ESP_GATTS_REG_EVT) { + if (param->reg.status == ESP_GATT_OK) { + gl_profile_tab[PROFILE_APP_IDX].gatts_if = gatts_if; + } else { + ESP_LOGE(GATTS_TAG, "Reg app failed, app_id %04x, status %d", + param->reg.app_id, + param->reg.status); + return; + } + } + do { + int idx; + for (idx = 0; idx < PROFILE_NUM; idx++) { + if (gatts_if == ESP_GATT_IF_NONE || gatts_if == gl_profile_tab[idx].gatts_if) { + if (gl_profile_tab[idx].gatts_cb) { + gl_profile_tab[idx].gatts_cb(event, gatts_if, param); + } + } + } + } while (0); +} + +void app_main(void) +{ + esp_err_t ret; + + ESP_LOGI(GATTS_TAG, "BLE ACL Latency Test - Peripheral"); + + /* Initialize NVS */ + 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); + + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(GATTS_TAG, "%s initialize controller failed: %s", __func__, esp_err_to_name(ret)); + return; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (ret) { + ESP_LOGE(GATTS_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret)); + return; + } + + ret = esp_bluedroid_init(); + if (ret) { + ESP_LOGE(GATTS_TAG, "%s init bluetooth failed: %s", __func__, esp_err_to_name(ret)); + return; + } + + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(GATTS_TAG, "%s enable bluetooth failed: %s", __func__, esp_err_to_name(ret)); + return; + } + + ret = esp_ble_gatts_register_callback(gatts_event_handler); + if (ret){ + ESP_LOGE(GATTS_TAG, "gatts register error, error code = %x", ret); + return; + } + + ret = esp_ble_gap_register_callback(gap_event_handler); + if (ret){ + ESP_LOGE(GATTS_TAG, "gap register error, error code = %x", ret); + return; + } + + ret = esp_ble_gatts_app_register(PROFILE_APP_ID); + if (ret){ + ESP_LOGE(GATTS_TAG, "gatts app register error, error code = %x", ret); + return; + } + + esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(517); + if (local_mtu_ret){ + ESP_LOGE(GATTS_TAG, "set local MTU failed, error code = %x", local_mtu_ret); + } + + ESP_LOGI(GATTS_TAG, "Peripheral ready, waiting for connection..."); +} diff --git a/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/sdkconfig.defaults b/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/sdkconfig.defaults new file mode 100644 index 0000000000..a218a4da6a --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/sdkconfig.defaults @@ -0,0 +1,7 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_BT_ENABLED=y +# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set +CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y +# CONFIG_BT_LE_50_FEATURE_SUPPORT is not set diff --git a/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/sdkconfig.defaults.esp32c2 b/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/sdkconfig.defaults.esp32c2 new file mode 100644 index 0000000000..9759e23400 --- /dev/null +++ b/examples/bluetooth/bluedroid/ble/ble_acl_latency/periph/sdkconfig.defaults.esp32c2 @@ -0,0 +1,13 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_IDF_TARGET="esp32c2" +CONFIG_BT_ENABLED=y +# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set +CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y +# CONFIG_BT_LE_50_FEATURE_SUPPORT is not set +CONFIG_BT_LE_HCI_EVT_BUF_SIZE=257 + +# XTAL Freq Config +CONFIG_XTAL_FREQ_26=y +CONFIG_XTAL_FREQ=26 From 771c74700e391262bb40fab7f4dbbd93f69e0fb6 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 7 Jan 2026 19:19:17 +0530 Subject: [PATCH 161/226] fix(nimble): Add packet sending change in case of controller only configuration --- components/bt/porting/transport/src/hci_transport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/bt/porting/transport/src/hci_transport.c b/components/bt/porting/transport/src/hci_transport.c index 9d2e0a1204..52658697ba 100644 --- a/components/bt/porting/transport/src/hci_transport.c +++ b/components/bt/porting/transport/src/hci_transport.c @@ -26,7 +26,8 @@ hci_transport_controller_packet_rx(hci_driver_data_type_t data_type, uint8_t *da r_ble_hci_trans_hs_cmd_tx(data); } -#if CONFIG_BT_BLUEDROID_ENABLED || (CONFIG_BT_NIMBLE_ENABLED && (CONFIG_BT_NIMBLE_ROLE_CENTRAL || CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)) +#if CONFIG_BT_CONTROLLER_ONLY || CONFIG_BT_BLUEDROID_ENABLED || \ + (CONFIG_BT_NIMBLE_ENABLED && (CONFIG_BT_NIMBLE_ROLE_CENTRAL || CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)) if (data_type == HCI_DRIVER_TYPE_ACL) { r_ble_hci_trans_hs_acl_tx((struct os_mbuf *) data); } From 91ba3b2d495d51c0af30575fda31f5b2aa48495b Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Fri, 27 Jun 2025 23:05:37 +0530 Subject: [PATCH 162/226] fix(esp_wifi): Add blacklist logic in roaming app --- .../wifi_apps/roaming_app/src/Kconfig.roaming | 24 ++++ .../wifi_apps/roaming_app/src/esp_roaming_i.h | 9 ++ .../wifi_apps/roaming_app/src/roaming_app.c | 125 ++++++++++++++++++ 3 files changed, 158 insertions(+) diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming b/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming index 22f641377d..3b19d8d568 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming +++ b/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming @@ -182,3 +182,27 @@ config ESP_WIFI_ROAMING_RRM_MONITOR_THRESHOLD range -99 0 help The RSSI threshold beyond which we start sending periodic neighbor report requests. + +menu "Blacklist Configuration" + config ESP_WIFI_ROAMING_AUTO_BLACKLISTING + bool "Enable automatic BSSID blacklisting" + default y + help + Enable this to automatically blacklist BSSIDs after multiple failed connection attempts. + + config ESP_WIFI_ROAMING_MAX_CONN_FAILURES + int "Maximum connection failures" + depends on ESP_WIFI_ROAMING_AUTO_BLACKLISTING + range 1 10 + default 3 + help + Maximum number of connection failures before a BSSID is blacklisted. + + config ESP_WIFI_ROAMING_BLACKLIST_TIMEOUT + int "Blacklist timeout (in seconds)" + depends on ESP_WIFI_ROAMING_AUTO_BLACKLISTING + range 10 3600 + default 300 + help + Time in seconds for which a BSSID remains in the blacklist. +endmenu # "Blacklist Configuration" diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h b/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h index 9ca515e6af..73c7d0f48f 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h +++ b/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h @@ -134,6 +134,15 @@ struct roaming_app { #endif #if PERIODIC_SCAN_MONITORING bool periodic_scan_active; +#endif +#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING + struct blacklist_entry { + uint8_t bssid[ETH_ALEN]; + uint8_t failures; + struct timeval timestamp; + }; + struct blacklist_entry bssid_blacklist[CONFIG_ESP_WIFI_ROAMING_MAX_CANDIDATES]; + uint8_t bssid_blacklist_count; #endif bool allow_reconnect; }; diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c index 40bf63a087..6fc92e0221 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c +++ b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c @@ -180,6 +180,30 @@ static void roaming_app_disconnected_event_handler(void *ctx, void *data) wifi_event_sta_disconnected_t *disconn = data; ESP_LOGD(ROAMING_TAG, "station got disconnected reason=%d", disconn->reason); +#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING + if (disconn->reason == WIFI_REASON_CONNECTION_FAIL || disconn->reason == WIFI_REASON_AUTH_FAIL) { + bool found = false; + for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { + if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, disconn->bssid, ETH_ALEN) == 0) { + g_roaming_app.bssid_blacklist[i].failures++; + gettimeofday(&g_roaming_app.bssid_blacklist[i].timestamp, NULL); + ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " connection failures: %d", MAC2STR(disconn->bssid), g_roaming_app.bssid_blacklist[i].failures); + if (g_roaming_app.bssid_blacklist[i].failures >= CONFIG_ESP_WIFI_ROAMING_MAX_CONN_FAILURES) { + ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " blacklisted", MAC2STR(disconn->bssid)); + } + found = true; + break; + } + } + if (!found && g_roaming_app.bssid_blacklist_count < CONFIG_ESP_WIFI_ROAMING_MAX_CANDIDATES) { + memcpy(g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].bssid, disconn->bssid, ETH_ALEN); + g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].failures = 1; + gettimeofday(&g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].timestamp, NULL); + g_roaming_app.bssid_blacklist_count++; + ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " added to blacklist tracking", MAC2STR(disconn->bssid)); + } + } +#endif if (disconn->reason == WIFI_REASON_ROAMING) { ESP_LOGD(ROAMING_TAG, "station roaming, do nothing"); } else if (g_roaming_app.allow_reconnect == false) { @@ -585,6 +609,50 @@ static bool candidate_profile_match(wifi_ap_record_t candidate) { return candidate_security_match(candidate); } +#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST +static bool is_bssid_blacklisted(const uint8_t *bssid) +{ + for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { + if (memcmp(g_roaming_app.bssid_blacklist[i], bssid, ETH_ALEN) == 0) { + return true; + } + } + return false; +} +#endif + +#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING +static void remove_expired_blacklist_entries(void) +{ + struct timeval now; + gettimeofday(&now, NULL); + for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { + if (time_diff_sec(&now, &g_roaming_app.bssid_blacklist[i].timestamp) > CONFIG_ESP_WIFI_ROAMING_BLACKLIST_TIMEOUT) { + ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " removed from blacklist due to timeout", MAC2STR(g_roaming_app.bssid_blacklist[i].bssid)); + for (int j = i; j < g_roaming_app.bssid_blacklist_count - 1; j++) { + g_roaming_app.bssid_blacklist[j] = g_roaming_app.bssid_blacklist[j + 1]; + } + g_roaming_app.bssid_blacklist_count--; + i--; // Decrement i to recheck the current index + } + } +} +#endif + +static bool is_bssid_blacklisted(const uint8_t *bssid) +{ +#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING + remove_expired_blacklist_entries(); + for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { + if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, bssid, ETH_ALEN) == 0 && + g_roaming_app.bssid_blacklist[i].failures >= CONFIG_ESP_WIFI_ROAMING_MAX_CONN_FAILURES) { + return true; + } + } +#endif + return false; +} + /* Remember to always call this function with the ROAM_SCAN_RESULTS_LOCK */ static void parse_scan_results_and_roam(void) { @@ -597,6 +665,10 @@ static void parse_scan_results_and_roam(void) wifi_ap_record_t ap_info; roaming_app_get_ap_info(&ap_info); for (i = 0; i < g_roaming_app.scanned_aps.current_count; i++) { + if (is_bssid_blacklisted(g_roaming_app.scanned_aps.ap_records[i].bssid)) { + ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " is blacklisted, skipping", MAC2STR(g_roaming_app.scanned_aps.ap_records[i].bssid)); + continue; + } rssi_diff = g_roaming_app.scanned_aps.ap_records[i].rssi - ap_info.rssi; ESP_LOGD(ROAMING_TAG, "The difference between ("MACSTR", "MACSTR") with rssi (%d,%d) is : %d while the threshold is %d and the best rssi diff yet is %d, thecand_auth is %d", MAC2STR(g_roaming_app.scanned_aps.ap_records[i].bssid),MAC2STR(ap_info.bssid), @@ -906,6 +978,10 @@ void roam_init_app(void) ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_NEIGHBOR_REP, &roaming_app_neighbor_report_recv_handler, NULL)); #endif /*PERIODIC_RRM_MONITORING*/ +#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING + memset(g_roaming_app.bssid_blacklist, 0, sizeof(g_roaming_app.bssid_blacklist)); + g_roaming_app.bssid_blacklist_count = 0; +#endif ESP_LOGI(ROAMING_TAG, "Roaming app initialization done"); } @@ -944,6 +1020,55 @@ void roam_deinit_app(void) } } +#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST +esp_err_t esp_wifi_blacklist_add(const uint8_t *bssid) +{ + if (!bssid) { + return ESP_ERR_INVALID_ARG; + } + if (g_roaming_app.bssid_blacklist_count >= CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST_COUNT) { + ESP_LOGE(ROAMING_TAG, "Blacklist is full"); + return ESP_ERR_NO_MEM; + } + for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { + if (memcmp(g_roaming_app.bssid_blacklist[i], bssid, ETH_ALEN) == 0) { + ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " already in blacklist", MAC2STR(bssid)); + return ESP_OK; // Already blacklisted + } + } + memcpy(g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count], bssid, ETH_ALEN); + g_roaming_app.bssid_blacklist_count++; + ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " added to blacklist", MAC2STR(bssid)); + return ESP_OK; +} + +esp_err_t esp_wifi_blacklist_remove(const uint8_t *bssid) +{ + if (!bssid) { + return ESP_ERR_INVALID_ARG; + } + int found_index = -1; + for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { + if (memcmp(g_roaming_app.bssid_blacklist[i], bssid, ETH_ALEN) == 0) { + found_index = i; + break; + } + } + + if (found_index != -1) { + // Shift elements to fill the gap + for (int i = found_index; i < g_roaming_app.bssid_blacklist_count - 1; i++) { + memcpy(g_roaming_app.bssid_blacklist[i], g_roaming_app.bssid_blacklist[i + 1], ETH_ALEN); + } + g_roaming_app.bssid_blacklist_count--; + ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " removed from blacklist", MAC2STR(bssid)); + } else { + ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " not found in blacklist", MAC2STR(bssid)); + } + return ESP_OK; +} +#endif + /* No need for this to be done in pptask ctx */ esp_err_t roam_get_config_params(struct roam_config *config) { From be1515baf34ddaebe19a5cb35263615970b1327a Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Fri, 25 Jul 2025 12:12:41 +0530 Subject: [PATCH 163/226] fix(roaming_app): resolve issues in blacklisting logic This commit addresses several issues in the BSSID blacklisting feature of the roaming application: - Merged duplicate functions into a single, unified function, resolving a compilation error. - Corrected and to properly access the member of the struct, fixing invalid memory access. - Introduced in Kconfig to enable the manual blacklisting feature and made auto-blacklisting dependent on it. - Updated to use the correct BSSID from . - Optimized the removal of expired blacklist entries by using for better efficiency. --- .../wifi_apps/roaming_app/src/Kconfig.roaming | 14 ++++++ .../wifi_apps/roaming_app/src/esp_roaming_i.h | 3 +- .../wifi_apps/roaming_app/src/roaming_app.c | 48 +++++++++---------- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming b/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming index 3b19d8d568..dd95bee9e4 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming +++ b/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming @@ -184,8 +184,15 @@ config ESP_WIFI_ROAMING_RRM_MONITOR_THRESHOLD The RSSI threshold beyond which we start sending periodic neighbor report requests. menu "Blacklist Configuration" + config ESP_WIFI_ROAMING_BSSID_BLACKLIST + bool "Enable BSSID blacklisting" + default n + help + Enable this to blacklist BSSIDs. + config ESP_WIFI_ROAMING_AUTO_BLACKLISTING bool "Enable automatic BSSID blacklisting" + depends on ESP_WIFI_ROAMING_BSSID_BLACKLIST default y help Enable this to automatically blacklist BSSIDs after multiple failed connection attempts. @@ -205,4 +212,11 @@ menu "Blacklist Configuration" default 300 help Time in seconds for which a BSSID remains in the blacklist. + + config ESP_WIFI_ROAMING_MAX_CANDIDATES + int "Maximum number of roaming candidates" + range 1 10 + default 5 + help + Maximum number of roaming candidates to consider. This also defines the size of the blacklist. endmenu # "Blacklist Configuration" diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h b/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h index 73c7d0f48f..8c8efbc2cf 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h +++ b/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h @@ -140,8 +140,7 @@ struct roaming_app { uint8_t bssid[ETH_ALEN]; uint8_t failures; struct timeval timestamp; - }; - struct blacklist_entry bssid_blacklist[CONFIG_ESP_WIFI_ROAMING_MAX_CANDIDATES]; + } bssid_blacklist[CONFIG_ESP_WIFI_ROAMING_MAX_CANDIDATES]; uint8_t bssid_blacklist_count; #endif bool allow_reconnect; diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c index 6fc92e0221..7b3cd5de62 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c +++ b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c @@ -184,23 +184,23 @@ static void roaming_app_disconnected_event_handler(void *ctx, void *data) if (disconn->reason == WIFI_REASON_CONNECTION_FAIL || disconn->reason == WIFI_REASON_AUTH_FAIL) { bool found = false; for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { - if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, disconn->bssid, ETH_ALEN) == 0) { + if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, g_roaming_app.current_bss.ap.bssid, ETH_ALEN) == 0) { g_roaming_app.bssid_blacklist[i].failures++; gettimeofday(&g_roaming_app.bssid_blacklist[i].timestamp, NULL); - ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " connection failures: %d", MAC2STR(disconn->bssid), g_roaming_app.bssid_blacklist[i].failures); + ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " connection failures: %d", MAC2STR(g_roaming_app.current_bss.ap.bssid), g_roaming_app.bssid_blacklist[i].failures); if (g_roaming_app.bssid_blacklist[i].failures >= CONFIG_ESP_WIFI_ROAMING_MAX_CONN_FAILURES) { - ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " blacklisted", MAC2STR(disconn->bssid)); + ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " blacklisted", MAC2STR(g_roaming_app.current_bss.ap.bssid)); } found = true; break; } } if (!found && g_roaming_app.bssid_blacklist_count < CONFIG_ESP_WIFI_ROAMING_MAX_CANDIDATES) { - memcpy(g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].bssid, disconn->bssid, ETH_ALEN); + memcpy(g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].bssid, g_roaming_app.current_bss.ap.bssid, ETH_ALEN); g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].failures = 1; gettimeofday(&g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].timestamp, NULL); g_roaming_app.bssid_blacklist_count++; - ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " added to blacklist tracking", MAC2STR(disconn->bssid)); + ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " added to blacklist tracking", MAC2STR(g_roaming_app.current_bss.ap.bssid)); } } #endif @@ -609,17 +609,6 @@ static bool candidate_profile_match(wifi_ap_record_t candidate) { return candidate_security_match(candidate); } -#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST -static bool is_bssid_blacklisted(const uint8_t *bssid) -{ - for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { - if (memcmp(g_roaming_app.bssid_blacklist[i], bssid, ETH_ALEN) == 0) { - return true; - } - } - return false; -} -#endif #if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING static void remove_expired_blacklist_entries(void) @@ -629,8 +618,9 @@ static void remove_expired_blacklist_entries(void) for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { if (time_diff_sec(&now, &g_roaming_app.bssid_blacklist[i].timestamp) > CONFIG_ESP_WIFI_ROAMING_BLACKLIST_TIMEOUT) { ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " removed from blacklist due to timeout", MAC2STR(g_roaming_app.bssid_blacklist[i].bssid)); - for (int j = i; j < g_roaming_app.bssid_blacklist_count - 1; j++) { - g_roaming_app.bssid_blacklist[j] = g_roaming_app.bssid_blacklist[j + 1]; + int remaining_entries = g_roaming_app.bssid_blacklist_count - i - 1; + if (remaining_entries > 0) { + memmove(&g_roaming_app.bssid_blacklist[i], &g_roaming_app.bssid_blacklist[i + 1], remaining_entries * sizeof(struct blacklist_entry)); } g_roaming_app.bssid_blacklist_count--; i--; // Decrement i to recheck the current index @@ -649,6 +639,13 @@ static bool is_bssid_blacklisted(const uint8_t *bssid) return true; } } +#endif +#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST + for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { + if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, bssid, ETH_ALEN) == 0) { + return true; + } + } #endif return false; } @@ -1026,17 +1023,19 @@ esp_err_t esp_wifi_blacklist_add(const uint8_t *bssid) if (!bssid) { return ESP_ERR_INVALID_ARG; } - if (g_roaming_app.bssid_blacklist_count >= CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST_COUNT) { + if (g_roaming_app.bssid_blacklist_count >= CONFIG_ESP_WIFI_ROAMING_MAX_CANDIDATES) { ESP_LOGE(ROAMING_TAG, "Blacklist is full"); return ESP_ERR_NO_MEM; } for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { - if (memcmp(g_roaming_app.bssid_blacklist[i], bssid, ETH_ALEN) == 0) { + if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, bssid, ETH_ALEN) == 0) { ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " already in blacklist", MAC2STR(bssid)); return ESP_OK; // Already blacklisted } } - memcpy(g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count], bssid, ETH_ALEN); + memcpy(g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].bssid, bssid, ETH_ALEN); + g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].failures = CONFIG_ESP_WIFI_ROAMING_MAX_CONN_FAILURES; + gettimeofday(&g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].timestamp, NULL); g_roaming_app.bssid_blacklist_count++; ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " added to blacklist", MAC2STR(bssid)); return ESP_OK; @@ -1049,7 +1048,7 @@ esp_err_t esp_wifi_blacklist_remove(const uint8_t *bssid) } int found_index = -1; for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { - if (memcmp(g_roaming_app.bssid_blacklist[i], bssid, ETH_ALEN) == 0) { + if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, bssid, ETH_ALEN) == 0) { found_index = i; break; } @@ -1057,8 +1056,9 @@ esp_err_t esp_wifi_blacklist_remove(const uint8_t *bssid) if (found_index != -1) { // Shift elements to fill the gap - for (int i = found_index; i < g_roaming_app.bssid_blacklist_count - 1; i++) { - memcpy(g_roaming_app.bssid_blacklist[i], g_roaming_app.bssid_blacklist[i + 1], ETH_ALEN); + int remaining_entries = g_roaming_app.bssid_blacklist_count - found_index - 1; + if (remaining_entries > 0) { + memmove(&g_roaming_app.bssid_blacklist[found_index], &g_roaming_app.bssid_blacklist[found_index + 1], remaining_entries * sizeof(struct blacklist_entry)); } g_roaming_app.bssid_blacklist_count--; ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " removed from blacklist", MAC2STR(bssid)); From 38302784c7e72b94a692a0748f7eb2a8afae95b6 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Fri, 25 Jul 2025 14:06:51 +0530 Subject: [PATCH 164/226] feat(roaming): ignore WPA2-only APs on transition disable This commit introduces a new feature to the roaming logic. If the currently connected AP has the 'transition disable' bit set in its RSN IE, the roaming logic will now ignore any scanned APs that only support WPA2-PSK. This prevents a security downgrade when roaming in a mixed WPA2/WPA3 environment. A new Kconfig option, CONFIG_ESP_WIFI_IGNORE_WPA2_ONLY_ON_TRANSITION_DISABLE, has been added to control this feature. It is disabled by default. --- .../wifi_apps/roaming_app/src/Kconfig.roaming | 9 ++++++ .../wifi_apps/roaming_app/src/roaming_app.c | 32 +++++++++++++++++++ .../esp_supplicant/src/esp_wpas_glue.c | 5 +++ .../esp_supplicant/src/esp_wpas_glue.h | 4 ++- components/wpa_supplicant/src/rsn_supp/wpa.c | 6 ++++ .../wpa_supplicant/src/rsn_supp/wpa_i.h | 3 ++ 6 files changed, 58 insertions(+), 1 deletion(-) diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming b/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming index dd95bee9e4..221dff7355 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming +++ b/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming @@ -219,4 +219,13 @@ menu "Blacklist Configuration" default 5 help Maximum number of roaming candidates to consider. This also defines the size of the blacklist. + + config ESP_WIFI_ROAMING_PREVENT_DOWNGRADE + bool "Prevent security downgrade when roaming" + default n + help + If the currently connected AP sends a "transition disable" bit, + this option will make the roaming logic ignore less secure APs. + This helps prevent security downgrades when roaming in a mixed + security environment (e.g., WPA2/WPA3). endmenu # "Blacklist Configuration" diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c index 7b3cd5de62..87182fee67 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c +++ b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c @@ -605,8 +605,40 @@ static bool candidate_security_match(wifi_ap_record_t candidate) return false; } +#include "esp_wpas_glue.h" + static bool candidate_profile_match(wifi_ap_record_t candidate) { + u8 transition_disable = wpa_supplicant_get_transition_disable(); + +#if CONFIG_ESP_WIFI_ROAMING_PREVENT_DOWNGRADE + if (transition_disable & TRANSITION_DISABLE_WPA3_PERSONAL) { + if (candidate.authmode == WIFI_AUTH_WPA2_PSK) { + return false; + } + } + if (transition_disable & TRANSITION_DISABLE_ENHANCED_OPEN) { + if (candidate.authmode == WIFI_AUTH_OPEN) { + return false; + } + } + if (transition_disable & TRANSITION_DISABLE_WPA3_ENTERPRISE) { + if (candidate.authmode == WIFI_AUTH_WPA2_ENTERPRISE) { + return false; + } + } +#if TODO // application doesn't have a way to know SAE-PK enabled AP atm + if (transition_disable & TRANSITION_DISABLE_SAE_PK) { + /* This is a simplification. A more accurate check would involve + * parsing the candidate's RSN IE to see if it supports SAE-PK. + * For now, we reject all SAE APs if SAE-PK is enforced. */ + if (candidate.authmode == WIFI_AUTH_WPA3_PSK) { + return false; + } + } +#endif +#endif + return candidate_security_match(candidate); } diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c index 948f271397..42cbbe92d8 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c @@ -189,4 +189,9 @@ void wpa_sm_disassociate(struct wpa_sm *sm, int reason_code) { /*check if need clear internal state and data value*/ } + +u8 wpa_supplicant_get_transition_disable(void) +{ + return wpa_sm_get_transition_disable(&gWpaSm); +} #endif diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h index 48ff0a6379..775c5b29f0 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -35,4 +35,6 @@ void wpa_supplicant_transition_disable(struct wpa_sm *sm, u8 bitmap); int hostapd_send_eapol(const u8 *source, const u8 *sta_addr, const u8 *data, size_t data_len); + +u8 wpa_supplicant_get_transition_disable(void); #endif /* WPAS_GLUE_H */ diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index 75fe1f5094..4dfcd00a41 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -1340,6 +1340,7 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm, if (ie.transition_disable) { wpa_supplicant_transition_disable(sm, ie.transition_disable[0]); + sm->transition_disable = ie.transition_disable[0]; } if (sm->key_install && sm->key_info & WPA_KEY_INFO_INSTALL && sm->use_ext_key_id) { @@ -1357,6 +1358,11 @@ failed: wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED); } +u8 wpa_sm_get_transition_disable(struct wpa_sm *sm) +{ + return sm->transition_disable; +} + static int wpa_supplicant_activate_ptk(struct wpa_sm *sm) { int keylen; diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_i.h b/components/wpa_supplicant/src/rsn_supp/wpa_i.h index b31aeb1e1a..b07015eede 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_i.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa_i.h @@ -86,6 +86,7 @@ struct wpa_sm { struct wpa_gtk_data gd; //used for calllback save param u16 key_info; //used for txcallback param u16 txcb_flags; + u8 transition_disable; bool ap_notify_completed_rsne; wifi_pmf_config_t pmf_cfg; u8 eapol1_count; @@ -208,6 +209,8 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher, int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len); +u8 wpa_sm_get_transition_disable(struct wpa_sm *sm); + int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, const struct wpa_eapol_key *key, struct wpa_ptk *ptk); #endif /* WPA_I_H */ From 0ef0d068db8f5d771e57b6ec6d916a91e88db7b2 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Tue, 9 Sep 2025 14:58:03 +0530 Subject: [PATCH 165/226] fix(esp_wifi): Address some review comments and issues --- .../wifi_apps/roaming_app/src/Kconfig.roaming | 12 +- .../wifi_apps/roaming_app/src/esp_roaming_i.h | 4 +- .../wifi_apps/roaming_app/src/roaming_app.c | 252 +++++++++++------- .../esp_supplicant/src/esp_wpas_glue.h | 2 + .../wpa_supplicant/src/rsn_supp/wpa_i.h | 2 + 5 files changed, 164 insertions(+), 108 deletions(-) diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming b/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming index 221dff7355..7406d9b12f 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming +++ b/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming @@ -139,13 +139,7 @@ menu "Scan Configuration" Duration for which the results from the most recent scans can be used by the roaming app for determining the roaming candidates. - config ESP_WIFI_ROAMING_MAX_CANDIDATES - int "Max Candidates in the network" - default 3 - range 3 20 - help - Max candidates that can be considered while scanning as a part of the - network at one time. + endmenu #"Scan Configuration" @@ -193,7 +187,6 @@ menu "Blacklist Configuration" config ESP_WIFI_ROAMING_AUTO_BLACKLISTING bool "Enable automatic BSSID blacklisting" depends on ESP_WIFI_ROAMING_BSSID_BLACKLIST - default y help Enable this to automatically blacklist BSSIDs after multiple failed connection attempts. @@ -207,11 +200,12 @@ menu "Blacklist Configuration" config ESP_WIFI_ROAMING_BLACKLIST_TIMEOUT int "Blacklist timeout (in seconds)" - depends on ESP_WIFI_ROAMING_AUTO_BLACKLISTING + depends on ESP_WIFI_ROAMING_BSSID_BLACKLIST range 10 3600 default 300 help Time in seconds for which a BSSID remains in the blacklist. + This applies to both automatically and manually blacklisted BSSIDs. config ESP_WIFI_ROAMING_MAX_CANDIDATES int "Maximum number of roaming candidates" diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h b/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h index 8c8efbc2cf..4afda4c0aa 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h +++ b/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h @@ -135,10 +135,12 @@ struct roaming_app { #if PERIODIC_SCAN_MONITORING bool periodic_scan_active; #endif -#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING +#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST struct blacklist_entry { uint8_t bssid[ETH_ALEN]; +#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING uint8_t failures; +#endif struct timeval timestamp; } bssid_blacklist[CONFIG_ESP_WIFI_ROAMING_MAX_CANDIDATES]; uint8_t bssid_blacklist_count; diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c index 87182fee67..7d4fc295c1 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c +++ b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c @@ -28,7 +28,10 @@ #include "utils/eloop.h" #include "rom/ets_sys.h" #include "common/ieee802_11_defs.h" -static struct roaming_app g_roaming_app; +#include "common/wpa_common.h" +#include "esp_wpas_glue.h" + +struct roaming_app g_roaming_app; typedef void (* scan_done_cb_t)(void *arg, ETS_STATUS status); extern int esp_wifi_promiscuous_scan_start(wifi_scan_config_t *config, scan_done_cb_t cb); @@ -44,6 +47,7 @@ static void *neighbor_list_lock = NULL; static int wifi_post_roam_event(struct cand_bss *bss); static void determine_best_ap(int8_t rssi_threshold); +static bool is_bssid_blacklisted(const uint8_t *bssid); #if PERIODIC_RRM_MONITORING static void roaming_app_periodic_rrm_internal_handler(void *data, void *ctx); #endif @@ -190,17 +194,34 @@ static void roaming_app_disconnected_event_handler(void *ctx, void *data) ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " connection failures: %d", MAC2STR(g_roaming_app.current_bss.ap.bssid), g_roaming_app.bssid_blacklist[i].failures); if (g_roaming_app.bssid_blacklist[i].failures >= CONFIG_ESP_WIFI_ROAMING_MAX_CONN_FAILURES) { ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " blacklisted", MAC2STR(g_roaming_app.current_bss.ap.bssid)); + /* The BSSID is now blacklisted. The logic later in this function + * will check the blacklist and trigger a scan for a new AP + * instead of trying to reconnect to this one. */ } found = true; break; } } - if (!found && g_roaming_app.bssid_blacklist_count < CONFIG_ESP_WIFI_ROAMING_MAX_CANDIDATES) { - memcpy(g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].bssid, g_roaming_app.current_bss.ap.bssid, ETH_ALEN); - g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].failures = 1; - gettimeofday(&g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].timestamp, NULL); - g_roaming_app.bssid_blacklist_count++; - ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " added to blacklist tracking", MAC2STR(g_roaming_app.current_bss.ap.bssid)); + if (!found) { + if (g_roaming_app.bssid_blacklist_count < CONFIG_ESP_WIFI_ROAMING_MAX_CANDIDATES) { + memcpy(g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].bssid, g_roaming_app.current_bss.ap.bssid, ETH_ALEN); + g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].failures = 1; + gettimeofday(&g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].timestamp, NULL); + g_roaming_app.bssid_blacklist_count++; + ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " added to blacklist tracking", MAC2STR(g_roaming_app.current_bss.ap.bssid)); + } else { + int oldest_idx = 0; + for (int i = 1; i < g_roaming_app.bssid_blacklist_count; i++) { + if (g_roaming_app.bssid_blacklist[i].timestamp.tv_sec < g_roaming_app.bssid_blacklist[oldest_idx].timestamp.tv_sec) { + oldest_idx = i; + } + } + ESP_LOGD(ROAMING_TAG, "Blacklist is full. Replacing oldest entry for " MACSTR, MAC2STR(g_roaming_app.bssid_blacklist[oldest_idx].bssid)); + memcpy(g_roaming_app.bssid_blacklist[oldest_idx].bssid, g_roaming_app.current_bss.ap.bssid, ETH_ALEN); + g_roaming_app.bssid_blacklist[oldest_idx].failures = 1; + gettimeofday(&g_roaming_app.bssid_blacklist[oldest_idx].timestamp, NULL); + ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " added to blacklist tracking", MAC2STR(g_roaming_app.current_bss.ap.bssid)); + } } } #endif @@ -209,17 +230,26 @@ static void roaming_app_disconnected_event_handler(void *ctx, void *data) } else if (g_roaming_app.allow_reconnect == false) { ESP_LOGD(ROAMING_TAG, "station initiated disconnect, do nothing"); } else { +#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST + if (is_bssid_blacklisted(g_roaming_app.current_bss.ap.bssid)) { + ESP_LOGD(ROAMING_TAG, "AP " MACSTR " is blacklisted, finding another AP", MAC2STR(g_roaming_app.current_bss.ap.bssid)); + determine_best_ap(0); + } else { +#endif #if LEGACY_ROAM_ENABLED - /* - * Resetting the Bssid param as it is possible that a previous force - * roam has set config to connect to a specific bssid and now further - * roaming attempts using BTM could lead to a spiral of connecting to - * the previous AP */ - if (g_roaming_app.force_roam_ongoing) { - legacy_roam_clear_bssid_flag(); - } + /* + * Resetting the Bssid param as it is possible that a previous force + * roam has set config to connect to a specific bssid and now further + * roaming attempts using BTM could lead to a spiral of connecting to + * the previous AP */ + if (g_roaming_app.force_roam_ongoing) { + legacy_roam_clear_bssid_flag(); + } #endif /*LEGACY_ROAM_ENABLED*/ - esp_wifi_connect(); + esp_wifi_connect(); +#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST + } +#endif } os_free(disconn); } @@ -482,7 +512,7 @@ void roaming_app_trigger_roam(struct cand_bss *bss) gettimeofday(&now, NULL); ESP_LOGD(ROAMING_TAG,"Processing trigger roaming request."); if (time_diff_sec(&now, &g_roaming_app.last_roamed_time) < g_roaming_app.config.backoff_time ) { - ESP_LOGD(ROAMING_TAG,"Ignoring request as time difference to last request is %ld",time_diff_sec(&now, &g_roaming_app.last_roamed_time)); + ESP_LOGD(ROAMING_TAG,"Ignoring request as time difference to last request is %ld",time_diff_sec(&now, &g_roaming_app.last_roamed_time)); goto free_bss; } #if NETWORK_ASSISTED_ROAMING_ENABLED @@ -516,7 +546,6 @@ void roaming_app_trigger_roam_internal_handler(void *ctx, void *data) } else { roaming_app_trigger_roam((struct cand_bss *)data); } - } static int wifi_post_roam_event(struct cand_bss *bss) @@ -553,7 +582,6 @@ void print_ap_records(struct scanned_ap_info *ap_info) } - #if PERIODIC_RRM_MONITORING static void periodic_rrm_request(struct timeval *now) { @@ -570,6 +598,35 @@ static void periodic_rrm_request(struct timeval *now) static bool candidate_security_match(wifi_ap_record_t candidate) { + u8 transition_disable = wpa_supplicant_get_transition_disable(); + +#if CONFIG_ESP_WIFI_ROAMING_PREVENT_DOWNGRADE + if (transition_disable & TRANSITION_DISABLE_WPA3_PERSONAL) { + if (candidate.authmode == WIFI_AUTH_WPA2_PSK) { + return false; + } + } + if (transition_disable & TRANSITION_DISABLE_ENHANCED_OPEN) { + if (candidate.authmode == WIFI_AUTH_OPEN) { + return false; + } + } + if (transition_disable & TRANSITION_DISABLE_WPA3_ENTERPRISE) { + if (candidate.authmode == WIFI_AUTH_WPA2_ENTERPRISE) { + return false; + } + } +#if TODO // application doesn't have a way to know SAE-PK enabled AP atm + if (transition_disable & TRANSITION_DISABLE_SAE_PK) { + /* This is a simplification. A more accurate check would involve + * parsing the candidate's RSN IE to see if it supports SAE-PK. + * For now, we reject all SAE APs if SAE-PK is enforced. */ + if (candidate.authmode == WIFI_AUTH_WPA3_PSK) { + return false; + } + } +#endif +#endif wifi_auth_mode_t curr_auth = g_roaming_app.current_bss.ap.authmode; wifi_auth_mode_t cand_auth = candidate.authmode; ESP_LOGV(ROAMING_TAG, "Cand authmode : %d, Current Authmode : %d", cand_auth, curr_auth); @@ -605,77 +662,39 @@ static bool candidate_security_match(wifi_ap_record_t candidate) return false; } -#include "esp_wpas_glue.h" - -static bool candidate_profile_match(wifi_ap_record_t candidate) -{ - u8 transition_disable = wpa_supplicant_get_transition_disable(); - -#if CONFIG_ESP_WIFI_ROAMING_PREVENT_DOWNGRADE - if (transition_disable & TRANSITION_DISABLE_WPA3_PERSONAL) { - if (candidate.authmode == WIFI_AUTH_WPA2_PSK) { - return false; - } - } - if (transition_disable & TRANSITION_DISABLE_ENHANCED_OPEN) { - if (candidate.authmode == WIFI_AUTH_OPEN) { - return false; - } - } - if (transition_disable & TRANSITION_DISABLE_WPA3_ENTERPRISE) { - if (candidate.authmode == WIFI_AUTH_WPA2_ENTERPRISE) { - return false; - } - } -#if TODO // application doesn't have a way to know SAE-PK enabled AP atm - if (transition_disable & TRANSITION_DISABLE_SAE_PK) { - /* This is a simplification. A more accurate check would involve - * parsing the candidate's RSN IE to see if it supports SAE-PK. - * For now, we reject all SAE APs if SAE-PK is enforced. */ - if (candidate.authmode == WIFI_AUTH_WPA3_PSK) { - return false; - } - } -#endif -#endif - - return candidate_security_match(candidate); -} - -#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING +#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST static void remove_expired_blacklist_entries(void) { struct timeval now; gettimeofday(&now, NULL); + int j = 0; for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { - if (time_diff_sec(&now, &g_roaming_app.bssid_blacklist[i].timestamp) > CONFIG_ESP_WIFI_ROAMING_BLACKLIST_TIMEOUT) { - ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " removed from blacklist due to timeout", MAC2STR(g_roaming_app.bssid_blacklist[i].bssid)); - int remaining_entries = g_roaming_app.bssid_blacklist_count - i - 1; - if (remaining_entries > 0) { - memmove(&g_roaming_app.bssid_blacklist[i], &g_roaming_app.bssid_blacklist[i + 1], remaining_entries * sizeof(struct blacklist_entry)); + if (time_diff_sec(&now, &g_roaming_app.bssid_blacklist[i].timestamp) <= CONFIG_ESP_WIFI_ROAMING_BLACKLIST_TIMEOUT) { + if (i != j) { + g_roaming_app.bssid_blacklist[j] = g_roaming_app.bssid_blacklist[i]; } - g_roaming_app.bssid_blacklist_count--; - i--; // Decrement i to recheck the current index + j++; + } else { + ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " removed from blacklist due to timeout", MAC2STR(g_roaming_app.bssid_blacklist[i].bssid)); } } + g_roaming_app.bssid_blacklist_count = j; } #endif static bool is_bssid_blacklisted(const uint8_t *bssid) { -#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING +#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST remove_expired_blacklist_entries(); - for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { - if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, bssid, ETH_ALEN) == 0 && - g_roaming_app.bssid_blacklist[i].failures >= CONFIG_ESP_WIFI_ROAMING_MAX_CONN_FAILURES) { - return true; - } - } -#endif -#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, bssid, ETH_ALEN) == 0) { +#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING + if (g_roaming_app.bssid_blacklist[i].failures >= CONFIG_ESP_WIFI_ROAMING_MAX_CONN_FAILURES) { + return true; + } +#else return true; +#endif } } #endif @@ -704,7 +723,7 @@ static void parse_scan_results_and_roam(void) g_roaming_app.scanned_aps.ap_records[i].rssi, ap_info.rssi, rssi_diff, rssi_threshold, best_rssi_diff, g_roaming_app.scanned_aps.ap_records[i].authmode); if ((memcmp(g_roaming_app.scanned_aps.ap_records[i].bssid, ap_info.bssid, ETH_ALEN) != 0) && - candidate_profile_match(g_roaming_app.scanned_aps.ap_records[i]) && rssi_diff > best_rssi_diff ) { + candidate_security_match(g_roaming_app.scanned_aps.ap_records[i]) && rssi_diff > best_rssi_diff ) { best_rssi_diff = rssi_diff; best_ap_index = i; } @@ -747,7 +766,7 @@ static void scan_done_event_handler(void *arg, ETS_STATUS status) g_roaming_app.scan_ongoing = false; ROAM_SCAN_RESULTS_UNLOCK(); } -static void conduct_scan(void) +static bool conduct_scan(void) { /* Update scan time in global structure */ gettimeofday(&g_roaming_app.scanned_aps.time, NULL); @@ -755,9 +774,10 @@ static void conduct_scan(void) os_memset(&g_roaming_app.scanned_aps, 0, sizeof(struct scanned_ap_info)); if (esp_wifi_promiscuous_scan_start(&g_roaming_app.config.scan_config, scan_done_event_handler) < 0) { ESP_LOGE(ROAMING_TAG, "failed to issue scan"); - return; + return false; } ESP_LOGI(ROAMING_TAG, "Issued Scan"); + return true; } static void determine_best_ap(int8_t rssi_threshold) @@ -770,7 +790,9 @@ static void determine_best_ap(int8_t rssi_threshold) g_roaming_app.scan_ongoing = true; g_roaming_app.current_rssi_threshold = rssi_threshold; if (time_diff_sec(&now,&g_roaming_app.scanned_aps.time) > SCAN_RESULTS_USABILITY_WINDOW) { - conduct_scan(); + if (!conduct_scan()) { + g_roaming_app.scan_ongoing = false; + } } else { parse_scan_results_and_roam(); g_roaming_app.scan_ongoing = false; @@ -920,7 +942,6 @@ cleanup: return ret; } - static esp_err_t init_config_params(void) { g_roaming_app.config.backoff_time = ROAMING_BACKOFF_TIME; @@ -997,6 +1018,7 @@ void roam_init_app(void) ESP_LOGE(ROAMING_TAG, "No roaming method enabled. Roaming app cannot be initialized"); return; #endif + memset(&g_roaming_app, 0, sizeof(g_roaming_app)); #if LOW_RSSI_ROAMING_ENABLED ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_BSS_RSSI_LOW, &roaming_app_rssi_low_handler, NULL)); @@ -1007,10 +1029,6 @@ void roam_init_app(void) ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_NEIGHBOR_REP, &roaming_app_neighbor_report_recv_handler, NULL)); #endif /*PERIODIC_RRM_MONITORING*/ -#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING - memset(g_roaming_app.bssid_blacklist, 0, sizeof(g_roaming_app.bssid_blacklist)); - g_roaming_app.bssid_blacklist_count = 0; -#endif ESP_LOGI(ROAMING_TAG, "Roaming app initialization done"); } @@ -1038,6 +1056,10 @@ void roam_deinit_app(void) &roaming_app_neighbor_report_recv_handler)); /* Disabling the periodic scan and RRM events */ g_roaming_app.periodic_rrm_active = false; + if (g_roaming_app.btm_neighbor_list) { + os_free(g_roaming_app.btm_neighbor_list); + g_roaming_app.btm_neighbor_list = NULL; + } if (neighbor_list_lock) { os_mutex_delete(neighbor_list_lock); neighbor_list_lock = NULL; @@ -1050,34 +1072,51 @@ void roam_deinit_app(void) } #if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST +static void roaming_app_blacklist_add_handler(void *ctx, void *data) +{ + uint8_t *bssid = data; + if (g_roaming_app.bssid_blacklist_count >= CONFIG_ESP_WIFI_ROAMING_MAX_CANDIDATES) { + ESP_LOGE(ROAMING_TAG, "Blacklist is full"); + os_free(bssid); + return; + } + for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { + if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, bssid, ETH_ALEN) == 0) { + ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " already in blacklist", MAC2STR(bssid)); + os_free(bssid); + return; // Already blacklisted + } + } + memcpy(g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].bssid, bssid, ETH_ALEN); +#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING + g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].failures = CONFIG_ESP_WIFI_ROAMING_MAX_CONN_FAILURES; +#endif + gettimeofday(&g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].timestamp, NULL); + g_roaming_app.bssid_blacklist_count++; + ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " added to blacklist", MAC2STR(bssid)); + os_free(bssid); +} + esp_err_t esp_wifi_blacklist_add(const uint8_t *bssid) { if (!bssid) { return ESP_ERR_INVALID_ARG; } - if (g_roaming_app.bssid_blacklist_count >= CONFIG_ESP_WIFI_ROAMING_MAX_CANDIDATES) { - ESP_LOGE(ROAMING_TAG, "Blacklist is full"); + uint8_t *bssid_copy = os_malloc(ETH_ALEN); + if (!bssid_copy) { return ESP_ERR_NO_MEM; } - for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { - if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, bssid, ETH_ALEN) == 0) { - ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " already in blacklist", MAC2STR(bssid)); - return ESP_OK; // Already blacklisted - } + memcpy(bssid_copy, bssid, ETH_ALEN); + if (eloop_register_timeout(0, 0, roaming_app_blacklist_add_handler, NULL, bssid_copy) != 0) { + os_free(bssid_copy); + return ESP_FAIL; } - memcpy(g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].bssid, bssid, ETH_ALEN); - g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].failures = CONFIG_ESP_WIFI_ROAMING_MAX_CONN_FAILURES; - gettimeofday(&g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].timestamp, NULL); - g_roaming_app.bssid_blacklist_count++; - ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " added to blacklist", MAC2STR(bssid)); return ESP_OK; } -esp_err_t esp_wifi_blacklist_remove(const uint8_t *bssid) +static void roaming_app_blacklist_remove_handler(void *ctx, void *data) { - if (!bssid) { - return ESP_ERR_INVALID_ARG; - } + uint8_t *bssid = data; int found_index = -1; for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) { if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, bssid, ETH_ALEN) == 0) { @@ -1097,6 +1136,23 @@ esp_err_t esp_wifi_blacklist_remove(const uint8_t *bssid) } else { ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " not found in blacklist", MAC2STR(bssid)); } + os_free(bssid); +} + +esp_err_t esp_wifi_blacklist_remove(const uint8_t *bssid) +{ + if (!bssid) { + return ESP_ERR_INVALID_ARG; + } + uint8_t *bssid_copy = os_malloc(ETH_ALEN); + if (!bssid_copy) { + return ESP_ERR_NO_MEM; + } + memcpy(bssid_copy, bssid, ETH_ALEN); + if (eloop_register_timeout(0, 0, roaming_app_blacklist_remove_handler, NULL, bssid_copy) != 0) { + os_free(bssid_copy); + return ESP_FAIL; + } return ESP_OK; } #endif diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h index 775c5b29f0..1a1d57993b 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h @@ -7,6 +7,8 @@ #ifndef WPAS_GLUE_H #define WPAS_GLUE_H +#include "rsn_supp/wpa_i.h" + u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type, const void *data, u16 data_len, size_t *msg_len, void **data_pos); diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_i.h b/components/wpa_supplicant/src/rsn_supp/wpa_i.h index b07015eede..909073e610 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_i.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa_i.h @@ -9,6 +9,8 @@ #ifndef WPA_I_H #define WPA_I_H +#include "common/defs.h" + extern struct wpa_sm gWpaSm; #define DEFAULT_EAPOL_VERSION 1 From ddbc41abf2d2a8806965d6fbdb000e84a6a84e1b Mon Sep 17 00:00:00 2001 From: "tarun.kumar" Date: Tue, 16 Sep 2025 21:38:38 +0530 Subject: [PATCH 166/226] fix(wifi) : Resetting current bssid for every roaming connection intiated - Bssid reset after btm or legacy roam - Making few changes in CMake for wpa_supplicant and esp_wifi --- components/esp_wifi/CMakeLists.txt | 2 +- .../roaming_app/include/esp_roaming.h | 4 ++++ .../wifi_apps/roaming_app/src/roaming_app.c | 24 +++++++++++++------ components/wpa_supplicant/CMakeLists.txt | 1 + .../esp_supplicant/src/esp_common.c | 4 ++++ 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/components/esp_wifi/CMakeLists.txt b/components/esp_wifi/CMakeLists.txt index 2cd6ec22e2..e20f4cd9e0 100644 --- a/components/esp_wifi/CMakeLists.txt +++ b/components/esp_wifi/CMakeLists.txt @@ -63,7 +63,7 @@ idf_component_register(SRCS "${srcs}" PRIV_REQUIRES esptool_py esp_pm esp_timer nvs_flash wpa_supplicant hal lwip esp_coex PRIV_INCLUDE_DIRS ../wpa_supplicant/src/ ../wpa_supplicant/esp_supplicant/src/ - wifi_apps/roaming_app/include + wifi_apps/roaming_app/include wifi_apps/roaming_app/src LDFRAGMENTS "${ldfragments}") if(CONFIG_ESP_WIFI_ENABLED OR CONFIG_ESP_HOST_WIFI_ENABLED) diff --git a/components/esp_wifi/wifi_apps/roaming_app/include/esp_roaming.h b/components/esp_wifi/wifi_apps/roaming_app/include/esp_roaming.h index 6ed20ce949..dff094c3b8 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/include/esp_roaming.h +++ b/components/esp_wifi/wifi_apps/roaming_app/include/esp_roaming.h @@ -37,6 +37,10 @@ void roam_sta_disconnected(void *disconn); esp_err_t roam_get_config_params(struct roam_config *config); esp_err_t roam_set_config_params(struct roam_config *config); +#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP +void esp_wifi_roaming_set_current_bssid(const uint8_t *bssid); +#endif + #ifdef __cplusplus } #endif diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c index 7d4fc295c1..04f45f9eef 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c +++ b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c @@ -57,6 +57,13 @@ static void roaming_app_periodic_scan_internal_handler(void *data, void *ctx); static const char *ROAMING_TAG = "ROAM"; +void esp_wifi_roaming_set_current_bssid(const uint8_t *bssid) +{ + if (bssid) { + memcpy(g_roaming_app.current_bss.ap.bssid, bssid, ETH_ALEN); + } +} + static inline long time_diff_sec(struct timeval *a, struct timeval *b) { return (a->tv_sec - b->tv_sec); @@ -183,7 +190,11 @@ static void roaming_app_disconnected_event_handler(void *ctx, void *data) #endif /*PERIODIC_SCAN_MONITORING*/ wifi_event_sta_disconnected_t *disconn = data; - ESP_LOGD(ROAMING_TAG, "station got disconnected reason=%d", disconn->reason); +#define RSSI_INVALID -128 + g_roaming_app.current_bss.ap.rssi = RSSI_INVALID; +#undef RSSI_INVALID + + ESP_LOGD(ROAMING_TAG, "station got disconnected reason=%d, rssi =%d", disconn->reason, disconn->rssi); #if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING if (disconn->reason == WIFI_REASON_CONNECTION_FAIL || disconn->reason == WIFI_REASON_AUTH_FAIL) { bool found = false; @@ -498,6 +509,7 @@ static void trigger_legacy_roam(struct cand_bss *bss) wifi_cfg.sta.bssid_set = true; os_memcpy(wifi_cfg.sta.bssid, bss->bssid, ETH_ALEN); esp_wifi_internal_issue_disconnect(WIFI_REASON_BSS_TRANSITION_DISASSOC); + esp_wifi_roaming_set_current_bssid(bss->bssid); esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg); esp_wifi_connect(); ESP_LOGI(ROAMING_TAG, "Disconnecting and connecting to "MACSTR" on account of better rssi",MAC2STR(bss->bssid)); @@ -710,19 +722,17 @@ static void parse_scan_results_and_roam(void) int8_t rssi_diff = 0; uint8_t i; int8_t best_ap_index = -1; - wifi_ap_record_t ap_info; - roaming_app_get_ap_info(&ap_info); for (i = 0; i < g_roaming_app.scanned_aps.current_count; i++) { if (is_bssid_blacklisted(g_roaming_app.scanned_aps.ap_records[i].bssid)) { ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " is blacklisted, skipping", MAC2STR(g_roaming_app.scanned_aps.ap_records[i].bssid)); continue; } - rssi_diff = g_roaming_app.scanned_aps.ap_records[i].rssi - ap_info.rssi; + rssi_diff = g_roaming_app.scanned_aps.ap_records[i].rssi - g_roaming_app.current_bss.ap.rssi; ESP_LOGD(ROAMING_TAG, "The difference between ("MACSTR", "MACSTR") with rssi (%d,%d) is : %d while the threshold is %d and the best rssi diff yet is %d, thecand_auth is %d", - MAC2STR(g_roaming_app.scanned_aps.ap_records[i].bssid),MAC2STR(ap_info.bssid), - g_roaming_app.scanned_aps.ap_records[i].rssi, ap_info.rssi, + MAC2STR(g_roaming_app.scanned_aps.ap_records[i].bssid),MAC2STR(g_roaming_app.current_bss.ap.bssid), + g_roaming_app.scanned_aps.ap_records[i].rssi, g_roaming_app.current_bss.ap.rssi, rssi_diff, rssi_threshold, best_rssi_diff, g_roaming_app.scanned_aps.ap_records[i].authmode); - if ((memcmp(g_roaming_app.scanned_aps.ap_records[i].bssid, ap_info.bssid, ETH_ALEN) != 0) && + if ((memcmp(g_roaming_app.scanned_aps.ap_records[i].bssid, g_roaming_app.current_bss.ap.bssid, ETH_ALEN) != 0) && candidate_security_match(g_roaming_app.scanned_aps.ap_records[i]) && rssi_diff > best_rssi_diff ) { best_rssi_diff = rssi_diff; best_ap_index = i; diff --git a/components/wpa_supplicant/CMakeLists.txt b/components/wpa_supplicant/CMakeLists.txt index cafc14a27b..4039ab4345 100644 --- a/components/wpa_supplicant/CMakeLists.txt +++ b/components/wpa_supplicant/CMakeLists.txt @@ -245,6 +245,7 @@ idf_component_register(SRCS "${srcs}" "${esp_srcs}" "${tls_src}" "${roaming_src} INCLUDE_DIRS include port/include esp_supplicant/include PRIV_INCLUDE_DIRS src src/utils esp_supplicant/src src/crypto ../esp_wifi/wifi_apps/roaming_app/include + ../esp_wifi/wifi_apps/roaming_app/src LDFRAGMENTS ${linker_fragments} PRIV_REQUIRES mbedtls esp_timer esp_wifi) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_common.c b/components/wpa_supplicant/esp_supplicant/src/esp_common.c index 2187e28cb8..239aacc971 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_common.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_common.c @@ -24,6 +24,7 @@ #include "rsn_supp/wpa.h" #include "esp_private/wifi.h" #include "esp_wifi_types_generic.h" +#include "esp_roaming.h" /* Utility Functions */ esp_err_t esp_supplicant_str_to_mac(const char *str, uint8_t dest[6]) @@ -663,6 +664,9 @@ void wpa_supplicant_connect(struct wpa_supplicant *wpa_s, config->sta.channel = bss->channel; /* supplicant connect will only be called in case of bss transition(roaming) */ esp_wifi_internal_issue_disconnect(WIFI_REASON_BSS_TRANSITION_DISASSOC); +#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP + esp_wifi_roaming_set_current_bssid(bss->bssid); +#endif esp_wifi_set_config(WIFI_IF_STA, config); os_free(config); esp_wifi_connect(); From cf2c1738c0fc7d6e4878be3bae6d778dfee7570f Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Sun, 28 Sep 2025 23:19:15 +0530 Subject: [PATCH 167/226] fix(esp_wifi): Add some fixes in roaming app --- components/esp_wifi/src/wifi_init.c | 8 -- .../wifi_apps/roaming_app/src/roaming_app.c | 131 ++++++++---------- .../esp_supplicant/src/esp_wpa_main.c | 7 + 3 files changed, 68 insertions(+), 78 deletions(-) diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index d1c298b2ff..ea050fe0ab 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -198,10 +198,6 @@ static esp_err_t wifi_deinit_internal(void) esp_supplicant_deinit(); -#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP - roam_deinit_app(); -#endif - #if CONFIG_ESP_WIFI_SLP_SAMPLE_BEACON_FEATURE wifi_beacon_offset_config_t offset_config = WIFI_BEACON_OFFSET_CONFIG_DEFAULT(false); esp_wifi_beacon_offset_configure(&offset_config); @@ -471,10 +467,6 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) goto _deinit; } -#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP - roam_init_app(); -#endif - } else { goto _deinit; } diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c index 04f45f9eef..cd63dc79bd 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c +++ b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c @@ -35,15 +35,6 @@ struct roaming_app g_roaming_app; typedef void (* scan_done_cb_t)(void *arg, ETS_STATUS status); extern int esp_wifi_promiscuous_scan_start(wifi_scan_config_t *config, scan_done_cb_t cb); -static void *scan_results_lock = NULL; -#define ROAM_SCAN_RESULTS_LOCK() os_mutex_lock(scan_results_lock) -#define ROAM_SCAN_RESULTS_UNLOCK() os_mutex_unlock(scan_results_lock) - -#if PERIODIC_RRM_MONITORING -static void *neighbor_list_lock = NULL; -#define ROAM_NEIGHBOR_LIST_LOCK() os_mutex_lock(neighbor_list_lock) -#define ROAM_NEIGHBOR_LIST_UNLOCK() os_mutex_unlock(neighbor_list_lock) -#endif /*PERIODIC_RRM_MONITORING*/ static int wifi_post_roam_event(struct cand_bss *bss); static void determine_best_ap(int8_t rssi_threshold); @@ -150,12 +141,6 @@ static void init_periodic_rrm_event(void) ESP_LOGI(ROAMING_TAG, "RRM monitor is disabled in config"); return; } - if (!neighbor_list_lock) { - neighbor_list_lock = os_recursive_mutex_create(); - if (!neighbor_list_lock) { - ESP_LOGE(ROAMING_TAG, "%s: failed to create roaming neighbor list lock", __func__); - } - } ESP_LOGV(ROAMING_TAG, "Initialised Periodic RRM Monitoring event!"); g_roaming_app.periodic_rrm_active = true; if (eloop_register_timeout(g_roaming_app.config.rrm_monitor_time, 0, roaming_app_periodic_rrm_internal_handler, NULL, NULL)) { @@ -422,26 +407,27 @@ cleanup: } return buf; } -static void roaming_app_neighbor_report_recv_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) + +static void roaming_app_neighbor_report_recv_internal_handler(void *ctx, void *data) { + wifi_event_neighbor_report_t *neighbor_report_event = data; if (!g_roaming_app.rrm_request_active) { ESP_LOGV(ROAMING_TAG, "Not the response for our Neighbor Report Request"); - return; + goto cleanup; } g_roaming_app.rrm_request_active = false; - if (!event_data) { + if (!neighbor_report_event) { ESP_LOGE(ROAMING_TAG, "No data received for neighbor report"); - return; + goto cleanup; } - wifi_event_neighbor_report_t *neighbor_report_event = (wifi_event_neighbor_report_t*)event_data; ESP_LOGD(ROAMING_TAG, "Received cb for Neighbor Report Request"); uint8_t *pos = (uint8_t *)neighbor_report_event->report; if (!pos) { ESP_LOGE(ROAMING_TAG, "Neighbor report is empty"); - return; + goto cleanup; } uint8_t report_len = neighbor_report_event->report_len; @@ -449,22 +435,42 @@ static void roaming_app_neighbor_report_recv_handler(void* arg, esp_event_base_t ESP_LOGD(ROAMING_TAG, "rrm: neighbor report len=%d", report_len); ESP_LOG_BUFFER_HEXDUMP(ROAMING_TAG, pos, report_len, ESP_LOG_DEBUG); - ROAM_NEIGHBOR_LIST_LOCK(); if (g_roaming_app.btm_neighbor_list) { os_free(g_roaming_app.btm_neighbor_list); g_roaming_app.btm_neighbor_list = NULL; } /* create neighbor list */ g_roaming_app.btm_neighbor_list = get_btm_neighbor_list(pos + 1, report_len - 1); - ROAM_NEIGHBOR_LIST_UNLOCK(); +cleanup: + if (neighbor_report_event) { + os_free(neighbor_report_event); + } +} + +static void roaming_app_neighbor_report_recv_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) +{ + wifi_event_neighbor_report_t *event = (wifi_event_neighbor_report_t*)event_data; + if (!event) { + return; + } + wifi_event_neighbor_report_t *event_copy = os_malloc(sizeof(wifi_event_neighbor_report_t) + event->report_len); + if (!event_copy) { + ESP_LOGE(ROAMING_TAG, "Failed to allocate memory for neighbor report event"); + return; + } + memcpy(event_copy, event, sizeof(wifi_event_neighbor_report_t) + event->report_len); + + if (eloop_register_timeout(0, 0, roaming_app_neighbor_report_recv_internal_handler, NULL, event_copy) != 0) { + os_free(event_copy); + } } #endif /*PERIODIC_RRM_MONITORING*/ #if LOW_RSSI_ROAMING_ENABLED -static void roaming_app_rssi_low_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) +static void roaming_app_rssi_low_internal_handler(void *ctx, void *data) { - wifi_event_bss_rssi_low_t *event = event_data; + wifi_event_bss_rssi_low_t *event = data; ESP_LOGI(ROAMING_TAG, "%s:bss rssi is=%ld", __func__, event->rssi); roaming_app_get_ap_info(&g_roaming_app.current_bss.ap); @@ -473,25 +479,34 @@ static void roaming_app_rssi_low_handler(void* arg, esp_event_base_t event_base, ESP_LOGD(ROAMING_TAG, "Resetting RSSI Threshold to %d", g_roaming_app.current_low_rssi_threshold); esp_wifi_set_rssi_threshold(g_roaming_app.current_low_rssi_threshold); + os_free(event); +} + +static void roaming_app_rssi_low_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) +{ + wifi_event_bss_rssi_low_t *event = event_data; + if (!event) { + return; + } + wifi_event_bss_rssi_low_t *event_copy = os_malloc(sizeof(wifi_event_bss_rssi_low_t)); + if (!event_copy) { + ESP_LOGE(ROAMING_TAG, "Failed to allocate memory for rssi low event"); + return; + } + memcpy(event_copy, event, sizeof(wifi_event_bss_rssi_low_t)); + + if (eloop_register_timeout(0, 0, roaming_app_rssi_low_internal_handler, NULL, event_copy) != 0) { + os_free(event_copy); + } } #endif #if NETWORK_ASSISTED_ROAMING_ENABLED static void trigger_network_assisted_roam(void) { -#if PERIODIC_RRM_MONITORING - if (g_roaming_app.current_bss.rrm_support) { - ROAM_NEIGHBOR_LIST_LOCK(); - } -#endif /*PERIODIC_RRM_MONITORING*/ if (esp_wnm_send_bss_transition_mgmt_query(REASON_RSSI, g_roaming_app.btm_neighbor_list, 1) < 0) { ESP_LOGD(ROAMING_TAG, "failed to send btm query"); } -#if PERIODIC_RRM_MONITORING - if (g_roaming_app.current_bss.rrm_support) { - ROAM_NEIGHBOR_LIST_UNLOCK(); - } -#endif /*PERIODIC_RRM_MONITORING*/ ESP_LOGD(ROAMING_TAG, "Sent BTM Query"); gettimeofday(&g_roaming_app.last_roamed_time, NULL); #if LEGACY_ROAM_ENABLED @@ -630,9 +645,6 @@ static bool candidate_security_match(wifi_ap_record_t candidate) } #if TODO // application doesn't have a way to know SAE-PK enabled AP atm if (transition_disable & TRANSITION_DISABLE_SAE_PK) { - /* This is a simplification. A more accurate check would involve - * parsing the candidate's RSN IE to see if it supports SAE-PK. - * For now, we reject all SAE APs if SAE-PK is enforced. */ if (candidate.authmode == WIFI_AUTH_WPA3_PSK) { return false; } @@ -649,9 +661,6 @@ static bool candidate_security_match(wifi_ap_record_t candidate) wifi_config_t wifi_cfg = {0}; esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg); if (wifi_cfg.sta.owe_enabled && OWE_COMPATIBLE(curr_auth, cand_auth)) { - /* - * OWE <--> Open allowed if threshold is Open - */ if (wifi_cfg.sta.threshold.authmode == WIFI_AUTH_OPEN) { ESP_LOGV(ROAMING_TAG, "transition between OWE and open permitted"); return true; @@ -661,7 +670,7 @@ static bool candidate_security_match(wifi_ap_record_t candidate) } } else if (wifi_cfg.sta.threshold.authmode > cand_auth) { /* If the authmode of the candidate AP is less than our threshold, it - * will fail during connection*/ + * will fail during connection */ ESP_LOGV(ROAMING_TAG, "Authmode threshold failure %d -> %d", wifi_cfg.sta.threshold.authmode, cand_auth); return false; } else if (PSK_COMPATIBLE(curr_auth, cand_auth)) { @@ -713,7 +722,6 @@ static bool is_bssid_blacklisted(const uint8_t *bssid) return false; } -/* Remember to always call this function with the ROAM_SCAN_RESULTS_LOCK */ static void parse_scan_results_and_roam(void) { int8_t rssi_threshold = g_roaming_app.current_rssi_threshold; @@ -762,26 +770,21 @@ static void parse_scan_results_and_roam(void) static void scan_done_event_handler(void *arg, ETS_STATUS status) { if (status == ETS_OK) { - ROAM_SCAN_RESULTS_LOCK(); ESP_LOGD(ROAMING_TAG, "Scan Done properly"); g_roaming_app.scanned_aps.current_count = MAX_CANDIDATE_COUNT; esp_wifi_scan_get_ap_records(&g_roaming_app.scanned_aps.current_count, g_roaming_app.scanned_aps.ap_records); print_ap_records(&g_roaming_app.scanned_aps); parse_scan_results_and_roam(); - ROAM_SCAN_RESULTS_UNLOCK(); } else { ESP_LOGD(ROAMING_TAG, "Scan Done with error %d ", status); } - ROAM_SCAN_RESULTS_LOCK(); g_roaming_app.scan_ongoing = false; - ROAM_SCAN_RESULTS_UNLOCK(); } static bool conduct_scan(void) { - /* Update scan time in global structure */ gettimeofday(&g_roaming_app.scanned_aps.time, NULL); - /* Issue scan */ os_memset(&g_roaming_app.scanned_aps, 0, sizeof(struct scanned_ap_info)); + /* Issue scan */ if (esp_wifi_promiscuous_scan_start(&g_roaming_app.config.scan_config, scan_done_event_handler) < 0) { ESP_LOGE(ROAMING_TAG, "failed to issue scan"); return false; @@ -794,7 +797,6 @@ static void determine_best_ap(int8_t rssi_threshold) { struct timeval now; gettimeofday(&now, NULL); - ROAM_SCAN_RESULTS_LOCK(); /* If the scan results are recent enough or a scan is already ongoing we should not trigger a new scan */ if (!g_roaming_app.scan_ongoing) { g_roaming_app.scan_ongoing = true; @@ -810,7 +812,6 @@ static void determine_best_ap(int8_t rssi_threshold) } else if(rssi_threshold < g_roaming_app.current_rssi_threshold) { g_roaming_app.current_rssi_threshold = rssi_threshold; } - ROAM_SCAN_RESULTS_UNLOCK(); } #if PERIODIC_SCAN_MONITORING static void periodic_scan_roam(struct timeval *now) @@ -914,6 +915,7 @@ static int8_t parse_scan_chan_list(void) { int8_t ret = 0; char *scan_chan_string = NULL; + char *scan_chan_string_p = NULL; if (validate_scan_chan_list(SCAN_PREFERRED_CHAN_LIST) == false) { ESP_LOGE(ROAMING_TAG, "scan chan list validation failed."); ret = -1; @@ -927,22 +929,27 @@ static int8_t parse_scan_chan_list(void) } strlcpy(scan_chan_string, SCAN_PREFERRED_CHAN_LIST, strlen(SCAN_PREFERRED_CHAN_LIST) + 1); char* token; - token = strsep(&scan_chan_string, ","); + scan_chan_string_p = scan_chan_string; + token = strsep(&scan_chan_string_p, ","); g_roaming_app.config.scan_config.channel_bitmap.ghz_2_channels = 0; + g_roaming_app.config.scan_config.channel_bitmap.ghz_5_channels = 0; while (token != NULL) { uint8_t channel = atoi(token); /* Check if the number is within the required range */ if (channel >= 1 && channel <= 14) { - /* Check if the number is already present in the array */ g_roaming_app.config.scan_config.channel_bitmap.ghz_2_channels |= (1 << channel); +#if CONFIG_SOC_WIFI_SUPPORT_5G + } else if (channel >= 36 && channel <= 177) { + g_roaming_app.config.scan_config.channel_bitmap.ghz_5_channels |= CHANNEL_TO_BIT(channel); +#endif } else { ESP_LOGE(ROAMING_TAG, "Channel out of range: %d", channel); ret = -1; goto cleanup; } - token = strsep(&scan_chan_string, ","); + token = strsep(&scan_chan_string_p, ","); } cleanup: @@ -997,14 +1004,6 @@ static esp_err_t init_config_params(void) static esp_err_t init_scan_config(void) { - if (!scan_results_lock) { - scan_results_lock = os_recursive_mutex_create(); - if (!scan_results_lock) { - ESP_LOGE(ROAMING_TAG, "%s: failed to create scan results lock", __func__); - return ESP_FAIL; - } - } - if (strcmp(DEFAULT_PREFERRED_SCAN_CHAN_LIST, SCAN_PREFERRED_CHAN_LIST)) { ESP_ERROR_CHECK(parse_scan_chan_list()); } @@ -1070,15 +1069,7 @@ void roam_deinit_app(void) os_free(g_roaming_app.btm_neighbor_list); g_roaming_app.btm_neighbor_list = NULL; } - if (neighbor_list_lock) { - os_mutex_delete(neighbor_list_lock); - neighbor_list_lock = NULL; - } #endif /*PERIODIC_RRM_MONITORING*/ - if (scan_results_lock) { - os_mutex_delete(scan_results_lock); - scan_results_lock = NULL; - } } #if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c index 2490a4003a..b0333289ad 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -31,6 +31,7 @@ #include "esp_eap_client.h" #include "esp_common_i.h" #include "esp_owe_i.h" +#include "esp_roaming.h" #include "esp_wps.h" #include "esp_wps_i.h" @@ -140,6 +141,9 @@ bool wpa_attach(void) ret = (esp_wifi_register_eapol_txdonecb_internal(eapol_txcb) == ESP_OK); } esp_set_scan_ie(); +#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP + roam_init_app(); +#endif return ret; } @@ -192,6 +196,9 @@ void wpa_ap_get_peer_spp_msg(void *sm_data, bool *spp_cap, bool *spp_req) bool wpa_deattach(void) { struct wpa_sm *sm = &gWpaSm; +#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP + roam_deinit_app(); +#endif esp_wpa3_free_sae_data(); #ifdef CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT if (sm->wpa_sm_eap_disable) { From 4347dc6ff293a9bf653b62bb07b95473035ff551 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Tue, 30 Sep 2025 09:33:28 +0530 Subject: [PATCH 168/226] fix(esp_wifi): Cancel roaming_app_periodic_scan_internal_handler correctly --- components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c index cd63dc79bd..2934e7f1d4 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c +++ b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c @@ -1059,12 +1059,14 @@ void roam_deinit_app(void) #if PERIODIC_SCAN_MONITORING g_roaming_app.periodic_scan_active = false; + eloop_cancel_timeout(roaming_app_periodic_scan_internal_handler, NULL, NULL); #endif /*PERIODIC_SCAN_MONITORING*/ #if PERIODIC_RRM_MONITORING ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_NEIGHBOR_REP, &roaming_app_neighbor_report_recv_handler)); /* Disabling the periodic scan and RRM events */ g_roaming_app.periodic_rrm_active = false; + eloop_cancel_timeout(roaming_app_periodic_rrm_internal_handler, NULL, NULL); if (g_roaming_app.btm_neighbor_list) { os_free(g_roaming_app.btm_neighbor_list); g_roaming_app.btm_neighbor_list = NULL; From 9835845d98c962334319a18c42fde1043feab2c9 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Mon, 6 Oct 2025 11:42:38 +0530 Subject: [PATCH 169/226] fix(esp_wifi): Check conditional compilation for roaming app features --- .../esp_wifi/wifi_apps/roaming_app/include/esp_roaming.h | 2 ++ .../esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h | 8 +++++++- .../esp_wifi/wifi_apps/roaming_app/src/roaming_app.c | 9 +++++++-- .../wifi/roaming/roaming_11kvr/main/roaming_example.c | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/components/esp_wifi/wifi_apps/roaming_app/include/esp_roaming.h b/components/esp_wifi/wifi_apps/roaming_app/include/esp_roaming.h index dff094c3b8..28ccb7a79e 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/include/esp_roaming.h +++ b/components/esp_wifi/wifi_apps/roaming_app/include/esp_roaming.h @@ -16,9 +16,11 @@ struct roam_config { int8_t low_rssi_threshold; uint8_t rssi_threshold_reduction_offset; bool scan_monitor; +#if CONFIG_ESP_WIFI_ROAMING_PERIODIC_SCAN_MONITOR uint8_t scan_interval; int8_t scan_rssi_threshold; uint8_t scan_rssi_diff; +#endif bool legacy_roam_enabled; uint8_t btm_retry_cnt; bool btm_roaming_enabled; diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h b/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h index 4afda4c0aa..29d3effc5b 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h +++ b/components/esp_wifi/wifi_apps/roaming_app/src/esp_roaming_i.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,12 +22,18 @@ extern "C" { #define ROAMING_BACKOFF_TIME CONFIG_ESP_WIFI_ROAMING_BACKOFF_TIME /* Low RSSI based roaming configuration */ +#ifndef CONFIG_ESP_WIFI_ROAMING_LOW_RSSI_ROAMING +#define CONFIG_ESP_WIFI_ROAMING_LOW_RSSI_ROAMING 0 +#endif #define LOW_RSSI_ROAMING_ENABLED CONFIG_ESP_WIFI_ROAMING_LOW_RSSI_ROAMING #if LOW_RSSI_ROAMING_ENABLED #define ROAMING_LOW_RSSI_THRESHOLD CONFIG_ESP_WIFI_ROAMING_LOW_RSSI_THRESHOLD #define RSSI_THRESHOLD_REDUCTION_OFFSET CONFIG_ESP_WIFI_ROAMING_LOW_RSSI_OFFSET #endif /*LOW_RSSI_ROAMING_ENABLED*/ +#ifndef CONFIG_ESP_WIFI_ROAMING_PERIODIC_SCAN_MONITOR +#define CONFIG_ESP_WIFI_ROAMING_PERIODIC_SCAN_MONITOR 0 +#endif /* Periodic Scan based Roaming configuration */ #define PERIODIC_SCAN_MONITORING CONFIG_ESP_WIFI_ROAMING_PERIODIC_SCAN_MONITOR #if PERIODIC_SCAN_MONITORING diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c index 2934e7f1d4..c7b84d5c0f 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c +++ b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c @@ -625,9 +625,8 @@ static void periodic_rrm_request(struct timeval *now) static bool candidate_security_match(wifi_ap_record_t candidate) { - u8 transition_disable = wpa_supplicant_get_transition_disable(); - #if CONFIG_ESP_WIFI_ROAMING_PREVENT_DOWNGRADE + u8 transition_disable = wpa_supplicant_get_transition_disable(); if (transition_disable & TRANSITION_DISABLE_WPA3_PERSONAL) { if (candidate.authmode == WIFI_AUTH_WPA2_PSK) { return false; @@ -968,9 +967,11 @@ static esp_err_t init_config_params(void) g_roaming_app.config.rssi_threshold_reduction_offset = RSSI_THRESHOLD_REDUCTION_OFFSET; g_roaming_app.config.scan_monitor = PERIODIC_SCAN_MONITORING; +#if PERIODIC_SCAN_MONITORING g_roaming_app.config.scan_interval = SCAN_MONITOR_INTERVAL; g_roaming_app.config.scan_rssi_threshold = SCAN_MONITOR_RSSI_THRESHOLD; g_roaming_app.config.scan_rssi_diff = SCAN_ROAM_RSSI_DIFF; +#endif /* PERIODIC_SCAN_MONITORING */ g_roaming_app.config.legacy_roam_enabled = LEGACY_ROAM_ENABLED; g_roaming_app.config.btm_retry_cnt = BSS_TM_RETRY_COUNT; @@ -986,9 +987,11 @@ static esp_err_t init_config_params(void) g_roaming_app.config.backoff_time, g_roaming_app.config.low_rssi_roam_trigger, g_roaming_app.config.low_rssi_threshold, g_roaming_app.config.rssi_threshold_reduction_offset); +#if PERIODIC_SCAN_MONITORING ESP_LOGD(ROAMING_TAG, "scan_monitor=%d scan_interval=%d scan_rssi_threshold=%d scan_rssi_diff=%d", g_roaming_app.config.scan_monitor, g_roaming_app.config.scan_interval, g_roaming_app.config.scan_rssi_threshold, g_roaming_app.config.scan_rssi_diff); +#endif /* PERIODIC_SCAN_MONITORING */ ESP_LOGD(ROAMING_TAG, "legacy_roam_enabled=%d, btm_retry_cnt=%d btm_roaming_enabled=%d", g_roaming_app.config.legacy_roam_enabled, @@ -1179,9 +1182,11 @@ static int update_config_params(void *data) g_roaming_app.config.backoff_time, g_roaming_app.config.low_rssi_roam_trigger, g_roaming_app.config.low_rssi_threshold, g_roaming_app.config.rssi_threshold_reduction_offset); +#if PERIODIC_SCAN_MONITORING ESP_LOGI(ROAMING_TAG, "scan_monitor=%d scan_interval=%d scan_rssi_threshold=%d scan_rssi_diff=%d", g_roaming_app.config.scan_monitor, g_roaming_app.config.scan_interval, g_roaming_app.config.scan_rssi_threshold, g_roaming_app.config.scan_rssi_diff); +#endif ESP_LOGI(ROAMING_TAG, "legacy_roam_enabled=%d, btm_retry_cnt=%d btm_roaming_enabled=%d", g_roaming_app.config.legacy_roam_enabled, diff --git a/examples/wifi/roaming/roaming_11kvr/main/roaming_example.c b/examples/wifi/roaming/roaming_11kvr/main/roaming_example.c index edf0669494..d108cca8fe 100644 --- a/examples/wifi/roaming/roaming_11kvr/main/roaming_example.c +++ b/examples/wifi/roaming/roaming_11kvr/main/roaming_example.c @@ -325,7 +325,7 @@ static void esp_neighbor_report_recv_handler(void* arg, esp_event_base_t event_b g_neighbor_report_active = false; uint8_t cand_list = 0; wifi_event_neighbor_report_t *neighbor_report_event = (wifi_event_neighbor_report_t*)event_data; - uint8_t *pos = (uint8_t *)neighbor_report_event->report; + uint8_t *pos = (uint8_t *)neighbor_report_event->n_report; char * neighbor_list = NULL; if (!pos) { ESP_LOGE(TAG, "Neighbor report is empty"); From 1cea05a41690080e74b2e1d8d19149d0316235ab Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Thu, 9 Oct 2025 14:57:23 +0530 Subject: [PATCH 170/226] fix(esp_wifi): Use correct variable for neighbour report --- examples/wifi/roaming/roaming_11kvr/main/roaming_example.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wifi/roaming/roaming_11kvr/main/roaming_example.c b/examples/wifi/roaming/roaming_11kvr/main/roaming_example.c index d108cca8fe..edf0669494 100644 --- a/examples/wifi/roaming/roaming_11kvr/main/roaming_example.c +++ b/examples/wifi/roaming/roaming_11kvr/main/roaming_example.c @@ -325,7 +325,7 @@ static void esp_neighbor_report_recv_handler(void* arg, esp_event_base_t event_b g_neighbor_report_active = false; uint8_t cand_list = 0; wifi_event_neighbor_report_t *neighbor_report_event = (wifi_event_neighbor_report_t*)event_data; - uint8_t *pos = (uint8_t *)neighbor_report_event->n_report; + uint8_t *pos = (uint8_t *)neighbor_report_event->report; char * neighbor_list = NULL; if (!pos) { ESP_LOGE(TAG, "Neighbor report is empty"); From c9b5b40bc128a9c214a947ae0049f1464d7057e7 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Thu, 9 Oct 2025 15:53:10 +0530 Subject: [PATCH 171/226] fix(esp_wifi): Change some defaults in roaming app - Closes https://github.com/espressif/esp-idf/issues/17687 --- components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming b/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming index 7406d9b12f..57bc23649a 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming +++ b/components/esp_wifi/wifi_apps/roaming_app/src/Kconfig.roaming @@ -73,7 +73,7 @@ menu "Roaming Methods" config ESP_WIFI_ROAMING_NETWORK_ASSISTED_ROAM bool "Support Network Assisted roaming using 802.11v" depends on ESP_WIFI_WNM_SUPPORT - default n + default y help Roaming between APs using network assisted Roaming. This involves BSS Transition Management mechanisms outlined in 802.11v. @@ -154,7 +154,7 @@ config ESP_WIFI_ROAMING_BACKOFF_TIME config ESP_WIFI_ROAMING_PERIODIC_RRM_MONITORING bool "Send periodic neighbor report request to AP for internal list updation" depends on ESP_WIFI_RRM_SUPPORT - default y + default n help This option will enable station to keep sending RRM neighbor list request to AP and update its internal list. From 8506035f5a6498258e3095fac5983fb8643ca911 Mon Sep 17 00:00:00 2001 From: morris Date: Thu, 8 Jan 2026 18:25:42 +0800 Subject: [PATCH 172/226] refactor(gdma): enhance M2M capability handling --- .../esp_driver_spi/src/gpspi/spi_common.c | 2 -- components/esp_hw_support/dma/gdma.c | 34 ++++++++++++------- components/hal/esp32c2/include/hal/gdma_ll.h | 2 ++ components/hal/esp32c3/include/hal/gdma_ll.h | 2 ++ .../hal/esp32c5/include/hal/ahb_dma_ll.h | 2 ++ components/hal/esp32c6/include/hal/gdma_ll.h | 2 ++ .../hal/esp32c61/include/hal/ahb_dma_ll.h | 2 ++ components/hal/esp32h2/include/hal/gdma_ll.h | 2 ++ components/hal/esp32h21/include/hal/gdma_ll.h | 2 ++ .../hal/esp32h4/include/hal/ahb_dma_ll.h | 2 ++ components/hal/esp32p4/include/hal/gdma_ll.h | 8 +++++ components/hal/esp32s3/include/hal/gdma_ll.h | 2 ++ 12 files changed, 48 insertions(+), 14 deletions(-) diff --git a/components/esp_driver_spi/src/gpspi/spi_common.c b/components/esp_driver_spi/src/gpspi/spi_common.c index 98da337c77..d55703fa1c 100644 --- a/components/esp_driver_spi/src/gpspi/spi_common.c +++ b/components/esp_driver_spi/src/gpspi/spi_common.c @@ -227,7 +227,6 @@ static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_ch if (dma_chan == SPI_DMA_CH_AUTO) { gdma_channel_alloc_config_t tx_alloc_config = { - .flags.reserve_sibling = 1, #if CONFIG_SPI_MASTER_ISR_IN_IRAM .flags.isr_cache_safe = true, #endif @@ -237,7 +236,6 @@ static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_ch gdma_channel_alloc_config_t rx_alloc_config = { .direction = GDMA_CHANNEL_DIRECTION_RX, - .sibling_chan = dma_ctx->tx_dma_chan, #if CONFIG_SPI_MASTER_ISR_IN_IRAM .flags.isr_cache_safe = true, #endif diff --git a/components/esp_hw_support/dma/gdma.c b/components/esp_hw_support/dma/gdma.c index 29211df99e..a1348db51c 100644 --- a/components/esp_hw_support/dma/gdma.c +++ b/components/esp_hw_support/dma/gdma.c @@ -11,7 +11,7 @@ * +-----------------------------------+--+ +--+-----------------------------------+ * | GDMA-Group-X | | | | GDMA-Group-Y | * | +-------------+ +------------+ | | | | +-------------+ +------------+ | - * | | GDMA-Pair-0 |... |GDMA-Pair-N | | | | | | GDMA-Pair-0 |... |GDMA-Pair-N | | + * | | GDMA-Pair-0 |... |GDMA-Pair-N | | | | | | GDMA-Pair-0 |... |GDMA-Pair-M | | * | | | | | | | | | | | | | | * | | TX-Chan |... | TX-Chan | | | | | | TX-Chan |... | TX-Chan | | * | | RX-Chan | | RX-Chan | | | | | | RX-Chan | | RX-Chan | | @@ -70,6 +70,7 @@ typedef struct { int start_group_id; int end_group_id; int pairs_per_group; + uint32_t m2m_capable_mask; void (*hal_init)(gdma_hal_context_t *hal, const gdma_hal_config_t *config); } gdma_channel_search_info_t; @@ -116,6 +117,13 @@ static esp_err_t do_allocate_gdma_channel(const gdma_channel_search_info_t *sear ESP_GOTO_ON_FALSE(group, ESP_ERR_NO_MEM, err, TAG, "no mem for group(%d)", i); group->bus_id = search_info->bus_id; for (int j = 0; j < pairs_per_group && search_code; j++) { // loop to search pair + // Check M2M capability BEFORE acquiring pair to avoid unnecessary allocation + if (config->flags.reserve_sibling) { // Both channels requested (implicit M2M usage) + if (!((1 << j) & search_info->m2m_capable_mask)) { + ESP_LOGV(TAG, "pair(%d,%d) not M2M capable, skip", i, j); + continue; // Skip pairs that don't support M2M + } + } pair = gdma_acquire_pair_handle(group, j); ESP_GOTO_ON_FALSE(pair, ESP_ERR_NO_MEM, err, TAG, "no mem for pair(%d,%d)", i, j); portENTER_CRITICAL(&pair->spinlock); @@ -175,7 +183,7 @@ search_done: } (*ret_chan)->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; - ESP_LOGD(TAG, "new %s channel (%d,%d) at %p", (config->direction == GDMA_CHANNEL_DIRECTION_TX) ? "tx" : "rx", + ESP_LOGV(TAG, "new %s channel (%d,%d) at %p", (config->direction == GDMA_CHANNEL_DIRECTION_TX) ? "tx" : "rx", group->group_id, pair->pair_id, *ret_chan); return ESP_OK; @@ -203,6 +211,7 @@ esp_err_t gdma_new_ahb_channel(const gdma_channel_alloc_config_t *config, gdma_c .start_group_id = GDMA_LL_AHB_GROUP_START_ID, .end_group_id = GDMA_LL_AHB_GROUP_START_ID + GDMA_LL_AHB_NUM_GROUPS, .pairs_per_group = GDMA_LL_AHB_PAIRS_PER_GROUP, + .m2m_capable_mask = GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK, .hal_init = gdma_ahb_hal_init, }; return do_allocate_gdma_channel(&search_info, config, ret_chan); @@ -217,6 +226,7 @@ esp_err_t gdma_new_axi_channel(const gdma_channel_alloc_config_t *config, gdma_c .start_group_id = GDMA_LL_AXI_GROUP_START_ID, .end_group_id = GDMA_LL_AXI_GROUP_START_ID + GDMA_LL_AXI_NUM_GROUPS, .pairs_per_group = GDMA_LL_AXI_PAIRS_PER_GROUP, + .m2m_capable_mask = GDMA_LL_AXI_M2M_CAPABLE_PAIR_MASK, .hal_init = gdma_axi_hal_init, }; return do_allocate_gdma_channel(&search_info, config, ret_chan); @@ -607,7 +617,7 @@ static void gdma_release_group_handle(gdma_group_t *group) gdma_ll_enable_bus_clock(group_id, false); } free(group); - ESP_LOGD(TAG, "del group %d", group_id); + ESP_LOGV(TAG, "del group %d", group_id); } } @@ -644,7 +654,7 @@ static gdma_group_t *gdma_acquire_group_handle(int group_id, void (*hal_init)(gd .group_id = group_id, }; hal_init(&group->hal, &config); - ESP_LOGD(TAG, "new group (%d) at %p", group_id, group); + ESP_LOGV(TAG, "new group (%d) at %p", group_id, group); } else { free(pre_alloc_group); } @@ -672,7 +682,7 @@ static void gdma_release_pair_handle(gdma_pair_t *pair) #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_GDMA_SUPPORT_SLEEP_RETENTION gdma_sleep_retention_deinit(group->group_id, pair_id); #endif - ESP_LOGD(TAG, "del pair (%d,%d)", group->group_id, pair_id); + ESP_LOGV(TAG, "del pair (%d,%d)", group->group_id, pair_id); gdma_release_group_handle(group); } } @@ -712,7 +722,7 @@ static gdma_pair_t *gdma_acquire_pair_handle(gdma_group_t *group, int pair_id) #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_GDMA_SUPPORT_SLEEP_RETENTION gdma_sleep_retention_init(group->group_id, pair_id); #endif - ESP_LOGD(TAG, "new pair (%d,%d) at %p", group->group_id, pair_id, pair); + ESP_LOGV(TAG, "new pair (%d,%d) at %p", group->group_id, pair_id, pair); } else { free(pre_alloc_pair); } @@ -739,11 +749,11 @@ static esp_err_t gdma_del_tx_channel(gdma_channel_t *dma_channel) gdma_hal_enable_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_TX, UINT32_MAX, false); // disable all interrupt events gdma_hal_clear_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_TX, UINT32_MAX); // clear all pending events portEXIT_CRITICAL(&pair->spinlock); - ESP_LOGD(TAG, "uninstall interrupt service for tx channel (%d,%d)", group_id, pair_id); + ESP_LOGV(TAG, "uninstall interrupt service for tx channel (%d,%d)", group_id, pair_id); } free(tx_chan); - ESP_LOGD(TAG, "del tx channel (%d,%d)", group_id, pair_id); + ESP_LOGV(TAG, "del tx channel (%d,%d)", group_id, pair_id); // channel has a reference on pair, release it now gdma_release_pair_handle(pair); return ESP_OK; @@ -768,11 +778,11 @@ static esp_err_t gdma_del_rx_channel(gdma_channel_t *dma_channel) gdma_hal_enable_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_RX, UINT32_MAX, false); // disable all interrupt events gdma_hal_clear_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_RX, UINT32_MAX); // clear all pending events portEXIT_CRITICAL(&pair->spinlock); - ESP_LOGD(TAG, "uninstall interrupt service for rx channel (%d,%d)", group_id, pair_id); + ESP_LOGV(TAG, "uninstall interrupt service for rx channel (%d,%d)", group_id, pair_id); } free(rx_chan); - ESP_LOGD(TAG, "del rx channel (%d,%d)", group_id, pair_id); + ESP_LOGV(TAG, "del rx channel (%d,%d)", group_id, pair_id); gdma_release_pair_handle(pair); return ESP_OK; } @@ -884,7 +894,7 @@ static esp_err_t gdma_install_rx_interrupt(gdma_rx_channel_t *rx_chan) gdma_hal_enable_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_RX, UINT32_MAX, false); // disable all interrupt events gdma_hal_clear_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_RX, UINT32_MAX); // clear all pending events portEXIT_CRITICAL(&pair->spinlock); - ESP_LOGD(TAG, "install interrupt service for rx channel (%d,%d)", group->group_id, pair_id); + ESP_LOGV(TAG, "install interrupt service for rx channel (%d,%d)", group->group_id, pair_id); err: return ret; @@ -916,7 +926,7 @@ static esp_err_t gdma_install_tx_interrupt(gdma_tx_channel_t *tx_chan) gdma_hal_enable_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_TX, UINT32_MAX, false); // disable all interrupt events gdma_hal_clear_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_TX, UINT32_MAX); // clear all pending events portEXIT_CRITICAL(&pair->spinlock); - ESP_LOGD(TAG, "install interrupt service for tx channel (%d,%d)", group->group_id, pair_id); + ESP_LOGV(TAG, "install interrupt service for tx channel (%d,%d)", group->group_id, pair_id); err: return ret; diff --git a/components/hal/esp32c2/include/hal/gdma_ll.h b/components/hal/esp32c2/include/hal/gdma_ll.h index ee877d5b3e..ff327126de 100644 --- a/components/hal/esp32c2/include/hal/gdma_ll.h +++ b/components/hal/esp32c2/include/hal/gdma_ll.h @@ -47,6 +47,8 @@ extern "C" { #define GDMA_LL_AHB_PAIRS_PER_GROUP 1 // Number of GDMA pairs in each AHB group #define GDMA_LL_AHB_TX_RX_SHARE_INTERRUPT 1 // TX and RX channel in the same pair will share the same interrupt source number +#define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x01 // pair 0 is M2M capable + #define GDMA_LL_AHB_DESC_ALIGNMENT 4 #define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1 diff --git a/components/hal/esp32c3/include/hal/gdma_ll.h b/components/hal/esp32c3/include/hal/gdma_ll.h index f7b3147e4d..511d692613 100644 --- a/components/hal/esp32c3/include/hal/gdma_ll.h +++ b/components/hal/esp32c3/include/hal/gdma_ll.h @@ -47,6 +47,8 @@ extern "C" { #define GDMA_LL_AHB_PAIRS_PER_GROUP 3 // Number of GDMA pairs in each AHB group #define GDMA_LL_AHB_TX_RX_SHARE_INTERRUPT 1 // TX and RX channel in the same pair will share the same interrupt source number +#define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x07 // pair 0,1,2 are M2M capable + #define GDMA_LL_AHB_DESC_ALIGNMENT 4 #define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1 diff --git a/components/hal/esp32c5/include/hal/ahb_dma_ll.h b/components/hal/esp32c5/include/hal/ahb_dma_ll.h index 787edf0ec5..4ea87aef8c 100644 --- a/components/hal/esp32c5/include/hal/ahb_dma_ll.h +++ b/components/hal/esp32c5/include/hal/ahb_dma_ll.h @@ -48,6 +48,8 @@ extern "C" { #define GDMA_LL_AHB_NUM_GROUPS 1 // Number of AHB GDMA groups #define GDMA_LL_AHB_PAIRS_PER_GROUP 3 // Number of GDMA pairs in each AHB group +#define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x07 // pair 0,1,2 are M2M capable + #define GDMA_LL_TX_ETM_EVENT_TABLE(group, chan, event) \ (uint32_t[1][3][GDMA_ETM_EVENT_MAX]){{{ \ [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH0, \ diff --git a/components/hal/esp32c6/include/hal/gdma_ll.h b/components/hal/esp32c6/include/hal/gdma_ll.h index 5a1d8d2417..62f4dea119 100644 --- a/components/hal/esp32c6/include/hal/gdma_ll.h +++ b/components/hal/esp32c6/include/hal/gdma_ll.h @@ -47,6 +47,8 @@ extern "C" { #define GDMA_LL_AHB_NUM_GROUPS 1 // Number of AHB GDMA groups #define GDMA_LL_AHB_PAIRS_PER_GROUP 3 // Number of GDMA pairs in each AHB group +#define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x07 // pair 0,1,2 are M2M capable + #define GDMA_LL_AHB_DESC_ALIGNMENT 4 #define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1 diff --git a/components/hal/esp32c61/include/hal/ahb_dma_ll.h b/components/hal/esp32c61/include/hal/ahb_dma_ll.h index d2f5f95bfb..67a789970a 100644 --- a/components/hal/esp32c61/include/hal/ahb_dma_ll.h +++ b/components/hal/esp32c61/include/hal/ahb_dma_ll.h @@ -48,6 +48,8 @@ extern "C" { #define GDMA_LL_AHB_NUM_GROUPS 1 // Number of AHB GDMA groups #define GDMA_LL_AHB_PAIRS_PER_GROUP 2 // Number of GDMA pairs in each AHB group +#define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x03 // pair 0,1 are M2M capable + #define GDMA_LL_TX_ETM_EVENT_TABLE(group, chan, event) \ (uint32_t[1][2][GDMA_ETM_EVENT_MAX]){{{ \ [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH0, \ diff --git a/components/hal/esp32h2/include/hal/gdma_ll.h b/components/hal/esp32h2/include/hal/gdma_ll.h index 5a1d8d2417..62f4dea119 100644 --- a/components/hal/esp32h2/include/hal/gdma_ll.h +++ b/components/hal/esp32h2/include/hal/gdma_ll.h @@ -47,6 +47,8 @@ extern "C" { #define GDMA_LL_AHB_NUM_GROUPS 1 // Number of AHB GDMA groups #define GDMA_LL_AHB_PAIRS_PER_GROUP 3 // Number of GDMA pairs in each AHB group +#define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x07 // pair 0,1,2 are M2M capable + #define GDMA_LL_AHB_DESC_ALIGNMENT 4 #define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1 diff --git a/components/hal/esp32h21/include/hal/gdma_ll.h b/components/hal/esp32h21/include/hal/gdma_ll.h index bf145e4778..4d0f42c613 100644 --- a/components/hal/esp32h21/include/hal/gdma_ll.h +++ b/components/hal/esp32h21/include/hal/gdma_ll.h @@ -50,6 +50,8 @@ extern "C" { #define GDMA_LL_AHB_DESC_ALIGNMENT 4 #define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1 +#define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x07 // pair 0,1,2 are M2M capable + #define GDMA_LL_TX_ETM_EVENT_TABLE(group, chan, event) \ (uint32_t[1][3][GDMA_ETM_EVENT_MAX]){{{ \ [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH0, \ diff --git a/components/hal/esp32h4/include/hal/ahb_dma_ll.h b/components/hal/esp32h4/include/hal/ahb_dma_ll.h index facd2dab5a..addac62de0 100644 --- a/components/hal/esp32h4/include/hal/ahb_dma_ll.h +++ b/components/hal/esp32h4/include/hal/ahb_dma_ll.h @@ -48,6 +48,8 @@ extern "C" { #define GDMA_LL_AHB_NUM_GROUPS 1 // Number of AHB GDMA groups #define GDMA_LL_AHB_PAIRS_PER_GROUP 5 // Number of GDMA pairs in each AHB group +#define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x1F // pair 0,1,2,3,4 are M2M capable + #define GDMA_LL_TX_ETM_EVENT_TABLE(group, chan, event) \ (uint32_t[1][5][GDMA_ETM_EVENT_MAX]){{{ \ [GDMA_ETM_EVENT_EOF] = GDMA_EVT_OUT_EOF_CH0, \ diff --git a/components/hal/esp32p4/include/hal/gdma_ll.h b/components/hal/esp32p4/include/hal/gdma_ll.h index 3f1410a1a6..6316a33f94 100644 --- a/components/hal/esp32p4/include/hal/gdma_ll.h +++ b/components/hal/esp32p4/include/hal/gdma_ll.h @@ -54,6 +54,14 @@ #define GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE 1 // AHB GDMA supports adjustable burst size #endif +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 +#define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x06 // only pair 1,2 are M2M capable +#else +#define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x07 // pair 0,1,2 are M2M capable +#endif + +#define GDMA_LL_AXI_M2M_CAPABLE_PAIR_MASK 0x07 // pair 0,1,2 are M2M capable + #define GDMA_LL_TX_ETM_EVENT_TABLE(group, chan, event) \ (uint32_t[2][GDMA_ETM_EVENT_MAX]){ \ { \ diff --git a/components/hal/esp32s3/include/hal/gdma_ll.h b/components/hal/esp32s3/include/hal/gdma_ll.h index d69c74fd1e..58cc22253c 100644 --- a/components/hal/esp32s3/include/hal/gdma_ll.h +++ b/components/hal/esp32s3/include/hal/gdma_ll.h @@ -66,6 +66,8 @@ extern "C" { #define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1 #define GDMA_LL_MAX_BURST_SIZE_PSRAM 64 // PSRAM controller doesn't support burst access with size > 64 bytes +#define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x1F // pair 0,1,2,3,4 are M2M capable + ///////////////////////////////////// Common ///////////////////////////////////////// /** From 7e832133d50dfed5d357e36196558043f3efabec Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Thu, 8 Jan 2026 21:13:42 +0800 Subject: [PATCH 173/226] change(ble): [AUTO_MR] Update lib_esp32h2 to acf48208 (cherry picked from commit 32b41c88e0c531ef1711c770a8fdc4ba00ce0ac2) Co-authored-by: Zhou Xiao --- components/bt/controller/lib_esp32h2/esp32h2-bt-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib index bfbcfa6ee4..1034b3c595 160000 --- a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib +++ b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib @@ -1 +1 @@ -Subproject commit bfbcfa6ee46f4e2e323d9ddf6069984d6f836aa4 +Subproject commit 1034b3c595cc3a570d2bfb6e0b08b45f3b1f5fae From eb3d2510ebd675ac109b1adcd8da76ed3197146b Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Thu, 8 Jan 2026 21:13:43 +0800 Subject: [PATCH 174/226] change(ble): [AUTO_MR] Update lib_esp32c5 to acf48208 (cherry picked from commit d61e0bf975a1eb59eaa8f0e19ee4993956b6a4f8) Co-authored-by: Zhou Xiao --- components/bt/controller/lib_esp32c5/esp32c5-bt-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32c5/esp32c5-bt-lib b/components/bt/controller/lib_esp32c5/esp32c5-bt-lib index 955958046d..95899f11a3 160000 --- a/components/bt/controller/lib_esp32c5/esp32c5-bt-lib +++ b/components/bt/controller/lib_esp32c5/esp32c5-bt-lib @@ -1 +1 @@ -Subproject commit 955958046d6306726cf10ff420805e33c429e0e8 +Subproject commit 95899f11a3f21aae115121ea778cfb8cb1047885 From c37e949021490b060a1976a2e09854974ececb89 Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Thu, 8 Jan 2026 21:13:43 +0800 Subject: [PATCH 175/226] change(ble): [AUTO_MR] Update lib_esp32c6 to acf48208 (cherry picked from commit 69522eaedb28a8c22fdcd77a310840e8ddce1a50) Co-authored-by: Zhou Xiao --- components/bt/controller/lib_esp32c6/esp32c6-bt-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib index 8175cc3655..d40be82077 160000 --- a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib +++ b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib @@ -1 +1 @@ -Subproject commit 8175cc3655be5a08d85dd38149d3dd79d7c1fe49 +Subproject commit d40be82077fab8d80aed1eecc39f30673dbcc90d From 1311fa809459e073f78b97a69290d8af0c092d9b Mon Sep 17 00:00:00 2001 From: "radek.tandler" Date: Thu, 18 Dec 2025 16:01:03 +0100 Subject: [PATCH 176/226] fix(nvs_flash): Fixed order of page state change to allow recovery --- components/nvs_flash/src/nvs_pagemanager.cpp | 23 +++++++++++--------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/components/nvs_flash/src/nvs_pagemanager.cpp b/components/nvs_flash/src/nvs_pagemanager.cpp index c5e3a17c69..e46e58b946 100644 --- a/components/nvs_flash/src/nvs_pagemanager.cpp +++ b/components/nvs_flash/src/nvs_pagemanager.cpp @@ -163,22 +163,25 @@ esp_err_t PageManager::requestNewPage() return ESP_ERR_NVS_NOT_ENOUGH_SPACE; } - esp_err_t err = activatePage(); + Page* erasedPage = maxUnusedItemsPageIt; + +#ifndef NDEBUG + size_t usedEntries = erasedPage->getUsedEntryCount(); +#endif + esp_err_t err = erasedPage->markFreeing(); + if (err != ESP_OK) { + return err; + } + + // Activating a new page first when markFreeing is done. The data recovery from power loss will be + // driven by the existence of the (transitional) FREEING state of a page. + err = activatePage(); if (err != ESP_OK) { return err; } Page* newPage = &mPageList.back(); - Page* erasedPage = maxUnusedItemsPageIt; - -#ifndef NDEBUG - size_t usedEntries = erasedPage->getUsedEntryCount(); -#endif - err = erasedPage->markFreeing(); - if (err != ESP_OK) { - return err; - } err = erasedPage->copyItems(*newPage); if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) { return err; From 2b5b772dfce6fbbf69fbd1b43440a159483ab49e Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 8 Jan 2026 11:22:55 +0800 Subject: [PATCH 177/226] change(esp_hw_support): update esp32 sleep parameters when disabling system sleep IRAM optimization --- components/esp_hw_support/sleep_modes.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index f71edb65b5..88c1b96388 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -156,7 +156,11 @@ #define FAST_CLK_SRC_CAL_CYCLES (2048) /* ~ 127.4 us */ #ifdef CONFIG_IDF_TARGET_ESP32 +#if !CONFIG_PM_SLP_IRAM_OPT +#define DEFAULT_SLEEP_OUT_OVERHEAD_US (476) +#else #define DEFAULT_SLEEP_OUT_OVERHEAD_US (212) +#endif #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (60) #elif CONFIG_IDF_TARGET_ESP32S2 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (147) From 31d7f49b76a52c62bccf75b628963d064224ed38 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 8 Jan 2026 11:22:55 +0800 Subject: [PATCH 178/226] change(esp_pm): fix ci failed test case of Automatic light occurs when tasks are suspended --- components/esp_pm/test_apps/esp_pm/sdkconfig.ci.limits | 2 -- components/freertos/Kconfig | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.limits b/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.limits index 2aec98155c..b0266392d9 100644 --- a/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.limits +++ b/components/esp_pm/test_apps/esp_pm/sdkconfig.ci.limits @@ -3,8 +3,6 @@ # Limit test esp_pm auto light sleep logic with faster ticks and faster code CONFIG_FREERTOS_HZ=1000 CONFIG_COMPILER_OPTIMIZATION_PERF=y -# Minimize the automatic light sleep entry threshold -CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP=2 # Enable PM options for automatic sleeping and DFS CONFIG_PM_DFS_INIT_AUTO=y diff --git a/components/freertos/Kconfig b/components/freertos/Kconfig index 1836dce9db..994e147cab 100644 --- a/components/freertos/Kconfig +++ b/components/freertos/Kconfig @@ -337,6 +337,7 @@ menu "FreeRTOS" # Todo: Rename to CONFIG_FREERTOS_EXPECTED_IDLE_TIME_BEFORE_SLEEP (IDF-4986) int "configEXPECTED_IDLE_TIME_BEFORE_SLEEP" depends on FREERTOS_USE_TICKLESS_IDLE + default 8 if !PM_SLP_IRAM_OPT && (FREERTOS_HZ > 200) default 3 range 2 4294967295 # Minimal value is 2 because of a check in FreeRTOS.h (search configEXPECTED_IDLE_TIME_BEFORE_SLEEP) From cf8ab3c7a408c1089a2dcc11dae2e5a1e45d88ab Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 25 Sep 2025 20:43:13 +0800 Subject: [PATCH 179/226] docs(Power Management): support esp32c5 system and wifi low power programming guide docs --- docs/docs_not_updated/esp32c5.txt | 2 - .../low-power-mode/low-power-mode-soc.rst | 131 +++++++++++++++-- .../low-power-mode/low-power-mode-wifi.rst | 24 ++-- .../sleep-current/esp32c5_light_sleep.inc | 27 ++++ .../sleep-current/esp32c5_modem_sleep.inc | 107 ++++++++++++++ .../sleep-current/esp32c5_summary.inc | 87 ++++++++++++ .../low-power-mode/low-power-mode-soc.rst | 133 ++++++++++++++++-- .../low-power-mode/low-power-mode-wifi.rst | 24 ++-- .../sleep-current/esp32c5_light_sleep.inc | 27 ++++ .../sleep-current/esp32c5_modem_sleep.inc | 107 ++++++++++++++ .../sleep-current/esp32c5_summary.inc | 87 ++++++++++++ 11 files changed, 719 insertions(+), 37 deletions(-) create mode 100644 docs/en/api-guides/sleep-current/esp32c5_light_sleep.inc create mode 100644 docs/en/api-guides/sleep-current/esp32c5_modem_sleep.inc create mode 100644 docs/en/api-guides/sleep-current/esp32c5_summary.inc create mode 100644 docs/zh_CN/api-guides/sleep-current/esp32c5_light_sleep.inc create mode 100644 docs/zh_CN/api-guides/sleep-current/esp32c5_modem_sleep.inc create mode 100644 docs/zh_CN/api-guides/sleep-current/esp32c5_summary.inc diff --git a/docs/docs_not_updated/esp32c5.txt b/docs/docs_not_updated/esp32c5.txt index 8f54062766..16b8b961f3 100644 --- a/docs/docs_not_updated/esp32c5.txt +++ b/docs/docs_not_updated/esp32c5.txt @@ -1,5 +1,3 @@ -api-guides/low-power-mode.rst -api-guides/deep-sleep-stub.rst api-guides/inc/external-ram-esp32-notes.rst api-reference/storage/vfs.rst api-reference/storage/spiffs.rst diff --git a/docs/en/api-guides/low-power-mode/low-power-mode-soc.rst b/docs/en/api-guides/low-power-mode/low-power-mode-soc.rst index 792d7bdabd..56a3f86b8d 100644 --- a/docs/en/api-guides/low-power-mode/low-power-mode-soc.rst +++ b/docs/en/api-guides/low-power-mode/low-power-mode-soc.rst @@ -218,10 +218,10 @@ Recommended Configuration - 1000 * - ``max_freq_mhz`` - - 160 + - The maximum CPU frequency supported by {IDF_TARGET_NAME} * - ``min_freq_mhz`` - - 40 + - {CONFIG_XTAL_FREQ} * - ``light_sleep_enable`` - false @@ -288,6 +288,14 @@ This section introduces the recommended configuration and configuration steps fo Due to the shared power pins between flash and PSRAM, cutting power to PSRAM would result in data loss. Therefore, to ensure light sleep does not disrupt program execution, enabling this option requires that the system does not utilize PSRAM. +.. only:: SOC_PM_SUPPORT_TOP_PD + + - Power down Digital Peripheral modules and all child power domains under the TOP power domain in light sleep (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH`) + +.. only:: SOC_PM_SUPPORT_RTC_PERIPH_PD + + - Power down the RTC digital peripheral module. Automatically powered down the RTC digital peripherals during system sleep is the default system power management policy. Users can call `esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON)` to enable the RTC digital peripheral module while in sleep mode. + .. only:: esp32c2 - To reduce the on-chip RAM usage of the Power Management module (:ref:CONFIG_PM_SLEEP_FUNC_IN_IRAM), the options in the table below are used to control whether individual components of the Power Management module enable or disable on-chip RAM optimization when :ref:CONFIG_PM_SLEEP_FUNC_IN_IRAM is disabled. @@ -335,7 +343,7 @@ Configuration Steps: Recommended Configuration +++++++++++++++++++++++++++++ -.. only:: esp32c3 or esp32s3 +.. only:: esp32c6 or esp32c5 .. list-table:: :header-rows: 1 @@ -374,20 +382,125 @@ Recommended Configuration * - Power down CPU (:ref:`CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP`) - ON -.. only:: SOC_PM_SUPPORT_TAGMEM_PD + * - Power down flash in light sleep (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH`) + - OFF + + * - ``max_freq_mhz`` + - The maximum CPU frequency supported by {IDF_TARGET_NAME} + + * - ``min_freq_mhz`` + - {CONFIG_XTAL_FREQ} + + * - ``light_sleep_enable`` + - true + + .. note:: + Configurations not mentioned in the above table are set to default. + +.. only:: esp32s3 + + .. list-table:: + :header-rows: 1 + :widths: 30 15 + + * - Configuration Name + - Configuration Status + + * - Enable power management component (:ref:`CONFIG_PM_ENABLE`) + - ON + + * - Enable RTOS Tickless IDLE mode (:ref:`CONFIG_FREERTOS_USE_TICKLESS_IDLE`) + - ON + + * - RTOS Tick rate (Hz) (:ref:`CONFIG_FREERTOS_HZ`) + - 1000 + + * - Minimum IDLE Tick count before entering sleep mode (:ref:`CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP`) + - 3 + + * - Put light sleep related codes in IRAM (:ref:`CONFIG_PM_SLP_IRAM_OPT`) + - OFF + + * - Put RTOS IDLE related codes in IRAM (:ref:`CONFIG_PM_RTOS_IDLE_OPT`) + - OFF + + * - RTC slow clock source (:ref:`CONFIG_RTC_CLK_SRC`) + - Internal 150 kHz OSC + + * - Disable all GPIO when chip at sleep (:ref:`CONFIG_PM_SLP_DISABLE_GPIO`) + - ON + + * - Power down MAC and baseband (:ref:`CONFIG_ESP_PHY_MAC_BB_PD`) + - ON + + * - Power down CPU (:ref:`CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP`) + - ON * - Power down I/D-cache tag memory (:ref:`CONFIG_PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP`) - ON - * - Power down flash in light sleep (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH`) - OFF * - ``max_freq_mhz`` - - 160 + - The maximum CPU frequency supported by {IDF_TARGET_NAME} * - ``min_freq_mhz`` - - 40 + - {CONFIG_XTAL_FREQ} + + * - ``light_sleep_enable`` + - true + + .. note:: + Configurations not mentioned in the above table are set to default. + +.. only:: esp32c3 + + .. list-table:: + :header-rows: 1 + :widths: 30 15 + + * - Configuration Name + - Configuration Status + + * - Enable power management component (:ref:`CONFIG_PM_ENABLE`) + - ON + + * - Enable RTOS Tickless IDLE mode (:ref:`CONFIG_FREERTOS_USE_TICKLESS_IDLE`) + - ON + + * - RTOS Tick rate (Hz) (:ref:`CONFIG_FREERTOS_HZ`) + - 1000 + + * - Minimum IDLE Tick count before entering sleep mode (:ref:`CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP`) + - 3 + + * - Put light sleep related codes in IRAM (:ref:`CONFIG_PM_SLP_IRAM_OPT`) + - OFF + + * - Put RTOS IDLE related codes in IRAM (:ref:`CONFIG_PM_RTOS_IDLE_OPT`) + - OFF + + * - RTC slow clock source (:ref:`CONFIG_RTC_CLK_SRC`) + - Internal 150 kHz OSC + + * - Disable all GPIO when chip at sleep (:ref:`CONFIG_PM_SLP_DISABLE_GPIO`) + - ON + + * - Power down MAC and baseband (:ref:`CONFIG_ESP_PHY_MAC_BB_PD`) + - ON + + * - Power down CPU (:ref:`CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP`) + - ON + + * - Power down flash in light sleep (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH`) + - OFF + + * - ``max_freq_mhz`` + - The maximum CPU frequency supported by {IDF_TARGET_NAME} + + * - ``min_freq_mhz`` + - {CONFIG_XTAL_FREQ} * - ``light_sleep_enable`` - true @@ -432,7 +545,7 @@ Recommended Configuration - 160 * - ``min_freq_mhz`` - - 40 + - {CONFIG_XTAL_FREQ} * - ``light_sleep_enable`` - true @@ -480,7 +593,7 @@ Recommended Configuration - 120 * - ``min_freq_mhz`` - - 40 + - {CONFIG_XTAL_FREQ} * - ``light_sleep_enable`` - true diff --git a/docs/en/api-guides/low-power-mode/low-power-mode-wifi.rst b/docs/en/api-guides/low-power-mode/low-power-mode-wifi.rst index c09170b364..7ab7eecadf 100644 --- a/docs/en/api-guides/low-power-mode/low-power-mode-wifi.rst +++ b/docs/en/api-guides/low-power-mode/low-power-mode-wifi.rst @@ -5,9 +5,9 @@ Introduction to Low Power Mode in Wi-Fi Scenarios After the previous introduction to low power mode from a systemic perspective, this section delves into low power mode in Wi-Fi scenarios. Due to the complexity of Wi-Fi scenarios, basic principles of Wi-Fi power saving will be introduced before specific low power mode. This section is focused on station mode. -.. todo - add sleep-current/esp32c5_summary.inc and sleep-current/esp32c61_summary.inc +.. todo - add sleep-current/esp32c61_summary.inc -.. only:: not esp32c5 and not esp32c61 +.. only:: not esp32c61 Choosing Low Power Mode in Wi-Fi Scenarios --------------------------------------------- @@ -355,17 +355,17 @@ Modem-sleep Mode Configuration - 1000 * - ``max_freq_mhz`` - - 160 + - The maximum CPU frequency supported by {IDF_TARGET_NAME} * - ``min_freq_mhz`` - - 40 + - {CONFIG_XTAL_FREQ} * - ``light_sleep_enable`` - false - .. todo - add sleep-current/esp32c5_modem_sleep.inc sleep-current/esp32c61_modem_sleep.inc + .. todo - add sleep-current/esp32c61_modem_sleep.inc - .. only:: not esp32c5 and not esp32c61 + .. only:: not esp32c61 - Configuration Performance @@ -377,9 +377,9 @@ Auto Light-sleep Mode + Wi-Fi Scenario Configuration Auto Light-sleep mode in Wi-Fi scenarios does not require wake-up source configuration compared with a pure system. But the remaining part of configuration is basically the same in the two operation scenarios. Therefore, detailed introduction of configurable options, configuration steps, and recommended configurations can be found in the previous section :ref:`Deep-sleep Mode`, with the Wi-Fi-related configurations set to default. -.. todo - add sleep-current/esp32c5_light_sleep.inc and leep-current/esp32c61_light_sleep.inc +.. todo - add eep-current/esp32c61_light_sleep.inc -.. only:: not esp32c5 and not esp32c61 +.. only:: not esp32c61 - Configuration Performance @@ -415,3 +415,11 @@ Deep-sleep mode configuration in Wi-Fi scenarios is essentially the same as in a .. only:: esp32c2 Average current approximately 4.9 μA + + .. only:: esp32c6 + + Average current approximately 6.7 μA + + .. only:: esp32c5 + + Average current approximately 10.0 μA diff --git a/docs/en/api-guides/sleep-current/esp32c5_light_sleep.inc b/docs/en/api-guides/sleep-current/esp32c5_light_sleep.inc new file mode 100644 index 0000000000..5577f33535 --- /dev/null +++ b/docs/en/api-guides/sleep-current/esp32c5_light_sleep.inc @@ -0,0 +1,27 @@ +.. list-table:: + :header-rows: 1 + :widths: 20 10 20 20 20 + + * - CPU frequency + - DTIM + - Average current (mA) + - Max current (mA) + - Min current (mA) + + * - 240 MHz + - 1 + - 1.342 + - 80.375 + - 0.218 + + * - 240 MHz + - 3 + - 0.651 + - 81.179 + - 0.219 + + * - 240 MHz + - 10 + - 0.398 + - 80.518 + - 0.217 diff --git a/docs/en/api-guides/sleep-current/esp32c5_modem_sleep.inc b/docs/en/api-guides/sleep-current/esp32c5_modem_sleep.inc new file mode 100644 index 0000000000..b0e551ce6c --- /dev/null +++ b/docs/en/api-guides/sleep-current/esp32c5_modem_sleep.inc @@ -0,0 +1,107 @@ +.. list-table:: + :header-rows: 1 + :widths: 20 10 10 20 24 20 20 + + * - CPU frequency + - DFS + - DTIM + - Wi-Fi Band + - Average current (mA) + - Max current (mA) + - Min current (mA) + + * - 240 MHz + - ON + - 1 + - 2.4 GHz + - 24.766 + - 88.836 + - 23.139 + + * - 240 MHz + - OFF + - 1 + - 2.4 GHz + - 32.394 + - 97.378 + - 30.776 + + * - 240 MHz + - ON + - 3 + - 2.4 GHz + - 24.19 + - 89.176 + - 23.229 + + * - 240 MHz + - OFF + - 3 + - 2.4 GHz + - 31.618 + - 97.439 + - 30.778 + + * - 240 MHz + - ON + - 10 + - 2.4 GHz + - 23.998 + - 88.524 + - 23.252 + + * - 240 MHz + - OFF + - 10 + - 2.4 GHz + - 31.281 + - 98.254 + - 30.788 + + * - 240 MHz + - ON + - 1 + - 5 GHz + - 25.467 + - 114.746 + - 24.387 + + * - 240 MHz + - OFF + - 1 + - 5 GHz + - 32.329 + - 117.077 + - 31.948 + + * - 240 MHz + - ON + - 3 + - 5 GHz + - 25.208 + - 112.746 + - 24.421 + + * - 240 MHz + - OFF + - 3 + - 5 GHz + - 32.088 + - 117.227 + - 31.948 + + * - 240 MHz + - ON + - 10 + - 5 GHz + - 25.151 + - 114.438 + - 24.432 + + * - 160 MHz + - OFF + - 10 + - 5 GHz + - 32.011 + - 119.908 + - 31.955 diff --git a/docs/en/api-guides/sleep-current/esp32c5_summary.inc b/docs/en/api-guides/sleep-current/esp32c5_summary.inc new file mode 100644 index 0000000000..4df10c0851 --- /dev/null +++ b/docs/en/api-guides/sleep-current/esp32c5_summary.inc @@ -0,0 +1,87 @@ +.. list-table:: + :header-rows: 1 + :widths: 20 20 30 20 20 + + * - Item + - Modem-sleep + - Modem-sleep+DFS + - Auto Light-sleep + - Deep-sleep + + * - Sleep + - Automatic + - Automatic + - Automatic + - Manual + + * - Wake-up + - Automatic + - Automatic + - Automatic + - Configure Wake-up Source + + * - Wi-Fi Connection + - Maintain + - Maintain + - Maintain + - Disconnect + + * - CPU + - On + - On/Throttled + - Paused + - Off + + * - System Clock + - On + - On + - Off + - Off + + * - Peripherals + - On + - On + - On + - Off + + * - DTIM1 (2.4 GHz) + - 32.394 mA + - 24.766 mA + - 1.342 mA + - / + + * - DTIM1 (5 GHz) + - 32.329 mA + - 25.467 mA + - 1.514 mA + - / + + * - DTIM3 (2.4 GHz) + - 31.618 mA + - 24.19 mA + - 0.651 mA + - / + + * - DTIM3 (5 GHz) + - 32.088 mA + - 25.208 mA + - 0.764 mA + - / + + * - DTIM10 (2.4 GHz) + - 31.281 mA + - 23.998 mA + - 0.398 mA + - / + + * - DTIM10 (5 GHz) + - 32.011 mA + - 25.151 mA + - 0.451 mA + - / + + * - Average Current + - / + - / + - / + - 10.0 μA diff --git a/docs/zh_CN/api-guides/low-power-mode/low-power-mode-soc.rst b/docs/zh_CN/api-guides/low-power-mode/low-power-mode-soc.rst index a71940638c..24244d8732 100644 --- a/docs/zh_CN/api-guides/low-power-mode/low-power-mode-soc.rst +++ b/docs/zh_CN/api-guides/low-power-mode/low-power-mode-soc.rst @@ -218,10 +218,10 @@ DFS 有如下可配置选项: - 1000 * - ``max_freq_mhz`` - - 160 + - {IDF_TARGET_NAME} 支持的最大 CPU 频率 * - ``min_freq_mhz`` - - 40 + - {CONFIG_XTAL_FREQ} * - ``light_sleep_enable`` - false @@ -288,6 +288,14 @@ Light-sleep 模式配置 由于 flash 和 PSRAM 共用供电管脚,PSRAM 关闭供电将会导致数据丢失,因此,为保证 light sleep 不破坏程序运行状态,启用该选项的前提是系统没有使用 PSRAM。 +.. only:: SOC_PM_SUPPORT_TOP_PD + + - 关闭数字外设模块及 TOP 电源域下的所有子电源域 (:ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`) + +.. only:: SOC_PM_SUPPORT_RTC_PERIPH_PD + + - 关闭 RTC 数字外设模块,系统睡眠时自动关闭 RTC 数字外设是系统电源管理默认策略,用户可以调用 `esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON)` 在睡眠状态下开启 RTC 数字外设模块 + .. only:: esp32c2 - 减少 Power Managemet 模块片内 RAM 内存资源使用量 (:ref:`CONFIG_PM_SLEEP_FUNC_IN_IRAM`),当 :ref:`CONFIG_PM_SLEEP_FUNC_IN_IRAM` 禁止时,下面表格中选项分别用于控制 Power Management 模块各部分组件启用或禁止片内 RAM 优化 @@ -335,7 +343,61 @@ Light-sleep 模式配置 推荐配置 +++++++++ -.. only:: esp32c3 or esp32s3 +.. only:: esp32c6 or esp32c5 + + .. list-table:: + :header-rows: 1 + :widths: 30 15 + + * - 配置名称 + - 设置情况 + + * - 启用电源管理组件 (:ref:`CONFIG_PM_ENABLE`) + - ON + + * - 启用 Tickless IDLE 模式 (:ref:`CONFIG_FREERTOS_USE_TICKLESS_IDLE`) + - ON + + * - RTOS Tick rate (Hz) (:ref:`CONFIG_FREERTOS_HZ`) + - 1000 + + * - 进入睡眠模式前最小 IDLE Tick 数 (:ref:`CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP`) + - 3 + + * - 将 light sleep 相关代码放置在片内 RAM 中 (:ref:`CONFIG_PM_SLP_IRAM_OPT`) + - ON + + * - 将 RTOS IDLE 相关代码放置在片内 RAM 中 (:ref:`CONFIG_PM_RTOS_IDLE_OPT`) + - ON + + * - RTC 慢速时钟源 (:ref:`CONFIG_RTC_CLK_SRC`) + - 内部 150 kHz 振荡器 + + * - 芯片休眠时禁用所有 GPIO (:ref:`CONFIG_PM_SLP_DISABLE_GPIO`) + - ON + + * - 关闭 MAC 和基带 (:ref:`CONFIG_ESP_PHY_MAC_BB_PD`) + - ON + + * - 关闭 CPU (:ref:`CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP`) + - ON + + * - 在 light sleep 状态关闭 flash 供电 (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH`) + - OFF + + * - ``max_freq_mhz`` + - {IDF_TARGET_NAME} 支持的最大 CPU 频率 + + * - ``min_freq_mhz`` + - {CONFIG_XTAL_FREQ} + + * - ``light_sleep_enable`` + - true + + .. note:: + 上表中不涉及的配置均是默认。 + +.. only:: esp32s3 .. list-table:: :header-rows: 1 @@ -374,20 +436,71 @@ Light-sleep 模式配置 * - 关闭 CPU (:ref:`CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP`) - ON -.. only:: SOC_PM_SUPPORT_TAGMEM_PD - * - 关闭指令和数据缓存中的标签存储器 (I/D-cache tag memory) (:ref:`CONFIG_PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP`) - ON - * - 在 light sleep 状态关闭 flash 供电 (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH`) - OFF * - ``max_freq_mhz`` - - 160 + - {IDF_TARGET_NAME} 支持的最大 CPU 频率 * - ``min_freq_mhz`` - - 40 + - {CONFIG_XTAL_FREQ} + + * - ``light_sleep_enable`` + - true + + .. note:: + 上表中不涉及的配置均是默认。 + +.. only:: esp32c3 + + .. list-table:: + :header-rows: 1 + :widths: 30 15 + + * - 配置名称 + - 设置情况 + + * - 启用电源管理组件 (:ref:`CONFIG_PM_ENABLE`) + - ON + + * - 启用 Tickless IDLE 模式 (:ref:`CONFIG_FREERTOS_USE_TICKLESS_IDLE`) + - ON + + * - RTOS Tick rate (Hz) (:ref:`CONFIG_FREERTOS_HZ`) + - 1000 + + * - 进入睡眠模式前最小 IDLE Tick 数 (:ref:`CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP`) + - 3 + + * - 将 light sleep 相关代码放置在片内 RAM 中 (:ref:`CONFIG_PM_SLP_IRAM_OPT`) + - OFF + + * - 将 RTOS IDLE 相关代码放置在片内 RAM 中 (:ref:`CONFIG_PM_RTOS_IDLE_OPT`) + - OFF + + * - RTC 慢速时钟源 (:ref:`CONFIG_RTC_CLK_SRC`) + - 内部 150 kHz 振荡器 + + * - 芯片休眠时禁用所有 GPIO (:ref:`CONFIG_PM_SLP_DISABLE_GPIO`) + - ON + + * - 关闭 MAC 和基带 (:ref:`CONFIG_ESP_PHY_MAC_BB_PD`) + - ON + + * - 关闭 CPU (:ref:`CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP`) + - ON + + * - 在 light sleep 状态关闭 flash 供电 (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH`) + - OFF + + * - ``max_freq_mhz`` + - {IDF_TARGET_NAME} 支持的最大 CPU 频率 + + * - ``min_freq_mhz`` + - {CONFIG_XTAL_FREQ} * - ``light_sleep_enable`` - true @@ -432,7 +545,7 @@ Light-sleep 模式配置 - 160 * - ``min_freq_mhz`` - - 40 + - {CONFIG_XTAL_FREQ} * - ``light_sleep_enable`` - true @@ -480,7 +593,7 @@ Light-sleep 模式配置 - 120 * - ``min_freq_mhz`` - - 40 + - {CONFIG_XTAL_FREQ} * - ``light_sleep_enable`` - true diff --git a/docs/zh_CN/api-guides/low-power-mode/low-power-mode-wifi.rst b/docs/zh_CN/api-guides/low-power-mode/low-power-mode-wifi.rst index 2ffe3331e9..95be299570 100644 --- a/docs/zh_CN/api-guides/low-power-mode/low-power-mode-wifi.rst +++ b/docs/zh_CN/api-guides/low-power-mode/low-power-mode-wifi.rst @@ -5,9 +5,9 @@ Wi-Fi 场景下低功耗模式介绍 本节将结合纯系统下的功耗模式来介绍 Wi-Fi 场景下的低功耗模式。因为 Wi-Fi 场景的复杂性,本节会首先介绍 Wi-Fi 省电的基本原理,然后再介绍具体的低功耗模式。本节主要针对 station 模式。 -.. todo - add sleep-current/esp32c5_summary.inc and sleep-current/esp32c61_summary.inc +.. todo - add sleep-current/esp32c61_summary.inc -.. only:: not esp32c5 and not esp32c61 +.. only:: not esp32c61 Wi-Fi 场景如何选择低功耗模式 -------------------------------------- @@ -355,17 +355,17 @@ Modem-sleep 模式配置 - 1000 * - ``max_freq_mhz`` - - 160 + - {IDF_TARGET_NAME} 支持的最大 CPU 频率 * - ``min_freq_mhz`` - - 40 + - {CONFIG_XTAL_FREQ} * - ``light_sleep_enable`` - false - .. todo - add sleep-current/esp32c5_modem_sleep.inc sleep-current/esp32c61_modem_sleep.inc + .. todo - add sleep-current/esp32c61_modem_sleep.inc - .. only:: not esp32c5 and not esp32c61 + .. only:: not esp32c61 - 配置表现 @@ -377,9 +377,9 @@ Auto Light-sleep 模式 + Wi-Fi 场景配置 Auto Light-sleep 在 Wi-Fi 场景下的配置比纯系统下少了唤醒源的配置要求,其余几乎与纯系统下配置一致,因此可配置选项、配置步骤、推荐配置的详细介绍可以参考上文 :ref:`Deep-sleep 模式`。同时 Wi-Fi 相关配置保持默认。 -.. todo - add sleep-current/esp32c5_light_sleep.inc and leep-current/esp32c61_light_sleep.inc +.. todo - add sleep-current/esp32c61_light_sleep.inc -.. only:: not esp32c5 and not esp32c61 +.. only:: not esp32c61 - 配置表现 @@ -415,3 +415,11 @@ Deep-sleep 模式在 Wi-Fi 场景下的配置与纯系统下配置基本一致 .. only:: esp32c2 平均电流约 4.9 μA + + .. only:: esp32c6 + + 平均电流约 6.7 μA + + .. only:: esp32c5 + + 平均电流约 10.0 μA diff --git a/docs/zh_CN/api-guides/sleep-current/esp32c5_light_sleep.inc b/docs/zh_CN/api-guides/sleep-current/esp32c5_light_sleep.inc new file mode 100644 index 0000000000..6673f03295 --- /dev/null +++ b/docs/zh_CN/api-guides/sleep-current/esp32c5_light_sleep.inc @@ -0,0 +1,27 @@ +.. list-table:: + :header-rows: 1 + :widths: 20 10 20 20 20 + + * - CPU 频率 + - DTIM + - 平均电流 (mA) + - 最大电流 (mA) + - 最小电流 (mA) + + * - 240 MHz + - 1 + - 1.342 + - 80.375 + - 0.218 + + * - 240 MHz + - 3 + - 0.651 + - 81.179 + - 0.219 + + * - 240 MHz + - 10 + - 0.398 + - 80.518 + - 0.217 diff --git a/docs/zh_CN/api-guides/sleep-current/esp32c5_modem_sleep.inc b/docs/zh_CN/api-guides/sleep-current/esp32c5_modem_sleep.inc new file mode 100644 index 0000000000..55623d7ec8 --- /dev/null +++ b/docs/zh_CN/api-guides/sleep-current/esp32c5_modem_sleep.inc @@ -0,0 +1,107 @@ +.. list-table:: + :header-rows: 1 + :widths: 20 10 10 20 24 20 20 + + * - CPU 频率 + - DFS + - DTIM + - Wi-Fi Band + - 平均电流 (mA) + - 最大电流 (mA) + - 最小电流 (mA) + + * - 240 MHz + - ON + - 1 + - 2.4 GHz + - 24.766 + - 88.836 + - 23.139 + + * - 240 MHz + - OFF + - 1 + - 2.4 GHz + - 32.394 + - 97.378 + - 30.776 + + * - 240 MHz + - ON + - 3 + - 2.4 GHz + - 24.19 + - 89.176 + - 23.229 + + * - 240 MHz + - OFF + - 3 + - 2.4 GHz + - 31.618 + - 97.439 + - 30.778 + + * - 240 MHz + - ON + - 10 + - 2.4 GHz + - 23.998 + - 88.524 + - 23.252 + + * - 240 MHz + - OFF + - 10 + - 2.4 GHz + - 31.281 + - 98.254 + - 30.788 + + * - 240 MHz + - ON + - 1 + - 5 GHz + - 25.467 + - 114.746 + - 24.387 + + * - 240 MHz + - OFF + - 1 + - 5 GHz + - 32.329 + - 117.077 + - 31.948 + + * - 240 MHz + - ON + - 3 + - 5 GHz + - 25.208 + - 112.746 + - 24.421 + + * - 240 MHz + - OFF + - 3 + - 5 GHz + - 32.088 + - 117.227 + - 31.948 + + * - 240 MHz + - ON + - 10 + - 5 GHz + - 25.151 + - 114.438 + - 24.432 + + * - 160 MHz + - OFF + - 10 + - 5 GHz + - 32.011 + - 119.908 + - 31.955 diff --git a/docs/zh_CN/api-guides/sleep-current/esp32c5_summary.inc b/docs/zh_CN/api-guides/sleep-current/esp32c5_summary.inc new file mode 100644 index 0000000000..ca51abd706 --- /dev/null +++ b/docs/zh_CN/api-guides/sleep-current/esp32c5_summary.inc @@ -0,0 +1,87 @@ +.. list-table:: + :header-rows: 1 + :widths: 20 20 30 20 20 + + * - 项目 + - Modem-sleep + - Modem-sleep+DFS + - Auto Light-sleep + - Deep-sleep + + * - 休眠 + - 自动 + - 自动 + - 自动 + - 手动 + + * - 唤醒 + - 自动 + - 自动 + - 自动 + - 配置唤醒源 + + * - Wi-Fi连接 + - 保持 + - 保持 + - 保持 + - 断开 + + * - CPU + - 开 + - 开/降频 + - 暂停或关 + - 关 + + * - 系统时钟 + - 开 + - 开 + - 关 + - 关 + + * - 外设 + - 开 + - 开 + - 暂停或关 + - 关 + + * - DTIM1 (2.4 GHz) + - 32.394 mA + - 24.766 mA + - 1.342 mA + - / + + * - DTIM1 (5 GHz) + - 32.329 mA + - 25.467 mA + - 1.514 mA + - / + + * - DTIM3 (2.4 GHz) + - 31.618 mA + - 24.19 mA + - 0.651 mA + - / + + * - DTIM3 (5 GHz) + - 32.088 mA + - 25.208 mA + - 0.764 mA + - / + + * - DTIM10 (2.4 GHz) + - 31.281 mA + - 23.998 mA + - 0.398 mA + - / + + * - DTIM10 (5 GHz) + - 32.011 mA + - 25.151 mA + - 0.451 mA + - / + + * - 平均电流 + - / + - / + - / + - 10.0 μA From aced53e693ab848c7e45472a4a2763b7e6cab7a6 Mon Sep 17 00:00:00 2001 From: Jin Cheng Date: Mon, 5 Jan 2026 17:34:26 +0800 Subject: [PATCH 180/226] fix(bt/controller): fixed wrong key type during changing connection link key --- components/bt/controller/lib_esp32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32 b/components/bt/controller/lib_esp32 index 05e9c75b89..1359f195ed 160000 --- a/components/bt/controller/lib_esp32 +++ b/components/bt/controller/lib_esp32 @@ -1 +1 @@ -Subproject commit 05e9c75b8977a3767c5cf5afedcd4c7f8c0f5f62 +Subproject commit 1359f195ed834130739f0130322e1a1cd5464a11 From b7050c93263db2d2f8c32bbad88847af21282d21 Mon Sep 17 00:00:00 2001 From: yangfeng Date: Mon, 1 Dec 2025 11:44:53 +0800 Subject: [PATCH 181/226] docs(bt): update Classic Bluetooth api reference of GAP --- .../api/include/api/esp_gap_bt_api.h | 147 ++++++++++-------- .../en/api-reference/bluetooth/esp_gap_bt.rst | 7 +- 2 files changed, 85 insertions(+), 69 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h index 07866b8a3c..7d535c80d1 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.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 */ @@ -38,16 +38,16 @@ typedef enum { ESP_BT_SET_COD_RESERVED_2 = 0x10, /*!< overwrite the two least significant bits reserved_2 whose default value is 0b00; other values of reserved_2 are invalid according to Bluetooth Core Specification 5.4 */ } esp_bt_cod_mode_t; -#define ESP_BT_GAP_AFH_CHANNELS_LEN 10 -typedef uint8_t esp_bt_gap_afh_channels[ESP_BT_GAP_AFH_CHANNELS_LEN]; +#define ESP_BT_GAP_AFH_CHANNELS_LEN 10 /*!< length of AFH channel map in bytes */ +typedef uint8_t esp_bt_gap_afh_channels[ESP_BT_GAP_AFH_CHANNELS_LEN]; /*!< AFH channels */ - -/// Discoverability and Connectability mode +/// Connectability mode typedef enum { ESP_BT_NON_CONNECTABLE, /*!< Non-connectable */ ESP_BT_CONNECTABLE, /*!< Connectable */ } esp_bt_connection_mode_t; +/// Discoverability mode typedef enum { ESP_BT_NON_DISCOVERABLE, /*!< Non-discoverable */ ESP_BT_LIMITED_DISCOVERABLE, /*!< Limited Discoverable */ @@ -75,7 +75,7 @@ typedef struct { void *val; /*!< Device property value */ } esp_bt_gap_dev_prop_t; -/// Extended Inquiry Response data type +/* Extended Inquiry Response data type */ #define ESP_BT_EIR_TYPE_FLAGS 0x01 /*!< Flag with information such as BR/EDR and LE support */ #define ESP_BT_EIR_TYPE_INCMPL_16BITS_UUID 0x02 /*!< Incomplete list of 16-bit service UUIDs */ #define ESP_BT_EIR_TYPE_CMPL_16BITS_UUID 0x03 /*!< Complete list of 16-bit service UUIDs */ @@ -90,50 +90,50 @@ typedef struct { #define ESP_BT_EIR_TYPE_MANU_SPECIFIC 0xff /*!< Manufacturer specific data */ #define ESP_BT_EIR_TYPE_MAX_NUM 12 /*!< MAX number of EIR type */ -typedef uint8_t esp_bt_eir_type_t; +typedef uint8_t esp_bt_eir_type_t; /*!< EIR type */ /* ACL Packet Types */ -#define ESP_BT_ACL_PKT_TYPES_MASK_DM1 0x0008 -#define ESP_BT_ACL_PKT_TYPES_MASK_DH1 0x0010 -#define ESP_BT_ACL_PKT_TYPES_MASK_DM3 0x0400 -#define ESP_BT_ACL_PKT_TYPES_MASK_DH3 0x0800 -#define ESP_BT_ACL_PKT_TYPES_MASK_DM5 0x4000 -#define ESP_BT_ACL_PKT_TYPES_MASK_DH5 0x8000 -#define ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH1 0x0002 -#define ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH1 0x0004 -#define ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH3 0x0100 -#define ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH3 0x0200 -#define ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH5 0x1000 -#define ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH5 0x2000 +#define ESP_BT_ACL_PKT_TYPES_MASK_DM1 0x0008 /*!< DM1 packet type mask */ +#define ESP_BT_ACL_PKT_TYPES_MASK_DH1 0x0010 /*!< DH1 packet type mask */ +#define ESP_BT_ACL_PKT_TYPES_MASK_DM3 0x0400 /*!< DM3 packet type mask */ +#define ESP_BT_ACL_PKT_TYPES_MASK_DH3 0x0800 /*!< DH3 packet type mask */ +#define ESP_BT_ACL_PKT_TYPES_MASK_DM5 0x4000 /*!< DM5 packet type mask */ +#define ESP_BT_ACL_PKT_TYPES_MASK_DH5 0x8000 /*!< DH5 packet type mask */ +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH1 0x0002 /*!< No 2-DH1 packet type mask */ +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH1 0x0004 /*!< No 3-DH1 packet type mask */ +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH3 0x0100 /*!< No 2-DH3 packet type mask */ +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH3 0x0200 /*!< No 3-DH3 packet type mask */ +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH5 0x1000 /*!< No 2-DH5 packet type mask */ +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH5 0x2000 /*!< No 3-DH5 packet type mask */ -// DM1 can not be disabled. All options are mandatory to include DM1. -#define ESP_BT_ACL_DM1_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DM1 | 0x330e) /* 0x330e */ -#define ESP_BT_ACL_DH1_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DH1 | 0x330e) /* 0x331e */ -#define ESP_BT_ACL_DM3_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DM3 | 0x330e) /* 0x370e */ -#define ESP_BT_ACL_DH3_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DH3 | 0x330e) /* 0x3b0e */ -#define ESP_BT_ACL_DM5_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DM5 | 0x330e) /* 0x730e */ -#define ESP_BT_ACL_DH5_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DH5 | 0x330e) /* 0xb30e */ -#define ESP_BT_ACL_2_DH1_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH1 & 0x330e) /* 0x330c */ -#define ESP_BT_ACL_3_DH1_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH1 & 0x330e) /* 0x330a */ -#define ESP_BT_ACL_2_DH3_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH3 & 0x330e) /* 0x320e */ -#define ESP_BT_ACL_3_DH3_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH3 & 0x330e) /* 0x310e */ -#define ESP_BT_ACL_2_DH5_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH5 & 0x330e) /* 0x230e */ -#define ESP_BT_ACL_3_DH5_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH5 & 0x330e) /* 0x130e */ +/* DM1 can not be disabled. All options are mandatory to include DM1. */ +#define ESP_BT_ACL_DM1_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DM1 | 0x330e) /*!< 0x330e */ +#define ESP_BT_ACL_DH1_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DH1 | 0x330e) /*!< 0x331e */ +#define ESP_BT_ACL_DM3_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DM3 | 0x330e) /*!< 0x370e */ +#define ESP_BT_ACL_DH3_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DH3 | 0x330e) /*!< 0x3b0e */ +#define ESP_BT_ACL_DM5_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DM5 | 0x330e) /*!< 0x730e */ +#define ESP_BT_ACL_DH5_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DH5 | 0x330e) /*!< 0xb30e */ +#define ESP_BT_ACL_2_DH1_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH1 & 0x330e) /*!< 0x330c */ +#define ESP_BT_ACL_3_DH1_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH1 & 0x330e) /*!< 0x330a */ +#define ESP_BT_ACL_2_DH3_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH3 & 0x330e) /*!< 0x320e */ +#define ESP_BT_ACL_3_DH3_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH3 & 0x330e) /*!< 0x310e */ +#define ESP_BT_ACL_2_DH5_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH5 & 0x330e) /*!< 0x230e */ +#define ESP_BT_ACL_3_DH5_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH5 & 0x330e) /*!< 0x130e */ -typedef uint16_t esp_bt_acl_pkt_type_t; +typedef uint16_t esp_bt_acl_pkt_type_t; /*!< ACL packet type */ /* Range of encryption key size */ -#define ESP_BT_ENC_KEY_SIZE_CTRL_MAX (16) -#define ESP_BT_ENC_KEY_SIZE_CTRL_MIN (7) +#define ESP_BT_ENC_KEY_SIZE_CTRL_MAX (16) /*!< Maximum of encryption key size */ +#define ESP_BT_ENC_KEY_SIZE_CTRL_MIN (7) /*!< Minimum of encryption key size */ /* ESP_BT_EIR_FLAG bit definition */ -#define ESP_BT_EIR_FLAG_LIMIT_DISC (0x01 << 0) -#define ESP_BT_EIR_FLAG_GEN_DISC (0x01 << 1) -#define ESP_BT_EIR_FLAG_BREDR_NOT_SPT (0x01 << 2) -#define ESP_BT_EIR_FLAG_DMT_CONTROLLER_SPT (0x01 << 3) -#define ESP_BT_EIR_FLAG_DMT_HOST_SPT (0x01 << 4) +#define ESP_BT_EIR_FLAG_LIMIT_DISC (0x01 << 0) /*!< Limited discoverable flag */ +#define ESP_BT_EIR_FLAG_GEN_DISC (0x01 << 1) /*!< General discoverable flag */ +#define ESP_BT_EIR_FLAG_BREDR_NOT_SPT (0x01 << 2) /*!< BR/EDR not supported flag */ +#define ESP_BT_EIR_FLAG_DMT_CONTROLLER_SPT (0x01 << 3) /*!< DMT controller supported flag */ +#define ESP_BT_EIR_FLAG_DMT_HOST_SPT (0x01 << 4) /*!< DMT host supported flag */ -#define ESP_BT_EIR_MAX_LEN 240 +#define ESP_BT_EIR_MAX_LEN 240 /*!< Maximum of EIR length */ /// EIR data content, according to "Supplement to the Bluetooth Core Specification" typedef struct { bool fec_required; /*!< FEC is required or not, true by default */ @@ -161,6 +161,7 @@ typedef enum { ESP_BT_COD_SRVC_INFORMATION = 0x400, /*!< Information, e.g., WEB-server, WAP-server */ } esp_bt_cod_srvc_t; +/// Pin type typedef enum{ ESP_BT_PIN_TYPE_VARIABLE = 0, /*!< Refer to BTM_PIN_TYPE_VARIABLE */ ESP_BT_PIN_TYPE_FIXED = 1, /*!< Refer to BTM_PIN_TYPE_FIXED */ @@ -169,29 +170,27 @@ typedef enum{ #define ESP_BT_PIN_CODE_LEN 16 /*!< Max pin code length */ typedef uint8_t esp_bt_pin_code_t[ESP_BT_PIN_CODE_LEN]; /*!< Pin Code (upto 128 bits) MSB is 0 */ +/// SP parameter type typedef enum { ESP_BT_SP_IOCAP_MODE = 0, /*!< Set IO mode */ //ESP_BT_SP_OOB_DATA, //TODO /*!< Set OOB data */ } esp_bt_sp_param_t; -/* relate to BTM_IO_CAP_xxx in stack/btm_api.h */ -#define ESP_BT_IO_CAP_OUT 0 /*!< DisplayOnly */ /* relate to BTM_IO_CAP_OUT in stack/btm_api.h */ -#define ESP_BT_IO_CAP_IO 1 /*!< DisplayYesNo */ /* relate to BTM_IO_CAP_IO in stack/btm_api.h */ -#define ESP_BT_IO_CAP_IN 2 /*!< KeyboardOnly */ /* relate to BTM_IO_CAP_IN in stack/btm_api.h */ -#define ESP_BT_IO_CAP_NONE 3 /*!< NoInputNoOutput */ /* relate to BTM_IO_CAP_NONE in stack/btm_api.h */ +/* Input/Output capabilities */ +#define ESP_BT_IO_CAP_OUT 0 /*!< DisplayOnly */ +#define ESP_BT_IO_CAP_IO 1 /*!< DisplayYesNo */ +#define ESP_BT_IO_CAP_IN 2 /*!< KeyboardOnly */ +#define ESP_BT_IO_CAP_NONE 3 /*!< NoInputNoOutput */ typedef uint8_t esp_bt_io_cap_t; /*!< Combination of the IO Capability */ - -/* BTM Power manager modes */ +/* BT Power manager modes */ #define ESP_BT_PM_MD_ACTIVE 0x00 /*!< Active mode */ #define ESP_BT_PM_MD_HOLD 0x01 /*!< Hold mode */ #define ESP_BT_PM_MD_SNIFF 0x02 /*!< Sniff mode */ #define ESP_BT_PM_MD_PARK 0x03 /*!< Park state */ -typedef uint8_t esp_bt_pm_mode_t; +typedef uint8_t esp_bt_pm_mode_t; /*!< BT Power manager mode type */ - - -/// Bits of major service class field +/* Bits of major service class field */ #define ESP_BT_COD_SRVC_BIT_MASK (0xffe000) /*!< Major service bit mask */ #define ESP_BT_COD_SRVC_BIT_OFFSET (13) /*!< Major service bit offset */ @@ -199,9 +198,9 @@ typedef uint8_t esp_bt_pm_mode_t; typedef enum { ESP_BT_COD_MAJOR_DEV_MISC = 0, /*!< Miscellaneous */ ESP_BT_COD_MAJOR_DEV_COMPUTER = 1, /*!< Computer */ - ESP_BT_COD_MAJOR_DEV_PHONE = 2, /*!< Phone(cellular, cordless, pay phone, modem */ + ESP_BT_COD_MAJOR_DEV_PHONE = 2, /*!< Phone (cellular, cordless, pay phone, modem) */ ESP_BT_COD_MAJOR_DEV_LAN_NAP = 3, /*!< LAN, Network Access Point */ - ESP_BT_COD_MAJOR_DEV_AV = 4, /*!< Audio/Video(headset, speaker, stereo, video display, VCR */ + ESP_BT_COD_MAJOR_DEV_AV = 4, /*!< Audio/Video (headset, speaker, stereo, video display, VCR) */ ESP_BT_COD_MAJOR_DEV_PERIPHERAL = 5, /*!< Peripheral(mouse, joystick, keyboard) */ ESP_BT_COD_MAJOR_DEV_IMAGING = 6, /*!< Imaging(printer, scanner, camera, display */ ESP_BT_COD_MAJOR_DEV_WEARABLE = 7, /*!< Wearable */ @@ -232,20 +231,19 @@ typedef enum { ESP_BT_COD_MINOR_PERIPHERAL_HAND_GESTURAL_INPUT = 0x09, /*!< Hand Gestural Input */ } esp_bt_cod_minor_peripheral_t; -/// Bits of major device class field +/* Bits of major device class field */ #define ESP_BT_COD_MAJOR_DEV_BIT_MASK (0x1f00) /*!< Major device bit mask */ #define ESP_BT_COD_MAJOR_DEV_BIT_OFFSET (8) /*!< Major device bit offset */ -/// Bits of minor device class field +/* Bits of minor device class field */ #define ESP_BT_COD_MINOR_DEV_BIT_MASK (0xfc) /*!< Minor device bit mask */ #define ESP_BT_COD_MINOR_DEV_BIT_OFFSET (2) /*!< Minor device bit offset */ -/// Bits of format type +/* Bits of format type */ #define ESP_BT_COD_FORMAT_TYPE_BIT_MASK (0x03) /*!< Format type bit mask */ #define ESP_BT_COD_FORMAT_TYPE_BIT_OFFSET (0) /*!< Format type bit offset */ -/// Class of device format type 1 -#define ESP_BT_COD_FORMAT_TYPE_1 (0x00) +#define ESP_BT_COD_FORMAT_TYPE_1 (0x00) /*!< Class of device format type 1 */ /** Bluetooth Device Discovery state */ typedef enum { @@ -253,7 +251,7 @@ typedef enum { ESP_BT_GAP_DISCOVERY_STARTED, /*!< Device discovery started */ } esp_bt_gap_discovery_state_t; -/// Type of link key +/* Type of link key */ #define ESP_BT_LINK_KEY_COMB (0x00) /*!< Combination Key */ #define ESP_BT_LINK_KEY_DBG_COMB (0x03) /*!< Debug Combination Key */ #define ESP_BT_LINK_KEY_UNAUTHED_COMB_P192 (0x04) /*!< Unauthenticated Combination Key generated from P-192 */ @@ -261,13 +259,13 @@ typedef enum { #define ESP_BT_LINK_KEY_CHG_COMB (0x06) /*!< Changed Combination Key */ #define ESP_BT_LINK_KEY_UNAUTHED_COMB_P256 (0x07) /*!< Unauthenticated Combination Key generated from P-256 */ #define ESP_BT_LINK_KEY_AUTHED_COMB_P256 (0x08) /*!< Authenticated Combination Key generated from P-256 */ -typedef uint8_t esp_bt_link_key_type_t; +typedef uint8_t esp_bt_link_key_type_t; /*!< Link key type */ -/// Type of encryption +/* Type of encryption */ #define ESP_BT_ENC_MODE_OFF (0x00) /*!< Link Level Encryption is OFF */ #define ESP_BT_ENC_MODE_E0 (0x01) /*!< Link Level Encryption is ON with E0 */ #define ESP_BT_ENC_MODE_AES (0x02) /*!< Link Level Encryption is ON with AES-CCM */ -typedef uint8_t esp_bt_enc_mode_t; +typedef uint8_t esp_bt_enc_mode_t; /*!< encryption mode type */ /// BT GAP callback events typedef enum { @@ -284,7 +282,7 @@ typedef enum { ESP_BT_GAP_CONFIG_EIR_DATA_EVT, /*!< Config EIR data event */ ESP_BT_GAP_SET_AFH_CHANNELS_EVT, /*!< Set AFH channels event */ ESP_BT_GAP_READ_REMOTE_NAME_EVT, /*!< Read Remote Name event */ - ESP_BT_GAP_MODE_CHG_EVT, + ESP_BT_GAP_MODE_CHG_EVT, /*!< Mode change event */ ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT, /*!< remove bond device complete event */ ESP_BT_GAP_QOS_CMPL_EVT, /*!< QOS complete event */ ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT, /*!< ACL connection complete status event */ @@ -304,11 +302,11 @@ typedef enum { ESP_BT_INQ_MODE_LIMITED_INQUIRY, /*!< Limited inquiry mode */ } esp_bt_inq_mode_t; -/** Minimum and Maximum inquiry length*/ +/* Minimum and Maximum inquiry length */ #define ESP_BT_GAP_MIN_INQ_LEN (0x01) /*!< Minimum inquiry duration, unit is 1.28s */ #define ESP_BT_GAP_MAX_INQ_LEN (0x30) /*!< Maximum inquiry duration, unit is 1.28s */ -/** Minimum, Default and Maximum poll interval **/ +/* Minimum, Default and Maximum poll interval */ #define ESP_BT_GAP_TPOLL_MIN (0x0006) /*!< Minimum poll interval, unit is 625 microseconds */ #define ESP_BT_GAP_TPOLL_DFT (0x0028) /*!< Default poll interval, unit is 625 microseconds */ #define ESP_BT_GAP_TPOLL_MAX (0x1000) /*!< Maximum poll interval, unit is 625 microseconds */ @@ -358,7 +356,7 @@ typedef union { } rmt_srvc_rec; /*!< specific service record from remote device parameter struct */ /** - * @brief ESP_BT_GAP_READ_RSSI_DELTA_EVT * + * @brief ESP_BT_GAP_READ_RSSI_DELTA_EVT */ struct read_rssi_delta_param { esp_bd_addr_t bda; /*!< remote bluetooth device address*/ @@ -367,7 +365,7 @@ typedef union { } read_rssi_delta; /*!< read rssi parameter struct */ /** - * @brief ESP_BT_GAP_CONFIG_EIR_DATA_EVT * + * @brief ESP_BT_GAP_CONFIG_EIR_DATA_EVT */ struct config_eir_data_param { esp_bt_status_t stat; /*!< config EIR status: @@ -609,6 +607,8 @@ static inline bool esp_bt_gap_is_valid_cod(uint32_t cod) /** * @brief register callback function. This function should be called after esp_bluedroid_enable() completes successfully * + * @param[in] callback : callback function + * * @return * - ESP_OK : Succeed * - ESP_FAIL: others @@ -668,6 +668,8 @@ esp_err_t esp_bt_gap_cancel_discovery(void); * @brief Start SDP to get remote services. This function should be called after esp_bluedroid_enable() completes successfully. * esp_bt_gap_cb_t will be called with ESP_BT_GAP_RMT_SRVCS_EVT after service discovery ends. * + * @param[in] remote_bda : remote bluetooth device address + * * @return * - ESP_OK : Succeed * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled @@ -680,6 +682,10 @@ esp_err_t esp_bt_gap_get_remote_services(esp_bd_addr_t remote_bda); * esp_bluedroid_enable() completes successfully. * * esp_bt_gap_cb_t will be called with ESP_BT_GAP_RMT_SRVC_REC_EVT after service discovery ends + * + * @param[in] remote_bda : remote bluetooth device address + * @param[in] uuid : uuid + * * @return * - ESP_OK : Succeed * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled @@ -956,6 +962,9 @@ esp_err_t esp_bt_gap_get_page_timeout(void); * An ESP_BT_GAP_SET_ACL_PPKT_TYPES_EVT event will reported to * the APP layer. * + * @param[in] remote_bda : remote bluetooth device address + * @param[in] pkt_types : packet type + * * @return - ESP_OK: success * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - other: failed @@ -965,6 +974,8 @@ esp_err_t esp_bt_gap_set_acl_pkt_types(esp_bd_addr_t remote_bda, esp_bt_acl_pkt_ /** * @brief Set the minimal size of encryption key * + * @param[in] key_size : the size of encryption key + * * @return - ESP_OK: success * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - other: failed diff --git a/docs/en/api-reference/bluetooth/esp_gap_bt.rst b/docs/en/api-reference/bluetooth/esp_gap_bt.rst index 7206eb7496..76fe246b4b 100644 --- a/docs/en/api-reference/bluetooth/esp_gap_bt.rst +++ b/docs/en/api-reference/bluetooth/esp_gap_bt.rst @@ -1,6 +1,11 @@ -Classic Bluetooth® GAP API +Bluetooth® Classic GAP API ========================== +Overview +-------- + +The Bluetooth Classic GAP (Generic Access Profile) API provides interfaces for device discovery, pairing, and security management, allowing applications to control visibility, initiate connections, and configure authentication and encryption for Bluetooth Classic links. + Application Examples -------------------- From 5da8d6df5371b3d870b4a76809d6b8d199978d85 Mon Sep 17 00:00:00 2001 From: yangfeng Date: Mon, 1 Dec 2025 17:29:51 +0800 Subject: [PATCH 182/226] docs(bt): update Classic Bluetooth api reference of A2DP --- .../bluedroid/api/include/api/esp_a2dp_api.h | 56 ++++++++----------- docs/en/api-reference/bluetooth/esp_a2dp.rst | 5 ++ .../classic_bt/a2dp_sink_stream/main/main.c | 2 +- .../avrcp_absolute_volume/main/main.c | 2 +- .../classic_bt/avrcp_ct_cover_art/main/main.c | 2 +- .../classic_bt/avrcp_ct_metadata/main/main.c | 2 +- 6 files changed, 31 insertions(+), 38 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h b/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h index 71d3d597e9..24f6aef8f1 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h @@ -19,56 +19,44 @@ extern "C" { typedef uint16_t esp_a2d_conn_hdl_t; /*!< Connection handle, associate with specific device that connected */ -/** - * @brief Media codec types supported by A2DP. - */ +/* Media codec types supported by A2DP. */ #define ESP_A2D_MCT_SBC (0) /*!< SBC */ #define ESP_A2D_MCT_M12 (0x01) /*!< MPEG-1, 2 Audio */ #define ESP_A2D_MCT_M24 (0x02) /*!< MPEG-2, 4 AAC */ #define ESP_A2D_MCT_ATRAC (0x04) /*!< ATRAC family */ #define ESP_A2D_MCT_NON_A2DP (0xff) /*!< NON-A2DP */ -typedef uint8_t esp_a2d_mct_t; +typedef uint8_t esp_a2d_mct_t; /*!< Media codec type of A2DP */ -/** - * @brief Protocol service capabilities. This value is a mask. - */ +/* Protocol service capabilities. This value is a mask. */ #define ESP_A2D_PSC_DELAY_RPT (1<<0) /*!< Delay Report */ -typedef uint16_t esp_a2d_psc_t; +typedef uint16_t esp_a2d_psc_t; /*!< Protocol service capabilities type */ -/** - * @brief A2DP SBC sampling frequency bit mask in CIE - */ +/* A2DP SBC sampling frequency bit mask in CIE */ #define ESP_A2D_SBC_CIE_SF_16K (0x8) /*!< SBC sampling frequency 16kHz */ #define ESP_A2D_SBC_CIE_SF_32K (0x4) /*!< SBC sampling frequency 32kHz */ #define ESP_A2D_SBC_CIE_SF_44K (0x2) /*!< SBC sampling frequency 44.1kHz */ #define ESP_A2D_SBC_CIE_SF_48K (0x1) /*!< SBC sampling frequency 48kHz */ -/** - * @brief A2DP SBC channel mode bit mask in CIE - */ +/* A2DP SBC channel mode bit mask in CIE */ #define ESP_A2D_SBC_CIE_CH_MODE_MONO (0x8) /*!< SBC channel mode Mono */ #define ESP_A2D_SBC_CIE_CH_MODE_DUAL_CHANNEL (0x4) /*!< SBC channel mode Dual Channel */ #define ESP_A2D_SBC_CIE_CH_MODE_STEREO (0x2) /*!< SBC channel mode Stereo */ -#define ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO (0x1) /*!< SBC channel mode Stereo */ +#define ESP_A2D_SBC_CIE_CH_MODE_JOINT_STEREO (0x1) /*!< SBC channel mode Joint Stereo */ -/** - * @brief A2DP SBC block length bit mask in CIE - */ +/* A2DP SBC block length bit mask in CIE */ #define ESP_A2D_SBC_CIE_BLOCK_LEN_4 (0x8) /*!< SBC block length 4 */ #define ESP_A2D_SBC_CIE_BLOCK_LEN_8 (0x4) /*!< SBC block length 8 */ #define ESP_A2D_SBC_CIE_BLOCK_LEN_12 (0x2) /*!< SBC block length 12 */ #define ESP_A2D_SBC_CIE_BLOCK_LEN_16 (0x1) /*!< SBC block length 16 */ -/** - * @brief A2DP SBC number of subbands bit mask in CIE - */ +/* A2DP SBC number of subbands bit mask in CIE */ #define ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 (0x2) /*!< SBC number of subbands 4 */ #define ESP_A2D_SBC_CIE_NUM_SUBBANDS_8 (0x1) /*!< SBC number of subbands 8 */ -/** - * @brief A2DP SBC allocation method bit mask in CIE - */ -#define ESP_A2D_SBC_CIE_ALLOC_MTHD_SRN (0x2) /*!< SBC allocation method SNR */ +/* A2DP SBC allocation method bit mask in CIE */ +#define ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR (0x2) /*!< SBC allocation method SNR */ +/*!< @deprecated Renamed to ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR */ +#define ESP_A2D_SBC_CIE_ALLOC_MTHD_SRN _Pragma("GCC warning \"'ESP_A2D_SBC_CIE_ALLOC_MTHD_SRN' macro is deprecated, use 'ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR'\"") ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR #define ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS (0x1) /*!< SBC allocation method Loudness */ /** @@ -136,10 +124,10 @@ typedef struct { */ typedef struct { esp_a2d_mct_t type; /*!< A2DP media codec type */ -#define ESP_A2D_CIE_LEN_SBC (4) -#define ESP_A2D_CIE_LEN_M12 (4) -#define ESP_A2D_CIE_LEN_M24 (6) -#define ESP_A2D_CIE_LEN_ATRAC (7) +#define ESP_A2D_CIE_LEN_SBC (4) /*!< SBC cie length */ +#define ESP_A2D_CIE_LEN_M12 (4) /*!< MPEG-1,2 cie length */ +#define ESP_A2D_CIE_LEN_M24 (6) /*!< MPEG-2,4 AAC cie length */ +#define ESP_A2D_CIE_LEN_ATRAC (7) /*!< ATRAC family cie length */ union { uint8_t sbc[ESP_A2D_CIE_LEN_SBC] __attribute__((deprecated)); /*!< SBC codec capabilities, deprecated, use sbc_info instead */ uint8_t m12[ESP_A2D_CIE_LEN_M12] __attribute__((deprecated)); /*!< MPEG-1,2 audio codec capabilities, deprecated, use m12_info instead */ @@ -206,7 +194,7 @@ typedef enum { */ typedef enum { ESP_A2D_DEINIT_SUCCESS = 0, /*!< A2DP profile deinit successful event */ - ESP_A2D_INIT_SUCCESS /*!< A2DP profile deinit successful event */ + ESP_A2D_INIT_SUCCESS /*!< A2DP profile init successful event */ } esp_a2d_init_state_t; /** @@ -245,7 +233,7 @@ typedef enum { ESP_A2D_AUDIO_CFG_EVT, /*!< audio codec is configured */ ESP_A2D_MEDIA_CTRL_ACK_EVT, /*!< acknowledge event in response to media control commands */ ESP_A2D_PROF_STATE_EVT, /*!< indicate a2dp init&deinit complete */ - ESP_A2D_SEP_REG_STATE_EVT, /*!< indicate a2dp steam endpoint register status */ + ESP_A2D_SEP_REG_STATE_EVT, /*!< indicate a2dp stream endpoint register status */ ESP_A2D_SNK_PSC_CFG_EVT, /*!< protocol service capabilities configured,only used for A2DP SINK */ ESP_A2D_SNK_SET_DELAY_VALUE_EVT, /*!< indicate a2dp sink set delay report value complete, only used for A2DP SINK */ ESP_A2D_SNK_GET_DELAY_VALUE_EVT, /*!< indicate a2dp sink get delay report value complete, only used for A2DP SINK */ @@ -353,9 +341,9 @@ typedef union { /** * @brief A2DP profile callback function type * - * @param event : Event type + * @param[in] event : Event type * - * @param param : Pointer to callback parameter + * @param[in] param : Pointer to callback parameter */ typedef void (* esp_a2d_cb_t)(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param); @@ -602,7 +590,7 @@ esp_err_t esp_a2d_source_register_stream_endpoint(uint8_t seid, const esp_a2d_mc esp_err_t esp_a2d_source_deinit(void); /** - * @brief Send a audio buff with encoded audio data to sink, the audio data len shall not bigger than + * @brief Send an audio buffer with encoded audio data to sink. The audio data length shall not be bigger than * audio connection mtu (retrieved from ESP_A2D_CONNECTION_STATE_EVT). if the return value is * ESP_OK, then the audio buff is consumed, otherwise, audio buff can be reused by user. * diff --git a/docs/en/api-reference/bluetooth/esp_a2dp.rst b/docs/en/api-reference/bluetooth/esp_a2dp.rst index c3ecdc2c31..8e1105e258 100644 --- a/docs/en/api-reference/bluetooth/esp_a2dp.rst +++ b/docs/en/api-reference/bluetooth/esp_a2dp.rst @@ -1,6 +1,11 @@ Bluetooth® A2DP API =================== +Overview +-------- + +A2DP (Advanced Audio Distribution Profile) enables high-quality audio streaming from one device to another over Bluetooth. It is primarily used for streaming audio from source devices such as smartphones, computers, and media players to sink devices such as Bluetooth speakers, headphones, and car audio systems. Users can use the A2DP APIs to transmit or receive audio streams. + Application Examples -------------------- diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/main.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/main.c index 863c0127d1..680d13ad13 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink_stream/main/main.c @@ -139,7 +139,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) ESP_A2D_SBC_CIE_BLOCK_LEN_12 | ESP_A2D_SBC_CIE_BLOCK_LEN_16; mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8; - mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SRN | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS; + mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS; mcc.cie.sbc_info.max_bitpool = 250; mcc.cie.sbc_info.min_bitpool = 2; /* register stream end point, only support SBC currently */ diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/main.c b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/main.c index 47a494816c..a5c45d0e43 100644 --- a/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_absolute_volume/main/main.c @@ -212,7 +212,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) ESP_A2D_SBC_CIE_BLOCK_LEN_12 | ESP_A2D_SBC_CIE_BLOCK_LEN_16; mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8; - mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SRN | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS; + mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS; mcc.cie.sbc_info.max_bitpool = 250; mcc.cie.sbc_info.min_bitpool = 2; /* register stream end point, only support SBC currently */ diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/main.c b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/main.c index f2d6d91108..00b2f538f1 100644 --- a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_cover_art/main/main.c @@ -94,7 +94,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) ESP_A2D_SBC_CIE_BLOCK_LEN_12 | ESP_A2D_SBC_CIE_BLOCK_LEN_16; mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8; - mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SRN | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS; + mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS; mcc.cie.sbc_info.max_bitpool = 250; mcc.cie.sbc_info.min_bitpool = 2; /* register stream end point, only support SBC currently */ diff --git a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/main.c b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/main.c index 3267570d8c..92f7f5f7b4 100644 --- a/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/avrcp_ct_metadata/main/main.c @@ -256,7 +256,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) ESP_A2D_SBC_CIE_BLOCK_LEN_12 | ESP_A2D_SBC_CIE_BLOCK_LEN_16; mcc.cie.sbc_info.num_subbands = ESP_A2D_SBC_CIE_NUM_SUBBANDS_4 | ESP_A2D_SBC_CIE_NUM_SUBBANDS_8; - mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SRN | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS; + mcc.cie.sbc_info.alloc_mthd = ESP_A2D_SBC_CIE_ALLOC_MTHD_SNR | ESP_A2D_SBC_CIE_ALLOC_MTHD_LOUDNESS; mcc.cie.sbc_info.max_bitpool = 250; mcc.cie.sbc_info.min_bitpool = 2; /* register stream end point, only support SBC currently */ From d3944162d85c585e9dde874aa1a0ec29e41d48b8 Mon Sep 17 00:00:00 2001 From: yangfeng Date: Wed, 10 Dec 2025 12:16:28 +0800 Subject: [PATCH 183/226] docs(bt): update Classic Bluetooth api reference of AVRCP --- .../bluedroid/api/include/api/esp_avrc_api.h | 43 +++++++++++++------ docs/en/api-reference/bluetooth/esp_avrc.rst | 6 +-- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_avrc_api.h b/components/bt/host/bluedroid/api/include/api/esp_avrc_api.h index 6fae9c1b29..90570411e2 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_avrc_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_avrc_api.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 */ @@ -18,9 +18,9 @@ extern "C" { #define ESP_AVRC_TRANS_LABEL_MAX 15 /*!< max transaction label */ -#define ESP_AVRC_CA_IMAGE_HANDLE_LEN 7 /* The image handle length is fixed to 7, specified by Basic Image Profile */ -#define ESP_AVRC_CA_MTU_MIN 255 /* Minimal MTU can be used in Cover Art OBEX connection */ -#define ESP_AVRC_CA_MTU_MAX 1691 /* Maximum MTU can be used in Cover Art OBEX connection */ +#define ESP_AVRC_CA_IMAGE_HANDLE_LEN 7 /*!< The image handle length is fixed to 7, specified by Basic Image Profile */ +#define ESP_AVRC_CA_MTU_MIN 255 /*!< Minimal MTU can be used in Cover Art OBEX connection */ +#define ESP_AVRC_CA_MTU_MAX 1691 /*!< Maximum MTU can be used in Cover Art OBEX connection */ /// AVRC feature bit mask typedef enum { @@ -113,7 +113,7 @@ typedef enum { typedef enum { ESP_AVRC_PSTH_FILTER_ALLOWED_CMD = 0, /*!< all of the PASSTHROUGH commands that can possibly be used, immutable */ ESP_AVRC_PSTH_FILTER_SUPPORTED_CMD = 1, /*!< PASSTHROUGH commands selectively supported according to the current configuration */ - ESP_AVRC_PSTH_FILTER_SUPPORT_MAX, + ESP_AVRC_PSTH_FILTER_SUPPORT_MAX, /*!< Maximum value for PASSTHROUGH command filter */ } esp_avrc_psth_filter_t; /// AVRC passthrough command bit mask @@ -121,6 +121,7 @@ typedef struct { uint16_t bits[8]; /*!< bit mask representation of PASSTHROUGH commands */ } esp_avrc_psth_bit_mask_t; +/// AVRC operation code bit mask typedef enum { ESP_AVRC_BIT_MASK_OP_TEST = 0, /*!< operation code to test a specific bit */ ESP_AVRC_BIT_MASK_OP_SET = 1, /*!< operation code to set a specific bit */ @@ -186,14 +187,14 @@ typedef enum { ESP_AVRC_RN_ADDRESSED_PLAYER_CHANGE = 0x0b, /*!< the addressed player changed */ ESP_AVRC_RN_UIDS_CHANGE = 0x0c, /*!< UIDs changed */ ESP_AVRC_RN_VOLUME_CHANGE = 0x0d, /*!< volume changed locally on TG */ - ESP_AVRC_RN_MAX_EVT + ESP_AVRC_RN_MAX_EVT /*!< maximum value for notification event */ } esp_avrc_rn_event_ids_t; /// AVRC target notification event notification capability typedef enum { ESP_AVRC_RN_CAP_ALLOWED_EVT = 0, /*!< all of the notification events that can possibly be supported, immutable */ ESP_AVRC_RN_CAP_SUPPORTED_EVT = 1, /*!< notification events selectively supported according to the current configuration */ - ESP_AVRC_RN_CAP_MAX, + ESP_AVRC_RN_CAP_MAX, /*!< maximum value for the notification event capability */ } esp_avrc_rn_evt_cap_t; /// AVRC target notification event capability bit mask @@ -213,7 +214,7 @@ typedef enum { ESP_AVRC_PS_REPEAT_MODE = 0x02, /*!< repeat mode */ ESP_AVRC_PS_SHUFFLE_MODE = 0x03, /*!< shuffle mode */ ESP_AVRC_PS_SCAN_MODE = 0x04, /*!< scan mode on or off */ - ESP_AVRC_PS_MAX_ATTR + ESP_AVRC_PS_MAX_ATTR /*!< Maximum value for player setting attribute ids*/ } esp_avrc_ps_attr_ids_t; /// AVRC equalizer modes @@ -232,9 +233,9 @@ typedef enum { /// AVRC shuffle modes typedef enum { - ESP_AVRC_PS_SHUFFLE_OFF = 0x1, /* Date: Wed, 10 Dec 2025 14:18:56 +0800 Subject: [PATCH 184/226] docs(bt): update Classic Bluetooth api reference of SPP --- .../bluedroid/api/include/api/esp_spp_api.h | 29 ++++++++++++------- docs/en/api-reference/bluetooth/esp_spp.rst | 9 ++++-- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_spp_api.h b/components/bt/host/bluedroid/api/include/api/esp_spp_api.h index e6cdf2fc69..f8a9c52403 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_spp_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_spp_api.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 */ @@ -42,15 +42,18 @@ Due to certain limitations, do not use these mask modes: 2. ESP_SPP_SEC_MODE4_LEVEL4 3. ESP_SPP_SEC_MITM */ -#define ESP_SPP_SEC_NONE 0x0000 /*!< No security. relate to BTA_SEC_NONE in bta/bta_api.h */ -#define ESP_SPP_SEC_AUTHORIZE 0x0001 /*!< Authorization required (only needed for out going connection ) relate to BTA_SEC_AUTHORIZE in bta/bta_api.h*/ -#define ESP_SPP_SEC_AUTHENTICATE 0x0012 /*!< Authentication required. relate to BTA_SEC_AUTHENTICATE in bta/bta_api.h*/ -#define ESP_SPP_SEC_ENCRYPT 0x0024 /*!< Encryption required. relate to BTA_SEC_ENCRYPT in bta/bta_api.h*/ -#define ESP_SPP_SEC_MODE4_LEVEL4 0x0040 /*!< Mode 4 level 4 service, i.e. incoming/outgoing MITM and P-256 encryption relate to BTA_SEC_MODE4_LEVEL4 in bta/bta_api.h*/ -#define ESP_SPP_SEC_MITM 0x3000 /*!< Man-In-The_Middle protection relate to BTA_SEC_MITM in bta/bta_api.h*/ -#define ESP_SPP_SEC_IN_16_DIGITS 0x4000 /*!< Min 16 digit for pin code relate to BTA_SEC_IN_16_DIGITS in bta/bta_api.h*/ -typedef uint16_t esp_spp_sec_t; +#define ESP_SPP_SEC_NONE 0x0000 /*!< No security. */ +#define ESP_SPP_SEC_AUTHORIZE 0x0001 /*!< Authorization required (only needed for out going connection ) */ +#define ESP_SPP_SEC_AUTHENTICATE 0x0012 /*!< Authentication required. */ +#define ESP_SPP_SEC_ENCRYPT 0x0024 /*!< Encryption required. */ +#define ESP_SPP_SEC_MODE4_LEVEL4 0x0040 /*!< Mode 4 level 4 service, i.e. incoming/outgoing MITM and P-256 encryption. */ +#define ESP_SPP_SEC_MITM 0x3000 /*!< Man-In-The-Middle protection. */ +#define ESP_SPP_SEC_IN_16_DIGITS 0x4000 /*!< Min 16 digit for pin code. */ +typedef uint16_t esp_spp_sec_t; /*!< SPP security type */ +/** + * @brief SPP status type. + */ typedef enum { ESP_SPP_SUCCESS = 0, /*!< Successful operation. */ ESP_SPP_FAILURE, /*!< Generic failure. */ @@ -63,11 +66,17 @@ typedef enum { ESP_SPP_NO_SERVER, /*!< No SPP server */ } esp_spp_status_t; +/** + * @brief SPP role type. + */ typedef enum { ESP_SPP_ROLE_MASTER = 0, /*!< Role: master */ ESP_SPP_ROLE_SLAVE = 1, /*!< Role: slave */ } esp_spp_role_t; +/** + * @brief SPP mode type. + */ typedef enum { ESP_SPP_MODE_CB = 0, /*!< When data is coming, a callback will come with data */ ESP_SPP_MODE_VFS = 1, /*!< Use VFS to write/read data */ @@ -318,7 +327,7 @@ esp_err_t esp_spp_deinit(void); /** - * @brief This function is called to performs service discovery for the services provided by the given peer device. + * @brief Perform service discovery for the services provided by the given peer device. * When the operation is completed, the callback function will be called with ESP_SPP_DISCOVERY_COMP_EVT. * This function must be called after esp_spp_init()/esp_spp_enhanced_init() successful and before esp_spp_deinit(). * diff --git a/docs/en/api-reference/bluetooth/esp_spp.rst b/docs/en/api-reference/bluetooth/esp_spp.rst index cb9e2cc833..5d7bd66699 100644 --- a/docs/en/api-reference/bluetooth/esp_spp.rst +++ b/docs/en/api-reference/bluetooth/esp_spp.rst @@ -1,5 +1,10 @@ -SPP API -======= +Bluetooth® SPP API +================== + +Overview +-------- + +SPP (Serial Port Profile) enables serial communication between Bluetooth devices, allowing them to exchange data over a virtual serial link. SPP API provides functionality to create both SPP initiators (clients) and acceptors (servers), enabling operation under different security requirements. Application Examples -------------------- From 38ad274b6f1d9fd58f3806c3c35058a3ca475ec8 Mon Sep 17 00:00:00 2001 From: yangfeng Date: Wed, 10 Dec 2025 14:23:09 +0800 Subject: [PATCH 185/226] docs(bt): update Classic Bluetooth api reference of HFP Define --- .../bluedroid/api/include/api/esp_hf_defs.h | 55 ++++++++++--------- .../api-reference/bluetooth/esp_hf_defs.rst | 16 +++++- 2 files changed, 42 insertions(+), 29 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_hf_defs.h b/components/bt/host/bluedroid/api/include/api/esp_hf_defs.h index e6ca2e70ee..5001e81d9d 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_hf_defs.h +++ b/components/bt/host/bluedroid/api/include/api/esp_hf_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 */ @@ -13,7 +13,7 @@ extern "C" { #endif -typedef uint16_t esp_hf_sync_conn_hdl_t; +typedef uint16_t esp_hf_sync_conn_hdl_t; /*!< HFP synchronous connection handle */ /// profile states typedef enum { @@ -27,8 +27,8 @@ typedef enum { /// in-band ring tone state typedef enum { - ESP_HF_IN_BAND_RINGTONE_NOT_PROVIDED = 0, - ESP_HF_IN_BAND_RINGTONE_PROVIDED, + ESP_HF_IN_BAND_RINGTONE_NOT_PROVIDED = 0, /*!< Indicates that the in-band ringtone is not provided by the Hands-Free device */ + ESP_HF_IN_BAND_RINGTONE_PROVIDED, /*!< Indicates that the in-band ringtone is provided by the Hands-Free device */ } esp_hf_in_band_ring_state_t; /// voice recognition state @@ -51,16 +51,17 @@ typedef enum { ESP_HF_AUDIO_STATE_CONNECTED_MSBC, /*!< mSBC audio connection is established */ } esp_hf_audio_state_t; +/// Bluetooth HFP audio volume type typedef enum { - ESP_HF_VOLUME_TYPE_SPK = 0, - ESP_HF_VOLUME_TYPE_MIC + ESP_HF_VOLUME_TYPE_SPK = 0, /*!< speaker */ + ESP_HF_VOLUME_TYPE_MIC /*!< microphone */ } esp_hf_volume_type_t; /// +CIND network service availability status typedef enum { - ESP_HF_NETWORK_STATE_NOT_AVAILABLE = 0, - ESP_HF_NETWORK_STATE_AVAILABLE + ESP_HF_NETWORK_STATE_NOT_AVAILABLE = 0, /*!< Indicates that the network service is not available */ + ESP_HF_NETWORK_STATE_AVAILABLE /*!< Indicates that the network service is available */ } esp_hf_network_state_t; /// +CIEV report type @@ -77,8 +78,8 @@ typedef enum { /** +CIEV Service type */ typedef enum { - ESP_HF_SERVICE_TYPE_HOME = 0, - ESP_HF_SERVICE_TYPE_ROAMING + ESP_HF_SERVICE_TYPE_HOME = 0, /*!< Indicates the service is in the home */ + ESP_HF_SERVICE_TYPE_ROAMING /*!< Indicates the service is in roaming */ } esp_hf_service_type_t; /// +CIND call status indicator values @@ -133,9 +134,9 @@ typedef enum { /// +CLCC call mode typedef enum { - ESP_HF_CURRENT_CALL_MODE_VOICE = 0, - ESP_HF_CURRENT_CALL_MODE_DATA = 1, - ESP_HF_CURRENT_CALL_MODE_FAX = 2, + ESP_HF_CURRENT_CALL_MODE_VOICE = 0, /*!< the current call is a voice call */ + ESP_HF_CURRENT_CALL_MODE_DATA = 1, /*!< the current call is a data call */ + ESP_HF_CURRENT_CALL_MODE_FAX = 2, /*!< the current call is a fax call */ } esp_hf_current_call_mode_t; /// +CLCC address type @@ -168,22 +169,22 @@ typedef enum { /* +NREC */ typedef enum { - ESP_HF_NREC_STOP = 0, - ESP_HF_NREC_START + ESP_HF_NREC_STOP = 0, /*!< Stop the NREC */ + ESP_HF_NREC_START /*!< Start the NREC */ } esp_hf_nrec_t; ///+CCWA response status typedef enum { - ESP_HF_CALL_WAITING_INACTIVE, - ESP_HF_CALL_WAITING_ACTIVE, + ESP_HF_CALL_WAITING_INACTIVE, /*!< inactive call waiting */ + ESP_HF_CALL_WAITING_ACTIVE, /*!< active call waiting */ } esp_hf_call_waiting_status_t; /* WBS codec setting */ typedef enum { - ESP_HF_WBS_NONE, - ESP_HF_WBS_NO, - ESP_HF_WBS_YES + ESP_HF_WBS_NONE, /*!< No Wideband Speech (WBS) codec support */ + ESP_HF_WBS_NO, /*!< Wideband Speech (WBS) codec is not enabled */ + ESP_HF_WBS_YES /*!< Wideband Speech (WBS) codec is enabled */ }esp_hf_wbs_config_t; /// Bluetooth HFP RFCOMM connection and service level connection status @@ -198,11 +199,11 @@ typedef enum { /// AT+CHLD command values typedef enum { ESP_HF_CHLD_TYPE_REL = 0, /*!< <0>, Terminate all held or set UDUB("busy") to a waiting call */ - ESP_HF_CHLD_TYPE_REL_ACC, /*!< <1>, Terminate all active calls and accepts a waiting/held call */ - ESP_HF_CHLD_TYPE_HOLD_ACC, /*!< <2>, Hold all active calls and accepts a waiting/held call */ + ESP_HF_CHLD_TYPE_REL_ACC, /*!< <1>, Terminate all active calls and accept a waiting/held call */ + ESP_HF_CHLD_TYPE_HOLD_ACC, /*!< <2>, Hold all active calls and accept a waiting/held call */ ESP_HF_CHLD_TYPE_MERGE, /*!< <3>, Add all held calls to a conference */ - ESP_HF_CHLD_TYPE_MERGE_DETACH, /*!< <4>, connect the two calls and disconnects the subscriber from both calls */ - ESP_HF_CHLD_TYPE_REL_X, /*!< <1x>, releases specified calls only */ + ESP_HF_CHLD_TYPE_MERGE_DETACH, /*!< <4>, connect the two calls and disconnect the subscriber from both calls */ + ESP_HF_CHLD_TYPE_REL_X, /*!< <1x>, release specified calls only */ ESP_HF_CHLD_TYPE_PRIV_X, /*!< <2x>, request private consultation mode with specified call */ } esp_hf_chld_type_t; @@ -220,8 +221,8 @@ typedef enum { /* AT response code - OK/Error */ typedef enum { - ESP_HF_AT_RESPONSE_ERROR = 0, - ESP_HF_AT_RESPONSE_OK + ESP_HF_AT_RESPONSE_ERROR = 0, /*!< error in the AT command response */ + ESP_HF_AT_RESPONSE_OK /*!< successful AT command response */ } esp_hf_at_response_t; /// Extended Audio Gateway Error Result Code Response @@ -242,7 +243,7 @@ typedef enum { ESP_HF_CME_MEMORY_FULL = 20, /*!< memory full */ ESP_HF_CME_INVALID_INDEX = 21, /*!< invalid index */ ESP_HF_CME_MEMORY_FAILURE = 23, /*!< memory failure */ - ESP_HF_CME_TEXT_STRING_TOO_LONG = 24, /*!< test string too long */ + ESP_HF_CME_TEXT_STRING_TOO_LONG = 24, /*!< text string too long */ ESP_HF_CME_INVALID_CHARACTERS_IN_TEXT_STRING = 25, /*!< invalid characters in text string */ ESP_HF_CME_DIAL_STRING_TOO_LONG = 26, /*!< dial string too long*/ ESP_HF_CME_INVALID_CHARACTERS_IN_DIAL_STRING = 27, /*!< invalid characters in dial string */ diff --git a/docs/en/api-reference/bluetooth/esp_hf_defs.rst b/docs/en/api-reference/bluetooth/esp_hf_defs.rst index 4f9d3f9d2b..400f11a40d 100644 --- a/docs/en/api-reference/bluetooth/esp_hf_defs.rst +++ b/docs/en/api-reference/bluetooth/esp_hf_defs.rst @@ -1,5 +1,17 @@ -HFP Defines -=========== +Bluetooth® HFP Defines +====================== + +Overview +-------- + +This file contains definitions for constants, enumerations, and structures used in the Bluetooth Hands-Free Profile (HFP), enabling features like call management, audio control, and network status reporting. + +Application Examples +-------------------- + +- :example:`bluetooth/bluedroid/classic_bt/hfp_hf` demonstrates how to use the Hands-Free Client Component to communicate with a device that implements Hands-Free Audio Gateway (HF-AG), such as a smartphone. + +- :example:`bluetooth/bluedroid/classic_bt/hfp_ag` demonstrates how to use the Hands-Free Audio Gateway (HF-AG) component to communicate with a device that implements Hands-Free Client Role, such as a headphone set. It provides commands for configuring the project, establishing connections, controlling volume, and answering or rejecting calls. API Reference ------------- From aab8605340d60dfca2afcf0aa1525e4c7090f715 Mon Sep 17 00:00:00 2001 From: yangfeng Date: Wed, 10 Dec 2025 14:52:51 +0800 Subject: [PATCH 186/226] docs(bt): update Classic Bluetooth api reference of HFP Client --- .../api/include/api/esp_hf_client_api.h | 68 +++++++++---------- .../api-reference/bluetooth/esp_hf_client.rst | 9 ++- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h b/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h index 53bf03965f..be6eeb1cdc 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h @@ -16,9 +16,9 @@ extern "C" { #endif -#define ESP_BT_HF_CLIENT_NUMBER_LEN (32) -#define ESP_BT_HF_CLIENT_OPERATOR_NAME_LEN (16) -#define ESP_BT_HF_AT_SEND_XAPL_LEN (14) +#define ESP_BT_HF_CLIENT_NUMBER_LEN (32) /*!< Maximum length of the phone number string in HFP Client */ +#define ESP_BT_HF_CLIENT_OPERATOR_NAME_LEN (16) /*!< Maximum length of the operator name string in HFP Client */ +#define ESP_BT_HF_AT_SEND_XAPL_LEN (14) /*!< Length of the XAPL string in AT command for HFP Client */ /// Bluetooth HFP RFCOMM connection and service level connection status typedef enum { @@ -26,7 +26,7 @@ typedef enum { ESP_HF_CLIENT_CONNECTION_STATE_CONNECTING, /*!< connecting remote device on the RFCOMM data link*/ ESP_HF_CLIENT_CONNECTION_STATE_CONNECTED, /*!< RFCOMM connection established */ ESP_HF_CLIENT_CONNECTION_STATE_SLC_CONNECTED, /*!< service level connection established */ - ESP_HF_CLIENT_CONNECTION_STATE_DISCONNECTING, /*!< disconnecting with remote device on the RFCOMM dat link*/ + ESP_HF_CLIENT_CONNECTION_STATE_DISCONNECTING, /*!< disconnecting with remote device on the RFCOMM data link*/ } esp_hf_client_connection_state_t; /// Bluetooth HFP audio connection status @@ -53,35 +53,35 @@ typedef struct { } esp_hf_client_profile_status_t; /* features masks of AG */ -#define ESP_HF_CLIENT_PEER_FEAT_3WAY 0x01 /* Three-way calling */ -#define ESP_HF_CLIENT_PEER_FEAT_ECNR 0x02 /* Echo cancellation and/or noise reduction */ -#define ESP_HF_CLIENT_PEER_FEAT_VREC 0x04 /* Voice recognition */ -#define ESP_HF_CLIENT_PEER_FEAT_INBAND 0x08 /* In-band ring tone */ -#define ESP_HF_CLIENT_PEER_FEAT_VTAG 0x10 /* Attach a phone number to a voice tag */ -#define ESP_HF_CLIENT_PEER_FEAT_REJECT 0x20 /* Ability to reject incoming call */ -#define ESP_HF_CLIENT_PEER_FEAT_ECS 0x40 /* Enhanced Call Status */ -#define ESP_HF_CLIENT_PEER_FEAT_ECC 0x80 /* Enhanced Call Control */ -#define ESP_HF_CLIENT_PEER_FEAT_EXTERR 0x100 /* Extended error codes */ -#define ESP_HF_CLIENT_PEER_FEAT_CODEC 0x200 /* Codec Negotiation */ +#define ESP_HF_CLIENT_PEER_FEAT_3WAY 0x01 /*!< Three-way calling */ +#define ESP_HF_CLIENT_PEER_FEAT_ECNR 0x02 /*!< Echo cancellation and/or noise reduction */ +#define ESP_HF_CLIENT_PEER_FEAT_VREC 0x04 /*!< Voice recognition */ +#define ESP_HF_CLIENT_PEER_FEAT_INBAND 0x08 /*!< In-band ring tone */ +#define ESP_HF_CLIENT_PEER_FEAT_VTAG 0x10 /*!< Attach a phone number to a voice tag */ +#define ESP_HF_CLIENT_PEER_FEAT_REJECT 0x20 /*!< Ability to reject incoming call */ +#define ESP_HF_CLIENT_PEER_FEAT_ECS 0x40 /*!< Enhanced Call Status */ +#define ESP_HF_CLIENT_PEER_FEAT_ECC 0x80 /*!< Enhanced Call Control */ +#define ESP_HF_CLIENT_PEER_FEAT_EXTERR 0x100 /*!< Extended error codes */ +#define ESP_HF_CLIENT_PEER_FEAT_CODEC 0x200 /*!< Codec Negotiation */ /* HFP 1.7+ */ -#define ESP_HF_CLIENT_PEER_FEAT_HF_IND 0x400 /* HF Indicators */ -#define ESP_HF_CLIENT_PEER_FEAT_ESCO_S4 0x800 /* eSCO S4 Setting Supported */ +#define ESP_HF_CLIENT_PEER_FEAT_HF_IND 0x400 /*!< HF Indicators */ +#define ESP_HF_CLIENT_PEER_FEAT_ESCO_S4 0x800 /*!< eSCO S4 Setting Supported */ /* CHLD feature masks of AG */ -#define ESP_HF_CLIENT_CHLD_FEAT_REL 0x01 /* 0 Release waiting call or held calls */ -#define ESP_HF_CLIENT_CHLD_FEAT_REL_ACC 0x02 /* 1 Release active calls and accept other waiting or held call */ -#define ESP_HF_CLIENT_CHLD_FEAT_REL_X 0x04 /* 1x Release specified active call only */ -#define ESP_HF_CLIENT_CHLD_FEAT_HOLD_ACC 0x08 /* 2 Active calls on hold and accept other waiting or held call */ -#define ESP_HF_CLIENT_CHLD_FEAT_PRIV_X 0x10 /* 2x Request private mode with specified call(put the rest on hold) */ -#define ESP_HF_CLIENT_CHLD_FEAT_MERGE 0x20 /* 3 Add held call to multiparty */ -#define ESP_HF_CLIENT_CHLD_FEAT_MERGE_DETACH 0x40 /* 4 Connect two calls and leave(disconnect from multiparty) */ +#define ESP_HF_CLIENT_CHLD_FEAT_REL 0x01 /*!< 0 Release waiting call or held calls */ +#define ESP_HF_CLIENT_CHLD_FEAT_REL_ACC 0x02 /*!< 1 Release active calls and accept other waiting or held call */ +#define ESP_HF_CLIENT_CHLD_FEAT_REL_X 0x04 /*!< 1x Release specified active call only */ +#define ESP_HF_CLIENT_CHLD_FEAT_HOLD_ACC 0x08 /*!< 2 Active calls on hold and accept other waiting or held call */ +#define ESP_HF_CLIENT_CHLD_FEAT_PRIV_X 0x10 /*!< 2x Request private mode with specified call(put the rest on hold) */ +#define ESP_HF_CLIENT_CHLD_FEAT_MERGE 0x20 /*!< 3 Add held call to multiparty */ +#define ESP_HF_CLIENT_CHLD_FEAT_MERGE_DETACH 0x40 /*!< 4 Connect two calls and leave(disconnect from multiparty) */ /* XAPL feature masks*/ -#define ESP_HF_CLIENT_XAPL_FEAT_RESERVED 0x01 /* reserved */ -#define ESP_HF_CLIENT_XAPL_FEAT_BATTERY_REPORT 0x02 /* The accessory supports battery reporting (reserved only for battery operated accessories) */ -#define ESP_HF_CLIENT_XAPL_FEAT_DOCKED 0x04 /* The accessory is docked or powered (reserved only for battery operated accessories). */ -#define ESP_HF_CLIENT_XAPL_FEAT_SIRI_STATUS_REPORT 0x08 /* The accessory supports Siri status reporting */ -#define ESP_HF_CLIENT_XAPL_NR_STATUS_REPORT 0x10 /* the accessory supports noise reduction (NR) status reporting */ +#define ESP_HF_CLIENT_XAPL_FEAT_RESERVED 0x01 /*!< reserved */ +#define ESP_HF_CLIENT_XAPL_FEAT_BATTERY_REPORT 0x02 /*!< The accessory supports battery reporting (reserved only for battery operated accessories) */ +#define ESP_HF_CLIENT_XAPL_FEAT_DOCKED 0x04 /*!< The accessory is docked or powered (reserved only for battery operated accessories). */ +#define ESP_HF_CLIENT_XAPL_FEAT_SIRI_STATUS_REPORT 0x08 /*!< The accessory supports Siri status reporting */ +#define ESP_HF_CLIENT_XAPL_NR_STATUS_REPORT 0x10 /*!< The accessory supports noise reduction (NR) status reporting */ /// HF CLIENT callback events typedef enum { @@ -186,7 +186,7 @@ typedef union { */ struct hf_client_call_setup_ind_param { esp_hf_call_setup_status_t status; /*!< call setup status indicator */ - } call_setup; /*!< HF callback param of ESP_HF_CLIENT_BVRA_EVT */ + } call_setup; /*!< HF callback param of `ESP_HF_CLIENT_CIND_CALL_SETUP_EVT` */ /** * @brief ESP_HF_CLIENT_CIND_CALL_HELD_EVT @@ -200,7 +200,7 @@ typedef union { */ struct hf_client_btrh_param { esp_hf_btrh_status_t status; /*!< call hold and response status result code */ - } btrh; /*!< HF callback param of ESP_HF_CLIENT_BRTH_EVT */ + } btrh; /*!< HF callback param of ESP_HF_CLIENT_BTRH_EVT */ /** * @brief ESP_HF_CLIENT_CLIP_EVT @@ -214,7 +214,7 @@ typedef union { */ struct hf_client_ccwa_param { const char *number; /*!< phone number string of waiting call */ - } ccwa; /*!< HF callback param of ESP_HF_CLIENT_BVRA_EVT */ + } ccwa; /*!< HF callback param of ESP_HF_CLIENT_CCWA_EVT */ /** * @brief ESP_HF_CLIENT_CLCC_EVT @@ -304,9 +304,9 @@ typedef void (* esp_hf_client_audio_data_cb_t)(esp_hf_sync_conn_hdl_t sync_conn_ /** * @brief HFP client callback function type * - * @param event : Event type + * @param[in] event : Event type * - * @param param : Pointer to callback parameter + * @param[in] param : Pointer to callback parameter */ typedef void (* esp_hf_client_cb_t)(esp_hf_client_cb_event_t event, esp_hf_client_cb_param_t *param); @@ -599,7 +599,7 @@ esp_err_t esp_hf_client_send_dtmf(char code); * * @brief Send command to enable Vendor specific feature to indicate battery level * and docker status - * This is Apple-specific commands, but used by most device, including Android and Windows + * This is an Apple-specific command, but used by most devices, including Android and Windows * * @param[in] information: XAPL vendorID-productID-version, such as "0505-1995-0610" * vendorID: A string representation of the hex value of the vendor ID from the manufacturer, without the 0x prefix. diff --git a/docs/en/api-reference/bluetooth/esp_hf_client.rst b/docs/en/api-reference/bluetooth/esp_hf_client.rst index ab28889212..816ee803db 100644 --- a/docs/en/api-reference/bluetooth/esp_hf_client.rst +++ b/docs/en/api-reference/bluetooth/esp_hf_client.rst @@ -1,5 +1,10 @@ -HFP Client API -============== +Bluetooth® HFP Client API +========================= + +Overview +-------- + +HFP (Hands-Free Profile) Client API provides functions to enable a Bluetooth device to act as an HFP Client, allowing communication with an Audio Gateway (AG) device, such as a smartphone, to handle voice calls, volume control, and other hands-free operations. Application Examples -------------------- From 9e11c7ba000c83e960258cdc5ce1c86d3d7fcbcc Mon Sep 17 00:00:00 2001 From: yangfeng Date: Wed, 10 Dec 2025 15:03:47 +0800 Subject: [PATCH 187/226] docs(bt): update Classic Bluetooth api reference of HFP AG --- .../bluedroid/api/include/api/esp_hf_ag_api.h | 52 +++++++++---------- docs/en/api-reference/bluetooth/esp_hf_ag.rst | 9 +++- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h b/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h index f34c52c42d..df21f68131 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h @@ -17,29 +17,29 @@ extern "C" { #endif /* features masks of HF AG */ -#define ESP_HF_PEER_FEAT_3WAY 0x01 /* Three-way calling */ -#define ESP_HF_PEER_FEAT_ECNR 0x02 /* Echo cancellation and/or noise reduction */ -#define ESP_HF_PEER_FEAT_VREC 0x04 /* Voice recognition */ -#define ESP_HF_PEER_FEAT_INBAND 0x08 /* In-band ring tone */ -#define ESP_HF_PEER_FEAT_VTAG 0x10 /* Attach a phone number to a voice tag */ -#define ESP_HF_PEER_FEAT_REJECT 0x20 /* Ability to reject incoming call */ -#define ESP_HF_PEER_FEAT_ECS 0x40 /* Enhanced Call Status */ -#define ESP_HF_PEER_FEAT_ECC 0x80 /* Enhanced Call Control */ -#define ESP_HF_PEER_FEAT_EXTERR 0x100 /* Extended error codes */ -#define ESP_HF_PEER_FEAT_CODEC 0x200 /* Codec Negotiation */ +#define ESP_HF_PEER_FEAT_3WAY 0x01 /*!< Three-way calling */ +#define ESP_HF_PEER_FEAT_ECNR 0x02 /*!< Echo cancellation and/or noise reduction */ +#define ESP_HF_PEER_FEAT_VREC 0x04 /*!< Voice recognition */ +#define ESP_HF_PEER_FEAT_INBAND 0x08 /*!< In-band ring tone */ +#define ESP_HF_PEER_FEAT_VTAG 0x10 /*!< Attach a phone number to a voice tag */ +#define ESP_HF_PEER_FEAT_REJECT 0x20 /*!< Ability to reject incoming call */ +#define ESP_HF_PEER_FEAT_ECS 0x40 /*!< Enhanced Call Status */ +#define ESP_HF_PEER_FEAT_ECC 0x80 /*!< Enhanced Call Control */ +#define ESP_HF_PEER_FEAT_EXTERR 0x100 /*!< Extended error codes */ +#define ESP_HF_PEER_FEAT_CODEC 0x200 /*!< Codec Negotiation */ /* HFP 1.7+ */ -#define ESP_HF_PEER_FEAT_HF_IND 0x400 /* HF Indicators */ -#define ESP_HF_PEER_FEAT_ESCO_S4 0x800 /* eSCO S4 Setting Supported */ +#define ESP_HF_PEER_FEAT_HF_IND 0x400 /*!< HF Indicators */ +#define ESP_HF_PEER_FEAT_ESCO_S4 0x800 /*!< eSCO S4 Setting Supported */ /* CHLD feature masks of HF AG */ -#define ESP_HF_CHLD_FEAT_REL 0x01 /* 0 Release waiting call or held calls */ -#define ESP_HF_CHLD_FEAT_REL_ACC 0x02 /* 1 Release active calls and accept other waiting or held call */ -#define ESP_HF_CHLD_FEAT_REL_X 0x04 /* 1x Release specified active call only */ -#define ESP_HF_CHLD_FEAT_HOLD_ACC 0x08 /* 2 Active calls on hold and accept other waiting or held call */ -#define ESP_HF_CHLD_FEAT_PRIV_X 0x10 /* 2x Request private mode with specified call(put the rest on hold) */ -#define ESP_HF_CHLD_FEAT_MERGE 0x20 /* 3 Add held call to multiparty */ -#define ESP_HF_CHLD_FEAT_MERGE_DETACH 0x40 /* 4 Connect two calls and leave(disconnect from multiparty) */ +#define ESP_HF_CHLD_FEAT_REL 0x01 /*!< 0 Release waiting call or held calls */ +#define ESP_HF_CHLD_FEAT_REL_ACC 0x02 /*!< 1 Release active calls and accept other waiting or held call */ +#define ESP_HF_CHLD_FEAT_REL_X 0x04 /*!< 1x Release specified active call only */ +#define ESP_HF_CHLD_FEAT_HOLD_ACC 0x08 /*!< 2 Active calls on hold and accept other waiting or held call */ +#define ESP_HF_CHLD_FEAT_PRIV_X 0x10 /*!< 2x Request private mode with specified call(put the rest on hold) */ +#define ESP_HF_CHLD_FEAT_MERGE 0x20 /*!< 3 Add held call to multiparty */ +#define ESP_HF_CHLD_FEAT_MERGE_DETACH 0x40 /*!< 4 Connect two calls and leave(disconnect from multiparty) */ /// HF callback events typedef enum @@ -60,7 +60,7 @@ typedef enum ESP_HF_ATA_RESPONSE_EVT, /*!< Answer an Incoming Call */ ESP_HF_CHUP_RESPONSE_EVT, /*!< Reject an Incoming Call */ - ESP_HF_DIAL_EVT, /*!< Origin an outgoing call with specific number or the dial the last number */ + ESP_HF_DIAL_EVT, /*!< Originate an outgoing call with specific number or dial the last number */ ESP_HF_WBS_RESPONSE_EVT, /*!< Codec Status */ ESP_HF_BCS_RESPONSE_EVT, /*!< Final Codec Choice */ ESP_HF_PKT_STAT_NUMS_GET_EVT, /*!< Request number of packet different status */ @@ -90,7 +90,7 @@ typedef union * @brief ESP_HF_CONNECTION_STATE_EVT */ struct hf_conn_stat_param { - esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */ + esp_bd_addr_t remote_bda; /*!< Remote Bluetooth device address */ esp_hf_connection_state_t state; /*!< Connection state */ uint32_t peer_feat; /*!< HF supported features */ uint32_t chld_feat; /*!< AG supported features on call hold and multiparty services */ @@ -228,10 +228,10 @@ typedef union uint32_t rx_total; /*!< the total number of packets received */ uint32_t rx_correct; /*!< the total number of packets data correctly received */ uint32_t rx_err; /*!< the total number of packets data with possible invalid */ - uint32_t rx_none; /*!< the total number of packets data no received */ + uint32_t rx_none; /*!< the total number of packets data not received */ uint32_t rx_lost; /*!< the total number of packets data partially lost */ - uint32_t tx_total; /*!< the total number of packets send */ - uint32_t tx_discarded; /*!< the total number of packets send lost */ + uint32_t tx_total; /*!< the total number of packets sent */ + uint32_t tx_discarded; /*!< the total number of packets sent and lost */ } pkt_nums; /*!< AG callback param of ESP_HF_PKT_STAT_NUMS_GET_EVT */ /** @@ -246,9 +246,9 @@ typedef union /** * @brief HF AG callback function type * - * @param event : Event type + * @param[in] event : Event type * - * @param param : Pointer to callback parameter + * @param[in] param : Pointer to callback parameter */ typedef void (* esp_hf_cb_t) (esp_hf_cb_event_t event, esp_hf_cb_param_t *param); diff --git a/docs/en/api-reference/bluetooth/esp_hf_ag.rst b/docs/en/api-reference/bluetooth/esp_hf_ag.rst index ab15744144..64b3b40ba1 100644 --- a/docs/en/api-reference/bluetooth/esp_hf_ag.rst +++ b/docs/en/api-reference/bluetooth/esp_hf_ag.rst @@ -1,5 +1,10 @@ -HFP AG API -============== +Bluetooth® HFP AG API +===================== + +Overview +-------- + +HFP (Hands-Free Profile) AG API provides functions for a Bluetooth device to act as an Audio Gateway (AG), enabling communication with HFP Client devices such as headsets or car kits. It supports connection management, call handling, volume control, and other hands-free operations. Application Examples -------------------- From 389e50abf4d90067224bed0b208a3c343a00245b Mon Sep 17 00:00:00 2001 From: yangfeng Date: Wed, 10 Dec 2025 15:35:21 +0800 Subject: [PATCH 188/226] docs(bt): update Classic Bluetooth api reference of HID Device --- .../bluedroid/api/include/api/esp_hidd_api.h | 55 ++++++++++--------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_hidd_api.h b/components/bt/host/bluedroid/api/include/api/esp_hidd_api.h index f16bbcb0fa..2348e752d5 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_hidd_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_hidd_api.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 * @@ -16,7 +16,7 @@ extern "C" { #endif -/// subclass of hid device +/* subclass of hid device */ #define ESP_HID_CLASS_UNKNOWN (0x00<<2) /*!< unknown HID device subclass */ #define ESP_HID_CLASS_JOS (0x01<<2) /*!< joystick */ #define ESP_HID_CLASS_GPD (0x02<<2) /*!< game pad */ @@ -57,9 +57,9 @@ typedef enum { */ typedef enum { ESP_HIDD_CONN_STATE_CONNECTED, /*!< HID connection established */ - ESP_HIDD_CONN_STATE_CONNECTING, /*!< connection to remote Bluetooth device */ + ESP_HIDD_CONN_STATE_CONNECTING, /*!< connecting to remote Bluetooth device */ ESP_HIDD_CONN_STATE_DISCONNECTED, /*!< connection released */ - ESP_HIDD_CONN_STATE_DISCONNECTING, /*!< disconnecting to remote Bluetooth device*/ + ESP_HIDD_CONN_STATE_DISCONNECTING, /*!< disconnecting from remote Bluetooth device*/ ESP_HIDD_CONN_STATE_UNKNOWN, /*!< unknown connection state */ } esp_hidd_connection_state_t; @@ -116,32 +116,35 @@ typedef struct { * @brief HID device callback function events */ typedef enum { - ESP_HIDD_INIT_EVT = 0, /*!< When HID device is initialized, the event comes */ - ESP_HIDD_DEINIT_EVT, /*!< When HID device is deinitialized, the event comes */ - ESP_HIDD_REGISTER_APP_EVT, /*!< When HID device application registered, the event comes */ - ESP_HIDD_UNREGISTER_APP_EVT, /*!< When HID device application unregistered, the event comes */ - ESP_HIDD_OPEN_EVT, /*!< When HID device connection to host opened, the event comes */ - ESP_HIDD_CLOSE_EVT, /*!< When HID device connection to host closed, the event comes */ - ESP_HIDD_SEND_REPORT_EVT, /*!< When HID device send report to lower layer, the event comes */ - ESP_HIDD_REPORT_ERR_EVT, /*!< When HID device report handshanke error to lower layer, the event comes */ - ESP_HIDD_GET_REPORT_EVT, /*!< When HID device receives GET_REPORT request from host, the event comes */ - ESP_HIDD_SET_REPORT_EVT, /*!< When HID device receives SET_REPORT request from host, the event comes */ - ESP_HIDD_SET_PROTOCOL_EVT, /*!< When HID device receives SET_PROTOCOL request from host, the event comes */ - ESP_HIDD_INTR_DATA_EVT, /*!< When HID device receives DATA from host on intr, the event comes */ - ESP_HIDD_VC_UNPLUG_EVT, /*!< When HID device initiates Virtual Cable Unplug, the event comes */ - ESP_HIDD_API_ERR_EVT /*!< When HID device has API error, the event comes */ + ESP_HIDD_INIT_EVT = 0, /*!< HID device initialized. */ + ESP_HIDD_DEINIT_EVT, /*!< HID device deinitialized. */ + ESP_HIDD_REGISTER_APP_EVT, /*!< HID device application registered. */ + ESP_HIDD_UNREGISTER_APP_EVT, /*!< HID device application unregistered. */ + ESP_HIDD_OPEN_EVT, /*!< HID device connection to host opened. */ + ESP_HIDD_CLOSE_EVT, /*!< HID device connection to host closed. */ + ESP_HIDD_SEND_REPORT_EVT, /*!< HID device sent report to lower layer. */ + ESP_HIDD_REPORT_ERR_EVT, /*!< HID device reported handshake error to lower layer. */ + ESP_HIDD_GET_REPORT_EVT, /*!< HID device received GET_REPORT request from host. */ + ESP_HIDD_SET_REPORT_EVT, /*!< HID device received SET_REPORT request from host. */ + ESP_HIDD_SET_PROTOCOL_EVT, /*!< HID device received SET_PROTOCOL request from host. */ + ESP_HIDD_INTR_DATA_EVT, /*!< HID device received DATA from host on interrupt channel. */ + ESP_HIDD_VC_UNPLUG_EVT, /*!< HID device initiated Virtual Cable Unplug. */ + ESP_HIDD_API_ERR_EVT /*!< HID device had API error. */ } esp_hidd_cb_event_t; +/** + * @brief HID device status + */ typedef enum { - ESP_HIDD_SUCCESS, - ESP_HIDD_ERROR, /*!< general ESP HD error */ + ESP_HIDD_SUCCESS, /*!< successful */ + ESP_HIDD_ERROR, /*!< general ESP HID error */ ESP_HIDD_NO_RES, /*!< out of system resources */ ESP_HIDD_BUSY, /*!< Temporarily can not handle this request. */ ESP_HIDD_NO_DATA, /*!< No data. */ - ESP_HIDD_NEED_INIT, /*!< HIDD module shall init first */ - ESP_HIDD_NEED_DEINIT, /*!< HIDD module shall deinit first */ - ESP_HIDD_NEED_REG, /*!< HIDD module shall register first */ - ESP_HIDD_NEED_DEREG, /*!< HIDD module shall deregister first */ + ESP_HIDD_NEED_INIT, /*!< HIDD module must be initialized first. */ + ESP_HIDD_NEED_DEINIT, /*!< HIDD module must be deinitialized first. */ + ESP_HIDD_NEED_REG, /*!< HIDD module must be registered first. */ + ESP_HIDD_NEED_DEREG, /*!< HIDD module must be deregistered first. */ ESP_HIDD_NO_CONNECTION, /*!< connection may have been closed */ } esp_hidd_status_t; @@ -270,8 +273,8 @@ typedef union { /** * @brief HID device callback function type. - * @param event: Event type - * @param param: Point to callback parameter, currently is union type + * @param[in] event: Event type + * @param[in] param: Point to callback parameter, currently is union type */ typedef void (*esp_hd_cb_t)(esp_hidd_cb_event_t event, esp_hidd_cb_param_t *param); From 171f8ab06dc27b78cc4de5b74449a3e4ae663565 Mon Sep 17 00:00:00 2001 From: yangfeng Date: Wed, 10 Dec 2025 15:41:43 +0800 Subject: [PATCH 189/226] docs(bt): update Classic Bluetooth api reference of HID Host --- components/bt/host/bluedroid/api/include/api/esp_hidh_api.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_hidh_api.h b/components/bt/host/bluedroid/api/include/api/esp_hidh_api.h index 51a0d43f7b..e23416c211 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_hidh_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_hidh_api.h @@ -52,7 +52,7 @@ typedef enum { ESP_HIDH_BUSY, /*!< vendor-defined: temporarily can not handle this request */ ESP_HIDH_NO_DATA, /*!< vendor-defined: no data. */ ESP_HIDH_NEED_INIT, /*!< vendor-defined: HIDH module shall initialize first */ - ESP_HIDH_NEED_DEINIT, /*!< vendor-defined: HIDH module shall de-deinitialize first */ + ESP_HIDH_NEED_DEINIT, /*!< vendor-defined: HIDH module shall deinitialize first */ ESP_HIDH_NO_CONNECTION, /*!< vendor-defined: connection may have been closed */ } esp_hidh_status_t; @@ -309,8 +309,8 @@ typedef union { /** * @brief HID host callback function type - * @param event: Event type - * @param param: Point to callback parameter, currently is union type + * @param[in] event: Event type + * @param[in] param: Point to callback parameter, currently is union type */ typedef void (*esp_hh_cb_t)(esp_hidh_cb_event_t event, esp_hidh_cb_param_t *param); From e0e056201322378d597aff85cc3bd199c91682de Mon Sep 17 00:00:00 2001 From: yangfeng Date: Wed, 10 Dec 2025 16:02:57 +0800 Subject: [PATCH 190/226] docs(bt): update Classic Bluetooth api reference of L2CAP --- .../api/include/api/esp_l2cap_bt_api.h | 30 ++++++++++--------- .../api-reference/bluetooth/esp_l2cap_bt.rst | 7 ++++- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h b/components/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h index 982cbdaa85..faa13ccdc5 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_l2cap_bt_api.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 */ @@ -28,17 +28,18 @@ typedef enum { ESP_BT_L2CAP_NO_SERVER, /*!< No server */ } esp_bt_l2cap_status_t; -/** - * @brief Security Setting Mask. Use these three mask mode: - * 1. ESP_BT_L2CAP_SEC_NONE - * 2. ESP_BT_L2CAP_SEC_AUTHENTICATE - * 3. (ESP_BT_L2CAP_SEC_ENCRYPT|ESP_BT_L2CAP_SEC_AUTHENTICATE) +/* + * Security setting mask for L2CAP. + * - Use one of the following mask modes: + * 1. `ESP_BT_L2CAP_SEC_NONE` + * 2. `ESP_BT_L2CAP_SEC_AUTHENTICATE` + * 3. (`ESP_BT_L2CAP_SEC_ENCRYPT` | `ESP_BT_L2CAP_SEC_AUTHENTICATE`) */ #define ESP_BT_L2CAP_SEC_NONE 0x0000 /*!< No security */ #define ESP_BT_L2CAP_SEC_AUTHORIZE 0x0001 /*!< Authorization required */ #define ESP_BT_L2CAP_SEC_AUTHENTICATE 0x0012 /*!< Authentication required */ #define ESP_BT_L2CAP_SEC_ENCRYPT 0x0024 /*!< Encryption required */ -typedef uint32_t esp_bt_l2cap_cntl_flags_t; +typedef uint32_t esp_bt_l2cap_cntl_flags_t; /*!< L2CAP control flags type */ /** * @brief L2CAP status parameters @@ -146,8 +147,8 @@ typedef union { /** * @brief L2CAP callback function type. * - * @param event: Event type - * @param param: Point to callback parameter, currently is union type + * @param[in] event: Event type + * @param[in] param: Point to callback parameter, currently is union type */ typedef void (* esp_bt_l2cap_cb_t)(esp_bt_l2cap_cb_event_t event, esp_bt_l2cap_cb_param_t *param); @@ -203,11 +204,12 @@ esp_err_t esp_bt_l2cap_deinit(void); esp_err_t esp_bt_l2cap_connect(esp_bt_l2cap_cntl_flags_t cntl_flag, uint16_t remote_psm, esp_bd_addr_t peer_bd_addr); /** - * @brief This function create a L2CAP server and starts listening for an - * L2CAP connection request from a remote Bluetooth device. - * When the server is started successfully, the callback is called with ESP_BT_L2CAP_START_EVT. - * When the connection is established, the callback is called with ESP_BT_L2CAP_OPEN_EVT. - * This function must be called after esp_bt_l2cap_init() successful and before esp_bt_l2cap_deinit(). +* @brief Create an L2CAP server and start listening for connection requests. + * + * @note + * - When the server is started successfully, the callback is called with `ESP_BT_L2CAP_START_EVT`. + * - When the connection is established, the callback is called with `ESP_BT_L2CAP_OPEN_EVT`. + * - This function must be called after `esp_bt_l2cap_init()` and before `esp_bt_l2cap_deinit()`. * * @param[in] cntl_flag: Lower 16-bit security settings mask. * @param[in] local_psm: Dynamic PSM. diff --git a/docs/en/api-reference/bluetooth/esp_l2cap_bt.rst b/docs/en/api-reference/bluetooth/esp_l2cap_bt.rst index c390b435fa..a2f96388b9 100644 --- a/docs/en/api-reference/bluetooth/esp_l2cap_bt.rst +++ b/docs/en/api-reference/bluetooth/esp_l2cap_bt.rst @@ -1,6 +1,11 @@ -Classic Bluetooth® L2CAP API +Bluetooth® Classic L2CAP API ============================ +Overview +-------- + +Bluetooth Classic L2CAP (Logical Link Control and Adaptation Layer Protocol) API provides functions for data transmission between Bluetooth devices. It supports both client and server roles, allowing the creation of L2CAP connections for reliable, high-throughput communication. + Application Examples -------------------- From c05ed8670f937d2ce71b95558cb920fae545a703 Mon Sep 17 00:00:00 2001 From: yangfeng Date: Wed, 10 Dec 2025 16:54:41 +0800 Subject: [PATCH 191/226] docs(bt): update Classic Bluetooth api reference of SDP --- .../bt/host/bluedroid/api/include/api/esp_sdp_api.h | 12 ++++++++---- docs/en/api-reference/bluetooth/esp_sdp.rst | 13 ++++++++++--- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_sdp_api.h b/components/bt/host/bluedroid/api/include/api/esp_sdp_api.h index 5c74851f31..4045f914e9 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_sdp_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_sdp_api.h @@ -25,9 +25,13 @@ extern "C" { #define ESP_SDP_UUID_SAP 0x112D /*!< SIM Access Profile UUID */ #define ESP_SDP_UUID_DIP 0x1200 /*!< Device Identification Profile UUID */ +/// Build a Bluetooth UUID16 #define ESP_SDP_BUILD_BT_UUID16(uuid16_val) \ (esp_bt_uuid_t) { .len = ESP_UUID_LEN_16, .uuid = {.uuid16 = (uint16_t)(uuid16_val),}, } +/** + * @brief SDP status parameters + */ typedef enum { ESP_SDP_SUCCESS = 0, /*!< Successful operation. */ ESP_SDP_FAILURE, /*!< Generic failure. */ @@ -233,8 +237,8 @@ typedef union { /** * @brief SDP callback function type. * - * @param event: Event type - * @param param: Point to callback parameter, currently is union type + * @param[in] event: Event type + * @param[in] param: Point to callback parameter, currently is union type */ typedef void (* esp_sdp_cb_t)(esp_sdp_cb_event_t event, esp_sdp_cb_param_t *param); @@ -275,7 +279,7 @@ esp_err_t esp_sdp_init(void); esp_err_t esp_sdp_deinit(void); /** - * @brief This function is called to performs service discovery for the services provided by the given peer device. + * @brief Perform service discovery for the services provided by the given peer device. * When the operation is completed, the callback function will be called with ESP_SDP_SEARCH_COMP_EVT. * This function must be called after esp_sdp_init() successful and before esp_sdp_deinit(). * @@ -302,7 +306,7 @@ esp_err_t esp_sdp_search_record(esp_bd_addr_t bd_addr, esp_bt_uuid_t uuid); esp_err_t esp_sdp_create_record(esp_bluetooth_sdp_record_t *record); /** - * @brief This function is called to remove a SDP record. + * @brief Remove an SDP record. * When the operation is completed, the callback function will be called with ESP_SDP_REMOVE_RECORD_COMP_EVT. * This function must be called after esp_sdp_init() successful and before esp_sdp_deinit(). * diff --git a/docs/en/api-reference/bluetooth/esp_sdp.rst b/docs/en/api-reference/bluetooth/esp_sdp.rst index 75a893731e..3bd53c2423 100644 --- a/docs/en/api-reference/bluetooth/esp_sdp.rst +++ b/docs/en/api-reference/bluetooth/esp_sdp.rst @@ -1,10 +1,17 @@ -Bluetooth® SDP APIs -=================== +Bluetooth® SDP API +================== Overview -------- -Bluetooth SDP reference APIs. +SDP (Service Discovery Protocol) API enables devices to discover services and service attributes offered by remote Bluetooth devices. It supports service search, service attribute retrieval, and the establishment of service connections. + +Application Examples +-------------------- + +- :example:`bluetooth/bluedroid/classic_bt/bt_l2cap_client` demonstrates how to use SDP APIs to search for services on remote Bluetooth devices. It shows how to register SDP callbacks, initialize SDP, perform service discovery using ``esp_sdp_search_record()``, and retrieve the L2CAP PSM (Protocol/Service Multiplexer) value from the search results to establish an L2CAP connection. + +- :example:`bluetooth/bluedroid/classic_bt/bt_l2cap_server` demonstrates how to use SDP APIs to create and publish service records. It shows how to register SDP callbacks, initialize SDP, create an SDP record using ``esp_sdp_create_record()`` with L2CAP PSM information, making the service discoverable by remote clients. API Reference ------------- From 3472c66976d8f1a8ba61c3415e507358709f8d6f Mon Sep 17 00:00:00 2001 From: Ondrej Kosta Date: Wed, 7 Jan 2026 16:29:31 +0100 Subject: [PATCH 192/226] fix(esp_eth): made 10M loopback test less strict --- .../test_apps/main/esp_eth_test_apps.c | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/components/esp_eth/test_apps/main/esp_eth_test_apps.c b/components/esp_eth/test_apps/main/esp_eth_test_apps.c index c71686893a..efd0d8a4d4 100644 --- a/components/esp_eth/test_apps/main/esp_eth_test_apps.c +++ b/components/esp_eth/test_apps/main/esp_eth_test_apps.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -13,6 +13,7 @@ #include "esp_http_client.h" #include "esp_rom_md5.h" #include "esp_eth_test_common.h" +#include "unity.h" #define LOOPBACK_TEST_PACKET_SIZE 256 @@ -401,7 +402,7 @@ TEST_CASE("ethernet io loopback", "[ethernet]") #endif eth_duplex_t duplex_modes[] = {ETH_DUPLEX_HALF, ETH_DUPLEX_FULL}; - eth_speed_t speeds[] = {ETH_SPEED_10M, ETH_SPEED_100M}; + eth_speed_t speeds[] = {ETH_SPEED_100M, ETH_SPEED_10M}; emac_frame_t* test_packet = malloc(LOOPBACK_TEST_PACKET_SIZE); esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, test_packet->src); esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, test_packet->dest); @@ -447,7 +448,27 @@ TEST_CASE("ethernet io loopback", "[ethernet]") TEST_ASSERT_EQUAL(expected_duplex, actual_duplex); TEST_ESP_OK(esp_eth_transmit(eth_handle, test_packet, LOOPBACK_TEST_PACKET_SIZE)); - TEST_ASSERT(xSemaphoreTake(loopback_test_case_data_received, pdMS_TO_TICKS(10000)) == pdTRUE); + /* 10Mbps RMII loopback may have timing issues due to clock division architecture. RMII CLK stays 50MHz while the data signal must be held still for 10 cycles to + achieve the speed reduction. Everything, including control signals must be perfectly synchronized. This may be a challenge for some PHYs or PCB layouts.*/ + if (expected_speed == ETH_SPEED_10M) { + int i; + for (i = 0; i < 3; i++) { + if(xSemaphoreTake(loopback_test_case_data_received, pdMS_TO_TICKS(1000)) != pdTRUE) { + ESP_LOGW(TAG, "Timeout waiting for data received for 10 Mbps mode, trying again..."); + TEST_ESP_OK(esp_eth_stop(eth_handle)); + bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS)); + TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT); + TEST_ESP_OK(esp_eth_start(eth_handle)); + bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS)); + TEST_ESP_OK(esp_eth_transmit(eth_handle, test_packet, LOOPBACK_TEST_PACKET_SIZE)); + } else { + break; + } + } + TEST_ASSERT_LESS_THAN(3, i); + } else { + TEST_ASSERT(xSemaphoreTake(loopback_test_case_data_received, pdMS_TO_TICKS(1000)) == pdTRUE); + } TEST_ESP_OK(esp_eth_stop(eth_handle)); } } From 55bfa88360ebe11ed3cbd5b65af0a2c816de2394 Mon Sep 17 00:00:00 2001 From: Akshat Agrawal Date: Wed, 31 Dec 2025 12:20:16 +0530 Subject: [PATCH 193/226] bugfix(wifi): Ensure STA parses the FTM responder capability from the beacon correctly --- components/esp_wifi/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index f2221f65aa..a91a026a2e 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit f2221f65aa9bcb3d5ff54c68a7823c5f0d2b01aa +Subproject commit a91a026a2eacb7aef458be69d967e48c9e860624 From a4aff97a2187db58d04048435c2a7f46289ac702 Mon Sep 17 00:00:00 2001 From: Xiao Xufeng Date: Sun, 28 Dec 2025 21:24:22 +0800 Subject: [PATCH 194/226] fix(psram): fix inaccurate warning that encryption not enabled on PSRAM on ESP32-C5 v1.2 and C61 v1.1 --- components/esp_psram/system_layer/esp_psram.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/components/esp_psram/system_layer/esp_psram.c b/components/esp_psram/system_layer/esp_psram.c index f236e03b96..434ab3be6f 100644 --- a/components/esp_psram/system_layer/esp_psram.c +++ b/components/esp_psram/system_layer/esp_psram.c @@ -23,6 +23,7 @@ #include "hal/mmu_hal.h" #include "hal/mmu_ll.h" #include "hal/cache_ll.h" +#include "hal/efuse_hal.h" #include "soc/soc_caps.h" #include "esp_private/esp_psram_io.h" #include "esp_private/esp_psram_extram.h" @@ -116,8 +117,10 @@ ESP_SYSTEM_INIT_FN(add_psram_to_heap, CORE, BIT(0), 103) #if CONFIG_SPIRAM_BOOT_INIT && (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC) #if (CONFIG_IDF_TARGET_ESP32C5 && CONFIG_ESP32C5_REV_MIN_FULL <= 100) || (CONFIG_IDF_TARGET_ESP32C61 && CONFIG_ESP32C61_REV_MIN_FULL <= 100) - ESP_EARLY_LOGW(TAG, "Due to hardware issue on ESP32-C5/C61 (Rev v1.0), PSRAM contents won't be encrypted (for flash encryption enabled case)"); - ESP_EARLY_LOGW(TAG, "Please avoid using PSRAM for security sensitive data e.g., TLS stack allocations (CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC)"); + if (efuse_hal_chip_revision() <= 100) { + ESP_EARLY_LOGW(TAG, "Due to hardware issue on ESP32-C5/C61 (Rev v1.0), PSRAM contents won't be encrypted (for flash encryption enabled case)"); + ESP_EARLY_LOGW(TAG, "Please avoid using PSRAM for security sensitive data e.g., TLS stack allocations (CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC)"); + } #endif if (esp_psram_is_initialized()) { esp_err_t r = esp_psram_extram_add_to_heap_allocator(); @@ -422,8 +425,10 @@ esp_err_t esp_psram_init(void) #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA #if (CONFIG_IDF_TARGET_ESP32C5 && CONFIG_ESP32C5_REV_MIN_FULL <= 100) || (CONFIG_IDF_TARGET_ESP32C61 && CONFIG_ESP32C61_REV_MIN_FULL <= 100) - ESP_EARLY_LOGW(TAG, "Due to hardware issue on ESP32-C5/C61 (Rev v1.0), PSRAM contents won't be encrypted (for flash encryption enabled case)"); - ESP_EARLY_LOGW(TAG, "Please avoid using PSRAM for execution as the code/rodata shall be copied as plaintext and this could pose a security risk."); + if (efuse_hal_chip_revision() <= 100) { + ESP_EARLY_LOGW(TAG, "Due to hardware issue on ESP32-C5/C61 (Rev v1.0), PSRAM contents won't be encrypted (for flash encryption enabled case)"); + ESP_EARLY_LOGW(TAG, "Please avoid using PSRAM for execution as the code/rodata shall be copied as plaintext and this could pose a security risk."); + } #endif s_xip_psram_placement(&psram_available_size, &start_page); #endif From 06930027e4c5ad774502bd48614f495e4bab023e Mon Sep 17 00:00:00 2001 From: Chen Jichang Date: Mon, 12 Jan 2026 17:14:02 +0800 Subject: [PATCH 195/226] feat(parlio): add buffer size alignment warning for c6 Closes https://github.com/espressif/esp-idf/issues/17970 --- components/esp_driver_parlio/src/parlio_tx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/esp_driver_parlio/src/parlio_tx.c b/components/esp_driver_parlio/src/parlio_tx.c index 706a4e4e64..8f5e7a7fa4 100644 --- a/components/esp_driver_parlio/src/parlio_tx.c +++ b/components/esp_driver_parlio/src/parlio_tx.c @@ -660,6 +660,9 @@ esp_err_t parlio_tx_unit_transmit(parlio_tx_unit_handle_t tx_unit, const void *p ESP_RETURN_ON_FALSE(payload_bits <= tx_unit->max_transfer_bits, ESP_ERR_INVALID_ARG, TAG, "payload bit length too large"); #if !SOC_PARLIO_TRANS_BIT_ALIGN ESP_RETURN_ON_FALSE((payload_bits % 8) == 0, ESP_ERR_INVALID_ARG, TAG, "payload bit length must be multiple of 8"); + if (payload_bits % 32 != 0) { + ESP_LOGW(TAG, "payload bit length %d is not multiple of 32, it may cause unexpected behavior", payload_bits); + } #endif // !SOC_PARLIO_TRANS_BIT_ALIGN #if SOC_PARLIO_TX_SUPPORT_LOOP_TRANSMISSION From 54f5822499139bf9f79eea85d646cfa6e4e467de Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Thu, 8 Jan 2026 15:03:13 +0530 Subject: [PATCH 196/226] fix(nimble): Add AD type macros in example --- .../ble/ble_ibeacon/main/esp_ibeacon_api.c | 4 +-- .../bluetooth/nimble/ble_ancs/main/main.c | 8 ++--- .../ble_chan_sound_reflector/main/main.c | 8 ++--- .../ble_periodic_adv_with_cte/main/main.c | 2 +- .../nimble/ble_cts/cts_prph/main/main.c | 8 ++--- .../nimble/ble_htp/htp_prph/main/main.c | 8 ++--- .../ble_l2cap_coc/coc_bleprph/main/main.c | 8 ++--- .../nimble/ble_multi_adv/main/main.c | 32 +++++++++---------- .../ble_multi_conn_cent/main/main.c | 4 +-- .../ble_multi_conn_prph/main/main.c | 8 ++--- .../nimble/ble_phy/phy_prph/main/main.c | 24 +++++++------- .../proximity_sensor_prph/main/main.c | 8 ++--- examples/bluetooth/nimble/blecsc/main/main.c | 8 ++--- examples/bluetooth/nimble/bleprph/main/main.c | 8 ++--- .../nimble/bleprph_host_only/main/main.c | 8 ++--- .../bluetooth/nimble/power_save/main/main.c | 8 ++--- .../bleprph_throughput/main/main.c | 8 ++--- 17 files changed, 81 insertions(+), 81 deletions(-) diff --git a/examples/bluetooth/bluedroid/ble/ble_ibeacon/main/esp_ibeacon_api.c b/examples/bluetooth/bluedroid/ble/ble_ibeacon/main/esp_ibeacon_api.c index 132eb69195..9dad0849cf 100644 --- a/examples/bluetooth/bluedroid/ble/ble_ibeacon/main/esp_ibeacon_api.c +++ b/examples/bluetooth/bluedroid/ble/ble_ibeacon/main/esp_ibeacon_api.c @@ -29,9 +29,9 @@ const uint8_t uuid_zeros[ESP_UUID_LEN_128] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* For iBeacon packet format, please refer to Apple "Proximity Beacon Specification" doc */ /* Constant part of iBeacon data */ esp_ble_ibeacon_head_t ibeacon_common_head = { - .flags = {0x02, 0x01, 0x06}, + .flags = {0x02, ESP_BLE_AD_TYPE_FLAG, ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT}, .length = 0x1A, - .type = 0xFF, + .type = ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE, .company_id = 0x004C, .beacon_type = 0x1502 }; diff --git a/examples/bluetooth/nimble/ble_ancs/main/main.c b/examples/bluetooth/nimble/ble_ancs/main/main.c index 8ef98e691f..d64dbda751 100644 --- a/examples/bluetooth/nimble/ble_ancs/main/main.c +++ b/examples/bluetooth/nimble/ble_ancs/main/main.c @@ -69,10 +69,10 @@ static ble_uuid128_t data_source = BLE_UUID128_INIT( #if CONFIG_EXAMPLE_EXTENDED_ADV static uint8_t ext_adv_pattern_1[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x11, - 0x0e, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'a', 'n', 'c', 's', '-', 'e', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x18, 0x11, + 0x0e, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'a', 'n', 'c', 's', '-', 'e', }; #endif diff --git a/examples/bluetooth/nimble/ble_chan_sound_reflector/main/main.c b/examples/bluetooth/nimble/ble_chan_sound_reflector/main/main.c index 5ad76841a9..5779b32746 100644 --- a/examples/bluetooth/nimble/ble_chan_sound_reflector/main/main.c +++ b/examples/bluetooth/nimble/ble_chan_sound_reflector/main/main.c @@ -32,10 +32,10 @@ #if CONFIG_EXAMPLE_EXTENDED_ADV static uint8_t ext_adv_pattern_1[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x5B, 0x18, - 0x11, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'e', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x5B, 0x18, + 0x11, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'e', }; #endif static const char *tag = "NimBLE_BLE_CHAN_REFLECTOR"; diff --git a/examples/bluetooth/nimble/ble_cte/ble_periodic_adv_with_cte/main/main.c b/examples/bluetooth/nimble/ble_cte/ble_periodic_adv_with_cte/main/main.c index ef897d132e..24fbb2beff 100644 --- a/examples/bluetooth/nimble/ble_cte/ble_periodic_adv_with_cte/main/main.c +++ b/examples/bluetooth/nimble/ble_cte/ble_periodic_adv_with_cte/main/main.c @@ -19,7 +19,7 @@ /* Global constants */ static const char *TAG = "CTE_ADV_EXAMPLE"; -static uint8_t s_periodic_adv_raw_data[] = {0x0D, 0x09, 'C','T','E',' ','P','e','r','i','o','d','i','c'}; +static uint8_t s_periodic_adv_raw_data[] = {0x0D, BLE_HS_ADV_TYPE_COMP_NAME, 'C','T','E',' ','P','e','r','i','o','d','i','c'}; /* Configuration based on Kconfig settings */ #if CONFIG_EXAMPLE_RANDOM_ADDR diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c b/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c index 04ee0c3ead..b054ef9ecb 100644 --- a/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c @@ -19,10 +19,10 @@ #if CONFIG_EXAMPLE_EXTENDED_ADV static uint8_t ext_adv_pattern_1[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x05, 0x18, - 0x12, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'c', 't', 's', '-', 'p', 'r', 'p', 'h', '-', 'e', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x05, 0x18, + 0x12, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'c', 't', 's', '-', 'p', 'r', 'p', 'h', '-', 'e', }; #endif diff --git a/examples/bluetooth/nimble/ble_htp/htp_prph/main/main.c b/examples/bluetooth/nimble/ble_htp/htp_prph/main/main.c index 896c1d6fd4..e400a619c6 100644 --- a/examples/bluetooth/nimble/ble_htp/htp_prph/main/main.c +++ b/examples/bluetooth/nimble/ble_htp/htp_prph/main/main.c @@ -18,10 +18,10 @@ #if CONFIG_EXAMPLE_EXTENDED_ADV static uint8_t ext_adv_pattern_1[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x09, - 0x12, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'h', 't', 'p', '-', 'p', 'r', 'p', 'h', '-', 'e', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x18, 0x09, + 0x12, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'h', 't', 'p', '-', 'p', 'r', 'p', 'h', '-', 'e', }; #endif diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/main.c b/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/main.c index 641a2f43bc..a4e9cb5cef 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/main.c +++ b/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/main.c @@ -17,10 +17,10 @@ #if CONFIG_EXAMPLE_EXTENDED_ADV static uint8_t ext_adv_pattern_1[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x12, - 0x12, 0X09, 'e', 'x', 't', '-', 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'l', '2', 'c', 'o', 'c', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x18, 0x12, + 0x12, BLE_HS_ADV_TYPE_COMP_NAME, 'e', 'x', 't', '-', 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'l', '2', 'c', 'o', 'c', }; #endif diff --git a/examples/bluetooth/nimble/ble_multi_adv/main/main.c b/examples/bluetooth/nimble/ble_multi_adv/main/main.c index 03f93210fd..f7e2483a74 100644 --- a/examples/bluetooth/nimble/ble_multi_adv/main/main.c +++ b/examples/bluetooth/nimble/ble_multi_adv/main/main.c @@ -30,33 +30,33 @@ static void ble_multi_advertise(ble_addr_t addr); /* Advertising patterns */ static uint8_t legacy_dur_adv_pattern[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x11, - 0x12, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'l', 'e', 'g', 'a', 'c', 'y', '-', 'd', 'u', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x18, 0x11, + 0x12, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'l', 'e', 'g', 'a', 'c', 'y', '-', 'd', 'u', 'r' }; static uint8_t scannable_legacy_adv_pattern[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x11, - 0x13, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 's', 'c', 'a', 'n', '-', 'l', 'e', 'g', 'a', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x18, 0x11, + 0x13, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 's', 'c', 'a', 'n', '-', 'l', 'e', 'g', 'a', 'c', 'y' }; static uint8_t connectable_adv_pattern[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x11, - 0x12, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'c', 'o', 'n', 'n', 'e', 't', 'a', 'b', 'l', 'e' + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x18, 0x11, + 0x12, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'c', 'o', 'n', 'n', 'e', 't', 'a', 'b', 'l', 'e' }; static uint8_t non_conn_adv_pattern[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x11, - 0x10, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'n', 'o', 'n', '-', 'c', 'o', 'n', 'n' + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x18, 0x11, + 0x10, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'n', 'o', 'n', '-', 'c', 'o', 'n', 'n' }; /** diff --git a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_cent/main/main.c b/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_cent/main/main.c index c324092aee..d2e626f1af 100644 --- a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_cent/main/main.c +++ b/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_cent/main/main.c @@ -26,8 +26,8 @@ static const ble_uuid_t *remote_svc_uuid = 0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59); static uint8_t ext_adv_pattern_1[] = { - 0x02, 0x01, 0x06, - 0x14, 0X09, 'e', 's', 'p', '-', 'b', 'l', 'e', '-', 'r', 'o', 'l', 'e', '-', 'c', 'o', 'e', 'x', '-', 'e', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x14, BLE_HS_ADV_TYPE_COMP_NAME, 'e', 's', 'p', '-', 'b', 'l', 'e', '-', 'r', 'o', 'l', 'e', '-', 'c', 'o', 'e', 'x', '-', 'e', }; void ble_store_config_init(void); diff --git a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/main.c b/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/main.c index e4b0f4686a..e697bfff3f 100644 --- a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/main.c +++ b/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/main.c @@ -15,10 +15,10 @@ #if CONFIG_EXAMPLE_EXTENDED_ADV static uint8_t ext_adv_pattern_1[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x11, - 0x11, 0X09, 'e', 's', 'p', '-', 'm', 'u', 'l', 't', 'i', '-', 'c', 'o', 'n', 'n', '-', 'e', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x18, 0x11, + 0x11, BLE_HS_ADV_TYPE_COMP_NAME, 'e', 's', 'p', '-', 'm', 'u', 'l', 't', 'i', '-', 'c', 'o', 'n', 'n', '-', 'e', }; #endif diff --git a/examples/bluetooth/nimble/ble_phy/phy_prph/main/main.c b/examples/bluetooth/nimble/ble_phy/phy_prph/main/main.c index 4fce3bedb3..915f2b90d1 100644 --- a/examples/bluetooth/nimble/ble_phy/phy_prph/main/main.c +++ b/examples/bluetooth/nimble/ble_phy/phy_prph/main/main.c @@ -16,24 +16,24 @@ #include "phy_prph.h" static uint8_t ext_adv_pattern_1M[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0xAB, 0xF2, - 0x0e, 0X09, 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'p', 'h', 'y', '-', '1', 'M', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xAB, 0xF2, + 0x0e, BLE_HS_ADV_TYPE_COMP_NAME, 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'p', 'h', 'y', '-', '1', 'M', }; static uint8_t ext_adv_pattern_2M[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0xAB, 0xF2, - 0x0e, 0X09, 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'p', 'h', 'y', '-', '2', 'M', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xAB, 0xF2, + 0x0e, BLE_HS_ADV_TYPE_COMP_NAME, 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'p', 'h', 'y', '-', '2', 'M', }; static uint8_t ext_adv_pattern_coded[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0xAB, 0xF2, - 0x11, 0X09, 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'p', 'h', 'y', '-', 'c', 'o', 'd', 'e', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xAB, 0xF2, + 0x11, BLE_HS_ADV_TYPE_COMP_NAME, 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'p', 'h', 'y', '-', 'c', 'o', 'd', 'e', 'd', }; diff --git a/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_prph/main/main.c b/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_prph/main/main.c index 336f80c722..9b2190e83d 100644 --- a/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_prph/main/main.c +++ b/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_prph/main/main.c @@ -18,10 +18,10 @@ #if CONFIG_EXAMPLE_EXTENDED_ADV static uint8_t ext_adv_pattern_1[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x03, - 0x13, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'p', 'r', 'o', 'x', '-', 'p', 'r', 'p', 'h', '-', 'e', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x18, 0x03, + 0x13, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'p', 'r', 'o', 'x', '-', 'p', 'r', 'p', 'h', '-', 'e', }; #endif diff --git a/examples/bluetooth/nimble/blecsc/main/main.c b/examples/bluetooth/nimble/blecsc/main/main.c index 73c30906d9..c146c986c5 100644 --- a/examples/bluetooth/nimble/blecsc/main/main.c +++ b/examples/bluetooth/nimble/blecsc/main/main.c @@ -31,10 +31,10 @@ #if CONFIG_EXAMPLE_EXTENDED_ADV static uint8_t ext_adv_pattern_1[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x11, - 0x10, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'b', 'l', 'e', 'c', 's', 'c','-', 'e', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x18, 0x11, + 0x10, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'b', 'l', 'e', 'c', 's', 'c','-', 'e', }; #endif diff --git a/examples/bluetooth/nimble/bleprph/main/main.c b/examples/bluetooth/nimble/bleprph/main/main.c index 8b705fbd68..af47c35424 100644 --- a/examples/bluetooth/nimble/bleprph/main/main.c +++ b/examples/bluetooth/nimble/bleprph/main/main.c @@ -30,10 +30,10 @@ #if CONFIG_EXAMPLE_EXTENDED_ADV static uint8_t ext_adv_pattern_1[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x11, - 0x11, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'e', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x18, 0x11, + 0x11, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'e', }; #endif diff --git a/examples/bluetooth/nimble/bleprph_host_only/main/main.c b/examples/bluetooth/nimble/bleprph_host_only/main/main.c index a03b3157ea..9523937350 100644 --- a/examples/bluetooth/nimble/bleprph_host_only/main/main.c +++ b/examples/bluetooth/nimble/bleprph_host_only/main/main.c @@ -18,10 +18,10 @@ #if CONFIG_EXAMPLE_EXTENDED_ADV static uint8_t ext_adv_pattern_1[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x11, - 0x11, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'e', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x18, 0x11, + 0x11, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'e', }; #endif diff --git a/examples/bluetooth/nimble/power_save/main/main.c b/examples/bluetooth/nimble/power_save/main/main.c index 0e7e9bcf5b..790f0f7489 100644 --- a/examples/bluetooth/nimble/power_save/main/main.c +++ b/examples/bluetooth/nimble/power_save/main/main.c @@ -41,10 +41,10 @@ #if CONFIG_EXAMPLE_EXTENDED_ADV static uint8_t ext_adv_pattern_1[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x11, - 0x11, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'e', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x18, 0x11, + 0x11, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'e', }; #endif diff --git a/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/main.c b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/main.c index e15042207f..db9c525978 100644 --- a/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/main.c +++ b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/main.c @@ -19,10 +19,10 @@ #if CONFIG_EXAMPLE_EXTENDED_ADV static uint8_t ext_adv_pattern[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0xAB, 0xF2, - 0x0e, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'b', 'l', 'e', 'p', 'r', 'p', 'h' + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd, + 0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xAB, 0xF2, + 0x0e, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'b', 'l', 'e', 'p', 'r', 'p', 'h' }; static uint8_t s_current_phy; From f18228020f62b05a60b46af7b01ea771aa9165b0 Mon Sep 17 00:00:00 2001 From: Tan Yan Quan Date: Thu, 8 Jan 2026 15:18:27 +0800 Subject: [PATCH 197/226] feat(openthread): migrate iperf to use iperf-cmd component --- examples/openthread/ot_br/main/esp_ot_br.c | 3 ++- examples/openthread/ot_cli/main/esp_ot_cli.c | 3 ++- .../ot_examples_common/CMakeLists.txt | 2 +- .../ot_examples_common/Kconfig.projbuild | 10 ++++++++++ .../ot_examples_common/idf_component.yml | 1 + .../include/ot_examples_common.h | 8 +++++++- .../ot_examples_common/ot_console.c | 16 +++++++++++++--- examples/openthread/ot_trel/main/esp_ot_trel.c | 4 ++-- 8 files changed, 38 insertions(+), 9 deletions(-) diff --git a/examples/openthread/ot_br/main/esp_ot_br.c b/examples/openthread/ot_br/main/esp_ot_br.c index 5f8c4b44bd..110c32820c 100644 --- a/examples/openthread/ot_br/main/esp_ot_br.c +++ b/examples/openthread/ot_br/main/esp_ot_br.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 * @@ -97,6 +97,7 @@ void app_main(void) #if CONFIG_OPENTHREAD_CLI ot_console_start(); + ot_register_external_commands(); #endif #if CONFIG_ESP_COEX_EXTERNAL_COEXIST_ENABLE diff --git a/examples/openthread/ot_cli/main/esp_ot_cli.c b/examples/openthread/ot_cli/main/esp_ot_cli.c index ee83bcc22d..252615479f 100644 --- a/examples/openthread/ot_cli/main/esp_ot_cli.c +++ b/examples/openthread/ot_cli/main/esp_ot_cli.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 * @@ -58,6 +58,7 @@ void app_main(void) #if CONFIG_OPENTHREAD_CLI ot_console_start(); + ot_register_external_commands(); #endif static esp_openthread_config_t config = { diff --git a/examples/openthread/ot_common_components/ot_examples_common/CMakeLists.txt b/examples/openthread/ot_common_components/ot_examples_common/CMakeLists.txt index 321063eb94..b78a93b927 100644 --- a/examples/openthread/ot_common_components/ot_examples_common/CMakeLists.txt +++ b/examples/openthread/ot_common_components/ot_examples_common/CMakeLists.txt @@ -15,5 +15,5 @@ endif() idf_component_register( SRCS "${srcs}" INCLUDE_DIRS "include" - PRIV_REQUIRES console cmd_system esp_coex openthread + PRIV_REQUIRES console cmd_system esp_coex openthread iperf-cmd iperf ) diff --git a/examples/openthread/ot_common_components/ot_examples_common/Kconfig.projbuild b/examples/openthread/ot_common_components/ot_examples_common/Kconfig.projbuild index 94e38cf6c1..0bca5c2987 100644 --- a/examples/openthread/ot_common_components/ot_examples_common/Kconfig.projbuild +++ b/examples/openthread/ot_common_components/ot_examples_common/Kconfig.projbuild @@ -9,6 +9,16 @@ menu "Config for OpenThread Examples" If enabled, the Openthread Device will create or connect to Thread network with pre-configured network parameters automatically. Otherwise, user need to configure Thread via CLI command manually. + menu "External Console Commands" + config OPENTHREAD_IPERF_CMD_ENABLE + bool "Enable iperf command" + depends on OPENTHREAD_FTD || OPENTHREAD_MTD + default y + help + If enabled, iperf will be registered and available as a console command. + This allows network performance testing using iperf over the Thread network. + endmenu # External Console Commands + menu "External coexist wire type and pin config" depends on ESP_COEX_EXTERNAL_COEXIST_ENABLE diff --git a/examples/openthread/ot_common_components/ot_examples_common/idf_component.yml b/examples/openthread/ot_common_components/ot_examples_common/idf_component.yml index 77b231f2a7..64b8f724c2 100644 --- a/examples/openthread/ot_common_components/ot_examples_common/idf_component.yml +++ b/examples/openthread/ot_common_components/ot_examples_common/idf_component.yml @@ -1,4 +1,5 @@ ## IDF Component Manager Manifest File dependencies: + espressif/iperf-cmd: "^1.0.0" cmd_system: path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_system diff --git a/examples/openthread/ot_common_components/ot_examples_common/include/ot_examples_common.h b/examples/openthread/ot_common_components/ot_examples_common/include/ot_examples_common.h index 9c7ab22964..0c5c298c09 100644 --- a/examples/openthread/ot_common_components/ot_examples_common/include/ot_examples_common.h +++ b/examples/openthread/ot_common_components/ot_examples_common/include/ot_examples_common.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 * @@ -61,3 +61,9 @@ void ot_console_start(void); * */ void ot_network_auto_start(void); + +/** + * @brief Register external system commands (e.g., iperf). + * + */ +void ot_register_external_commands(void); diff --git a/examples/openthread/ot_common_components/ot_examples_common/ot_console.c b/examples/openthread/ot_common_components/ot_examples_common/ot_console.c index a293adf38c..6c679941d3 100644 --- a/examples/openthread/ot_common_components/ot_examples_common/ot_console.c +++ b/examples/openthread/ot_common_components/ot_examples_common/ot_console.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 * @@ -18,6 +18,10 @@ #include "esp_console.h" #include "cmd_system.h" +#if CONFIG_OPENTHREAD_IPERF_CMD_ENABLE +#include "iperf_cmd.h" +#endif + void ot_console_start(void) { esp_console_repl_t *repl = NULL; @@ -43,6 +47,12 @@ void ot_console_start(void) #error Unsupported console type #endif ESP_ERROR_CHECK(esp_console_start_repl(repl)); - - register_system(); +} + +void ot_register_external_commands(void) +{ + register_system(); +#if CONFIG_OPENTHREAD_IPERF_CMD_ENABLE + iperf_cmd_register_iperf(); +#endif } diff --git a/examples/openthread/ot_trel/main/esp_ot_trel.c b/examples/openthread/ot_trel/main/esp_ot_trel.c index d45b211b7b..3feddb069a 100644 --- a/examples/openthread/ot_trel/main/esp_ot_trel.c +++ b/examples/openthread/ot_trel/main/esp_ot_trel.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 * @@ -44,7 +44,6 @@ #include "esp_ot_cli_extension.h" #endif // CONFIG_OPENTHREAD_CLI_ESP_EXTENSION - #define TAG "ot_esp_trel" void app_main(void) @@ -68,6 +67,7 @@ void app_main(void) #if CONFIG_OPENTHREAD_CLI ot_console_start(); + ot_register_external_commands(); #endif static esp_openthread_config_t config = { From 556a29f9f9d1aa232a14ef94ce3872990ef073a4 Mon Sep 17 00:00:00 2001 From: Tan Yan Quan Date: Thu, 8 Jan 2026 15:53:56 +0800 Subject: [PATCH 198/226] feat(openthread/cli-ext): update cli-ext to v2.0.0 --- examples/openthread/ot_br/main/idf_component.yml | 2 +- examples/openthread/ot_cli/main/idf_component.yml | 2 +- examples/openthread/ot_trel/main/idf_component.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/openthread/ot_br/main/idf_component.yml b/examples/openthread/ot_br/main/idf_component.yml index b00b26c7bb..3dca30645e 100644 --- a/examples/openthread/ot_br/main/idf_component.yml +++ b/examples/openthread/ot_br/main/idf_component.yml @@ -1,7 +1,7 @@ ## IDF Component Manager Manifest File dependencies: espressif/esp_ot_cli_extension: - version: "~1.4.0" + version: "~2.0.0" espressif/mdns: "^1.0.3" ## Required IDF version idf: diff --git a/examples/openthread/ot_cli/main/idf_component.yml b/examples/openthread/ot_cli/main/idf_component.yml index 079266490f..49621895d6 100644 --- a/examples/openthread/ot_cli/main/idf_component.yml +++ b/examples/openthread/ot_cli/main/idf_component.yml @@ -1,7 +1,7 @@ ## IDF Component Manager Manifest File dependencies: espressif/esp_ot_cli_extension: - version: "~1.4.0" + version: "~2.0.0" idf: version: ">=4.1.0" ot_led: diff --git a/examples/openthread/ot_trel/main/idf_component.yml b/examples/openthread/ot_trel/main/idf_component.yml index 4318a41630..cb9759faca 100644 --- a/examples/openthread/ot_trel/main/idf_component.yml +++ b/examples/openthread/ot_trel/main/idf_component.yml @@ -1,7 +1,7 @@ ## IDF Component Manager Manifest File dependencies: espressif/esp_ot_cli_extension: - version: "~1.4.0" + version: "~2.0.0" espressif/mdns: "^1.0.3" idf: version: ">=4.1.0" From a8ea7f66f87d2653d65ba0f3f2b12411eda76559 Mon Sep 17 00:00:00 2001 From: Tan Yan Quan Date: Thu, 8 Jan 2026 17:36:08 +0800 Subject: [PATCH 199/226] docs(openthread): add iperf usage guide to ot_cli example readme --- examples/openthread/ot_cli/README.md | 46 +++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/examples/openthread/ot_cli/README.md b/examples/openthread/ot_cli/README.md index 4ffe0a0131..ca7f2611a0 100644 --- a/examples/openthread/ot_cli/README.md +++ b/examples/openthread/ot_cli/README.md @@ -128,5 +128,49 @@ You can refer to the [extension command](https://github.com/espressif/esp-thread The following examples are supported by `ot_cli`: * TCP and UDP Example -* Iperf Example +## Using iPerf to measure bandwidth + +iPerf is a tool used to obtain TCP or UDP throughput on the Thread network. To run iPerf, you need to have two Thread devices on the same network. + +Refer to [the iperf-cmd component](https://components.espressif.com/components/espressif/iperf-cmd) for details on specific configurations. + +### Typical usage on a thread network + +For measuring the TCP throughput, first create an iperf service on one node: +```bash +> iperf -V -s -t 20 -i 3 -p 5001 -f k +Done +``` + +Then create an iperf client connecting to the service on another node. Note that the [ML-EID](https://openthread.io/guides/thread-primer/ipv6-addressing#unicast_address_types) address is used for iperf. + +```bash +> ipaddr mleid +fdde:ad00:beef:0:a7c6:6311:9c8c:271b +Done + +> iperf -V -c fdde:ad00:beef:0:a7c6:6311:9c8c:271b -t 20 -i 1 -p 5001 -l 85 -f k +Done +[ ID] Interval Transfer Bandwidth +[ 1] 0.0- 1.0 sec 3.15 KBytes 25.16 Kbits/sec +[ 1] 1.0- 2.0 sec 2.89 KBytes 23.12 Kbits/sec +[ 1] 2.0- 3.0 sec 2.98 KBytes 23.80 Kbits/sec +... +[ 1] 9.0-10.0 sec 2.55 KBytes 20.40 Kbits/sec +[ 1] 0.0-10.0 sec 27.80 KBytes 22.24 Kbits/sec +``` + +For measuring the UDP throughput, first create an iperf service similarly: + +```bash +> iperf -V -u -s -t 20 -i 3 -p 5001 -f k +Done +``` + +Then create an iperf client: + +```bash +> iperf -V -u -c fdde:ad00:beef:0:a7c6:6311:9c8c:271b -t 20 -i 1 -p 5001 -l 85 -f k +Done +``` From cd42265af2237b10d0254eb85ff75e65da6877ff Mon Sep 17 00:00:00 2001 From: Tan Yan Quan Date: Mon, 29 Dec 2025 15:36:34 +0800 Subject: [PATCH 200/226] fix(openthread): restore LED state indicator for example code --- examples/openthread/ot_br/main/esp_ot_br.c | 3 +++ examples/openthread/ot_cli/main/esp_ot_cli.c | 3 +++ examples/openthread/ot_trel/main/esp_ot_trel.c | 3 +++ 3 files changed, 9 insertions(+) diff --git a/examples/openthread/ot_br/main/esp_ot_br.c b/examples/openthread/ot_br/main/esp_ot_br.c index 110c32820c..c9bb84eff0 100644 --- a/examples/openthread/ot_br/main/esp_ot_br.c +++ b/examples/openthread/ot_br/main/esp_ot_br.c @@ -123,6 +123,9 @@ void app_main(void) ESP_ERROR_CHECK(esp_coex_wifi_i154_enable()); #endif #endif +#if CONFIG_OPENTHREAD_STATE_INDICATOR_ENABLE + ESP_ERROR_CHECK(esp_openthread_state_indicator_init(esp_openthread_get_instance())); +#endif #if CONFIG_OPENTHREAD_NETWORK_AUTO_START ot_network_auto_start(); #endif diff --git a/examples/openthread/ot_cli/main/esp_ot_cli.c b/examples/openthread/ot_cli/main/esp_ot_cli.c index 252615479f..44a7d1abe8 100644 --- a/examples/openthread/ot_cli/main/esp_ot_cli.c +++ b/examples/openthread/ot_cli/main/esp_ot_cli.c @@ -74,6 +74,9 @@ void app_main(void) #if CONFIG_OPENTHREAD_CLI_ESP_EXTENSION esp_cli_custom_command_init(); #endif +#if CONFIG_OPENTHREAD_STATE_INDICATOR_ENABLE + ESP_ERROR_CHECK(esp_openthread_state_indicator_init(esp_openthread_get_instance())); +#endif #if CONFIG_OPENTHREAD_NETWORK_AUTO_START ot_network_auto_start(); #endif diff --git a/examples/openthread/ot_trel/main/esp_ot_trel.c b/examples/openthread/ot_trel/main/esp_ot_trel.c index 3feddb069a..5ffd6dc610 100644 --- a/examples/openthread/ot_trel/main/esp_ot_trel.c +++ b/examples/openthread/ot_trel/main/esp_ot_trel.c @@ -83,6 +83,9 @@ void app_main(void) #if CONFIG_OPENTHREAD_CLI_ESP_EXTENSION esp_cli_custom_command_init(); #endif +#if CONFIG_OPENTHREAD_STATE_INDICATOR_ENABLE + ESP_ERROR_CHECK(esp_openthread_state_indicator_init(esp_openthread_get_instance())); +#endif #if CONFIG_OPENTHREAD_NETWORK_AUTO_START ot_network_auto_start(); #endif From 76ab9e82c236e87c45d385f00686c15717bde667 Mon Sep 17 00:00:00 2001 From: muhaidong Date: Mon, 3 Nov 2025 14:58:34 +0800 Subject: [PATCH 201/226] docs(wifi): update wifi fragment doc --- components/soc/esp32c2/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32c2/include/soc/soc_caps.h | 1 + components/soc/esp32c3/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32c3/include/soc/soc_caps.h | 1 + components/soc/esp32c5/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32c5/include/soc/soc_caps.h | 1 + components/soc/esp32c6/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32c6/include/soc/soc_caps.h | 1 + components/soc/esp32c61/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32c61/include/soc/soc_caps.h | 1 + components/soc/esp32s3/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32s3/include/soc/soc_caps.h | 1 + docs/en/api-guides/wifi.rst | 4 ++-- docs/zh_CN/api-guides/wifi.rst | 4 ++-- 14 files changed, 34 insertions(+), 4 deletions(-) diff --git a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in index c024a9ab02..00e4c382b5 100644 --- a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in @@ -779,6 +779,10 @@ config SOC_WIFI_FTM_SUPPORT bool default y +config SOC_WIFI_TXOP_SUPPORT + bool + default y + config SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW bool default y diff --git a/components/soc/esp32c2/include/soc/soc_caps.h b/components/soc/esp32c2/include/soc/soc_caps.h index 6bd72b906f..f0e7f245c7 100644 --- a/components/soc/esp32c2/include/soc/soc_caps.h +++ b/components/soc/esp32c2/include/soc/soc_caps.h @@ -345,6 +345,7 @@ /*------------------------------------ WI-FI CAPS ------------------------------------*/ #define SOC_WIFI_HW_TSF (1) /*!< Support hardware TSF */ #define SOC_WIFI_FTM_SUPPORT (1) /*!< Support FTM */ +#define SOC_WIFI_TXOP_SUPPORT (1) /*!< Support TXOP */ #define SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW (1) /*!< Support delta early time for rf phy on/off */ #define SOC_WIFI_PHY_NEEDS_USB_WORKAROUND (1) /*!< SoC has WiFi and USB PHYs interference, needs a workaround */ diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index 17e001cf11..076c7e1069 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -1139,6 +1139,10 @@ config SOC_WIFI_WAPI_SUPPORT bool default y +config SOC_WIFI_TXOP_SUPPORT + bool + default y + config SOC_WIFI_CSI_SUPPORT bool default y diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 7f7de46c61..c624192fdb 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -473,6 +473,7 @@ #define SOC_WIFI_FTM_SUPPORT (1) /*!< Support FTM */ #define SOC_WIFI_GCMP_SUPPORT (1) /*!< Support GCMP(GCMP128 and GCMP256) */ #define SOC_WIFI_WAPI_SUPPORT (1) /*!< Support WAPI */ +#define SOC_WIFI_TXOP_SUPPORT (1) /*!< Support TXOP */ #define SOC_WIFI_CSI_SUPPORT (1) /*!< Support CSI */ #define SOC_WIFI_MESH_SUPPORT (1) /*!< Support WIFI MESH */ #define SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW (1) /*!< Support delta early time for rf phy on/off */ diff --git a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in index ccf75e989d..d09ba48f7f 100644 --- a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in @@ -1827,6 +1827,10 @@ config SOC_WIFI_WAPI_SUPPORT bool default y +config SOC_WIFI_TXOP_SUPPORT + bool + default y + config SOC_WIFI_CSI_SUPPORT bool default y diff --git a/components/soc/esp32c5/include/soc/soc_caps.h b/components/soc/esp32c5/include/soc/soc_caps.h index bb696ebb35..1d639e6a79 100644 --- a/components/soc/esp32c5/include/soc/soc_caps.h +++ b/components/soc/esp32c5/include/soc/soc_caps.h @@ -701,6 +701,7 @@ #define SOC_WIFI_FTM_SUPPORT (1) /*!< Support FTM */ #define SOC_WIFI_GCMP_SUPPORT (1) /*!< Support GCMP(GCMP128 and GCMP256) */ #define SOC_WIFI_WAPI_SUPPORT (1) /*!< Support WAPI */ +#define SOC_WIFI_TXOP_SUPPORT (1) /*!< Support TXOP */ #define SOC_WIFI_CSI_SUPPORT (1) /*!< Support CSI */ #define SOC_WIFI_MESH_SUPPORT (1) /*!< Support WIFI MESH */ #define SOC_WIFI_HE_SUPPORT (1) /*!< Support Wi-Fi 6 */ diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 6e0a205e53..36c2bf2e26 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -1591,6 +1591,10 @@ config SOC_WIFI_WAPI_SUPPORT bool default y +config SOC_WIFI_TXOP_SUPPORT + bool + default y + config SOC_WIFI_CSI_SUPPORT bool default y diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 1a3b8cb9cd..f0179b93a1 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -619,6 +619,7 @@ #define SOC_WIFI_FTM_SUPPORT (1) /*!< Support FTM */ #define SOC_WIFI_GCMP_SUPPORT (1) /*!< Support GCMP(GCMP128 and GCMP256) */ #define SOC_WIFI_WAPI_SUPPORT (1) /*!< Support WAPI */ +#define SOC_WIFI_TXOP_SUPPORT (1) /*!< Support TXOP */ #define SOC_WIFI_CSI_SUPPORT (1) /*!< Support CSI */ #define SOC_WIFI_MESH_SUPPORT (1) /*!< Support WIFI MESH */ #define SOC_WIFI_HE_SUPPORT (1) /*!< Support Wi-Fi 6 */ diff --git a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in index a1a51f3dd2..542b058f90 100644 --- a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in @@ -1299,6 +1299,10 @@ config SOC_WIFI_WAPI_SUPPORT bool default y +config SOC_WIFI_TXOP_SUPPORT + bool + default y + config SOC_WIFI_CSI_SUPPORT bool default y diff --git a/components/soc/esp32c61/include/soc/soc_caps.h b/components/soc/esp32c61/include/soc/soc_caps.h index 3ab56bcfc1..145d5d1168 100644 --- a/components/soc/esp32c61/include/soc/soc_caps.h +++ b/components/soc/esp32c61/include/soc/soc_caps.h @@ -518,6 +518,7 @@ #define SOC_WIFI_FTM_SUPPORT (1) /*!< Support FTM */ #define SOC_WIFI_GCMP_SUPPORT (1) /*!< Support GCMP(GCMP128 and GCMP256) */ #define SOC_WIFI_WAPI_SUPPORT (1) /*!< Support WAPI */ +#define SOC_WIFI_TXOP_SUPPORT (1) /*!< Support TXOP */ #define SOC_WIFI_CSI_SUPPORT (1) /*!< Support CSI */ #define SOC_WIFI_MESH_SUPPORT (1) /*!< Support WIFI MESH */ #define SOC_WIFI_HE_SUPPORT (1) /*!< Support Wi-Fi 6 */ diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index 7c92228f8b..a2cf8b0233 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -1491,6 +1491,10 @@ config SOC_WIFI_WAPI_SUPPORT bool default y +config SOC_WIFI_TXOP_SUPPORT + bool + default y + config SOC_WIFI_CSI_SUPPORT bool default y diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 689435d105..8a393413b2 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -585,6 +585,7 @@ #define SOC_WIFI_FTM_SUPPORT (1) /*!< Support FTM */ #define SOC_WIFI_GCMP_SUPPORT (1) /*!< Support GCMP(GCMP128 and GCMP256) */ #define SOC_WIFI_WAPI_SUPPORT (1) /*!< Support WAPI */ +#define SOC_WIFI_TXOP_SUPPORT (1) /*!< Support TXOP */ #define SOC_WIFI_CSI_SUPPORT (1) /*!< Support CSI */ #define SOC_WIFI_MESH_SUPPORT (1) /*!< Support WIFI MESH */ #define SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW (1) /*!< Support delta early time for rf phy on/off */ diff --git a/docs/en/api-guides/wifi.rst b/docs/en/api-guides/wifi.rst index d3e759e3e9..b76ac861ab 100644 --- a/docs/en/api-guides/wifi.rst +++ b/docs/en/api-guides/wifi.rst @@ -2925,11 +2925,11 @@ Wi-Fi AMSDU Wi-Fi Fragment ------------------------- -.. only:: esp32 or esp32s2 +.. only:: not SOC_WIFI_TXOP_SUPPORT supports Wi-Fi receiving fragment, but does not support Wi-Fi transmitting fragment. -.. only:: esp32c3 or esp32s3 or esp32c5 or esp32c6 +.. only:: SOC_WIFI_TXOP_SUPPORT {IDF_TARGET_NAME} supports Wi-Fi receiving and transmitting fragment. diff --git a/docs/zh_CN/api-guides/wifi.rst b/docs/zh_CN/api-guides/wifi.rst index fdf1a9e635..92e6229e7d 100644 --- a/docs/zh_CN/api-guides/wifi.rst +++ b/docs/zh_CN/api-guides/wifi.rst @@ -2901,11 +2901,11 @@ Wi-Fi AMSDU Wi-Fi 分片 ------------------------- -.. only:: esp32 or esp32s2 +.. only:: not SOC_WIFI_TXOP_SUPPORT 支持 Wi-Fi 接收分片,但不支持 Wi-Fi 发送分片。 -.. only:: esp32c3 or esp32s3 or esp32c6 or esp32c5 +.. only:: SOC_WIFI_TXOP_SUPPORT {IDF_TARGET_NAME} 支持 Wi-Fi 接收和发送分片。 From 5059f574d0d15fc42ca128e4b07cdd7343876d2a Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Mon, 3 Nov 2025 12:20:01 +0800 Subject: [PATCH 202/226] fix(esp_wifi): Validate dpp auth instance before using it --- components/wpa_supplicant/esp_supplicant/src/esp_dpp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index 818412ba38..2d221722eb 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -264,7 +264,7 @@ static void gas_query_timeout(void *eloop_data, void *user_ctx) { struct dpp_authentication *auth = user_ctx; - if (!auth || !auth->auth_success) { + if (!s_dpp_ctx.dpp_auth || !s_dpp_ctx.dpp_auth.auth_success || (s_dpp_ctx.dpp_auth != auth)) { wpa_printf(MSG_INFO, "DPP-GAS: Auth %p state not correct", auth); return; } From e64e900be8afcb5ae790665a97c5faa55d7fd038 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Fri, 5 Dec 2025 16:10:58 +0530 Subject: [PATCH 203/226] apply suggestion --- components/wpa_supplicant/esp_supplicant/src/esp_dpp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index 2d221722eb..ad59b8a913 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -264,7 +264,7 @@ static void gas_query_timeout(void *eloop_data, void *user_ctx) { struct dpp_authentication *auth = user_ctx; - if (!s_dpp_ctx.dpp_auth || !s_dpp_ctx.dpp_auth.auth_success || (s_dpp_ctx.dpp_auth != auth)) { + if (!s_dpp_ctx.dpp_auth || !s_dpp_ctx.dpp_auth->auth_success || (s_dpp_ctx.dpp_auth != auth)) { wpa_printf(MSG_INFO, "DPP-GAS: Auth %p state not correct", auth); return; } From bdfb0f9e1d7d6b12ba95865f5720264d33f02851 Mon Sep 17 00:00:00 2001 From: Jin Cheng Date: Fri, 9 Jan 2026 14:57:36 +0800 Subject: [PATCH 204/226] fix(bt/bluedroid): add status management for audio sink service channel --- .../audio_sink_service.h | 17 +++++++++- .../audio_sink_service_dac.c | 33 +++++++++++-------- .../audio_sink_service_i2s.c | 33 +++++++++++-------- 3 files changed, 56 insertions(+), 27 deletions(-) diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service.h b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service.h index 6fbe7382e2..0aaa7aa991 100644 --- a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service.h +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -11,6 +11,21 @@ #include #include "esp_a2dp_api.h" +#define RINGBUF_HIGHEST_WATER_LEVEL (32 * 1024) +#define RINGBUF_PREFETCH_WATER_LEVEL (20 * 1024) + +typedef enum { + RINGBUFFER_MODE_PROCESSING, /* ringbuffer is buffering incoming audio data */ + RINGBUFFER_MODE_PREFETCHING, /* ringbuffer is buffering incoming audio data */ + RINGBUFFER_MODE_DROPPING /* ringbuffer is not buffering (dropping) incoming audio data */ +} audio_sink_ringbuffer_mode_t; + +typedef enum { + CHANNEL_STATUS_IDLE, + CHANNEL_STATUS_OPENED, + CHANNEL_STATUS_ENABLED +} audio_sink_chan_st_t; + /** * @brief open audio sink service */ diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_dac.c b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_dac.c index a87873fe98..0e5e377c4c 100644 --- a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_dac.c +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_dac.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -21,17 +21,9 @@ /* log tag */ #define AUDIO_SNK_SRV_DAC_TAG "SNK_SRV_DAC" -#define RINGBUF_HIGHEST_WATER_LEVEL (32 * 1024) -#define RINGBUF_PREFETCH_WATER_LEVEL (20 * 1024) - -enum { - RINGBUFFER_MODE_PROCESSING, /* ringbuffer is buffering incoming audio data, I2S is working */ - RINGBUFFER_MODE_PREFETCHING, /* ringbuffer is buffering incoming audio data, I2S is waiting */ - RINGBUFFER_MODE_DROPPING /* ringbuffer is not buffering (dropping) incoming audio data, I2S is working */ -}; - typedef struct { dac_continuous_handle_t tx_chan; /* handle of dac continuous channel */ + audio_sink_chan_st_t chan_st; /* dac channel status */ TaskHandle_t write_task_handle; /* handle of writing task */ RingbufHandle_t ringbuf; /* handle of ringbuffer */ SemaphoreHandle_t write_semaphore; /* handle of write semaphore */ @@ -100,11 +92,17 @@ void audio_sink_srv_open(void) }; /* Allocate continuous channels */ ESP_ERROR_CHECK(dac_continuous_new_channels(&cont_cfg, &s_dac_cb.tx_chan)); + s_dac_cb.chan_st = CHANNEL_STATUS_OPENED; } void audio_sink_srv_close(void) { - ESP_ERROR_CHECK(dac_continuous_del_channels(s_dac_cb.tx_chan)); + audio_sink_srv_stop(); + + if (s_dac_cb.chan_st == CHANNEL_STATUS_OPENED) { + ESP_ERROR_CHECK(dac_continuous_del_channels(s_dac_cb.tx_chan)); + s_dac_cb.chan_st = CHANNEL_STATUS_IDLE; + } if (s_dac_cb.write_task_handle) { vTaskDelete(s_dac_cb.write_task_handle); s_dac_cb.write_task_handle = NULL; @@ -122,7 +120,13 @@ void audio_sink_srv_close(void) void audio_sink_srv_start(void) { - dac_continuous_enable(s_dac_cb.tx_chan); + if (s_dac_cb.chan_st != CHANNEL_STATUS_OPENED) { + ESP_LOGE(AUDIO_SNK_SRV_DAC_TAG, "%s, TX channel wrong state: %d", __func__, s_dac_cb.chan_st); + return; + } + ESP_ERROR_CHECK(dac_continuous_enable(s_dac_cb.tx_chan)); + s_dac_cb.chan_st = CHANNEL_STATUS_ENABLED; + ESP_LOGI(AUDIO_SNK_SRV_DAC_TAG, "ringbuffer data empty! mode changed: RINGBUFFER_MODE_PREFETCHING"); s_dac_cb.ringbuffer_mode = RINGBUFFER_MODE_PREFETCHING; if ((s_dac_cb.write_semaphore = xSemaphoreCreateBinary()) == NULL) { @@ -138,7 +142,10 @@ void audio_sink_srv_start(void) void audio_sink_srv_stop(void) { - ESP_ERROR_CHECK(dac_continuous_disable(s_dac_cb.tx_chan)); + if (s_dac_cb.chan_st == CHANNEL_STATUS_ENABLED) { + ESP_ERROR_CHECK(dac_continuous_disable(s_dac_cb.tx_chan)); + s_dac_cb.chan_st = CHANNEL_STATUS_OPENED; + } } void audio_sink_srv_codec_info_update(esp_a2d_mcc_t *mcc) diff --git a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_i2s.c b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_i2s.c index bed32c1546..dc53afe2b1 100644 --- a/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_i2s.c +++ b/examples/bluetooth/bluedroid/classic_bt/common/a2dp_utils/a2dp_sink_int_codec_utils/audio_sink_service_i2s.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -21,17 +21,9 @@ /* log tag */ #define AUDIO_SNK_SRV_I2S_TAG "SNK_SRV_I2S" -#define RINGBUF_HIGHEST_WATER_LEVEL (32 * 1024) -#define RINGBUF_PREFETCH_WATER_LEVEL (20 * 1024) - -enum { - RINGBUFFER_MODE_PROCESSING, /* ringbuffer is buffering incoming audio data, I2S is working */ - RINGBUFFER_MODE_PREFETCHING, /* ringbuffer is buffering incoming audio data, I2S is waiting */ - RINGBUFFER_MODE_DROPPING /* ringbuffer is not buffering (dropping) incoming audio data, I2S is working */ -}; - typedef struct { i2s_chan_handle_t tx_chan; /* handle of i2s channel */ + audio_sink_chan_st_t chan_st; /* i2s channel status */ TaskHandle_t write_task_handle; /* handle of writing task */ RingbufHandle_t ringbuf; /* handle of ringbuffer */ SemaphoreHandle_t write_semaphore;/* handle of write semaphore */ @@ -115,11 +107,17 @@ void audio_sink_srv_open(void) /* initialize I2S channel */ ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &s_i2s_cb.tx_chan, NULL)); ESP_ERROR_CHECK(i2s_channel_init_std_mode(s_i2s_cb.tx_chan, &std_cfg)); + s_i2s_cb.chan_st = CHANNEL_STATUS_OPENED; } void audio_sink_srv_close(void) { - ESP_ERROR_CHECK(i2s_del_channel(s_i2s_cb.tx_chan)); + audio_sink_srv_stop(); + + if (s_i2s_cb.chan_st == CHANNEL_STATUS_OPENED) { + ESP_ERROR_CHECK(i2s_del_channel(s_i2s_cb.tx_chan)); + s_i2s_cb.chan_st = CHANNEL_STATUS_IDLE; + } if (s_i2s_cb.write_task_handle) { vTaskDelete(s_i2s_cb.write_task_handle); s_i2s_cb.write_task_handle = NULL; @@ -137,7 +135,13 @@ void audio_sink_srv_close(void) void audio_sink_srv_start(void) { - i2s_channel_enable(s_i2s_cb.tx_chan); + if (s_i2s_cb.chan_st != CHANNEL_STATUS_OPENED) { + ESP_LOGE(AUDIO_SNK_SRV_I2S_TAG, "%s, TX channel wrong state: %d", __func__, s_i2s_cb.chan_st); + return; + } + ESP_ERROR_CHECK(i2s_channel_enable(s_i2s_cb.tx_chan)); + s_i2s_cb.chan_st = CHANNEL_STATUS_ENABLED; + ESP_LOGI(AUDIO_SNK_SRV_I2S_TAG, "ringbuffer data empty! mode changed: RINGBUFFER_MODE_PREFETCHING"); s_i2s_cb.ringbuffer_mode = RINGBUFFER_MODE_PREFETCHING; if ((s_i2s_cb.write_semaphore = xSemaphoreCreateBinary()) == NULL) { @@ -153,7 +157,10 @@ void audio_sink_srv_start(void) void audio_sink_srv_stop(void) { - ESP_ERROR_CHECK(i2s_channel_disable(s_i2s_cb.tx_chan)); + if (s_i2s_cb.chan_st == CHANNEL_STATUS_ENABLED) { + ESP_ERROR_CHECK(i2s_channel_disable(s_i2s_cb.tx_chan)); + s_i2s_cb.chan_st = CHANNEL_STATUS_OPENED; + } } void audio_sink_srv_codec_info_update(esp_a2d_mcc_t *mcc) From c43ad3a99c0aca332c37a24b99fa203778d59995 Mon Sep 17 00:00:00 2001 From: gongyantao Date: Wed, 24 Dec 2025 12:13:43 +0800 Subject: [PATCH 205/226] change(bt): Mark RSSI threshold-related macros as deprecated --- components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h index 7d535c80d1..886be4e89f 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h @@ -16,7 +16,9 @@ extern "C" { #endif /// RSSI threshold +/** @deprecated This macro will be deprecated in future versions */ #define ESP_BT_GAP_RSSI_HIGH_THRLD -20 /*!< High RSSI threshold */ +/** @deprecated This macro will be deprecated in future versions */ #define ESP_BT_GAP_RSSI_LOW_THRLD -45 /*!< Low RSSI threshold */ /// Class of device @@ -361,7 +363,7 @@ typedef union { struct read_rssi_delta_param { esp_bd_addr_t bda; /*!< remote bluetooth device address*/ esp_bt_status_t stat; /*!< read rssi status */ - int8_t rssi_delta; /*!< rssi delta value range -128 ~127, The value zero indicates that the RSSI is inside the Golden Receive Power Range, the Golden Receive Power Range is from ESP_BT_GAP_RSSI_LOW_THRLD to ESP_BT_GAP_RSSI_HIGH_THRLD */ + int8_t rssi_delta; /*!< rssi delta value range -128 ~127, The value zero indicates that the RSSI is inside the Golden Receive Power Range */ } read_rssi_delta; /*!< read rssi parameter struct */ /** From 28056346609c5e77950ba329f5241257c62b9a65 Mon Sep 17 00:00:00 2001 From: kinho <109323159+KinhoLeung@users.noreply.github.com> Date: Mon, 24 Nov 2025 23:19:49 +0800 Subject: [PATCH 206/226] fix:Report the full buffer length to the UAC stack by setting bytes_read in usb_uac_device_input_cb(), so the host correctly detects received audio data instead of seeing zero bytes. --- .../i2s/i2s_advance/i2s_usb/main/i2s_usb_example_main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/peripherals/i2s/i2s_advance/i2s_usb/main/i2s_usb_example_main.c b/examples/peripherals/i2s/i2s_advance/i2s_usb/main/i2s_usb_example_main.c index bf66f0d52b..2f1e8c2909 100644 --- a/examples/peripherals/i2s/i2s_advance/i2s_usb/main/i2s_usb_example_main.c +++ b/examples/peripherals/i2s/i2s_advance/i2s_usb/main/i2s_usb_example_main.c @@ -236,6 +236,11 @@ static esp_err_t usb_uac_device_input_cb(uint8_t *buf, size_t len, size_t *bytes return ESP_FAIL; } + /* Report full-length data for UAC */ + if (bytes_read) { + *bytes_read = len; + } + return ESP_OK; } From a9b2c87d492537bc93cc7a15256dcfad7a6bcdf7 Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Mon, 29 Dec 2025 16:29:27 +0800 Subject: [PATCH 207/226] feat(i2s): support to get more channel info --- components/esp_driver_i2s/i2s_common.c | 6 +++ components/esp_driver_i2s/i2s_pdm.c | 2 + components/esp_driver_i2s/i2s_private.h | 3 +- components/esp_driver_i2s/i2s_std.c | 28 ++++++++----- components/esp_driver_i2s/i2s_tdm.c | 42 +++++++++++++------ .../include/driver/i2s_common.h | 11 +++++ .../esp_driver_i2s/include/driver/i2s_types.h | 2 +- 7 files changed, 69 insertions(+), 25 deletions(-) diff --git a/components/esp_driver_i2s/i2s_common.c b/components/esp_driver_i2s/i2s_common.c index b1da9d1cae..73d1e6b58e 100644 --- a/components/esp_driver_i2s/i2s_common.c +++ b/components/esp_driver_i2s/i2s_common.c @@ -1202,6 +1202,12 @@ found: chan_info->dir = handle->dir; chan_info->role = handle->role; chan_info->mode = handle->mode; + chan_info->is_enabled = handle->state == I2S_CHAN_STATE_RUNNING; + chan_info->clk_src = handle->clk_src; + chan_info->sclk_hz = handle->sclk_hz; + chan_info->mclk_hz = handle->curr_mclk_hz; + chan_info->bclk_hz = handle->bclk_hz; + chan_info->mode_cfg = handle->mode_info; chan_info->total_dma_buf_size = handle->state >= I2S_CHAN_STATE_READY ? handle->dma.desc_num * handle->dma.buf_size : 0; if (handle->controller->full_duplex) { if (handle->dir == I2S_DIR_TX) { diff --git a/components/esp_driver_i2s/i2s_pdm.c b/components/esp_driver_i2s/i2s_pdm.c index 280518418c..526ec4f7b3 100644 --- a/components/esp_driver_i2s/i2s_pdm.c +++ b/components/esp_driver_i2s/i2s_pdm.c @@ -104,6 +104,7 @@ static esp_err_t i2s_pdm_tx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_tx handle->sclk_hz = clk_info.sclk; handle->origin_mclk_hz = ((uint64_t)clk_info.sclk * ret_mclk_div.denominator) / tmp_div; handle->curr_mclk_hz = handle->origin_mclk_hz; + handle->bclk_hz = clk_info.bclk; ESP_LOGD(TAG, "Clock division info: [sclk] %"PRIu32" Hz [mdiv] %"PRIu32" %"PRIu32"/%"PRIu32" [mclk] %"PRIu32" Hz [bdiv] %d [bclk] %"PRIu32" Hz", clk_info.sclk, ret_mclk_div.integer, ret_mclk_div.numerator, ret_mclk_div.denominator, handle->origin_mclk_hz, clk_info.bclk_div, clk_info.bclk); @@ -435,6 +436,7 @@ static esp_err_t i2s_pdm_rx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_rx handle->sclk_hz = clk_info.sclk; handle->origin_mclk_hz = ((uint64_t)clk_info.sclk * ret_mclk_div.denominator) / tmp_div; handle->curr_mclk_hz = handle->origin_mclk_hz; + handle->bclk_hz = clk_info.bclk; ESP_LOGD(TAG, "Clock division info: [sclk] %"PRIu32" Hz [mdiv] %"PRIu32" %"PRIu32"/%"PRIu32" [mclk] %"PRIu32" Hz [bdiv] %d [bclk] %"PRIu32" Hz", clk_info.sclk, ret_mclk_div.integer, ret_mclk_div.numerator, ret_mclk_div.denominator, handle->origin_mclk_hz, clk_info.bclk_div, clk_info.bclk); diff --git a/components/esp_driver_i2s/i2s_private.h b/components/esp_driver_i2s/i2s_private.h index fdd697fcf8..3ccd93f576 100644 --- a/components/esp_driver_i2s/i2s_private.h +++ b/components/esp_driver_i2s/i2s_private.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -176,6 +176,7 @@ struct i2s_channel_obj_t { uint32_t sclk_hz; /*!< Source clock frequency */ uint32_t origin_mclk_hz; /*!< Original mclk frequency */ uint32_t curr_mclk_hz; /*!< Current mclk frequency */ + uint32_t bclk_hz; /*!< BCLK frequency */ /* Locks and queues */ SemaphoreHandle_t mutex; /*!< Mutex semaphore for the channel operations */ SemaphoreHandle_t binary; /*!< Binary semaphore for writing / reading / enabling / disabling */ diff --git a/components/esp_driver_i2s/i2s_std.c b/components/esp_driver_i2s/i2s_std.c index 9f8ce6abce..32f4e4125c 100644 --- a/components/esp_driver_i2s/i2s_std.c +++ b/components/esp_driver_i2s/i2s_std.c @@ -105,6 +105,7 @@ static esp_err_t i2s_std_set_clock(i2s_chan_handle_t handle, const i2s_std_clk_c handle->sclk_hz = clk_info.sclk; handle->origin_mclk_hz = ((uint64_t)clk_info.sclk * ret_mclk_div.denominator) / tmp_div; handle->curr_mclk_hz = handle->origin_mclk_hz; + handle->bclk_hz = clk_info.bclk; ESP_LOGD(TAG, "Clock division info: [sclk] %"PRIu32" Hz [mdiv] %"PRIu32" %"PRIu32"/%"PRIu32" [mclk] %"PRIu32" Hz [bdiv] %d [bclk] %"PRIu32" Hz", clk_info.sclk, ret_mclk_div.integer, ret_mclk_div.numerator, ret_mclk_div.denominator, handle->origin_mclk_hz, clk_info.bclk_div, clk_info.bclk); @@ -112,13 +113,24 @@ static esp_err_t i2s_std_set_clock(i2s_chan_handle_t handle, const i2s_std_clk_c return ret; } +static i2s_std_slot_config_t s_i2s_std_normalize_slot_config(const i2s_std_slot_config_t *slot_cfg) +{ + i2s_std_slot_config_t normalized_slot_cfg = *slot_cfg; + /* 1. Normalize the slot bit width */ + normalized_slot_cfg.slot_bit_width = (int)normalized_slot_cfg.slot_bit_width < (int)normalized_slot_cfg.data_bit_width ? + normalized_slot_cfg.data_bit_width : normalized_slot_cfg.slot_bit_width; + + return normalized_slot_cfg; +} + static esp_err_t i2s_std_set_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg) { + i2s_std_slot_config_t norm_slot_cfg = s_i2s_std_normalize_slot_config(slot_cfg); /* Update the total slot num and active slot num */ handle->total_slot = 2; - handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; + handle->active_slot = norm_slot_cfg.slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; - uint32_t buf_size = i2s_get_buf_size(handle, slot_cfg->data_bit_width, handle->dma.frame_num); + uint32_t buf_size = i2s_get_buf_size(handle, norm_slot_cfg.data_bit_width, handle->dma.frame_num); ESP_RETURN_ON_FALSE(buf_size != 0, ESP_ERR_INVALID_ARG, TAG, "invalid data_bit_width"); /* The DMA buffer need to re-allocate if the buffer size changed */ if (handle->dma.buf_size != buf_size) { @@ -137,18 +149,15 @@ static esp_err_t i2s_std_set_slot(i2s_chan_handle_t handle, const i2s_std_slot_c portENTER_CRITICAL(&g_i2s.spinlock); /* Configure the hardware to apply STD format */ if (handle->dir == I2S_DIR_TX) { - i2s_hal_std_set_tx_slot(&(handle->controller->hal), is_slave, (i2s_hal_slot_config_t *)slot_cfg); + i2s_hal_std_set_tx_slot(&(handle->controller->hal), is_slave, (i2s_hal_slot_config_t *)&norm_slot_cfg); } else { - i2s_hal_std_set_rx_slot(&(handle->controller->hal), is_slave, (i2s_hal_slot_config_t *)slot_cfg); + i2s_hal_std_set_rx_slot(&(handle->controller->hal), is_slave, (i2s_hal_slot_config_t *)&norm_slot_cfg); } portEXIT_CRITICAL(&g_i2s.spinlock); /* Update the mode info: slot configuration */ i2s_std_config_t *std_cfg = (i2s_std_config_t *)(handle->mode_info); memcpy(&(std_cfg->slot_cfg), slot_cfg, sizeof(i2s_std_slot_config_t)); - /* Update the slot bit width to the actual slot bit width */ - std_cfg->slot_cfg.slot_bit_width = (int)std_cfg->slot_cfg.slot_bit_width < (int)std_cfg->slot_cfg.data_bit_width ? - std_cfg->slot_cfg.data_bit_width : std_cfg->slot_cfg.slot_bit_width; return ESP_OK; } @@ -244,9 +253,8 @@ static esp_err_t s_i2s_channel_try_to_constitude_std_duplex(i2s_chan_handle_t ha /* Judge if the two channels can constitute full-duplex */ if (!handle->controller->full_duplex) { i2s_std_config_t curr_cfg = *std_cfg; - /* Override the slot bit width to the actual slot bit width */ - curr_cfg.slot_cfg.slot_bit_width = (int)curr_cfg.slot_cfg.slot_bit_width < (int)curr_cfg.slot_cfg.data_bit_width ? - curr_cfg.slot_cfg.data_bit_width : curr_cfg.slot_cfg.slot_bit_width; + i2s_std_slot_config_t norm_slot_cfg = s_i2s_std_normalize_slot_config(&(std_cfg->slot_cfg)); + memcpy(&curr_cfg.slot_cfg, &norm_slot_cfg, sizeof(i2s_std_slot_config_t)); /* Compare the hardware configurations of the two channels, constitute the full-duplex if they are the same */ if (memcmp(another_handle->mode_info, &curr_cfg, sizeof(i2s_std_config_t)) == 0) { handle->controller->full_duplex = true; diff --git a/components/esp_driver_i2s/i2s_tdm.c b/components/esp_driver_i2s/i2s_tdm.c index b6ce716a2e..1aa4cf9d7f 100644 --- a/components/esp_driver_i2s/i2s_tdm.c +++ b/components/esp_driver_i2s/i2s_tdm.c @@ -102,6 +102,7 @@ static esp_err_t i2s_tdm_set_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_c handle->sclk_hz = clk_info.sclk; handle->origin_mclk_hz = ((uint64_t)clk_info.sclk * ret_mclk_div.denominator) / tmp_div; handle->curr_mclk_hz = handle->origin_mclk_hz; + handle->bclk_hz = clk_info.bclk; ESP_LOGD(TAG, "Clock division info: [sclk] %"PRIu32" Hz [mdiv] %"PRIu32" %"PRIu32"/%"PRIu32" [mclk] %"PRIu32" Hz [bdiv] %d [bclk] %"PRIu32" Hz", clk_info.sclk, ret_mclk_div.integer, ret_mclk_div.numerator, ret_mclk_div.denominator, handle->origin_mclk_hz, clk_info.bclk_div, clk_info.bclk); @@ -109,20 +110,39 @@ static esp_err_t i2s_tdm_set_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_c return ret; } +static i2s_tdm_slot_config_t s_i2s_tdm_normalize_slot_config(const i2s_tdm_slot_config_t *slot_cfg) +{ + i2s_tdm_slot_config_t normalized_slot_cfg = *slot_cfg; + uint32_t max_slot_num = 32 - __builtin_clz(normalized_slot_cfg.slot_mask); + /* 1. Normalize the ws width */ + normalized_slot_cfg.ws_width = normalized_slot_cfg.ws_width == I2S_TDM_AUTO_WS_WIDTH ? + normalized_slot_cfg.total_slot * normalized_slot_cfg.slot_bit_width / 2 : normalized_slot_cfg.ws_width; + + /* 2. Normalize the total slot number */ + normalized_slot_cfg.total_slot = normalized_slot_cfg.total_slot < max_slot_num ? max_slot_num : normalized_slot_cfg.total_slot; + // At least two slots in a frame if not using PCM short format + normalized_slot_cfg.total_slot = ((normalized_slot_cfg.total_slot < 2) && (normalized_slot_cfg.ws_width != 1)) ? 2 : normalized_slot_cfg.total_slot; + + /* 3. Normalize the slot bit width */ + normalized_slot_cfg.slot_bit_width = normalized_slot_cfg.slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO ? + normalized_slot_cfg.data_bit_width : normalized_slot_cfg.slot_bit_width; + return normalized_slot_cfg; +} + static esp_err_t i2s_tdm_set_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_config_t *slot_cfg) { ESP_RETURN_ON_FALSE(slot_cfg->slot_mask, ESP_ERR_INVALID_ARG, TAG, "At least one channel should be enabled"); + + i2s_tdm_slot_config_t norm_slot_cfg = s_i2s_tdm_normalize_slot_config(slot_cfg); /* Update the total slot num and active slot num */ - handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : __builtin_popcount(slot_cfg->slot_mask); - uint32_t max_slot_num = 32 - __builtin_clz(slot_cfg->slot_mask); - handle->total_slot = slot_cfg->total_slot < max_slot_num ? max_slot_num : slot_cfg->total_slot; + handle->active_slot = norm_slot_cfg.slot_mode == I2S_SLOT_MODE_MONO ? 1 : __builtin_popcount(norm_slot_cfg.slot_mask); + handle->total_slot = norm_slot_cfg.total_slot; // At least two slots in a frame if not using PCM short format - handle->total_slot = ((handle->total_slot < 2) && (slot_cfg->ws_width != 1)) ? 2 : handle->total_slot; - uint32_t slot_bits = slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; + uint32_t slot_bits = norm_slot_cfg.slot_bit_width; ESP_RETURN_ON_FALSE(handle->total_slot * slot_bits <= I2S_LL_SLOT_FRAME_BIT_MAX, ESP_ERR_INVALID_ARG, TAG, "total slots(%"PRIu32") * slot_bit_width(%"PRIu32") exceeds the maximum %d", handle->total_slot, slot_bits, (int)I2S_LL_SLOT_FRAME_BIT_MAX); - uint32_t buf_size = i2s_get_buf_size(handle, slot_cfg->data_bit_width, handle->dma.frame_num); + uint32_t buf_size = i2s_get_buf_size(handle, norm_slot_cfg.data_bit_width, handle->dma.frame_num); ESP_RETURN_ON_FALSE(buf_size != 0, ESP_ERR_INVALID_ARG, TAG, "invalid data_bit_width"); /* The DMA buffer need to re-allocate if the buffer size changed */ if (handle->dma.buf_size != buf_size) { @@ -149,10 +169,7 @@ static esp_err_t i2s_tdm_set_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_c /* Update the mode info: slot configuration */ i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t *)(handle->mode_info); - memcpy(&(tdm_cfg->slot_cfg), slot_cfg, sizeof(i2s_tdm_slot_config_t)); - /* Update the slot bit width to the actual slot bit width */ - tdm_cfg->slot_cfg.slot_bit_width = (int)tdm_cfg->slot_cfg.slot_bit_width < (int)tdm_cfg->slot_cfg.data_bit_width ? - tdm_cfg->slot_cfg.data_bit_width : tdm_cfg->slot_cfg.slot_bit_width; + memcpy(&(tdm_cfg->slot_cfg), &norm_slot_cfg, sizeof(i2s_tdm_slot_config_t)); return ESP_OK; } @@ -248,9 +265,8 @@ static void s_i2s_channel_try_to_constitude_tdm_duplex(i2s_chan_handle_t handle, if (another_handle && another_handle->state >= I2S_CHAN_STATE_READY) { if (!handle->controller->full_duplex) { i2s_tdm_config_t curr_cfg = *tdm_cfg; - /* Override the slot bit width to the actual slot bit width */ - curr_cfg.slot_cfg.slot_bit_width = (int)curr_cfg.slot_cfg.slot_bit_width < (int)curr_cfg.slot_cfg.data_bit_width ? - curr_cfg.slot_cfg.data_bit_width : curr_cfg.slot_cfg.slot_bit_width; + i2s_tdm_slot_config_t norm_slot_cfg = s_i2s_tdm_normalize_slot_config(&(tdm_cfg->slot_cfg)); + memcpy(&curr_cfg.slot_cfg, &norm_slot_cfg, sizeof(i2s_tdm_slot_config_t)); /* Compare the hardware configurations of the two channels, constitute the full-duplex if they are the same */ if (memcmp(another_handle->mode_info, &curr_cfg, sizeof(i2s_tdm_config_t)) == 0) { handle->controller->full_duplex = true; diff --git a/components/esp_driver_i2s/include/driver/i2s_common.h b/components/esp_driver_i2s/include/driver/i2s_common.h index 6cf5381343..672c51e810 100644 --- a/components/esp_driver_i2s/include/driver/i2s_common.h +++ b/components/esp_driver_i2s/include/driver/i2s_common.h @@ -89,11 +89,22 @@ typedef struct { i2s_role_t role; /*!< I2S role, I2S_ROLE_MASTER or I2S_ROLE_SLAVE */ i2s_dir_t dir; /*!< I2S channel direction */ i2s_comm_mode_t mode; /*!< I2S channel communication mode */ + bool is_enabled; /*!< I2S channel is enabled or not */ i2s_chan_handle_t pair_chan; /*!< I2S pair channel handle in duplex mode, always NULL in simplex mode */ uint32_t total_dma_buf_size; /*!< Total size of all the allocated DMA buffers * - 0 if the channel has not been initialized * - non-zero if the channel has been initialized */ + i2s_clock_src_t clk_src; /*!< Clock source of I2S */ + uint32_t sclk_hz; /*!< Source clock frequency */ + uint32_t mclk_hz; /*!< MCLK frequency */ + uint32_t bclk_hz; /*!< BCLK frequency */ + const void *mode_cfg; /*!< Mode configuration, it need to be casted to the corresponding type according to the communication mode + * - I2S_COMM_MODE_STD: i2s_std_config_t* + * - I2S_COMM_MODE_TDM: i2s_tdm_config_t* + * - I2S_COMM_MODE_PDM + I2S_DIR_RX: i2s_pdm_rx_config_t* + * - I2S_COMM_MODE_PDM + I2S_DIR_TX: i2s_pdm_tx_config_t* + */ } i2s_chan_info_t; /************************************************** Basic APIs ********************************************************/ diff --git a/components/esp_driver_i2s/include/driver/i2s_types.h b/components/esp_driver_i2s/include/driver/i2s_types.h index 9b501586b8..46d38ed870 100644 --- a/components/esp_driver_i2s/include/driver/i2s_types.h +++ b/components/esp_driver_i2s/include/driver/i2s_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ From 5ffa9d5dcb06ed891c0035826e9dc257c82e161e Mon Sep 17 00:00:00 2001 From: Chen Yudong Date: Thu, 15 Jan 2026 12:54:34 +0800 Subject: [PATCH 208/226] fix(example): add nvs_flash to mqtt ssl_ds requirement --- examples/protocols/mqtt/ssl_ds/main/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/protocols/mqtt/ssl_ds/main/CMakeLists.txt b/examples/protocols/mqtt/ssl_ds/main/CMakeLists.txt index 055d4c563a..e6d6094e5b 100644 --- a/examples/protocols/mqtt/ssl_ds/main/CMakeLists.txt +++ b/examples/protocols/mqtt/ssl_ds/main/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS "app_main.c" - PRIV_REQUIRES mqtt esp_netif + PRIV_REQUIRES mqtt esp_netif nvs_flash INCLUDE_DIRS ".") From 67a1e80e511605b81429c72b6d00f9d188588f9c Mon Sep 17 00:00:00 2001 From: armando Date: Fri, 9 Jan 2026 10:37:49 +0800 Subject: [PATCH 209/226] fix(mspi): fixed mspi dma burst timing issue --- components/esp_mm/esp_cache_msync.c | 2 +- components/esp_mm/include/esp_cache.h | 2 +- .../include/esp_private/esp_cache_private.h | 2 +- components/esp_psram/CMakeLists.txt | 2 +- .../include/esp_private/esp_psram_mspi.h | 34 +++++++++++++ components/esp_psram/system_layer/esp_psram.c | 20 ++++++-- .../esp_psram/system_layer/esp_psram_mspi.c | 50 +++++++++++++++++++ .../esp_psram/test_apps/psram/pytest_psram.py | 2 +- 8 files changed, 104 insertions(+), 10 deletions(-) create mode 100644 components/esp_psram/include/esp_private/esp_psram_mspi.h create mode 100644 components/esp_psram/system_layer/esp_psram_mspi.c diff --git a/components/esp_mm/esp_cache_msync.c b/components/esp_mm/esp_cache_msync.c index d296da1a9b..c94cb97eec 100644 --- a/components/esp_mm/esp_cache_msync.c +++ b/components/esp_mm/esp_cache_msync.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/esp_mm/include/esp_cache.h b/components/esp_mm/include/esp_cache.h index f8efcb979c..03db92f341 100644 --- a/components/esp_mm/include/esp_cache.h +++ b/components/esp_mm/include/esp_cache.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/esp_mm/include/esp_private/esp_cache_private.h b/components/esp_mm/include/esp_private/esp_cache_private.h index fc09ed44f1..2cd10d069c 100644 --- a/components/esp_mm/include/esp_private/esp_cache_private.h +++ b/components/esp_mm/include/esp_private/esp_cache_private.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/esp_psram/CMakeLists.txt b/components/esp_psram/CMakeLists.txt index 0b7f4c961e..53e5f00d23 100644 --- a/components/esp_psram/CMakeLists.txt +++ b/components/esp_psram/CMakeLists.txt @@ -15,7 +15,7 @@ if(${target} STREQUAL "esp32") list(APPEND priv_requires bootloader_support esp_driver_spi esp_driver_gpio) endif() -set(srcs) +set(srcs "system_layer/esp_psram_mspi.c") if(CONFIG_SPIRAM) list(APPEND srcs "system_layer/esp_psram.c") diff --git a/components/esp_psram/include/esp_private/esp_psram_mspi.h b/components/esp_psram/include/esp_private/esp_psram_mspi.h new file mode 100644 index 0000000000..7610d99c14 --- /dev/null +++ b/components/esp_psram/include/esp_private/esp_psram_mspi.h @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "sdkconfig.h" +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ESP_PSRAM_MSPI_MB_WORKAROUND (CONFIG_IDF_TARGET_ESP32C5 && CONFIG_ESP32C5_REV_MIN_FULL < 102) || (CONFIG_IDF_TARGET_ESP32C61 && CONFIG_ESP32C61_REV_MIN_FULL < 101) + +/** + * @brief Initialize PSRAM MSPI memory barrier + * + * @return ESP_OK on success, otherwise an error code + */ +esp_err_t esp_psram_mspi_mb_init(void); + +/** + * @brief PSRAM MSPI memory barrier + */ +void esp_psram_mspi_mb(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_psram/system_layer/esp_psram.c b/components/esp_psram/system_layer/esp_psram.c index f236e03b96..076c5b9287 100644 --- a/components/esp_psram/system_layer/esp_psram.c +++ b/components/esp_psram/system_layer/esp_psram.c @@ -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 */ @@ -28,6 +28,7 @@ #include "esp_private/esp_psram_extram.h" #include "esp_private/esp_mmu_map_private.h" #include "esp_private/esp_psram_impl.h" +#include "esp_private/esp_psram_mspi.h" #include "esp_private/startup_internal.h" #if SOC_SPIRAM_XIP_SUPPORTED #include "esp_private/mmu_psram_flash.h" @@ -113,6 +114,8 @@ static const DRAM_ATTR char TAG[] = "esp_psram"; ESP_SYSTEM_INIT_FN(add_psram_to_heap, CORE, BIT(0), 103) { + esp_err_t ret = ESP_FAIL; + #if CONFIG_SPIRAM_BOOT_INIT && (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC) #if (CONFIG_IDF_TARGET_ESP32C5 && CONFIG_ESP32C5_REV_MIN_FULL <= 100) || (CONFIG_IDF_TARGET_ESP32C61 && CONFIG_ESP32C61_REV_MIN_FULL <= 100) @@ -120,17 +123,24 @@ ESP_SYSTEM_INIT_FN(add_psram_to_heap, CORE, BIT(0), 103) ESP_EARLY_LOGW(TAG, "Please avoid using PSRAM for security sensitive data e.g., TLS stack allocations (CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC)"); #endif if (esp_psram_is_initialized()) { - esp_err_t r = esp_psram_extram_add_to_heap_allocator(); - if (r != ESP_OK) { + ret = esp_psram_extram_add_to_heap_allocator(); + if (ret != ESP_OK) { ESP_EARLY_LOGE(TAG, "External RAM could not be added to heap!"); - abort(); + return ret; } #if CONFIG_SPIRAM_USE_MALLOC heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL); #endif } #endif - return ESP_OK; + + ret = esp_psram_mspi_mb_init(); + if (ret != ESP_OK) { + ESP_EARLY_LOGE(TAG, "Failed to initialize PSRAM MSPI memory barrier!"); + return ret; + } + + return ret; } #if CONFIG_IDF_TARGET_ESP32 diff --git a/components/esp_psram/system_layer/esp_psram_mspi.c b/components/esp_psram/system_layer/esp_psram_mspi.c new file mode 100644 index 0000000000..cb62d14729 --- /dev/null +++ b/components/esp_psram/system_layer/esp_psram_mspi.c @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD +* +* SPDX-License-Identifier: Apache-2.0 +*/ + +#include +#include +#include +#include +#include "sdkconfig.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_intr_alloc.h" +#include "esp_cache.h" +#include "esp_heap_caps.h" +#include "esp_private/esp_psram_mspi.h" + +__attribute__((unused)) static DRAM_ATTR char TAG[] = "MSPI Timing"; + +#if ESP_PSRAM_MSPI_MB_WORKAROUND +static void *s_psram_mb_dummy_cacheline; //dummy cacheline for cache memory barrier +#endif + +esp_err_t esp_psram_mspi_mb_init(void) +{ +#if ESP_PSRAM_MSPI_MB_WORKAROUND + s_psram_mb_dummy_cacheline = heap_caps_calloc(1, CONFIG_CACHE_L1_CACHE_LINE_SIZE, MALLOC_CAP_SPIRAM | MALLOC_CAP_CACHE_ALIGNED); + if (!s_psram_mb_dummy_cacheline) { + ESP_EARLY_LOGE(TAG, "Failed to allocate dummy cacheline for PSRAM memory barrier!"); + } +#endif + + return ESP_OK; +} + +void IRAM_ATTR esp_psram_mspi_mb(void) +{ +#if ESP_PSRAM_MSPI_MB_WORKAROUND + if (s_psram_mb_dummy_cacheline) { + uint32_t *p = (uint32_t *)s_psram_mb_dummy_cacheline; + *p = (*p + 1) % UINT32_MAX; + __attribute__((unused)) esp_err_t ret = ESP_FAIL; + ret = esp_cache_msync(s_psram_mb_dummy_cacheline, sizeof(uint32_t), ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); //malloc is aligned, no need to writeback all + assert(ret == ESP_OK); + asm volatile("fence"); + } +#endif +} diff --git a/components/esp_psram/test_apps/psram/pytest_psram.py b/components/esp_psram/test_apps/psram/pytest_psram.py index 2cf712373d..124446d4ba 100644 --- a/components/esp_psram/test_apps/psram/pytest_psram.py +++ b/components/esp_psram/test_apps/psram/pytest_psram.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut From f19e08046bf5662080ffa55ec36e0870dc0cc648 Mon Sep 17 00:00:00 2001 From: armando Date: Thu, 8 Jan 2026 12:18:51 +0800 Subject: [PATCH 210/226] fix(uhci): fixed rx buffer potential corruption issue due to cache coherence issue caused by autowriteback --- components/esp_driver_uart/CMakeLists.txt | 2 +- components/esp_driver_uart/src/uhci.c | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/components/esp_driver_uart/CMakeLists.txt b/components/esp_driver_uart/CMakeLists.txt index bfca544594..6f1bc93c21 100644 --- a/components/esp_driver_uart/CMakeLists.txt +++ b/components/esp_driver_uart/CMakeLists.txt @@ -13,7 +13,7 @@ endif() if(${target} STREQUAL "linux") set(priv_requires esp_ringbuf) else() - set(priv_requires esp_pm esp_driver_gpio esp_ringbuf esp_mm) + set(priv_requires esp_pm esp_driver_gpio esp_ringbuf esp_mm esp_psram) endif() idf_component_register( diff --git a/components/esp_driver_uart/src/uhci.c b/components/esp_driver_uart/src/uhci.c index e390d047c9..be937d796d 100644 --- a/components/esp_driver_uart/src/uhci.c +++ b/components/esp_driver_uart/src/uhci.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,6 +34,7 @@ #include "esp_private/esp_dma_utils.h" #include "esp_private/gdma_link.h" #include "esp_private/esp_cache_private.h" +#include "esp_private/esp_psram_mspi.h" #include "uhci_private.h" #include "esp_memory_utils.h" #include "esp_cache.h" @@ -107,6 +108,7 @@ static bool uhci_gdma_rx_callback_done(gdma_channel_handle_t dma_chan, gdma_even { bool need_yield = false; uhci_controller_handle_t uhci_ctrl = (uhci_controller_handle_t) user_data; + bool is_buf_from_psram = esp_ptr_external_ram(uhci_ctrl->rx_dir.buffer_pointers[uhci_ctrl->rx_dir.node_index]); // If the data is not all received, handle it in not normal_eof block. Otherwise, in eof block. if (!event_data->flags.normal_eof) { size_t rx_size = uhci_ctrl->rx_dir.buffer_size_per_desc_node[uhci_ctrl->rx_dir.node_index]; @@ -116,9 +118,8 @@ static bool uhci_gdma_rx_callback_done(gdma_channel_handle_t dma_chan, gdma_even .flags.totally_received = false, }; - bool need_cache_sync = esp_ptr_internal(uhci_ctrl->rx_dir.buffer_pointers[uhci_ctrl->rx_dir.node_index]) ? (uhci_ctrl->int_mem_cache_line_size > 0) : (uhci_ctrl->ext_mem_cache_line_size > 0); - if (need_cache_sync) { - esp_cache_msync(uhci_ctrl->rx_dir.buffer_pointers[uhci_ctrl->rx_dir.node_index], rx_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + if (is_buf_from_psram) { + esp_psram_mspi_mb(); } if (uhci_ctrl->rx_dir.on_rx_trans_event) { need_yield |= uhci_ctrl->rx_dir.on_rx_trans_event(uhci_ctrl, &evt_data, uhci_ctrl->user_data); @@ -138,10 +139,8 @@ static bool uhci_gdma_rx_callback_done(gdma_channel_handle_t dma_chan, gdma_even .flags.totally_received = true, }; - bool need_cache_sync = esp_ptr_internal(uhci_ctrl->rx_dir.buffer_pointers[uhci_ctrl->rx_dir.node_index]) ? (uhci_ctrl->int_mem_cache_line_size > 0) : (uhci_ctrl->ext_mem_cache_line_size > 0); - size_t m2c_size = UHCI_ALIGN_UP(rx_size, uhci_ctrl->rx_dir.cache_line); - if (need_cache_sync) { - esp_cache_msync(uhci_ctrl->rx_dir.buffer_pointers[uhci_ctrl->rx_dir.node_index], m2c_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + if (is_buf_from_psram) { + esp_psram_mspi_mb(); } // release power manager lock if (uhci_ctrl->pm_lock) { @@ -347,6 +346,13 @@ esp_err_t uhci_receive(uhci_controller_handle_t uhci_ctrl, uint8_t *read_buffer, gdma_link_mount_buffers(uhci_ctrl->rx_dir.dma_link, 0, mount_configs, node_count, NULL); + // Invalidate cache before DMA starts to ensure no dirty cache lines. + // All DMA nodes (mount_configs) share the same contiguous user buffer, so checking mount_configs[0].buffer is sufficient. + bool need_cache_sync = esp_ptr_internal(mount_configs[0].buffer) ? (uhci_ctrl->int_mem_cache_line_size > 0) : (uhci_ctrl->ext_mem_cache_line_size > 0); + if (need_cache_sync) { + ESP_RETURN_ON_ERROR(esp_cache_msync(mount_configs[0].buffer, usable_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C), TAG, "cache sync failed"); + } + gdma_reset(uhci_ctrl->rx_dir.dma_chan); gdma_start(uhci_ctrl->rx_dir.dma_chan, gdma_link_get_head_addr(uhci_ctrl->rx_dir.dma_link)); From 402558201c39e1bf8a9bfe683b0edd4b37f2844b Mon Sep 17 00:00:00 2001 From: hebinglin Date: Mon, 12 Jan 2026 14:41:15 +0800 Subject: [PATCH 211/226] revert(esp_hw_support): force top domain power up during sleep This reverts commit 7912f9fafef4c90a2a644332c46af7fd5e91f148. --- components/esp_hw_support/sleep_modes.c | 5 ----- components/soc/esp32c5/include/soc/Kconfig.soc_caps.in | 4 ---- components/soc/esp32c5/include/soc/soc_caps.h | 1 - 3 files changed, 10 deletions(-) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 88c1b96388..31ce1374bd 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -2563,11 +2563,6 @@ FORCE_INLINE_ATTR bool top_domain_pd_allowed(void) { #if SOC_XTAL_CLOCK_PATH_DEPENDS_ON_TOP_DOMAIN top_pd_allowed &= (s_config.domain[ESP_PD_DOMAIN_XTAL].pd_option != ESP_PD_OPTION_ON); #endif -#if SOC_PM_TOP_PD_NOT_ALLOWED - // TODO: PM-436, Need to use efuse_hal_chip_revision() to determine whether - // the TOP domain power-down is allowed - top_pd_allowed = false; -#endif return top_pd_allowed; } diff --git a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in index ccf75e989d..44cbf417b2 100644 --- a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in @@ -1727,10 +1727,6 @@ config SOC_EXT_MEM_CACHE_TAG_IN_CPU_DOMAIN bool default y -config SOC_PM_TOP_PD_NOT_ALLOWED - bool - default y - config SOC_PM_PAU_LINK_NUM int default 5 diff --git a/components/soc/esp32c5/include/soc/soc_caps.h b/components/soc/esp32c5/include/soc/soc_caps.h index bb696ebb35..1c258a9451 100644 --- a/components/soc/esp32c5/include/soc/soc_caps.h +++ b/components/soc/esp32c5/include/soc/soc_caps.h @@ -664,7 +664,6 @@ #define SOC_PM_CPU_RETENTION_BY_SW (1) #define SOC_PM_MODEM_RETENTION_BY_REGDMA (1) #define SOC_EXT_MEM_CACHE_TAG_IN_CPU_DOMAIN (1) -#define SOC_PM_TOP_PD_NOT_ALLOWED (1) #define SOC_PM_PAU_LINK_NUM (5) #define SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE (1) From 69ced7c6701f6eaeb782fdc66ab675d4a88d1fd4 Mon Sep 17 00:00:00 2001 From: hebinglin Date: Mon, 12 Jan 2026 14:41:38 +0800 Subject: [PATCH 212/226] revert(unit-test): filter top domain power down check for some sleep test cases This reverts commit c6c2948a99bcaa47c8354fe44f62acf963821847. --- .../test_apps/gptimer/main/test_gptimer_sleep.c | 4 ++-- components/esp_driver_i2s/test_apps/i2s/main/test_i2s_sleep.c | 2 +- .../esp_driver_ledc/test_apps/ledc/main/test_ledc_sleep.c | 2 +- .../esp_driver_mcpwm/test_apps/mcpwm/main/test_mcpwm_sleep.c | 4 ++-- .../test_apps/parlio/main/test_parlio_sleep.c | 2 +- components/esp_driver_rmt/test_apps/rmt/main/test_rmt_sleep.c | 2 +- .../esp_driver_spi/test_apps/master/main/test_spi_master.c | 4 ++-- .../esp_driver_spi/test_apps/slave/main/test_spi_slave.c | 2 +- .../test_apps/slave_hd/main/test_spi_slave_hd.c | 4 ++-- .../temperature_sensor/main/test_temperature_sensor.cpp | 2 +- .../test_apps/esp_system_unity_tests/main/test_sleep.c | 2 +- .../test_apps/esp_system_unity_tests/main/test_task_wdt.c | 2 -- 12 files changed, 15 insertions(+), 17 deletions(-) diff --git a/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_sleep.c b/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_sleep.c index f9a9f5bc7a..9405ca9c25 100644 --- a/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_sleep.c +++ b/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_sleep.c @@ -85,7 +85,7 @@ static void test_gptimer_sleep_retention(bool allow_pd) printf("check if the sleep happened as expected\r\n"); TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); -#if SOC_TIMER_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !SOC_PM_TOP_PD_NOT_ALLOWED +#if SOC_TIMER_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP // check if the power domain also is powered down TEST_ASSERT_EQUAL(allow_pd ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP); #endif @@ -202,7 +202,7 @@ static void test_gptimer_etm_sleep_retention(bool back_up_before_sleep) printf("check if the sleep happened as expected\r\n"); TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); -#if SOC_TIMER_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !SOC_PM_TOP_PD_NOT_ALLOWED +#if SOC_TIMER_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP // check if the power domain also is powered down TEST_ASSERT_EQUAL(back_up_before_sleep ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP); #endif diff --git a/components/esp_driver_i2s/test_apps/i2s/main/test_i2s_sleep.c b/components/esp_driver_i2s/test_apps/i2s/main/test_i2s_sleep.c index 2a0a208de0..6b5b944f31 100644 --- a/components/esp_driver_i2s/test_apps/i2s/main/test_i2s_sleep.c +++ b/components/esp_driver_i2s/test_apps/i2s/main/test_i2s_sleep.c @@ -42,7 +42,7 @@ static void s_test_i2s_enter_light_sleep(int sec, bool allow_power_down) printf("Woke up from light sleep\n"); TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); -#if SOC_I2S_SUPPORT_SLEEP_RETENTION && !SOC_PM_TOP_PD_NOT_ALLOWED +#if SOC_I2S_SUPPORT_SLEEP_RETENTION // check if the power domain also is powered down TEST_ASSERT_EQUAL(allow_power_down ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP); #endif diff --git a/components/esp_driver_ledc/test_apps/ledc/main/test_ledc_sleep.c b/components/esp_driver_ledc/test_apps/ledc/main/test_ledc_sleep.c index 39bea57ef1..980d65b9ed 100644 --- a/components/esp_driver_ledc/test_apps/ledc/main/test_ledc_sleep.c +++ b/components/esp_driver_ledc/test_apps/ledc/main/test_ledc_sleep.c @@ -59,7 +59,7 @@ static void test_ledc_sleep_retention(bool allow_pd) printf("Check if the sleep happened as expected\r\n"); TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); -#if SOC_PMU_SUPPORTED && !SOC_PM_TOP_PD_NOT_ALLOWED +#if SOC_PMU_SUPPORTED // check if the TOP power domain on/off as desired TEST_ASSERT_EQUAL(allow_pd ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP); #endif diff --git a/components/esp_driver_mcpwm/test_apps/mcpwm/main/test_mcpwm_sleep.c b/components/esp_driver_mcpwm/test_apps/mcpwm/main/test_mcpwm_sleep.c index 94aa6b48c8..6c9a78bbec 100644 --- a/components/esp_driver_mcpwm/test_apps/mcpwm/main/test_mcpwm_sleep.c +++ b/components/esp_driver_mcpwm/test_apps/mcpwm/main/test_mcpwm_sleep.c @@ -84,7 +84,7 @@ static void test_mcpwm_timer_sleep_retention(bool allow_pd) printf("check if the sleep happened as expected\r\n"); TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); -#if SOC_MCPWM_SUPPORT_SLEEP_RETENTION && !SOC_PM_TOP_PD_NOT_ALLOWED +#if SOC_MCPWM_SUPPORT_SLEEP_RETENTION // check if the power domain also is powered down TEST_ASSERT_EQUAL(allow_pd ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP); #endif @@ -189,7 +189,7 @@ static void test_mcpwm_capture_timer_sleep_retention(bool allow_pd) printf("check if the sleep happened as expected\r\n"); TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); -#if SOC_MCPWM_SUPPORT_SLEEP_RETENTION && !SOC_PM_TOP_PD_NOT_ALLOWED +#if SOC_MCPWM_SUPPORT_SLEEP_RETENTION // check if the power domain also is powered down TEST_ASSERT_EQUAL(allow_pd ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP); #endif diff --git a/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_sleep.c b/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_sleep.c index e035b48bea..30223bb9e0 100644 --- a/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_sleep.c +++ b/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_sleep.c @@ -133,7 +133,7 @@ static void test_parlio_sleep_retention(bool allow_pd) printf("check if the sleep happened as expected\r\n"); TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); -#if SOC_PARLIO_SUPPORT_SLEEP_RETENTION && !SOC_PM_TOP_PD_NOT_ALLOWED +#if SOC_PARLIO_SUPPORT_SLEEP_RETENTION // check if the power domain also is powered down TEST_ASSERT_EQUAL(allow_pd ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP); #endif diff --git a/components/esp_driver_rmt/test_apps/rmt/main/test_rmt_sleep.c b/components/esp_driver_rmt/test_apps/rmt/main/test_rmt_sleep.c index f53f4db335..9328d78ac1 100644 --- a/components/esp_driver_rmt/test_apps/rmt/main/test_rmt_sleep.c +++ b/components/esp_driver_rmt/test_apps/rmt/main/test_rmt_sleep.c @@ -107,7 +107,7 @@ static void test_rmt_tx_rx_sleep_retention(bool allow_pd) printf("check if the sleep happened as expected\r\n"); TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); -#if SOC_RMT_SUPPORT_SLEEP_RETENTION && !SOC_PM_TOP_PD_NOT_ALLOWED +#if SOC_RMT_SUPPORT_SLEEP_RETENTION // check if the power domain also is powered down TEST_ASSERT_EQUAL(allow_pd ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP); #endif diff --git a/components/esp_driver_spi/test_apps/master/main/test_spi_master.c b/components/esp_driver_spi/test_apps/master/main/test_spi_master.c index 5ba2d040ab..edf3dfc70e 100644 --- a/components/esp_driver_spi/test_apps/master/main/test_spi_master.c +++ b/components/esp_driver_spi/test_apps/master/main/test_spi_master.c @@ -1886,7 +1886,7 @@ TEST_CASE("test_spi_master_sleep_retention", "[spi]") // check if the sleep happened as expected TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); -#if SOC_SPI_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !SOC_PM_TOP_PD_NOT_ALLOWED +#if SOC_SPI_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP // check if the power domain also is powered down TEST_ASSERT_EQUAL((buscfg.flags & SPICOMMON_BUSFLAG_SLP_ALLOW_PD) ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP); #endif @@ -1954,7 +1954,7 @@ TEST_CASE("test_spi_master_auto_sleep_retention", "[spi]") // check if the sleep happened as expected TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); -#if SOC_SPI_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !SOC_PM_TOP_PD_NOT_ALLOWED +#if SOC_SPI_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP // check if the power domain also is powered down TEST_ASSERT_EQUAL((buscfg.flags & SPICOMMON_BUSFLAG_SLP_ALLOW_PD) ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP); #endif diff --git a/components/esp_driver_spi/test_apps/slave/main/test_spi_slave.c b/components/esp_driver_spi/test_apps/slave/main/test_spi_slave.c index 33ddd18c82..6f126c7dbd 100644 --- a/components/esp_driver_spi/test_apps/slave/main/test_spi_slave.c +++ b/components/esp_driver_spi/test_apps/slave/main/test_spi_slave.c @@ -689,7 +689,7 @@ TEST_CASE("test_spi_slave_sleep_retention", "[spi]") // check if the sleep happened as expected TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); -#if SOC_SPI_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !SOC_PM_TOP_PD_NOT_ALLOWED +#if SOC_SPI_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP // check if the power domain also is powered down TEST_ASSERT_EQUAL((buscfg.flags & SPICOMMON_BUSFLAG_SLP_ALLOW_PD) ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP); #endif diff --git a/components/esp_driver_spi/test_apps/slave_hd/main/test_spi_slave_hd.c b/components/esp_driver_spi/test_apps/slave_hd/main/test_spi_slave_hd.c index 293b1e24ec..491c0fee36 100644 --- a/components/esp_driver_spi/test_apps/slave_hd/main/test_spi_slave_hd.c +++ b/components/esp_driver_spi/test_apps/slave_hd/main/test_spi_slave_hd.c @@ -945,7 +945,7 @@ TEST_CASE("test_spi_slave_hd_sleep_retention", "[spi]") printf("Waked up!\n"); // check if the sleep happened as expected TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); -#if SOC_SPI_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !SOC_PM_TOP_PD_NOT_ALLOWED +#if SOC_SPI_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP // check if the power domain also is powered down TEST_ASSERT_EQUAL((bus_cfg.flags & SPICOMMON_BUSFLAG_SLP_ALLOW_PD) ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP); #endif @@ -1023,7 +1023,7 @@ TEST_CASE("test_spi_slave_hd_append_sleep_retention", "[spi]") printf("Waked up!\n"); // check if the sleep happened as expected TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); -#if SOC_SPI_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !SOC_PM_TOP_PD_NOT_ALLOWED +#if SOC_SPI_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP // check if the power domain also is powered down TEST_ASSERT_EQUAL((bus_cfg.flags & SPICOMMON_BUSFLAG_SLP_ALLOW_PD) ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP); #endif diff --git a/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_sensor.cpp b/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_sensor.cpp index b4b32864a8..4fa8069a3e 100644 --- a/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_sensor.cpp +++ b/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_sensor.cpp @@ -186,7 +186,7 @@ static void test_temperature_sensor_sleep_retention(bool allow_pd) #endif printf("check if the sleep happened as expected\r\n"); TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); -#if SOC_TEMPERATURE_SENSOR_UNDER_PD_TOP_DOMAIN && !SOC_PM_TOP_PD_NOT_ALLOWED +#if SOC_TEMPERATURE_SENSOR_UNDER_PD_TOP_DOMAIN // check if the power domain also is powered down TEST_ASSERT_EQUAL(allow_pd ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP); #elif CONFIG_IDF_TARGET_ESP32P4 diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c b/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c index 54b8442b3d..1097c23fc6 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c @@ -323,7 +323,7 @@ static void test_psram_accessible_after_lightsleep(void) esp_light_sleep_start(); TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); -#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !SOC_PM_TOP_PD_NOT_ALLOWED +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP); TEST_ESP_OK(sleep_cpu_configure(false)); #endif diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c b/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c index 03129592a5..28db4dbb28 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c @@ -74,9 +74,7 @@ TEST_CASE("Task WDT task timeout after peripheral powerdown lightsleep", "[task_ esp_light_sleep_start(); -#if !SOC_PM_TOP_PD_NOT_ALLOWED TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP); -#endif TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); esp_sleep_set_sleep_context(NULL); From 416c56c1ef0121ceaecfb4f94f0c10da6dfa3507 Mon Sep 17 00:00:00 2001 From: hebinglin Date: Thu, 20 Nov 2025 21:07:32 +0800 Subject: [PATCH 213/226] feat(esp_hw_support): support top pd during sleep in esp32c5 eco3 --- components/esp_hw_support/sleep_modes.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 31ce1374bd..41bc062f54 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -2563,6 +2563,12 @@ FORCE_INLINE_ATTR bool top_domain_pd_allowed(void) { #if SOC_XTAL_CLOCK_PATH_DEPENDS_ON_TOP_DOMAIN top_pd_allowed &= (s_config.domain[ESP_PD_DOMAIN_XTAL].pd_option != ESP_PD_OPTION_ON); #endif +#if CONFIG_IDF_TARGET_ESP32C5 + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102)) { + // ESP32C5 chips lower than v1.2 are not supported to power down the TOP domain + top_pd_allowed = false; + } +#endif return top_pd_allowed; } From 902d13d48994e8c11d5cf957e61911852df334f5 Mon Sep 17 00:00:00 2001 From: hebinglin Date: Thu, 20 Nov 2025 21:14:02 +0800 Subject: [PATCH 214/226] change(esp_hw_support): remove sleep_mmu_retention related flow for esp32c5 eco1 --- .../include/esp_private/esp_sleep_internal.h | 18 +-- .../esp_hw_support/lowpower/CMakeLists.txt | 4 - .../lowpower/port/esp32c5/sleep_mmu.c | 152 ------------------ components/esp_hw_support/sleep_modes.c | 19 +-- components/esp_pm/linker.lf | 2 - components/esp_system/system_init_fn.txt | 1 - .../main/test_task_wdt.c | 8 +- 7 files changed, 3 insertions(+), 201 deletions(-) delete mode 100644 components/esp_hw_support/lowpower/port/esp32c5/sleep_mmu.c diff --git a/components/esp_hw_support/include/esp_private/esp_sleep_internal.h b/components/esp_hw_support/include/esp_private/esp_sleep_internal.h index 7f984e947f..96ada2d084 100644 --- a/components/esp_hw_support/include/esp_private/esp_sleep_internal.h +++ b/components/esp_hw_support/include/esp_private/esp_sleep_internal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -149,22 +149,6 @@ esp_err_t esp_deep_sleep_register_phy_hook(esp_deep_sleep_cb_t new_dslp_cb); void esp_deep_sleep_deregister_phy_hook(esp_deep_sleep_cb_t old_dslp_cb); #endif -#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD -/** - * @brief Backup or restore the MMU when the top domain is powered down. - * @param backup_or_restore decide to backup mmu or restore mmu - */ -void esp_sleep_mmu_retention(bool backup_or_restore); - -/** - * @brief Whether to allow the top domain to be powered off due to mmu domain requiring retention. - * - * In light sleep mode, only when the system can provide enough memory - * for mmu retention, the top power domain can be powered off. - */ -bool mmu_domain_pd_allowed(void); -#endif - /** * @brief Notify the sleep process that `sleep_time_overhead_out` needs to be remeasured, which must be called * in the following scenarios: diff --git a/components/esp_hw_support/lowpower/CMakeLists.txt b/components/esp_hw_support/lowpower/CMakeLists.txt index e71f8b67ed..22558a817b 100644 --- a/components/esp_hw_support/lowpower/CMakeLists.txt +++ b/components/esp_hw_support/lowpower/CMakeLists.txt @@ -24,10 +24,6 @@ if(CONFIG_P4_REV3_MSPI_CRASH_AFTER_POWER_UP_WORKAROUND) APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u p4_rev3_mspi_workaround") endif() -if(CONFIG_SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD AND CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP) - list(APPEND srcs "port/${target}/sleep_mmu.c") -endif() - if((CONFIG_SOC_PM_SUPPORT_MODEM_PD OR CONFIG_SOC_PM_SUPPORT_TOP_PD) AND CONFIG_SOC_PAU_SUPPORTED) list(APPEND srcs "port/${target}/sleep_clock.c") endif() diff --git a/components/esp_hw_support/lowpower/port/esp32c5/sleep_mmu.c b/components/esp_hw_support/lowpower/port/esp32c5/sleep_mmu.c deleted file mode 100644 index 3a1cad1728..0000000000 --- a/components/esp_hw_support/lowpower/port/esp32c5/sleep_mmu.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -#include "esp_attr.h" -#include "esp_check.h" -#include "esp_sleep.h" -#include "esp_log.h" -#include "esp_heap_caps.h" -#include "soc/soc_caps.h" -#include "sdkconfig.h" -#include "soc/spi_mem_reg.h" -#include "esp_private/startup_internal.h" - -static const char *TAG = "sleep_mmu"; - -typedef struct { - uint32_t start; - uint32_t end; -} mmu_domain_dev_regs_region_t; - -typedef struct { - mmu_domain_dev_regs_region_t *region; - int region_num; - uint32_t *regs_frame; -} mmu_domain_dev_sleep_frame_t; - -/** - * Internal structure which holds all requested light sleep mmu retention parameters - */ -typedef struct { - struct { - mmu_domain_dev_sleep_frame_t *mmu_table_frame; - } retent; -} sleep_mmu_retention_t; - -static DRAM_ATTR __attribute__((unused)) sleep_mmu_retention_t s_mmu_retention; - -static void * mmu_domain_dev_sleep_frame_alloc_and_init(const mmu_domain_dev_regs_region_t *regions, const int region_num) -{ - const int region_sz = sizeof(mmu_domain_dev_regs_region_t) * region_num; - int regs_frame_sz = 0; - for (int num = 0; num < region_num; num++) { - regs_frame_sz += regions[num].end - regions[num].start; - } - void *frame = heap_caps_malloc(sizeof(mmu_domain_dev_sleep_frame_t) + region_sz + regs_frame_sz, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL); - if (frame) { - mmu_domain_dev_regs_region_t *region = (mmu_domain_dev_regs_region_t *)(frame + sizeof(mmu_domain_dev_sleep_frame_t)); - memcpy(region, regions, region_num * sizeof(mmu_domain_dev_regs_region_t)); - void *regs_frame = frame + sizeof(mmu_domain_dev_sleep_frame_t) + region_sz; - memset(regs_frame, 0, regs_frame_sz); - *(mmu_domain_dev_sleep_frame_t *)frame = (mmu_domain_dev_sleep_frame_t) { - .region = region, - .region_num = region_num, - .regs_frame = (uint32_t *)regs_frame - }; - } - return frame; -} - -static inline void * mmu_domain_mmu_table_sleep_frame_alloc_and_init(void) -{ - #define MMU_TABLE_SIZE (512 * 4) - const static mmu_domain_dev_regs_region_t regions[] = { - { .start = SPI_MEM_MMU_ITEM_CONTENT_REG(0), .end = SPI_MEM_MMU_ITEM_CONTENT_REG(0) + MMU_TABLE_SIZE} - }; - return mmu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0])); -} - -static IRAM_ATTR void mmu_domain_dev_regs_save(mmu_domain_dev_sleep_frame_t *frame) -{ - assert(frame); - mmu_domain_dev_regs_region_t *region = frame->region; - uint32_t *regs_frame = frame->regs_frame; - - int offset = 0; - for (int i = 0; i < frame->region_num; i++) { - for (uint32_t addr = region[i].start; addr < region[i].end; addr+=4) { - REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), offset); - regs_frame[offset++] = REG_READ(SPI_MEM_MMU_ITEM_CONTENT_REG(0)); - } - } -} - -static IRAM_ATTR void mmu_domain_dev_regs_restore(mmu_domain_dev_sleep_frame_t *frame) -{ - assert(frame); - mmu_domain_dev_regs_region_t *region = frame->region; - uint32_t *regs_frame = frame->regs_frame; - - int offset = 0; - for (int i = 0; i < frame->region_num; i++) { - for (uint32_t addr = region[i].start; addr < region[i].end; addr+=4) { - REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), offset); - REG_WRITE(SPI_MEM_MMU_ITEM_CONTENT_REG(0),regs_frame[offset++]); - } - } -} - -IRAM_ATTR void esp_sleep_mmu_retention(bool backup_or_restore) -{ - if (backup_or_restore) { - mmu_domain_dev_regs_save(s_mmu_retention.retent.mmu_table_frame); - } else { - mmu_domain_dev_regs_restore(s_mmu_retention.retent.mmu_table_frame); - } -} - -static esp_err_t esp_sleep_mmu_retention_deinit(void) -{ - if (s_mmu_retention.retent.mmu_table_frame) { - heap_caps_free((void *)s_mmu_retention.retent.mmu_table_frame); - s_mmu_retention.retent.mmu_table_frame = NULL; - } - return ESP_OK; -} - -static esp_err_t esp_sleep_mmu_retention_init(void) -{ - if (s_mmu_retention.retent.mmu_table_frame == NULL) { - void *frame = mmu_domain_mmu_table_sleep_frame_alloc_and_init(); - if (frame == NULL) { - goto err; - } - s_mmu_retention.retent.mmu_table_frame = (mmu_domain_dev_sleep_frame_t *)frame; - } - return ESP_OK; -err: - esp_sleep_mmu_retention_deinit(); - return ESP_ERR_NO_MEM; -} - -bool mmu_domain_pd_allowed(void) -{ - return (s_mmu_retention.retent.mmu_table_frame != NULL); -} - -ESP_SYSTEM_INIT_FN(sleep_mmu_startup_init, SECONDARY, BIT(0), 108) -{ - esp_err_t ret; - ret = esp_sleep_mmu_retention_init(); - if (ret != ESP_OK) { - ESP_EARLY_LOGW(TAG, "Failed to enable TOP power down during light sleep."); - } - return ESP_OK; -} diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 41bc062f54..5d0c46a928 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -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 */ @@ -225,10 +225,6 @@ #define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ) #endif -#if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD -#define SLEEP_MMU_TABLE_RETENTION_OVERHEAD_US (1220) -#endif - #define RTC_MODULE_SLEEP_PREPARE_CYCLES (6) #define CHECK_SOURCE(source, value, mask) ((s_config.wakeup_triggers & mask) && \ @@ -923,9 +919,6 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP if (sleep_flags & PMU_SLEEP_PD_TOP) { -#if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD - esp_sleep_mmu_retention(true); -#endif #if CONFIG_IDF_TARGET_ESP32P4 && (CONFIG_ESP_REV_MIN_FULL == 300) sleep_retention_do_extra_retention(true); #endif @@ -953,9 +946,6 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP if (sleep_flags & PMU_SLEEP_PD_TOP) { -#if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD - esp_sleep_mmu_retention(false); -#endif #if SOC_PM_RETENTION_SW_TRIGGER_REGDMA sleep_retention_do_system_retention(false); #endif @@ -1497,10 +1487,6 @@ esp_err_t esp_light_sleep_start(void) int sleep_time_sw_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US + sleep_time_overhead_in + s_config.sleep_time_overhead_out; int sleep_time_hw_adjustment = pmu_sleep_calculate_hw_wait_time(sleep_flags, rtc_clk_slow_src_get(), s_config.rtc_clk_cal_period, s_config.fast_clk_cal_period); s_config.sleep_time_adjustment = sleep_time_sw_adjustment + sleep_time_hw_adjustment; -#if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD - int sleep_time_sw_mmu_table_restore = (sleep_flags & PMU_SLEEP_PD_TOP) ? SLEEP_MMU_TABLE_RETENTION_OVERHEAD_US : 0; - s_config.sleep_time_adjustment += sleep_time_sw_mmu_table_restore; -#endif #else uint32_t rtc_cntl_xtl_buf_wait_slp_cycles = rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, s_config.rtc_clk_cal_period); s_config.sleep_time_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US + sleep_time_overhead_in + s_config.sleep_time_overhead_out @@ -2551,9 +2537,6 @@ FORCE_INLINE_ATTR bool top_domain_pd_allowed(void) { top_pd_allowed &= cpu_domain_pd_allowed(); #else top_pd_allowed = false; -#endif -#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD - top_pd_allowed &= mmu_domain_pd_allowed(); #endif top_pd_allowed &= clock_domain_pd_allowed(); top_pd_allowed &= peripheral_domain_pd_allowed(); diff --git a/components/esp_pm/linker.lf b/components/esp_pm/linker.lf index acf6b7852c..20e3811c2e 100644 --- a/components/esp_pm/linker.lf +++ b/components/esp_pm/linker.lf @@ -32,8 +32,6 @@ entries: sleep_cpu:sleep_enable_cpu_retention (noflash) if PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y || (ESP32P4_SELECTS_REV_LESS_V3 = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP = y): sleep_cpu:cpu_domain_pd_allowed (noflash) - if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP = y: - sleep_mmu:mmu_domain_pd_allowed (noflash) esp_clk:esp_clk_slowclk_cal_set (noflash) esp_clk:esp_clk_slowclk_cal_get (noflash) esp_clk:esp_rtc_get_time_us (noflash) diff --git a/components/esp_system/system_init_fn.txt b/components/esp_system/system_init_fn.txt index 5e1b1c308c..aa667391b5 100644 --- a/components/esp_system/system_init_fn.txt +++ b/components/esp_system/system_init_fn.txt @@ -87,7 +87,6 @@ SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/p SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32h21/sleep_clock.c on BIT(0) SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32p4/sleep_clock.c on BIT(0) SECONDARY: 107: sleep_sys_periph_startup_init in components/esp_hw_support/sleep_system_peripheral.c on BIT(0) -SECONDARY: 108: sleep_mmu_startup_init in components/esp_hw_support/lowpower/port/esp32c5/sleep_mmu.c on BIT(0) # app_trace has to be initialized before systemview SECONDARY: 115: esp_apptrace_init in components/app_trace/app_trace.c on ESP_SYSTEM_INIT_ALL_CORES diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c b/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c index 28db4dbb28..c8dbbc15a1 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -64,13 +64,7 @@ TEST_CASE("Task WDT task timeout after peripheral powerdown lightsleep", "[task_ TEST_ESP_OK(sleep_cpu_configure(true)); esp_sleep_context_t sleep_ctx; esp_sleep_set_sleep_context(&sleep_ctx); -#if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD - /* There is a bug that PD TOP will reset mmu table, so we add mmu table retention during sleep, - and it will increase time overhead before entering sleep */ - esp_sleep_enable_timer_wakeup(100 * 1000); -#else esp_sleep_enable_timer_wakeup(10 * 1000); -#endif esp_light_sleep_start(); From 17c110d64014be4f169d0d393df9f0837c67d8c3 Mon Sep 17 00:00:00 2001 From: hebinglin Date: Fri, 9 Jan 2026 14:50:09 +0800 Subject: [PATCH 215/226] change(esp_driver): set cases with toppd check only run in esp32c5eco3 rather than eco2 --- .../test_apps/gptimer/pytest_gptimer.py | 34 +++++++++++++++- .../test_apps/i2s/pytest_i2s.py | 39 +++++++++++++++++- .../test_apps/ledc/pytest_ledc.py | 34 +++++++++++++++- .../test_apps/mcpwm/pytest_mcpwm.py | 31 +++++++++++++- .../test_apps/parlio/pytest_parlio_unity.py | 31 +++++++++++++- .../test_apps/rmt/pytest_rmt.py | 33 +++++++++++++-- .../sigma_delta/pytest_sigma_delta.py | 19 ++++++++- .../test_apps/master/pytest_spi_master.py | 40 ++++++++++++++++++- .../test_apps/slave/pytest_spi_slave.py | 22 +++++++++- .../test_apps/slave_hd/pytest_spi_slave_hd.py | 12 +++++- .../pytest_temperature_sensor.py | 22 +++++++++- .../main/test_random.c | 2 +- .../pytest_esp_hw_support.py | 2 +- .../pytest_esp_system_unity_tests.py | 36 +++++++++++++++-- tools/ci/idf_pytest/constants.py | 1 + 15 files changed, 329 insertions(+), 29 deletions(-) diff --git a/components/esp_driver_gptimer/test_apps/gptimer/pytest_gptimer.py b/components/esp_driver_gptimer/test_apps/gptimer/pytest_gptimer.py index b398c74ff0..ab1886a3f5 100644 --- a/components/esp_driver_gptimer/test_apps/gptimer/pytest_gptimer.py +++ b/components/esp_driver_gptimer/test_apps/gptimer/pytest_gptimer.py @@ -1,8 +1,9 @@ -# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut from pytest_embedded_idf.utils import idf_parametrize +from pytest_embedded_idf.utils import soc_filtered_targets @pytest.mark.generic @@ -14,11 +15,40 @@ from pytest_embedded_idf.utils import idf_parametrize ], indirect=True, ) -@idf_parametrize('target', ['supported_targets'], indirect=['target']) +@idf_parametrize( + 'target', soc_filtered_targets('SOC_GPTIMER_SUPPORTED == 1 and IDF_TARGET not in ["esp32c5"]'), indirect=['target'] +) def test_gptimer(dut: Dut) -> None: dut.run_all_single_board_cases() +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'cache_safe', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_gptimer_esp32c5(dut: Dut) -> None: + dut.run_all_single_board_cases() + + +@pytest.mark.generic +@pytest.mark.esp32c5_eco3 +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_gptimer_esp32c5_eco3(dut: Dut) -> None: + dut.run_all_single_board_cases() + + @pytest.mark.generic @pytest.mark.xtal_26mhz @pytest.mark.parametrize( diff --git a/components/esp_driver_i2s/test_apps/i2s/pytest_i2s.py b/components/esp_driver_i2s/test_apps/i2s/pytest_i2s.py index 9c34a48bbb..769cae7499 100644 --- a/components/esp_driver_i2s/test_apps/i2s/pytest_i2s.py +++ b/components/esp_driver_i2s/test_apps/i2s/pytest_i2s.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import pytest from pytest_embedded import Dut @@ -16,13 +16,48 @@ from pytest_embedded_idf.utils import idf_parametrize ) @idf_parametrize( 'target', - ['esp32', 'esp32s2', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c61'], + ['esp32', 'esp32s2', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c61'], indirect=['target'], ) def test_i2s(dut: Dut) -> None: dut.run_all_single_board_cases() +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'iram_safe', + ], + indirect=True, +) +@idf_parametrize( + 'target', + ['esp32c5'], + indirect=['target'], +) +def test_i2s_esp32c5(dut: Dut) -> None: + dut.run_all_single_board_cases() + + +@pytest.mark.generic +@pytest.mark.esp32c5_eco3 +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +@idf_parametrize( + 'target', + ['esp32c5'], + indirect=['target'], +) +def test_i2s_esp32c5_eco3(dut: Dut) -> None: + dut.run_all_single_board_cases() + + @pytest.mark.octal_psram @pytest.mark.parametrize( 'config', diff --git a/components/esp_driver_ledc/test_apps/ledc/pytest_ledc.py b/components/esp_driver_ledc/test_apps/ledc/pytest_ledc.py index 42f19403bf..0e0a2c9895 100644 --- a/components/esp_driver_ledc/test_apps/ledc/pytest_ledc.py +++ b/components/esp_driver_ledc/test_apps/ledc/pytest_ledc.py @@ -1,8 +1,9 @@ -# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded_idf import IdfDut from pytest_embedded_idf.utils import idf_parametrize +from pytest_embedded_idf.utils import soc_filtered_targets @pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='skip due to duplication with test_ledc_psram') @@ -15,12 +16,41 @@ from pytest_embedded_idf.utils import idf_parametrize ], indirect=True, ) -@idf_parametrize('target', ['supported_targets'], indirect=['target']) +@idf_parametrize( + 'target', soc_filtered_targets('SOC_LEDC_SUPPORTED == 1 and IDF_TARGET not in ["esp32c5"]'), indirect=['target'] +) @pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 rev3 migration # TODO: IDF-14398') def test_ledc(dut: IdfDut) -> None: dut.run_all_single_board_cases(reset=True) +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'iram_safe', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_ledc_esp32c5(dut: IdfDut) -> None: + dut.run_all_single_board_cases(reset=True) + + +@pytest.mark.generic +@pytest.mark.esp32c5_eco3 +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_ledc_esp32c5_eco3(dut: IdfDut) -> None: + dut.run_all_single_board_cases(reset=True) + + @pytest.mark.octal_psram @pytest.mark.parametrize( 'config', diff --git a/components/esp_driver_mcpwm/test_apps/mcpwm/pytest_mcpwm.py b/components/esp_driver_mcpwm/test_apps/mcpwm/pytest_mcpwm.py index fc6313a7e2..8e97681969 100644 --- a/components/esp_driver_mcpwm/test_apps/mcpwm/pytest_mcpwm.py +++ b/components/esp_driver_mcpwm/test_apps/mcpwm/pytest_mcpwm.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut @@ -14,7 +14,34 @@ from pytest_embedded_idf.utils import idf_parametrize ], indirect=True, ) -@idf_parametrize('target', ['esp32', 'esp32s3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target']) +@idf_parametrize('target', ['esp32', 'esp32s3', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target']) @pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 rev3 migration # TODO: IDF-14412') def test_mcpwm(dut: Dut) -> None: dut.run_all_single_board_cases() + + +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'cache_safe', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_mcpwm_esp32c5(dut: Dut) -> None: + dut.run_all_single_board_cases() + + +@pytest.mark.generic +@pytest.mark.esp32c5_eco3 +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_mcpwm_esp32c5_eco3(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py b/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py index 55b9dbb6c9..cd36a5fd07 100644 --- a/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py +++ b/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut @@ -14,7 +14,34 @@ from pytest_embedded_idf.utils import idf_parametrize ], indirect=True, ) -@idf_parametrize('target', ['esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target']) +@idf_parametrize('target', ['esp32c6', 'esp32h2', 'esp32p4'], indirect=['target']) @pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 rev3 migration # TODO: IDF-14413') def test_parlio(dut: Dut) -> None: dut.run_all_single_board_cases() + + +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'cache_safe', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_parlio_esp32c5(dut: Dut) -> None: + dut.run_all_single_board_cases() + + +@pytest.mark.generic +@pytest.mark.esp32c5_eco3 +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_parlio_esp32c5_eco3(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/esp_driver_rmt/test_apps/rmt/pytest_rmt.py b/components/esp_driver_rmt/test_apps/rmt/pytest_rmt.py index 1ef07f27e3..2d5686c658 100644 --- a/components/esp_driver_rmt/test_apps/rmt/pytest_rmt.py +++ b/components/esp_driver_rmt/test_apps/rmt/pytest_rmt.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut @@ -14,14 +14,39 @@ from pytest_embedded_idf.utils import idf_parametrize ], indirect=True, ) -@idf_parametrize( - 'target', ['esp32', 'esp32s2', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target'] -) +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target']) @pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 rev3 migration # TODO: IDF-14414') def test_rmt(dut: Dut) -> None: dut.run_all_single_board_cases() +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'cache_safe', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_rmt_esp32c5(dut: Dut) -> None: + dut.run_all_single_board_cases() + + +@pytest.mark.generic +@pytest.mark.esp32c5_eco3 +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_rmt_esp32c5_eco3(dut: Dut) -> None: + dut.run_all_single_board_cases() + + @pytest.mark.octal_psram @pytest.mark.parametrize( 'config', diff --git a/components/esp_driver_sdm/test_apps/sigma_delta/pytest_sigma_delta.py b/components/esp_driver_sdm/test_apps/sigma_delta/pytest_sigma_delta.py index 7f614064ab..c8fafe70fc 100644 --- a/components/esp_driver_sdm/test_apps/sigma_delta/pytest_sigma_delta.py +++ b/components/esp_driver_sdm/test_apps/sigma_delta/pytest_sigma_delta.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded_idf import IdfDut @@ -14,8 +14,23 @@ CONFIGS = [ @pytest.mark.parametrize('config', CONFIGS, indirect=True) @idf_parametrize( 'target', - ['esp32', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32h2', 'esp32p4'], + ['esp32', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32h2', 'esp32p4'], indirect=['target'], ) def test_sdm(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='sdm') + + +@pytest.mark.generic +@pytest.mark.parametrize('config', ['iram_safe'], indirect=True) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_sdm_esp32c5(dut: IdfDut) -> None: + dut.run_all_single_board_cases(group='sdm') + + +@pytest.mark.generic +@pytest.mark.esp32c5_eco3 +@pytest.mark.parametrize('config', ['release'], indirect=True) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_sdm_esp32c5_eco3(dut: IdfDut) -> None: + dut.run_all_single_board_cases(group='sdm') diff --git a/components/esp_driver_spi/test_apps/master/pytest_spi_master.py b/components/esp_driver_spi/test_apps/master/pytest_spi_master.py index 24b40d0dd9..f3e9beb454 100644 --- a/components/esp_driver_spi/test_apps/master/pytest_spi_master.py +++ b/components/esp_driver_spi/test_apps/master/pytest_spi_master.py @@ -1,7 +1,8 @@ -# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import pytest from pytest_embedded_idf.utils import idf_parametrize +from pytest_embedded_idf.utils import soc_filtered_targets @pytest.mark.generic @@ -13,7 +14,9 @@ from pytest_embedded_idf.utils import idf_parametrize ], indirect=True, ) -@idf_parametrize('target', ['supported_targets'], indirect=['target']) +@idf_parametrize( + 'target', soc_filtered_targets('SOC_GPSPI_SUPPORTED == 1 and IDF_TARGET not in ["esp32c5"]'), indirect=['target'] +) @pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 rev3 migration # TODO: IDF-14399') def test_master_single_dev(case_tester) -> None: # type: ignore for case in case_tester.test_menu: @@ -22,6 +25,39 @@ def test_master_single_dev(case_tester) -> None: # type: ignore case_tester.run_normal_case(case=case, reset=True) +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'freertos_flash', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_master_single_dev_esp32c5(case_tester) -> None: # type: ignore + for case in case_tester.test_menu: + if 'test_env' in case.attributes: + continue # If `test_env` is defined, should not run on generic runner + case_tester.run_normal_case(case=case, reset=True) + + +@pytest.mark.generic +@pytest.mark.esp32c5_eco3 +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_master_single_dev_esp32c5_eco3(case_tester) -> None: # type: ignore + for case in case_tester.test_menu: + if 'test_env' in case.attributes: + continue # If `test_env` is defined, should not run on generic runner + case_tester.run_normal_case(case=case, reset=True) + + # Job for test_env `external_flash` just for esp32 only @pytest.mark.flash_multi @pytest.mark.parametrize( diff --git a/components/esp_driver_spi/test_apps/slave/pytest_spi_slave.py b/components/esp_driver_spi/test_apps/slave/pytest_spi_slave.py index 90c6c17575..c85e7b1057 100644 --- a/components/esp_driver_spi/test_apps/slave/pytest_spi_slave.py +++ b/components/esp_driver_spi/test_apps/slave/pytest_spi_slave.py @@ -1,17 +1,35 @@ -# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import pytest from pytest_embedded_idf.utils import idf_parametrize +from pytest_embedded_idf.utils import soc_filtered_targets @pytest.mark.generic @pytest.mark.parametrize('config', ['release', 'iram_safe'], indirect=True) @pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 rev3 migration # TODO: IDF-14399') -@idf_parametrize('target', ['supported_targets'], indirect=['target']) +@idf_parametrize( + 'target', soc_filtered_targets('SOC_GPSPI_SUPPORTED == 1 and IDF_TARGET not in ["esp32c5"]'), indirect=['target'] +) def test_slave_single_dev(case_tester) -> None: # type: ignore case_tester.run_all_normal_cases(reset=True) +@pytest.mark.generic +@pytest.mark.parametrize('config', ['iram_safe'], indirect=True) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_slave_single_dev_esp32c5(case_tester) -> None: # type: ignore + case_tester.run_all_normal_cases(reset=True) + + +@pytest.mark.generic +@pytest.mark.esp32c5_eco3 +@pytest.mark.parametrize('config', ['release'], indirect=True) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_slave_single_dev_esp32c5_eco3(case_tester) -> None: # type: ignore + case_tester.run_all_normal_cases(reset=True) + + @pytest.mark.generic_multi_device @pytest.mark.parametrize('count, config', [(2, 'release'), (2, 'iram_safe')], indirect=True) @pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 rev3 migration # TODO: IDF-14399') diff --git a/components/esp_driver_spi/test_apps/slave_hd/pytest_spi_slave_hd.py b/components/esp_driver_spi/test_apps/slave_hd/pytest_spi_slave_hd.py index b19a86ab8a..b2332a18a2 100644 --- a/components/esp_driver_spi/test_apps/slave_hd/pytest_spi_slave_hd.py +++ b/components/esp_driver_spi/test_apps/slave_hd/pytest_spi_slave_hd.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import pytest from pytest_embedded_idf.utils import idf_parametrize @@ -11,13 +11,21 @@ from pytest_embedded_idf.utils import idf_parametrize @pytest.mark.temp_skip_ci(targets=['esp32p4', 'esp32c61'], reason='p4 rev3 migration # TODO: IDF-14399') @idf_parametrize( 'target', - ['esp32s2', 'esp32s3', 'esp32c2', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32c61', 'esp32h2', 'esp32p4'], + ['esp32s2', 'esp32s3', 'esp32c2', 'esp32c3', 'esp32c6', 'esp32c61', 'esp32h2', 'esp32p4'], indirect=['target'], ) def test_slave_hd_single_dev(case_tester) -> None: # type: ignore case_tester.run_all_normal_cases(reset=True, timeout=180) +@pytest.mark.generic +@pytest.mark.esp32c5_eco3 +@pytest.mark.parametrize('config', ['release'], indirect=True) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_slave_hd_single_dev_esp32c5_eco3(case_tester) -> None: # type: ignore + case_tester.run_all_normal_cases(reset=True, timeout=180) + + # if `test_env` not defined, will run on `generic_multi_device` by default @pytest.mark.generic_multi_device @pytest.mark.parametrize('count, config', [(2, 'release')], indirect=True) diff --git a/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py b/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py index f79a884efe..8a4e6d093d 100644 --- a/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py +++ b/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut @@ -16,13 +16,31 @@ from pytest_embedded_idf.utils import idf_parametrize ) @idf_parametrize( 'target', - ['esp32s2', 'esp32c3', 'esp32s3', 'esp32c2', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c5', 'esp32c61'], + ['esp32s2', 'esp32c3', 'esp32s3', 'esp32c2', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c61'], indirect=['target'], ) def test_temperature_sensor_driver(dut: Dut) -> None: dut.run_all_single_board_cases() +@pytest.mark.generic +@pytest.mark.esp32c5_eco3 +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +@idf_parametrize( + 'target', + ['esp32c5'], + indirect=['target'], +) +def test_temperature_sensor_driver_esp32c5_eco3(dut: Dut) -> None: + dut.run_all_single_board_cases() + + @pytest.mark.generic @pytest.mark.parametrize( 'config', diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_random.c b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_random.c index 81f7707718..bd9ed24fd5 100644 --- a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_random.c +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_random.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py index c874e8f204..beca94dde8 100644 --- a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut diff --git a/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py b/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py index 3d0d92f227..ecae9e65f7 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py +++ b/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py @@ -1,16 +1,17 @@ -# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut from pytest_embedded_idf.utils import idf_parametrize +from pytest_embedded_idf.utils import soc_filtered_targets @pytest.mark.generic @idf_parametrize( 'config,target', [ - ('default', 'supported_targets'), - ('pd_vddsdio', 'supported_targets'), + *(('default', target) for target in soc_filtered_targets('IDF_TARGET not in ["esp32c5"]')), + *(('pd_vddsdio', target) for target in soc_filtered_targets('IDF_TARGET not in ["esp32c5"]')), ('psram', 'esp32'), ('psram', 'esp32p4'), ('psram', 'esp32s2'), @@ -25,6 +26,35 @@ def test_esp_system(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=60) +@pytest.mark.generic +@idf_parametrize( + 'config', + [ + 'pd_vddsdio', + 'psram', + ], + indirect=['config'], +) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_esp_system_esp32c5(dut: Dut) -> None: + dut.run_all_single_board_cases(timeout=60) + + +@pytest.mark.generic +@pytest.mark.esp32c5_eco3 +@idf_parametrize( + 'config', + [ + 'default', + 'psram_with_pd_top', + ], + indirect=['config'], +) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) +def test_esp_system_esp32c5_eco3(dut: Dut) -> None: + dut.run_all_single_board_cases(timeout=60) + + @pytest.mark.generic @idf_parametrize('config', ['default'], indirect=['config']) @idf_parametrize('target', ['supported_targets'], indirect=['target']) diff --git a/tools/ci/idf_pytest/constants.py b/tools/ci/idf_pytest/constants.py index 9e1d354dff..17f107258e 100644 --- a/tools/ci/idf_pytest/constants.py +++ b/tools/ci/idf_pytest/constants.py @@ -150,6 +150,7 @@ ENV_MARKERS = { 'esp32c2eco4': 'esp32c2 major version(v2.0) chips', 'recovery_bootloader': 'Runner with recovery bootloader offset set in eFuse', 'esp32p4_eco4': 'Runner with esp32p4 eco4 connected', + 'esp32c5_eco3': 'Runner with esp32c5 eco3 connected', } # by default the timeout is 1h, for some special cases we need to extend it From 2ef26713119420368cfd09c4b1aaca22f61f2a12 Mon Sep 17 00:00:00 2001 From: wanglei Date: Thu, 20 Nov 2025 16:52:47 +0800 Subject: [PATCH 216/226] feature(esp_rom): add esp32c5 eco3 rom ld --- components/esp_rom/CMakeLists.txt | 3 + .../esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld | 306 ++++++++++++++++++ 2 files changed, 309 insertions(+) create mode 100644 components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 52f93375e9..00833ec22f 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -322,6 +322,9 @@ else() # Regular app build rom_linker_script("coexist") rom_linker_script("net80211") rom_linker_script("pp") + if(CONFIG_ESP32C5_REV_MIN_FULL GREATER_EQUAL 102) + rom_linker_script("eco3") + endif() elseif(target STREQUAL "esp32c61") # esp32c61.rom.api.ld has been split to several lds by components. # esp32c61.rom.api.ld is still reserved to map the APIs diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld new file mode 100644 index 0000000000..0e5cf6895a --- /dev/null +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld @@ -0,0 +1,306 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* +ESP32C5 ECO3 ROM address table +Version 3 API's imported from the ROM +*/ + +coex_core_timer_idx_get = 0x40000aec; +coex_status_get = 0x40000b0c; +ets_delay_us = 0x4000003c; +Cache_Set_IDROM_MMU_Size = 0x400006c4; + +ieee80211_encap_esfbuf = 0x40000b60; +ieee80211_set_tx_desc = 0x40000b70; +sta_input = 0x40000bd4; +sta_rx_eapol = 0x40000bd8; +sta_reset_beacon_timeout = 0x40000bdc; + +phy_rate_to_index = 0x400010e8; +phy_get_target_pwr = 0x400010ec; +phy_get_max_pwr = 0x400010f0; +phy_get_pwr_index = 0x400010f4; +phy_get_rc_dout = 0x400010f8; +phy_rc_cal = 0x400010fc; +phy_abs_temp = 0x40001100; +phy_set_chan_interp = 0x40001104; +phy_loop_clk_en = 0x40001108; +phy_get_data_sat = 0x4000110c; +phy_byte_to_word = 0x40001110; +phy_bb_bss_cbw40 = 0x40001118; +phy_set_chan_reg = 0x4000111c; +phy_i2c_master_reset = 0x40001120; +phy_chan14_mic_enable = 0x40001124; +phy_chan14_mic_cfg = 0x40001128; +phy_set_most_tpw = 0x4000112c; +phy_get_most_tpw = 0x40001130; +phy_tx_state_out = 0x40001134; +phy_ant_dft_cfg = 0x40001138; +phy_ant_wifitx_cfg = 0x4000113c; +phy_ant_wifirx_cfg = 0x40001140; +phy_ant_bttx_cfg = 0x40001144; +phy_ant_btrx_cfg = 0x40001148; +phy_chan_dump_cfg = 0x4000114c; +phy_chan_dump_cfg_752 = 0x40001150; +phy_enable_low_rate = 0x40001154; +phy_disable_low_rate = 0x40001158; +phy_is_low_rate_enabled = 0x4000115c; +phy_dig_reg_backup = 0x40001160; +phy_chan_filt_set = 0x40001164; +phy_rx11blr_cfg = 0x40001168; +phy_set_cca = 0x4000116c; +phy_set_rx_sense = 0x40001170; +phy_freq_module_resetn = 0x40001174; +phy_freq_chan_en_sw = 0x40001178; +phy_write_chan_freq = 0x4000117c; +phy_get_freq_mem_param = 0x40001180; +phy_get_freq_mem_addr = 0x40001184; +phy_wr_freq_mem = 0x40001188; +phy_read_rf_freq_mem = 0x4000118c; +phy_freq_i2c_mem_write = 0x40001190; +phy_freq_num_get_data = 0x40001194; +phy_freq_i2c_num_addr = 0x40001198; +phy_freq_i2c_write_set = 0x4000119c; +phy_en_hw_set_freq = 0x400011a4; +phy_dis_hw_set_freq = 0x400011a8; +phy_wait_freq_set_busy = 0x400011ac; +phy_i2c_enter_critical_ = 0x400011b0; +phy_i2c_exit_critical_ = 0x400011b4; +phy_i2c_clk_sel = 0x400011b8; +phy_get_i2c_read_mask_ = 0x400011bc; +phy_get_i2c_mst0_mask = 0x400011c0; +phy_get_i2c_hostid_ = 0x400011c4; +phy_chip_i2c_readReg_org = 0x400011c8; +phy_chip_i2c_readReg = 0x400011cc; +phy_i2c_paral_set_mst0 = 0x400011d0; +phy_i2c_paral_set_read = 0x400011d4; +phy_i2c_paral_read = 0x400011d8; +phy_i2c_paral_write = 0x400011dc; +phy_i2c_paral_write_num = 0x400011e0; +phy_i2c_paral_write_mask = 0x400011e4; +phy_i2c_readReg = 0x400011e8; +phy_chip_i2c_writeReg = 0x400011ec; +phy_i2c_writeReg = 0x400011f0; +phy_i2c_readReg_Mask = 0x400011f4; +phy_set_txcap_reg = 0x400011f8; +phy_i2c_sar2_init_code = 0x400011fc; +phy_i2c_pkdet_set = 0x40001200; +phy_filter_dcap_set = 0x40001204; +phy_i2c_rc_cal_set = 0x40001208; +phy_ckgen_5g_cal = 0x4000120c; +phy_ckgen_2g_cal = 0x40001210; +phy_adc_rate_set = 0x40001214; +phy_dac_rate_set = 0x40001218; +phy_encode_i2c_master = 0x4000121c; +phy_i2c_master_fill = 0x40001220; +phy_band_reg = 0x40001224; +phy_open_fe_bb_clk = 0x40001228; +phy_get_mac_addr = 0x4000122c; +phy_set_mac_data = 0x40001230; +phy_rfcal_data_sub = 0x40001234; +phy_rf_cal_data_recovery = 0x40001238; +phy_rf_cal_data_backup = 0x4000123c; +phy_rfcal_data_check = 0x40001240; +phy_pbus_force_mode = 0x40001244; +phy_pbus_force_test = 0x4000124c; +phy_pbus_rd = 0x40001250; +phy_pbus_debugmode = 0x40001254; +phy_pbus_workmode = 0x40001258; +phy_pbus_clear_reg = 0x4000125c; +phy_pbus_set_rxgain = 0x40001260; +phy_pbus_set_dco = 0x40001264; +phy_set_loopback_gain = 0x40001268; +phy_txcal_debuge_mode_ = 0x4000126c; +phy_txcal_work_mode = 0x40001270; +phy_write_pbus_mem = 0x40001274; +phy_set_pbus_mem_2g = 0x40001278; +phy_set_pbus_mem_5g = 0x4000127c; +phy_pbus_reg_store = 0x40001280; +phy_set_pbus_mem = 0x40001284; +phy_get_rx_pbus_freq = 0x40001288; +phy_set_rx_pbus_freq = 0x4000128c; +phy_pbus_xpd_iq_path = 0x40001290; +phy_pbus_set_rftx1_5g = 0x40001294; +phy_pwdet_reg_init = 0x40001298; +phy_pwdet_sar2_init = 0x4000129c; +phy_en_pwdet = 0x400012a0; +phy_get_sar_sig_ref = 0x400012a4; +phy_pwdet_tone_start = 0x400012a8; +phy_get_tone_sar_dout = 0x400012ac; +phy_get_fm_sar_dout = 0x400012b0; +phy_txtone_linear_pwr = 0x400012b4; +phy_linear_to_db = 0x400012b8; +phy_get_power_db = 0x400012bc; +phy_meas_tone_pwr_db = 0x400012c0; +phy_pwdet_wait_idle = 0x400012c4; +phy_pkdet_vol_start = 0x400012c8; +phy_read_sar_dout = 0x400012cc; +phy_read_sar2_code = 0x400012d0; +phy_get_sar2_vol = 0x400012d4; +phy_get_pkdet_data = 0x400012d8; +phy_rx_pkdet_dc_cal = 0x400012dc; +phy_disable_agc = 0x400012e0; +phy_enable_agc = 0x400012e4; +phy_disable_cca = 0x400012e8; +phy_enable_cca = 0x400012ec; +phy_write_gain_mem = 0x400012f0; +phy_bb_bss_cbw40_dig = 0x400012f4; +phy_tx_paon_set = 0x400012f8; +phy_i2cmst_reg_init = 0x400012fc; +phy_bt_gain_offset = 0x40001300; +phy_fe_reg_init = 0x40001304; +phy_mac_enable_bb = 0x40001308; +phy_bb_wdg_cfg = 0x4000130c; +phy_fe_txrx_reset = 0x40001310; +phy_set_rx_comp_ = 0x40001314; +phy_agc_max_gain_set = 0x40001318; +phy_agc_reg_init = 0x4000131c; +phy_bb_reg_init = 0x40001320; +phy_open_i2c_xpd = 0x40001324; +phy_force_txrx_off = 0x40001328; +phy_txiq_set_reg = 0x4000132c; +phy_rxiq_set_reg = 0x40001330; +phy_rx_gain_force = 0x40001334; +phy_set_txclk_en = 0x40001338; +phy_set_rxclk_en = 0x4000133c; +phy_start_tx_tone_step = 0x40001340; +phy_stop_tx_tone = 0x40001344; +phy_bb_wdg_test_en = 0x40001348; +phy_noise_floor_auto_set = 0x4000134c; +phy_read_hw_noisefloor = 0x40001350; +phy_iq_corr_enable = 0x40001354; +phy_wifi_agc_sat_gain = 0x40001358; +phy_bbpll_cal = 0x4000135c; +phy_ant_init = 0x40001360; +phy_wifi_fbw_sel = 0x40001364; +phy_bt_filter_reg = 0x40001368; +phy_rx_sense_set = 0x4000136c; +phy_tx_state_set = 0x40001370; +phy_close_pa = 0x40001374; +phy_freq_correct = 0x40001378; +phy_set_pbus_reg = 0x4000137c; +phy_wifi_rifs_mode_en = 0x40001380; +phy_rfagc_disable = 0x40001384; +phy_pkdadc_set = 0x40001388; +phy_nrx_freq_set = 0x4000138c; +phy_fe_adc_on = 0x40001390; +phy_force_pwr_index = 0x40001394; +phy_fft_scale_force = 0x40001398; +phy_force_rx_gain = 0x4000139c; +phy_wifi_enable_set = 0x400013a0; +phy_bb_cbw_chan_cfg = 0x400013a4; +phy_vht_support = 0x400013a8; +phy_csidump_force_lltf_cfg = 0x400013ac; +phy_hemu_ru26_good_res = 0x400013b0; +phy_bb_cfo_cfg = 0x400013b4; +phy_freq_band_reg_set = 0x400013b8; +phy_set_bb_wdg = 0x400013bc; +phy_sifs_reg_init = 0x400013c0; +phy_bbtx_outfilter = 0x400013c4; +phy_bb_wdt_rst_enable = 0x400013c8; +phy_bb_wdt_int_enable = 0x400013cc; +phy_bb_wdt_timeout_clear = 0x400013d0; +phy_bb_wdt_get_status = 0x400013d4; +phy_freq_to_chan = 0x400013d8; +phy_chan_to_freq = 0x400013dc; +phy_freq_to_index = 0x400013e0; +phy_iq_est_enable = 0x400013e4; +phy_iq_est_disable = 0x400013e8; +phy_dc_iq_est = 0x400013ec; +phy_set_cal_rxdc = 0x400013f0; +phy_rxiq_get_mis = 0x400013f4; +phy_rxiq_cover_mg_mp = 0x400013f8; +phy_rfcal_rxiq = 0x400013fc; +phy_get_rfcal_rxiq_data = 0x40001400; +phy_get_dco_comp = 0x40001404; +phy_pbus_rx_dco_cal = 0x40001408; +phy_rxdc_est_min = 0x4000140c; +phy_rx_dco_cal_1step = 0x40001410; +phy_set_lb_txiq = 0x40001414; +phy_rxiq_opt = 0x40001418; +phy_bb_gain_index = 0x40001430; +phy_rfrx_gain_index = 0x40001434; +phy_gen_rx_gain_table = 0x40001438; +phy_get_rxbb_dc = 0x4000143c; +phy_wr_rx_gain_mem = 0x40001440; +phy_set_tsens_power_ = 0x40001444; +phy_get_tsens_value_ = 0x40001448; +phy_tsens_read_init = 0x4000144c; +phy_code_to_temp = 0x40001450; +phy_tsens_dac_to_index = 0x40001454; +phy_tsens_dac_cal = 0x40001458; +phy_tsens_code_read = 0x4000145c; +phy_tsens_temp_read = 0x40001460; +phy_tsens_temp_read_local = 0x40001464; +phy_temp_to_power_ = 0x40001468; +phy_bt_txdc_cal = 0x4000146c; +phy_bt_txiq_cal = 0x40001470; +phy_txdc_cal = 0x40001474; +phy_txdc_cal_pwdet = 0x40001478; +phy_txiq_get_mis_pwr = 0x4000147c; +phy_txiq_cover = 0x40001480; +phy_rfcal_txiq = 0x40001484; +phy_get_power_atten = 0x40001488; +phy_pwdet_ref_code = 0x4000148c; +phy_pwdet_code_cal = 0x40001490; +phy_rfcal_txcap = 0x40001494; +phy_txcap_setting = 0x40001498; +phy_get_cal_chan = 0x4000149c; +phy_get_chan_cal_index = 0x400014a0; +phy_get_chan_cap = 0x400014a4; +phy_freq_to_mbgain = 0x400014a8; +phy_rfcal_pwrctrl = 0x400014ac; +phy_get_pwdet_offset_ = 0x400014b0; +phy_tx_pwctrl_init_cal = 0x400014b4; +phy_tx_pwctrl_init = 0x400014b8; +phy_bt_tx_pwctrl_init = 0x400014bc; +phy_txbbgain_to_index = 0x400014c0; +phy_index_to_txbbgain = 0x400014c4; +phy_bt_get_tx_gain = 0x400014c8; +phy_dig_gain_check = 0x400014cc; +phy_wifi_get_tx_gain = 0x400014d0; +phy_wifi_11g_rate_chg = 0x400014d4; +phy_set_tx_gain_mem = 0x400014dc; +phy_get_rate_fcc_index = 0x400014e0; +phy_get_chan_target_power = 0x400014e4; +phy_get_tx_gain_value = 0x400014e8; +phy_wifi_get_target_power = 0x400014ec; +phy_wifi_get_tx_tab_ = 0x400014f0; +phy_wifi_set_tx_gain = 0x400014f4; +phy_bt_get_tx_tab_ = 0x400014f8; +phy_bt_set_tx_gain = 0x400014fc; +phy_bt_tx_gain_init = 0x40001500; + +hal_mac_tx_set_ppdu = 0x40000c0c; +ic_mac_deinit = 0x40000c78; +ic_mac_init = 0x40000c7c; +lmacTxFrame = 0x40000cd0; +lmacDisableTransmit = 0x40000cd4; +pm_check_state = 0x40000d48; +pm_set_beacon_filter = 0x40000d6c; +pm_is_in_wifi_slice_threshold = 0x40000d70; +pm_keep_alive = 0x40000d78; +pm_process_tim = 0x40000da8; +pm_tbtt_process = 0x40000dbc; +pm_tx_data_process = 0x40000dd8; +pm_twt_process = 0x40000de8; +pm_mac_try_enable_modem_state = 0x40000dfc; +pm_update_next_tbtt = 0x40000e04; +pm_clear_wakeup_signal = 0x40000e0c; +pm_mac_disable_tsf_tbtt_soc_wakeup = 0x40000e10; +pm_mac_disable_tsf_tbtt_modem_wakeup = 0x40000e14; +pm_mac_enable_tsf_tbtt_soc_wakeup = 0x40000e18; +pm_mac_enable_tsf_tbtt_modem_wakeup = 0x40000e1c; +pm_mac_modem_params_rt_update = 0x40000e20; +ppMapTxQueue = 0x40000e64; +ppProcTxSecFrame = 0x40000e68; +ppProcessTxQ = 0x40000e70; +ppRxPkt = 0x40000e8c; +ppRxProtoProc = 0x40000e90; +ppProcessLifeTime = 0x40000ee4; +rcGetSched = 0x40000f40; +wDev_ProcessRxSucData = 0x40000fe0; +esp_test_tx_process_complete = 0x40001030; From 22fbe9684f08946b4cefb790ed729791204e2c13 Mon Sep 17 00:00:00 2001 From: wanglei Date: Thu, 20 Nov 2025 20:36:09 +0800 Subject: [PATCH 217/226] fix(ld): add missing eco3 newly added rom functions --- .../esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld | 101 +++++++++++++++++- 1 file changed, 97 insertions(+), 4 deletions(-) diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld index 0e5cf6895a..d2d7151ec4 100644 --- a/components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld @@ -3,10 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ -/* -ESP32C5 ECO3 ROM address table -Version 3 API's imported from the ROM -*/ +/*************************************** + eco3 fixed + ***************************************/ coex_core_timer_idx_get = 0x40000aec; coex_status_get = 0x40000b0c; @@ -304,3 +303,97 @@ ppProcessLifeTime = 0x40000ee4; rcGetSched = 0x40000f40; wDev_ProcessRxSucData = 0x40000fe0; esp_test_tx_process_complete = 0x40001030; + +/*************************************** + eco3 newly added + ***************************************/ + +/* Data (.data, .bss, .rodata) */ +s_offchan_tx_progress_in_ptr = 0x4085fc5c; +s_phy_get_max_pwr_new_ptr = 0x4085fc58; + +/* Functions */ +phy_get_index_pwr = 0x400015dc; +phy_get_pwr_by_rate = 0x400015e0; +phy_set_adc_rand = 0x400015e4; +phy_get_interp_data = 0x400015e8; +phy_pbus_print = 0x400015ec; +phy_internal_delay = 0x400015f0; +phy_ftm_comp = 0x400015f4; +phy_11p_set = 0x400015f8; +phy_freq_mem_backup = 0x400015fc; +phy_get_cca = 0x40001600; +phy_set_cca_cnt = 0x40001604; +phy_get_cca_cnt = 0x40001608; +phy_get_noise_floor = 0x4000160c; +phy_get_rssi = 0x40001610; +phy_rxevm_reset_mem = 0x40001614; +phy_rxevm_init_cfg = 0x40001618; +phy_freq_reg_init = 0x4000161c; +phy_freq_mem_data = 0x40001620; +phy_set_freq_sw_start = 0x40001624; +phy_freq_mem_change_5g_ = 0x40001628; +phy_i2c_bbpll_set = 0x4000162c; +phy_i2c_master_mem_txcap = 0x40001630; +phy_get_xtal_code = 0x40001634; +phy_get_dcap_degen = 0x40001638; +phy_get_vco_init = 0x4000163c; +phy_get_tcode = 0x40001640; +phy_get_tm7 = 0x40001644; +phy_get_dreg_1p1 = 0x40001648; +phy_set_freq_i2c_ = 0x4000164c; +phy_tatget_pwr_band = 0x40001650; +phy_band_i2c_set = 0x40001654; +phy_band_change = 0x40001658; +phy_close_fe_bb_clk = 0x4000165c; +phy_reg_init = 0x40001660; +phy_xpd_rf = 0x40001664; +phy_pbus_rd_addr = 0x40001668; +phy_rx_loop_cap_set = 0x4000166c; +phy_pbus_xpd_dpd_path = 0x40001670; +phy_rx_filter_mode = 0x40001674; +phy_dac_scale_set = 0x40001678; +phy_bbpll_recal = 0x4000167c; +bb_agc_reg_update = 0x40001680; +phy_bb_dcmem_clr = 0x40001684; +phy_txgain_comp_pacfg = 0x40001688; +phy_i2c_txrate_init = 0x4000168c; +phy_iq_swap_set = 0x40001690; +phy_bb_fsm_rst = 0x40001694; +phy_lltf_mask_en = 0x40001698; +phy_magtrk_scale_set = 0x4000169c; +phy_cfg_tx_magtrk = 0x400016a0; +phy_tx_magtrk_init = 0x400016a4; +phy_restart_cal = 0x400016a8; +phy_reset_ckgen = 0x400016ac; +phy_write_rfpll_sdm = 0x400016b0; +phy_rfpll_set_freq = 0x400016b4; +phy_set_rf_freq_offset = 0x400016b8; +phy_i2c_sdm_en = 0x400016bc; +phy_freq_cal_test = 0x400016c0; +phy_set_rfpll_freq = 0x400016c4; +phy_set_channel_rfpll_freq_ = 0x400016c8; +phy_read_pll_cap = 0x400016cc; +phy_set_chan_misc = 0x400016d0; +phy_chip_set_chan_offset = 0x400016d4; +phy_chip_set_chan_ana = 0x400016d8; +phy_freq_set_reg = 0x400016dc; +phy_rfrx_rxdc_cal = 0x400016e0; +phy_linear_to_db_64bits = 0x400016e4; +phy_get_iq_est_snr = 0x400016e8; +phy_get_loop_snr = 0x400016ec; +phy_get_rx_sig_pwr = 0x400016f0; +phy_adc_rate_cal_rxdc = 0x400016f4; +phy_set_iqcal_ckgen_code = 0x400016f8; +phy_dpd_rxdc_cal = 0x400016fc; +phy_txpwr_correct = 0x40001700; +phy_txpwr_cal_track = 0x40001704; +phy_bt_track_tx_power = 0x40001708; +phy_wifi_track_tx_power = 0x4000170c; +phy_txpwr_track_slow = 0x40001710; +phy_set_tsens_pwr = 0x40001714; +phy_bt_tx_gain_set = 0x40001718; +phy_get_chan_power_offset = 0x4000171c; +phy_chan_vs_index = 0x40001720; +phy_get_txiq_dcode_offset_ = 0x40001724; +phy_get_txiq_set = 0x40001728; From 7fca8a9c685557ff50fd5c278cfe1ea6f8ce907c Mon Sep 17 00:00:00 2001 From: wanglei Date: Mon, 24 Nov 2025 19:00:29 +0800 Subject: [PATCH 218/226] test(system): add esp32c5 eco3 build test --- tools/test_apps/system/build_test/sdkconfig.ci.esp32c5_rev102 | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tools/test_apps/system/build_test/sdkconfig.ci.esp32c5_rev102 diff --git a/tools/test_apps/system/build_test/sdkconfig.ci.esp32c5_rev102 b/tools/test_apps/system/build_test/sdkconfig.ci.esp32c5_rev102 new file mode 100644 index 0000000000..8aa5053fc7 --- /dev/null +++ b/tools/test_apps/system/build_test/sdkconfig.ci.esp32c5_rev102 @@ -0,0 +1,2 @@ +CONFIG_IDF_TARGET="esp32c5" +CONFIG_ESP32C5_REV_MIN_102=y From f810d59304afaf860ef519025d487b45daf9fea8 Mon Sep 17 00:00:00 2001 From: yinqingzhao Date: Tue, 30 Dec 2025 14:11:02 +0800 Subject: [PATCH 219/226] feat(wifi): update esp32c5 eco3 ld files --- .../esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld | 86 ++++++++++--------- .../esp32c5/ld/esp32c5.rom.net80211.ld | 4 +- .../esp_rom/esp32c5/ld/esp32c5.rom.pp.ld | 8 +- components/esp_wifi/src/wifi_init.c | 9 ++ 4 files changed, 61 insertions(+), 46 deletions(-) diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld index d2d7151ec4..f2af6037dd 100644 --- a/components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,15 +8,52 @@ ***************************************/ coex_core_timer_idx_get = 0x40000aec; -coex_status_get = 0x40000b0c; +//coex_status_get = 0x40000b0c; ets_delay_us = 0x4000003c; Cache_Set_IDROM_MMU_Size = 0x400006c4; -ieee80211_encap_esfbuf = 0x40000b60; -ieee80211_set_tx_desc = 0x40000b70; -sta_input = 0x40000bd4; -sta_rx_eapol = 0x40000bd8; -sta_reset_beacon_timeout = 0x40000bdc; +//ieee80211_encap_esfbuf = 0x40000b60; +//ieee80211_set_tx_desc = 0x40000b70; +//sta_input = 0x40000bd4; +//sta_rx_eapol = 0x40000bd8; +//sta_reset_beacon_timeout = 0x40000bdc; + +hal_mac_tx_set_ppdu = 0x40000c0c; +ic_mac_deinit = 0x40000c78; +ic_mac_init = 0x40000c7c; +lmacTxFrame = 0x40000cd0; +lmacDisableTransmit = 0x40000cd4; +pm_check_state = 0x40000d48; +//pm_set_beacon_filter = 0x40000d6c; +//pm_is_in_wifi_slice_threshold = 0x40000d70; +pm_keep_alive = 0x40000d78; +pm_process_tim = 0x40000da8; +//pm_tbtt_process = 0x40000dbc; +//pm_tx_data_process = 0x40000dd8; +pm_twt_process = 0x40000de8; +//pm_mac_try_enable_modem_state = 0x40000dfc; +//pm_update_next_tbtt = 0x40000e04; +pm_clear_wakeup_signal = 0x40000e0c; +pm_mac_disable_tsf_tbtt_soc_wakeup = 0x40000e10; +//pm_mac_disable_tsf_tbtt_modem_wakeup = 0x40000e14; +pm_mac_enable_tsf_tbtt_soc_wakeup = 0x40000e18; +//pm_mac_enable_tsf_tbtt_modem_wakeup = 0x40000e1c; +//pm_mac_modem_params_rt_update = 0x40000e20; +ppMapTxQueue = 0x40000e64; +//ppProcTxSecFrame = 0x40000e68; +//ppProcessTxQ = 0x40000e70; +ppRxPkt = 0x40000e8c; +ppRxProtoProc = 0x40000e90; +//ppProcessLifeTime = 0x40000ee4; +//rcGetSched = 0x40000f40; +//wDev_ProcessRxSucData = 0x40000fe0; +esp_test_tx_process_complete = 0x40001030; +pm_get_tbtt_count = 0x4000151c; +pm_enable_max_idle_timer = 0x400015b8; +//pm_beacon_offset_check = 0x400015cc; +pm_beacon_offset_get_average = 0x400015d0; +pm_beacon_offset_get_expect = 0x400015d4; +pm_beacon_offset_get_params = 0x400015d8; phy_rate_to_index = 0x400010e8; phy_get_target_pwr = 0x400010ec; @@ -42,7 +79,7 @@ phy_ant_wifitx_cfg = 0x4000113c; phy_ant_wifirx_cfg = 0x40001140; phy_ant_bttx_cfg = 0x40001144; phy_ant_btrx_cfg = 0x40001148; -phy_chan_dump_cfg = 0x4000114c; +//phy_chan_dump_cfg = 0x4000114c; phy_chan_dump_cfg_752 = 0x40001150; phy_enable_low_rate = 0x40001154; phy_disable_low_rate = 0x40001158; @@ -273,37 +310,6 @@ phy_bt_get_tx_tab_ = 0x400014f8; phy_bt_set_tx_gain = 0x400014fc; phy_bt_tx_gain_init = 0x40001500; -hal_mac_tx_set_ppdu = 0x40000c0c; -ic_mac_deinit = 0x40000c78; -ic_mac_init = 0x40000c7c; -lmacTxFrame = 0x40000cd0; -lmacDisableTransmit = 0x40000cd4; -pm_check_state = 0x40000d48; -pm_set_beacon_filter = 0x40000d6c; -pm_is_in_wifi_slice_threshold = 0x40000d70; -pm_keep_alive = 0x40000d78; -pm_process_tim = 0x40000da8; -pm_tbtt_process = 0x40000dbc; -pm_tx_data_process = 0x40000dd8; -pm_twt_process = 0x40000de8; -pm_mac_try_enable_modem_state = 0x40000dfc; -pm_update_next_tbtt = 0x40000e04; -pm_clear_wakeup_signal = 0x40000e0c; -pm_mac_disable_tsf_tbtt_soc_wakeup = 0x40000e10; -pm_mac_disable_tsf_tbtt_modem_wakeup = 0x40000e14; -pm_mac_enable_tsf_tbtt_soc_wakeup = 0x40000e18; -pm_mac_enable_tsf_tbtt_modem_wakeup = 0x40000e1c; -pm_mac_modem_params_rt_update = 0x40000e20; -ppMapTxQueue = 0x40000e64; -ppProcTxSecFrame = 0x40000e68; -ppProcessTxQ = 0x40000e70; -ppRxPkt = 0x40000e8c; -ppRxProtoProc = 0x40000e90; -ppProcessLifeTime = 0x40000ee4; -rcGetSched = 0x40000f40; -wDev_ProcessRxSucData = 0x40000fe0; -esp_test_tx_process_complete = 0x40001030; - /*************************************** eco3 newly added ***************************************/ @@ -374,7 +380,7 @@ phy_freq_cal_test = 0x400016c0; phy_set_rfpll_freq = 0x400016c4; phy_set_channel_rfpll_freq_ = 0x400016c8; phy_read_pll_cap = 0x400016cc; -phy_set_chan_misc = 0x400016d0; +//phy_set_chan_misc = 0x400016d0; phy_chip_set_chan_offset = 0x400016d4; phy_chip_set_chan_ana = 0x400016d8; phy_freq_set_reg = 0x400016dc; diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.net80211.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.net80211.ld index b83061f0c5..59cea29841 100644 --- a/components/esp_rom/esp32c5/ld/esp32c5.rom.net80211.ld +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.net80211.ld @@ -32,7 +32,7 @@ ic_ebuf_recycle_rx = 0x40000b40; ic_ebuf_recycle_tx = 0x40000b44; ic_reset_rx_ba = 0x40000b48; ic_ebuf_alloc = 0x40000b4c; -ic_reset_extra_softap_rx_ba = 0x40000b50; +//ic_reset_extra_softap_rx_ba = 0x40000b50; ieee80211_align_eb = 0x40000b54; ieee80211_ampdu_reorder = 0x40000b58; ieee80211_ampdu_start_age_timer = 0x40000b5c; @@ -68,7 +68,7 @@ wifi_is_started = 0x40000bd0; /*sta_input = 0x40000bd4;*/ //sta_rx_eapol = 0x40000bd8; //sta_reset_beacon_timeout = 0x40000bdc; -sta_get_beacon_timeout = 0x40000be0; +//sta_get_beacon_timeout = 0x40000be0; ampdu_process_multicast_address_qos_frame = 0x40000be4; /* Data (.data, .bss, .rodata) */ net80211_funcs = 0x4085ffac; diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.pp.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.pp.ld index 53079241dd..64e04af8d7 100644 --- a/components/esp_rom/esp32c5/ld/esp32c5.rom.pp.ld +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.pp.ld @@ -117,7 +117,7 @@ pm_local_tsf_process = 0x40000d68; /*pm_is_in_wifi_slice_threshold = 0x40000d70;*/ pm_is_waked = 0x40000d74; /*pm_keep_alive = 0x40000d78;*/ -pm_on_beacon_rx = 0x40000d7c; +//pm_on_beacon_rx = 0x40000d7c; pm_on_data_rx = 0x40000d80; pm_on_data_tx = 0x40000d84; pm_on_tbtt = 0x40000d88; @@ -127,9 +127,9 @@ pm_on_isr_set_twt_target = 0x40000d94; pm_on_isr_twt_wake = 0x40000d98; pm_on_tsf_timer = 0x40000d9c; pm_on_twt_force_tx = 0x40000da0; -pm_parse_beacon = 0x40000da4; +//pm_parse_beacon = 0x40000da4; /*pm_process_tim = 0x40000da8;*/ -pm_rx_beacon_process = 0x40000dac; +//pm_rx_beacon_process = 0x40000dac; pm_rx_data_process = 0x40000db0; pm_sleep = 0x40000db4; pm_sleep_for = 0x40000db8; @@ -204,7 +204,7 @@ ppProcTxDone = 0x40000ec8; ppMapWaitTxq = 0x40000ecc; ppProcessWaitingQueue = 0x40000ed0; ppDisableQueue = 0x40000ed4; -ppCalVHTDeliNum = 0x40000ed8; +//ppCalVHTDeliNum = 0x40000ed8; ppCalTxVHTSMPDULength = 0x40000edc; ppCheckTxRTS = 0x40000ee0; /*ppProcessLifeTime = 0x40000ee4;*/ diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index ea050fe0ab..3aeec4c0fe 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -709,6 +709,15 @@ void nan_ndp_resp_timeout_process(void *p) } #endif /* CONFIG_ESP_WIFI_NAN_ENABLE */ +#if CONFIG_IDF_TARGET_ESP32C5 +#if CONFIG_ESP32C5_REV_MIN_FULL <= 100 +void esp32c5_eco3_rom_ptr_init(void) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ +} +#endif +#endif + #if CONFIG_IDF_TARGET_ESP32C2 #if CONFIG_ESP32C2_REV_MIN_FULL < 200 void esp32c2_eco4_rom_ptr_init(void) From 877b9a171a8e81d9b76ea5280a7c31179d20d3d6 Mon Sep 17 00:00:00 2001 From: yinqingzhao Date: Tue, 30 Dec 2025 15:10:57 +0800 Subject: [PATCH 220/226] feat(rom): add esp32c61 eco4 ld files --- components/esp_rom/CMakeLists.txt | 4 +- .../esp_rom/esp32c61/ld/esp32c61.rom.eco4.ld | 369 ++++++++++++++++++ 2 files changed, 372 insertions(+), 1 deletion(-) create mode 100644 components/esp_rom/esp32c61/ld/esp32c61.rom.eco4.ld diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 00833ec22f..9be2ca49b7 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -332,9 +332,11 @@ else() # Regular app build rom_linker_script("coexist") rom_linker_script("net80211") rom_linker_script("pp") + if(CONFIG_ESP32C61_REV_MIN_FULL GREATER_EQUAL 101) + rom_linker_script("eco4") + endif() endif() - if(CONFIG_ESP_ROM_HAS_NEWLIB AND NOT target STREQUAL "esp32" AND NOT target STREQUAL "esp32s2") # ESP32 and S2 are a bit different, keep them as special cases in the target specific include section if(CONFIG_ESP32P4_REV_MIN_300) # TODO: IDF-13410 diff --git a/components/esp_rom/esp32c61/ld/esp32c61.rom.eco4.ld b/components/esp_rom/esp32c61/ld/esp32c61.rom.eco4.ld new file mode 100644 index 0000000000..64e4b6ade8 --- /dev/null +++ b/components/esp_rom/esp32c61/ld/esp32c61.rom.eco4.ld @@ -0,0 +1,369 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/*************************************** + eco4 fixed + ***************************************/ + +coex_core_timer_idx_get = 0x40000a54; +coex_status_get = 0x40000a74; +ieee80211_encap_esfbuf = 0x40000ac8; +ieee80211_set_tx_desc = 0x40000ad8; +sta_input = 0x40000b3c; +sta_rx_eapol = 0x40000b40; +sta_reset_beacon_timeout = 0x40000b44; +hal_mac_tx_set_ppdu = 0x40000b74; +ic_mac_deinit = 0x40000be8; +ic_mac_init = 0x40000bec; +lmacTxFrame = 0x40000c40; +lmacDisableTransmit = 0x40000c44; +pm_check_state = 0x40000cb4; +pm_set_beacon_filter = 0x40000cd8; +pm_is_in_wifi_slice_threshold = 0x40000cdc; +pm_keep_alive = 0x40000ce4; +pm_process_tim = 0x40000d14; +pm_tbtt_process = 0x40000d28; +pm_tx_data_process = 0x40000d44; +pm_twt_process = 0x40000d54; +pm_mac_try_enable_modem_state = 0x40000d68; +pm_update_next_tbtt = 0x40000d70; +pm_clear_wakeup_signal = 0x40000d78; +pm_mac_disable_tsf_tbtt_soc_wakeup = 0x40000d7c; +pm_mac_disable_tsf_tbtt_modem_wakeup = 0x40000d80; +pm_mac_enable_tsf_tbtt_soc_wakeup = 0x40000d84; +pm_mac_enable_tsf_tbtt_modem_wakeup = 0x40000d88; +pm_mac_modem_params_rt_update = 0x40000d8c; +pm_coex_pwr_update = 0x40000d9c; +ppMapTxQueue = 0x40000ddc; +ppProcTxSecFrame = 0x40000de0; +ppProcessTxQ = 0x40000de8; +ppRxFragmentProc = 0x40000e00; +ppRxPkt = 0x40000e04; +ppRxProtoProc = 0x40000e08; +ppProcessLifeTime = 0x40000e54; +rcGetSched = 0x40000eb4; +wDev_ProcessRxSucData = 0x40000f54; +pm_get_tbtt_count = 0x400014c8; +pm_beacon_offset_check = 0x40001564; +pm_beacon_offset_get_average = 0x40001568; +pm_beacon_offset_get_expect = 0x4000156c; +pm_beacon_offset_get_params = 0x40001570; +pm_enable_max_idle_timer = 0x40001578; + +phy_get_rc_dout = 0x40001058; +phy_rc_cal = 0x4000105c; +phy_abs_temp = 0x40001060; +phy_set_chan_cal_interp = 0x40001064; +phy_loopback_mode_en = 0x40001068; +phy_get_data_sat = 0x4000106c; +phy_byte_to_word = 0x40001070; +phy_bb_bss_cbw40 = 0x40001074; +phy_set_chan_reg = 0x40001078; +phy_i2c_master_reset = 0x4000107c; +phy_chan14_mic_enable = 0x40001080; +phy_chan14_mic_cfg = 0x40001084; +phy_freq_module_resetn = 0x40001088; +phy_freq_chan_en_sw = 0x4000108c; +phy_write_chan_freq = 0x40001090; +phy_get_freq_mem_param = 0x40001094; +phy_get_freq_mem_addr = 0x40001098; +phy_wr_rf_freq_mem = 0x4000109c; +phy_read_rf_freq_mem = 0x400010a0; +phy_freq_i2c_mem_write = 0x400010a4; +phy_freq_reg_init = 0x400010a8; +phy_freq_num_get_data = 0x400010ac; +phy_freq_i2c_num_addr = 0x400010b0; +phy_freq_i2c_write_set = 0x400010b4; +phy_pll_dac_mem_update = 0x400010b8; +phy_pll_cap_mem_update = 0x400010bc; +phy_en_hw_set_freq = 0x400010d4; +phy_dis_hw_set_freq = 0x400010d8; +phy_wait_freq_set_busy = 0x400010dc; +phy_set_chan_freq_sw_start = 0x400010e0; +phy_wait_i2c_sdm_stable = 0x400010e4; +phy_reg_init = 0x400010e8; +phy_xpd_rf = 0x400010ec; +phy_get_mac_addr = 0x400010f4; +phy_set_mac_data = 0x400010f8; +phy_rfcal_data_sub = 0x400010fc; +phy_rf_cal_data_recovery = 0x40001100; +phy_rf_cal_data_backup = 0x40001104; +phy_rfcal_data_check = 0x40001108; +phy_pwdet_reg_init = 0x4000110c; +phy_pwdet_sar2_init = 0x40001110; +phy_en_pwdet = 0x40001114; +phy_get_sar_sig_ref = 0x40001118; +phy_pwdet_tone_start = 0x4000111c; +phy_get_tone_sar_dout = 0x40001120; +phy_get_fm_sar_dout = 0x40001124; +phy_txtone_linear_pwr = 0x40001128; +phy_linear_to_db = 0x4000112c; +phy_get_power_db = 0x40001130; +phy_meas_tone_pwr_db = 0x40001134; +phy_pwdet_wait_idle = 0x40001138; +phy_pkdet_vol_start = 0x4000113c; +phy_read_sar_dout = 0x40001140; +phy_read_sar2_code = 0x40001144; +phy_get_sar2_vol = 0x40001148; +phy_get_pll_vol = 0x4000114c; +phy_tx_pwctrl_bg_init = 0x40001150; +phy_set_most_tpw = 0x40001154; +phy_get_most_tpw = 0x40001158; +phy_tx_state_out = 0x4000115c; +phy_ant_dft_cfg = 0x40001160; +phy_ant_wifitx_cfg = 0x40001164; +phy_ant_wifirx_cfg = 0x40001168; +phy_ant_bttx_cfg = 0x4000116c; +phy_ant_btrx_cfg = 0x40001170; +phy_chan_dump_cfg = 0x40001174; +phy_enable_low_rate = 0x40001178; +phy_disable_low_rate = 0x4000117c; +phy_is_low_rate_enabled = 0x40001180; +phy_dig_reg_backup = 0x40001184; +phy_chan_filt_set = 0x40001188; +phy_rx11blr_cfg = 0x4000118c; +phy_set_cca = 0x40001190; +phy_set_rx_sense = 0x40001194; +phy_rx_gain_force = 0x40001198; +phy_mhz2ieee = 0x4000119c; +phy_chan_to_freq = 0x400011a0; +phy_restart_cal = 0x400011a4; +phy_write_rfpll_sdm = 0x400011a8; +phy_wait_rfpll_cal_end = 0x400011ac; +phy_rfpll_set_freq = 0x400011b0; +phy_set_rf_freq_offset = 0x400011b4; +phy_set_rfpll_freq = 0x400011b8; +phy_set_channel_rfpll_freq = 0x400011bc; +phy_rfpll_cap_correct = 0x400011c0; +phy_rfpll_cap_init_cal = 0x400011c4; +phy_set_freq = 0x400011c8; +phy_write_pll_cap = 0x400011cc; +phy_read_pll_cap = 0x400011d0; +phy_chip_set_chan_misc = 0x400011d4; +phy_freq_set_reg = 0x400011d8; +phy_rfpll_chgp_cal = 0x400011dc; +phy_gen_rx_gain_table = 0x400011e0; +phy_get_rxbb_dc = 0x400011e4; +phy_wr_rx_gain_mem = 0x400011e8; +phy_rfpll_cap_track = 0x400011ec; +phy_txpwr_correct = 0x400011f4; +phy_txpwr_cal_track = 0x400011f8; +phy_bt_track_tx_power = 0x400011fc; +phy_wifi_track_tx_power = 0x40001200; +phy_bt_txdc_cal = 0x40001204; +phy_bt_txiq_cal = 0x40001208; +phy_txdc_cal_pwdet = 0x4000120c; +phy_txdc_cal = 0x40001210; +phy_txiq_get_mis_pwr = 0x40001214; +phy_txiq_cover = 0x40001218; +phy_rfcal_txiq = 0x4000121c; +phy_get_power_atten = 0x40001220; +phy_pwdet_ref_code = 0x40001224; +phy_pwdet_code_cal = 0x40001228; +phy_rfcal_txcap = 0x4000122c; +phy_rfcal_pwrctrl = 0x40001234; +phy_tx_pwctrl_init_cal = 0x40001238; +phy_i2c_enter_critical_ = 0x40001244; +phy_i2c_exit_critical_ = 0x40001248; +phy_i2c_clk_sel = 0x4000124c; +phy_get_i2c_read_mask_ = 0x40001250; +phy_get_i2c_mst0_mask = 0x40001254; +phy_get_i2c_hostid_ = 0x40001258; +phy_chip_i2c_readReg_org = 0x4000125c; +phy_chip_i2c_readReg = 0x40001260; +phy_i2c_paral_set_mst0 = 0x40001264; +phy_i2c_paral_set_read = 0x40001268; +phy_i2c_paral_read = 0x4000126c; +phy_i2c_paral_write = 0x40001270; +phy_i2c_paral_write_num = 0x40001274; +phy_i2c_paral_write_mask = 0x40001278; +phy_i2c_readReg = 0x4000127c; +phy_chip_i2c_writeReg = 0x40001280; +phy_i2c_writeReg = 0x40001284; +phy_i2c_readReg_Mask = 0x40001288; +phy_i2c_writeReg_Mask = 0x4000128c; +phy_set_txcap_reg = 0x40001290; +phy_i2c_sar2_init_code = 0x40001294; +phy_filter_dcap_set = 0x4000129c; +phy_i2c_rc_cal_set = 0x400012ac; +phy_i2c_bbpll_set = 0x400012b0; +phy_adc_rate_set = 0x400012b4; +phy_dac_rate_set = 0x400012b8; +phy_encode_i2c_master = 0x400012bc; +phy_i2c_master_fill = 0x400012c0; +phy_i2c_master_mem_txcap = 0x400012c4; +phy_pbus_force_mode = 0x400012d0; +phy_pbus_rd_addr = 0x400012d4; +phy_pbus_rd_shift = 0x400012d8; +phy_pbus_force_test = 0x400012dc; +phy_pbus_rd = 0x400012e0; +phy_pbus_debugmode = 0x400012e4; +phy_pbus_workmode = 0x400012e8; +phy_pbus_set_rxgain = 0x400012ec; +phy_pbus_xpd_rx_off = 0x400012f0; +phy_pbus_xpd_rx_on = 0x400012f4; +phy_pbus_xpd_tx_off = 0x400012f8; +phy_pbus_xpd_tx_on = 0x400012fc; +phy_pbus_set_dco = 0x40001300; +phy_set_loopback_gain = 0x40001304; +phy_txcal_debuge_mode_ = 0x40001308; +phy_txcal_work_mode = 0x4000130c; +phy_pbus_clear_reg = 0x40001310; +phy_save_pbus_reg = 0x40001314; +phy_write_pbus_mem = 0x40001318; +phy_set_pbus_mem = 0x4000131c; +phy_disable_agc = 0x40001320; +phy_enable_agc = 0x40001324; +phy_disable_cca = 0x40001328; +phy_enable_cca = 0x4000132c; +phy_write_gain_mem = 0x40001330; +phy_bb_bss_cbw40_dig = 0x40001334; +phy_mac_tx_chan_offset = 0x40001338; +phy_rx_11b_opt = 0x4000133c; +phy_tx_paon_set = 0x40001340; +phy_i2cmst_reg_init = 0x40001344; +phy_bt_gain_offset = 0x40001348; +phy_fe_reg_init = 0x4000134c; +phy_mac_enable_bb = 0x40001350; +phy_bb_wdg_cfg = 0x40001354; +phy_fe_txrx_reset = 0x40001358; +phy_set_rx_comp_ = 0x4000135c; +phy_agc_reg_init = 0x40001360; +phy_btbb_wifi_bb_cfg2 = 0x40001364; +phy_bb_reg_init = 0x40001368; +phy_open_i2c_xpd = 0x4000136c; +phy_force_txrx_off = 0x40001370; +phy_txiq_set_reg = 0x40001374; +phy_rxiq_set_reg = 0x40001378; +phy_set_txclk_en = 0x4000137c; +phy_set_rxclk_en = 0x40001380; +phy_start_tx_tone_step = 0x40001384; +phy_stop_tx_tone = 0x40001388; +phy_bb_wdg_test_en = 0x4000138c; +phy_noise_floor_auto_set = 0x40001390; +phy_read_hw_noisefloor = 0x40001394; +phy_iq_corr_enable = 0x40001398; +phy_wifi_agc_sat_gain = 0x4000139c; +phy_bbpll_cal = 0x400013a0; +phy_ant_init = 0x400013a4; +phy_wifi_fbw_sel = 0x400013a8; +phy_bt_filter_reg = 0x400013ac; +phy_rx_sense_set = 0x400013b0; +phy_tx_state_set = 0x400013b4; +phy_close_pa = 0x400013b8; +phy_freq_correct = 0x400013bc; +phy_set_pbus_reg = 0x400013c0; +phy_wifi_rifs_mode_en = 0x400013c4; +phy_nrx_freq_set = 0x400013c8; +phy_fe_adc_on = 0x400013cc; +phy_force_pwr_index = 0x400013d0; +phy_fft_scale_force = 0x400013d4; +phy_force_rx_gain = 0x400013d8; +phy_wifi_enable_set = 0x400013dc; +phy_bb_wdt_rst_enable = 0x400013e0; +phy_bb_wdt_int_enable = 0x400013e4; +phy_bb_wdt_timeout_clear = 0x400013e8; +phy_bb_wdt_get_status = 0x400013ec; +phy_iq_est_enable = 0x400013f0; +phy_iq_est_disable = 0x400013f4; +phy_dc_iq_est = 0x400013f8; +phy_set_cal_rxdc = 0x400013fc; +phy_rxiq_get_mis = 0x40001400; +phy_rxiq_cover_mg_mp = 0x40001404; +phy_rfcal_rxiq = 0x40001408; +phy_get_rfcal_rxiq_data = 0x4000140c; +phy_get_dco_comp = 0x40001410; +phy_pbus_rx_dco_cal = 0x40001414; +phy_rxdc_est_min = 0x40001418; +phy_pbus_rx_dco_cal_1step = 0x4000141c; +phy_get_iq_value = 0x40001420; +phy_set_lb_txiq = 0x40001424; +phy_set_rx_gain_cal_iq = 0x40001428; +phy_set_rx_gain_cal_dc = 0x4000142c; +phy_spur_reg_write_one_tone = 0x40001430; +phy_spur_cal = 0x40001434; +phy_spur_coef_cfg = 0x40001438; +phy_bb_gain_index = 0x4000143c; +phy_rfrx_gain_index = 0x40001440; +phy_set_tsens_power_ = 0x40001444; +phy_set_tsens_range_ = 0x40001448; +phy_get_tsens_value_ = 0x4000144c; +phy_tsens_read_init = 0x40001450; +phy_code_to_temp = 0x40001454; +phy_tsens_dac_to_index = 0x40001458; +phy_tsens_dac_cal = 0x4000145c; +phy_tsens_code_read = 0x40001460; +phy_tsens_temp_read = 0x40001464; +phy_tsens_temp_read_local = 0x40001468; +phy_temp_to_power = 0x4000146c; +phy_txbbgain_to_index = 0x40001470; +phy_index_to_txbbgain = 0x40001474; +phy_bt_index_to_bb = 0x40001478; +phy_bt_bb_to_index = 0x4000147c; +phy_bt_get_tx_gain = 0x40001480; +phy_dig_gain_check = 0x40001484; +phy_wifi_get_tx_gain = 0x40001488; +phy_wifi_11g_rate_chg = 0x4000148c; +phy_set_tx_gain_mem = 0x40001490; +phy_get_rate_fcc_index = 0x40001494; +phy_get_chan_target_power = 0x40001498; +phy_get_tx_gain_value = 0x4000149c; +phy_wifi_get_target_power = 0x400014a0; +phy_wifi_get_tx_tab_ = 0x400014a4; +phy_wifi_set_tx_gain = 0x400014a8; +phy_bt_get_tx_tab_ = 0x400014ac; +phy_bt_set_tx_gain = 0x400014b0; +phy_rate_to_index = 0x400014b8; +phy_get_target_pwr = 0x400014bc; +phy_get_max_pwr = 0x400014c0; +phy_get_pwr_index = 0x400014c4; +phy_chip_set_chan_ana = 0x400014d4; +phy_get_romfuncs = 0x400014d8; + +/*************************************** + eco4 newly added + ***************************************/ + +/* Data (.data, .bss, .rodata) */ +s_offchan_tx_progress_in_ptr = 0x4084fc5c; + + +/* Functions */ +phy_bb_agc_reg_update = 0x4000157c; +phy_bb_cbw_chan_cfg = 0x40001580; +phy_bb_cfo_cfg = 0x40001584; +phy_bb_dcmem_clr = 0x40001588; +phy_bbpll_recal = 0x4000158c; +phy_bbtx_outfilter = 0x40001590; +phy_csidump_force_lltf_cfg = 0x40001594; +phy_dac_scale_set = 0x40001598; +phy_dcode_cal_init = 0x4000159c; +phy_fe_reg_update = 0x400015a0; +phy_freq_band_reg_set = 0x400015a4; +phy_get_cca = 0x400015a8; +phy_get_cca_cnt = 0x400015ac; +phy_get_dreg1p6 = 0x400015b0; +phy_get_noise_floor = 0x400015b4; +phy_get_oc_dr1 = 0x400015b8; +phy_get_rssi = 0x400015bc; +phy_get_rx_sig_pwr = 0x400015c0; +phy_get_txiq_set = 0x400015c4; +phy_get_xtal_duty = 0x400015c8; +phy_hemu_ru26_good_res = 0x400015cc; +phy_i2c_txrate_init = 0x400015d0; +phy_lltf_mask_en = 0x400015d4; +phy_open_fe_bb_clk = 0x400015d8; +phy_reset_ckgen = 0x400015dc; +phy_rx_filter_mode = 0x400015e0; +phy_set_bb_wdg = 0x400015e4; +phy_set_cca_cnt = 0x400015e8; +phy_set_channel_dcode = 0x400015ec; +phy_set_ext_dcode = 0x400015f0; +phy_set_freq_i2c_ = 0x400015f4; +phy_sifs_reg_init = 0x400015f8; +phy_txgain_comp_pacfg = 0x400015fc; +phy_txpwr_track_slow = 0x40001600; +phy_vht_support = 0x40001604; From d09c9f2cfbb706d0eeaf0762c91402990d473814 Mon Sep 17 00:00:00 2001 From: yinqingzhao Date: Tue, 30 Dec 2025 20:16:39 +0800 Subject: [PATCH 221/226] feat(wifi): update esp32c61 ld files --- .../esp_rom/esp32c61/ld/esp32c61.rom.eco4.ld | 21 ++++++++++--------- .../esp32c61/ld/esp32c61.rom.net80211.ld | 4 ++-- components/esp_wifi/src/wifi_init.c | 9 ++++++++ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/components/esp_rom/esp32c61/ld/esp32c61.rom.eco4.ld b/components/esp_rom/esp32c61/ld/esp32c61.rom.eco4.ld index 64e4b6ade8..59a2bed37b 100644 --- a/components/esp_rom/esp32c61/ld/esp32c61.rom.eco4.ld +++ b/components/esp_rom/esp32c61/ld/esp32c61.rom.eco4.ld @@ -9,12 +9,14 @@ ***************************************/ coex_core_timer_idx_get = 0x40000a54; -coex_status_get = 0x40000a74; +//coex_status_get = 0x40000a74; +ets_delay_us = 0x4000003c; + ieee80211_encap_esfbuf = 0x40000ac8; ieee80211_set_tx_desc = 0x40000ad8; sta_input = 0x40000b3c; -sta_rx_eapol = 0x40000b40; -sta_reset_beacon_timeout = 0x40000b44; +//sta_rx_eapol = 0x40000b40; +//sta_reset_beacon_timeout = 0x40000b44; hal_mac_tx_set_ppdu = 0x40000b74; ic_mac_deinit = 0x40000be8; ic_mac_init = 0x40000bec; @@ -22,30 +24,29 @@ lmacTxFrame = 0x40000c40; lmacDisableTransmit = 0x40000c44; pm_check_state = 0x40000cb4; pm_set_beacon_filter = 0x40000cd8; -pm_is_in_wifi_slice_threshold = 0x40000cdc; +//pm_is_in_wifi_slice_threshold = 0x40000cdc; pm_keep_alive = 0x40000ce4; pm_process_tim = 0x40000d14; pm_tbtt_process = 0x40000d28; pm_tx_data_process = 0x40000d44; pm_twt_process = 0x40000d54; pm_mac_try_enable_modem_state = 0x40000d68; -pm_update_next_tbtt = 0x40000d70; +//pm_update_next_tbtt = 0x40000d70; pm_clear_wakeup_signal = 0x40000d78; pm_mac_disable_tsf_tbtt_soc_wakeup = 0x40000d7c; pm_mac_disable_tsf_tbtt_modem_wakeup = 0x40000d80; pm_mac_enable_tsf_tbtt_soc_wakeup = 0x40000d84; pm_mac_enable_tsf_tbtt_modem_wakeup = 0x40000d88; -pm_mac_modem_params_rt_update = 0x40000d8c; +//pm_mac_modem_params_rt_update = 0x40000d8c; pm_coex_pwr_update = 0x40000d9c; ppMapTxQueue = 0x40000ddc; ppProcTxSecFrame = 0x40000de0; ppProcessTxQ = 0x40000de8; -ppRxFragmentProc = 0x40000e00; ppRxPkt = 0x40000e04; ppRxProtoProc = 0x40000e08; -ppProcessLifeTime = 0x40000e54; +//ppProcessLifeTime = 0x40000e54; rcGetSched = 0x40000eb4; -wDev_ProcessRxSucData = 0x40000f54; +//wDev_ProcessRxSucData = 0x40000f54; pm_get_tbtt_count = 0x400014c8; pm_beacon_offset_check = 0x40001564; pm_beacon_offset_get_average = 0x40001568; @@ -118,7 +119,7 @@ phy_ant_wifitx_cfg = 0x40001164; phy_ant_wifirx_cfg = 0x40001168; phy_ant_bttx_cfg = 0x4000116c; phy_ant_btrx_cfg = 0x40001170; -phy_chan_dump_cfg = 0x40001174; +//phy_chan_dump_cfg = 0x40001174; phy_enable_low_rate = 0x40001178; phy_disable_low_rate = 0x4000117c; phy_is_low_rate_enabled = 0x40001180; diff --git a/components/esp_rom/esp32c61/ld/esp32c61.rom.net80211.ld b/components/esp_rom/esp32c61/ld/esp32c61.rom.net80211.ld index 4abb61d6e5..90100d3705 100644 --- a/components/esp_rom/esp32c61/ld/esp32c61.rom.net80211.ld +++ b/components/esp_rom/esp32c61/ld/esp32c61.rom.net80211.ld @@ -28,7 +28,7 @@ ic_ebuf_recycle_rx = 0x40000aa8; ic_ebuf_recycle_tx = 0x40000aac; ic_reset_rx_ba = 0x40000ab0; ic_ebuf_alloc = 0x40000ab4; -ic_reset_extra_softap_rx_ba = 0x40000ab8; +//ic_reset_extra_softap_rx_ba = 0x40000ab8; ieee80211_align_eb = 0x40000abc; ieee80211_ampdu_reorder = 0x40000ac0; ieee80211_ampdu_start_age_timer = 0x40000ac4; @@ -64,7 +64,7 @@ wifi_is_started = 0x40000b38; /*sta_input = 0x40000b3c;*/ //sta_rx_eapol = 0x40000b40; //sta_reset_beacon_timeout = 0x40000b44; -sta_get_beacon_timeout = 0x40000b48; +//sta_get_beacon_timeout = 0x40000b48; ampdu_process_multicast_address_qos_frame = 0x40000b4c; /* Data (.data, .bss, .rodata) */ net80211_funcs = 0x4084ffac; diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index 3aeec4c0fe..0461280d5a 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -718,6 +718,15 @@ void esp32c5_eco3_rom_ptr_init(void) #endif #endif +#if CONFIG_IDF_TARGET_ESP32C61 +#if CONFIG_ESP32C61_REV_MIN_FULL <= 100 +void esp32c61_eco4_rom_ptr_init(void) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ +} +#endif +#endif + #if CONFIG_IDF_TARGET_ESP32C2 #if CONFIG_ESP32C2_REV_MIN_FULL < 200 void esp32c2_eco4_rom_ptr_init(void) From cb96f9ef66e7c8e7adda46d44172be341cd14bf2 Mon Sep 17 00:00:00 2001 From: liuning Date: Thu, 8 Jan 2026 21:10:11 +0800 Subject: [PATCH 222/226] feat(coex): support c5 eco3 and c61 eco4 coexist rom --- components/esp_coex/lib | 2 +- components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld | 2 +- components/esp_rom/esp32c61/ld/esp32c61.rom.eco4.ld | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/esp_coex/lib b/components/esp_coex/lib index 63e292b57b..ee5cd79583 160000 --- a/components/esp_coex/lib +++ b/components/esp_coex/lib @@ -1 +1 @@ -Subproject commit 63e292b57b2cda9f9496a71a04bec43e1f0caeba +Subproject commit ee5cd79583c02f23e43e62931ffb55f5a4992d0f diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld index f2af6037dd..3f4dee36f1 100644 --- a/components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.eco3.ld @@ -8,7 +8,7 @@ ***************************************/ coex_core_timer_idx_get = 0x40000aec; -//coex_status_get = 0x40000b0c; +coex_status_get = 0x40000b0c; ets_delay_us = 0x4000003c; Cache_Set_IDROM_MMU_Size = 0x400006c4; diff --git a/components/esp_rom/esp32c61/ld/esp32c61.rom.eco4.ld b/components/esp_rom/esp32c61/ld/esp32c61.rom.eco4.ld index 59a2bed37b..18937e41a7 100644 --- a/components/esp_rom/esp32c61/ld/esp32c61.rom.eco4.ld +++ b/components/esp_rom/esp32c61/ld/esp32c61.rom.eco4.ld @@ -9,7 +9,7 @@ ***************************************/ coex_core_timer_idx_get = 0x40000a54; -//coex_status_get = 0x40000a74; +coex_status_get = 0x40000a74; ets_delay_us = 0x4000003c; ieee80211_encap_esfbuf = 0x40000ac8; From 880a3c4d80c4f0e006fe6748f43f99582c845452 Mon Sep 17 00:00:00 2001 From: yinqingzhao Date: Tue, 30 Dec 2025 20:13:26 +0800 Subject: [PATCH 223/226] test(system): add esp32c61 eco4 build test --- tools/test_apps/system/build_test/sdkconfig.ci.esp32c61_rev101 | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tools/test_apps/system/build_test/sdkconfig.ci.esp32c61_rev101 diff --git a/tools/test_apps/system/build_test/sdkconfig.ci.esp32c61_rev101 b/tools/test_apps/system/build_test/sdkconfig.ci.esp32c61_rev101 new file mode 100644 index 0000000000..7b69fea537 --- /dev/null +++ b/tools/test_apps/system/build_test/sdkconfig.ci.esp32c61_rev101 @@ -0,0 +1,2 @@ +CONFIG_IDF_TARGET="esp32c61" +CONFIG_ESP32C61_REV_MIN_101=y From 03d28533dd17bc57e096e6c19156c2337a15bfca Mon Sep 17 00:00:00 2001 From: yinqingzhao Date: Fri, 12 Dec 2025 10:44:31 +0800 Subject: [PATCH 224/226] feat(ci): re-enable ci build test of phy example for esp32c5 --- examples/phy/.build-test-rules.yml | 6 +++--- examples/phy/antenna/README.md | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/phy/.build-test-rules.yml b/examples/phy/.build-test-rules.yml index 3e70012edf..3ebe78f56e 100644 --- a/examples/phy/.build-test-rules.yml +++ b/examples/phy/.build-test-rules.yml @@ -2,9 +2,9 @@ examples/phy/antenna: disable: - - if: IDF_TARGET in ["esp32c5", "esp32c61", "esp32h21", "esp32h4"] + - if: IDF_TARGET in ["esp32c61", "esp32h21", "esp32h4"] temporary: true - reason: not supported yet # TODO: [ESP32C5] IDF-8851, [esp32c61] IDF-9859, [esp32h21] IDF-12041, [ESP32H4] IDF-12716 + reason: not supported yet # TODO: [esp32c61] IDF-9859, [esp32h21] IDF-12041, [ESP32H4] IDF-12716 - if: IDF_TARGET in ["esp32p4", "esp32h2"] reason: not supported examples/phy/cert_test: @@ -13,4 +13,4 @@ examples/phy/cert_test: reason: not supported - if: IDF_TARGET in ["esp32c61", "esp32h21", "esp32h4"] temporary: true - reason: not supported yet # TODO: [ESP32C5] IDF-8851, [esp32c61] IDF-9859, [esp32h21] IDF-12041, [ESP32H4] IDF-12716 + reason: not supported yet # TODO: [esp32c61] IDF-9859, [esp32h21] IDF-12041, [ESP32H4] IDF-12716 diff --git a/examples/phy/antenna/README.md b/examples/phy/antenna/README.md index 8551b80717..d060d6ba53 100644 --- a/examples/phy/antenna/README.md +++ b/examples/phy/antenna/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # Wi-Fi antenna soft switch Example From e4e04b09114495a72594d0327bbf2b69d98c2e5f Mon Sep 17 00:00:00 2001 From: yinqingzhao Date: Fri, 26 Dec 2025 12:33:44 +0800 Subject: [PATCH 225/226] fix(wpa_supplicant): fix race where STA is freed before WPA3 SAE finishes --- components/wpa_supplicant/src/ap/sta_info.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/components/wpa_supplicant/src/ap/sta_info.c b/components/wpa_supplicant/src/ap/sta_info.c index 0894486373..28daefb547 100644 --- a/components/wpa_supplicant/src/ap/sta_info.c +++ b/components/wpa_supplicant/src/ap/sta_info.c @@ -173,15 +173,14 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr) /* initialize STA info data */ os_memcpy(sta->addr, addr, ETH_ALEN); sta->next = hapd->sta_list; - hapd->sta_list = sta; - hapd->num_sta++; - ap_sta_hash_add(hapd, sta); #ifdef CONFIG_SAE sta->sae_commit_processing = false; sta->remove_pending = false; sta->lock = os_semphr_create(1, 1); #endif /* CONFIG_SAE */ - + hapd->sta_list = sta; + hapd->num_sta++; + ap_sta_hash_add(hapd, sta); return sta; } From dd08e83c6f2df521c92256f088e5a9c74e0d2968 Mon Sep 17 00:00:00 2001 From: yinqingzhao Date: Fri, 16 Jan 2026 11:46:55 +0800 Subject: [PATCH 226/226] feat(wifi): update wifi lib for esp32c5 v1.2 and esp32c61 v1.1 support --- components/esp_wifi/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index a91a026a2e..156aed2cb6 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit a91a026a2eacb7aef458be69d967e48c9e860624 +Subproject commit 156aed2cb6e6c9987dc2e7402fee907158cdf885