fix(esp_http_server): merge release/v6.0 to resolve backport conflict

Merge branch 'release/v6.0' into backport-48352-resolve to resolve a
conflict in esp_httpd_priv.h between this backport's sdkconfig.h
include and the ctrl-socket semaphore's freertos/semphr.h include.
This commit is contained in:
Hrushikesh Bhosale
2026-07-02 11:41:38 +05:30
1121 changed files with 36331 additions and 10307 deletions
+31 -7
View File
@@ -478,6 +478,18 @@ menu "Security features"
default y
depends on SOC_SECURE_BOOT_V2_ECC
# ECDSA based Secure Boot V2 is not functional for certain input vectors on these
# SoCs. The scheme stays available but, for hardware Secure Boot, must be explicitly
# turned on via SECURE_BOOT_V2_FORCE_ENABLE_ECDSA under "Allow potentially insecure
# options" (CONFIG_SECURE_BOOT_INSECURE).
#
# TODO: IDF-15721 - drop a SoC from this list once a fixing hardware ECO revision
# ships, gating on the selected minimum chip revision, e.g.:
# default y if IDF_TARGET_ESP32C5 && ESP32C5_REV_MIN_FULL < <fixed_rev>
config SECURE_BOOT_V2_ECDSA_INSECURE
bool
default y if IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C61 || IDF_TARGET_ESP32H2 || IDF_TARGET_ESP32P4
config SECURE_BOOT_V1_SUPPORTED
bool
default y
@@ -549,6 +561,10 @@ menu "Security features"
config SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
bool "ECDSA (V2)"
depends on SECURE_BOOT_V2_ECC_SUPPORTED && (SECURE_SIGNED_APPS_NO_SECURE_BOOT || SECURE_BOOT_V2_ENABLED)
# On the affected SoCs (SECURE_BOOT_V2_ECDSA_INSECURE), hardware Secure Boot with ECDSA
# is offered only when SECURE_BOOT_V2_FORCE_ENABLE_ECDSA is explicitly set. App signing
# without hardware Secure Boot is not affected by this gate.
depends on !SECURE_BOOT_V2_ENABLED || (!SECURE_BOOT_V2_ECDSA_INSECURE || SECURE_BOOT_V2_FORCE_ENABLE_ECDSA)
help
For Secure boot V2 (e.g., ESP32-C2 SoC), appends ECDSA based signature block to the application.
Refer to documentation before enabling.
@@ -931,6 +947,19 @@ menu "Security features"
# it's possible for the insecure menu to be disabled but the insecure option
# to remain on which is very bad.)
config SECURE_BOOT_V2_FORCE_ENABLE_ECDSA
bool "Force enable ECDSA based Secure Boot V2"
depends on SECURE_BOOT_INSECURE && SECURE_BOOT_V2_ECDSA_INSECURE
default n
help
ECDSA based Secure Boot V2 is not functional for certain input vectors on this SoC
and is therefore not offered by default. Refer to the hardware errata document for
details.
Setting this option re-enables the ECDSA based Secure Boot V2 signing scheme despite
the known vulnerability. Only set this option if you fully understand the risk. RSA
based Secure Boot V2 is the recommended scheme on SoCs that support it.
config SECURE_BOOT_ALLOW_ROM_BASIC
bool "Leave ROM BASIC Interpreter available on reset"
depends on (SECURE_BOOT_INSECURE || SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT) && IDF_TARGET_ESP32
@@ -983,13 +1012,8 @@ menu "Security features"
Revoking unused digest slots makes ensures that no trusted keys can be added later by an attacker.
If set, it means that you have a plan to use unused digests slots later.
Note that if you plan to enable secure boot during the first boot up, the bootloader will intentionally
revoke the unused digest slots while enabling secure boot, even if the above config is enabled because
keeping the unused key slots un-revoked would a security hazard.
In case for any development workflow if you need to avoid this revocation, you should enable
secure boot externally (host based mechanism) rather than enabling it during the boot up,
so that the bootloader would not need to enable secure boot and thus you could avoid its revocation
strategy.
This config is honored both at runtime in the app and while enabling secure boot during the first
boot up in the bootloader. When set, the unused digest slots are left un-revoked in both cases.
config SECURE_BOOT_SKIP_WRITE_PROTECTION_SCA
bool "Skip write-protection of SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH"
@@ -55,13 +55,25 @@ if(IGNORE_EXTRA_COMPONENT)
OUTPUT_VARIABLE EXTRA_COMPONENT_EXCLUDE_DIRS)
endif()
# Consider each directory in the project's bootloader_components as a component to be compiled
file(GLOB proj_components RELATIVE ${PROJECT_EXTRA_COMPONENTS} ${PROJECT_EXTRA_COMPONENTS}/*)
foreach(component ${proj_components})
# Only directories are considered components
if(IS_DIRECTORY "${PROJECT_EXTRA_COMPONENTS}/${component}" AND NOT ${component} IN_LIST IGNORE_EXTRA_COMPONENT)
list(APPEND COMPONENTS ${component})
endif()
foreach(extra_component_dir ${EXTRA_COMPONENT_DIRS})
if(EXISTS "${extra_component_dir}/CMakeLists.txt")
# BOOTLOADER_EXTRA_COMPONENT_DIRS may point directly to a single component.
# Add the directory name so the bootloader COMPONENTS filter keeps it.
get_filename_component(component "${extra_component_dir}" NAME)
if(NOT ${component} IN_LIST IGNORE_EXTRA_COMPONENT)
list(APPEND COMPONENTS ${component})
endif()
else()
# BOOTLOADER_EXTRA_COMPONENT_DIRS may also point to a directory containing
# multiple component directories. Add each child directory to the filter.
file(GLOB proj_components RELATIVE ${extra_component_dir} ${extra_component_dir}/*)
foreach(component ${proj_components})
# Only directories are considered components.
if(IS_DIRECTORY "${extra_component_dir}/${component}" AND NOT ${component} IN_LIST IGNORE_EXTRA_COMPONENT)
list(APPEND COMPONENTS ${component})
endif()
endforeach()
endif()
endforeach()
set(BOOTLOADER_BUILD 1)
@@ -31,7 +31,7 @@
#endif
bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */
bootloader_dram_seg_len = 0x5000;
bootloader_iram_loader_seg_len = 0x7000;
bootloader_iram_loader_seg_len = 0x8000;
bootloader_iram_seg_len = 0x2D00;
/* Start of the lower region is determined by region size and the end of the higher region */
@@ -54,9 +54,9 @@ MEMORY
* 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32p4/memory.ld.in to the same value.
*/
#if !CONFIG_ESP32P4_SELECTS_REV_LESS_V3
#define BOOTLOADER_IRAM_LOADER_SEG_START_EXPECTED 0x4FFAEFC0
#define BOOTLOADER_IRAM_LOADER_SEG_START_EXPECTED 0x4FFADFC0
#else
#define BOOTLOADER_IRAM_LOADER_SEG_START_EXPECTED 0x4FF2CBD0
#define BOOTLOADER_IRAM_LOADER_SEG_START_EXPECTED 0x4FF2BBD0
#endif
ASSERT(bootloader_iram_loader_seg_start == BOOTLOADER_IRAM_LOADER_SEG_START_EXPECTED,
"bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END");
@@ -347,8 +347,12 @@ static esp_err_t check_and_generate_secure_boot_keys(const esp_image_metadata_t
if (boot_key_digests.num_digests < SECURE_BOOT_NUM_BLOCKS) {
/* The revocation index can be 0, 1, 2. Bootloader count can be 1,2,3. */
for (unsigned i = boot_key_digests.num_digests; i < SECURE_BOOT_NUM_BLOCKS; i++) {
#ifndef CONFIG_SECURE_BOOT_ALLOW_UNUSED_DIGEST_SLOTS
ESP_LOGI(TAG, "Revoking empty key digest slot (%d)...", i);
esp_efuse_set_digest_revoke(i);
#else
ESP_LOGW(TAG, "Unused key digest slot (%d) left un-revoked due to the config SECURE_BOOT_ALLOW_UNUSED_DIGEST_SLOTS", i);
#endif
}
}
#endif // SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
@@ -58,7 +58,12 @@ esp_err_t verify_ecdsa_signature_block(const ets_secure_boot_signature_t *sig_bl
return ESP_ERR_INVALID_ARG;
}
psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
#if CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS
const psa_algorithm_t alg = PSA_ALG_ECDSA(PSA_ALG_SHA_384);
#else
const psa_algorithm_t alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
#endif
psa_set_key_algorithm(&key_attributes, alg);
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve_family));
/* Prepare the public key data from X and Y coordinates */
@@ -95,7 +100,7 @@ esp_err_t verify_ecdsa_signature_block(const ets_secure_boot_signature_t *sig_bl
}
/* Verify the signature */
status = psa_verify_hash(key_handle, PSA_ALG_ECDSA(PSA_ALG_SHA_256),
status = psa_verify_hash(key_handle, alg,
image_digest, ESP_SECURE_BOOT_DIGEST_LEN,
signature, 2 * key_size);
File diff suppressed because it is too large Load Diff
+6
View File
@@ -109,6 +109,12 @@ menu "Bluetooth"
This option is to configure the buffer size of the hci adv report cache in hci debug mode.
This is a ring buffer, the new data will overwrite the oldest data if the buffer is full.
config BT_HCI_LOG_INSIGHTS_ENABLE
depends on BT_HCI_LOG_DEBUG_EN
bool "Enable Insights for HCI LOGS BT Stack"
help
Enable this to allow the BT stack to send diagnostic events.
endmenu
menuconfig BLE_MESH
+204
View File
@@ -0,0 +1,204 @@
function(replace_log_compression_srcs)
if(NOT CONFIG_BLE_COMPRESSED_LOG_ENABLE)
return()
endif()
get_filename_component(CODE_BASE_PATH "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/.." ABSOLUTE)
# 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
# removing runtime formatting overhead, so logs are produced faster and
# with less system impact.
add_subdirectory(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ble_log/extension/log_compression)
set(LOG_COMPRESSION_TARGET "${LOG_COMPRESSION_TARGET}" PARENT_SCOPE)
if(LOG_COMPRESSION_TARGET)
# Replace the caller's srcs/include_dirs with the compressed-log ones
set(srcs "${LOG_COMPRESS_SRCS}" PARENT_SCOPE)
set(include_dirs "${LOG_COMPRESS_INCLUDE_DIRS}" PARENT_SCOPE)
# LOG_COMPRESS_FILES_WITH_FLAGS format: "file_path|compile_flags"
if(LOG_COMPRESS_FILES_WITH_FLAGS)
foreach(file_entry ${LOG_COMPRESS_FILES_WITH_FLAGS})
# Split by '|' to get file path and flags
string(REPLACE "|" ";" file_parts "${file_entry}")
list(GET file_parts 0 file_path)
list(GET file_parts 1 compile_flags)
set_source_files_properties(${file_path}
PROPERTIES COMPILE_FLAGS "${compile_flags}")
endforeach()
endif()
else()
# Only append extra include dirs, keep caller's srcs/include_dirs intact
set(_merged_include_dirs ${include_dirs} ${LOG_COMPRESS_INCLUDE_DIRS})
set(include_dirs "${_merged_include_dirs}" PARENT_SCOPE)
endif()
endfunction()
# Make the bt component library depend on the log-compression custom target
# so that the Python-driven code-generation step (log index headers and
# replacement sources referenced by LOG_COMPRESS_SRCS) finishes before the
# component is compiled. Does nothing if compressed log is disabled or no
# module actually participates in log compression.
function(register_log_compression_dependency)
if(NOT CONFIG_BLE_COMPRESSED_LOG_ENABLE)
return()
endif()
if(NOT LOG_COMPRESSION_TARGET)
return()
endif()
add_dependencies(${COMPONENT_LIB} ${LOG_COMPRESSION_TARGET})
endfunction()
function(wrap_uart_log_tx_interface)
if(NOT CONFIG_BT_ENABLED)
return()
endif()
# UART redir wrap flags — needed whenever BLE Log uses UART DMA on port 0,
# regardless of whether BLE controller is enabled.
if(DEFINED CONFIG_BLE_LOG_PRPH_UART_DMA_PORT)
if(CONFIG_BLE_LOG_PRPH_UART_DMA_PORT EQUAL 0)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=uart_tx_chars")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=uart_write_bytes")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=uart_write_bytes_with_break")
endif()
endif()
endfunction()
set(bt_common_srcs "" PARENT_SCOPE)
set(bt_common_include_dirs "" PARENT_SCOPE)
set(bt_common_priv_include_dirs "" PARENT_SCOPE)
# API headers that are used in the docs are also compiled
# even if CONFIG_BT_ENABLED=n as long as CONFIG_IDF_DOC_BUILD=y
if(CONFIG_IDF_DOC_BUILD)
set(bt_common_include_dirs
"${CMAKE_CURRENT_LIST_DIR}/api/include/api"
"${CMAKE_CURRENT_LIST_DIR}/btc/profile/esp/blufi/include"
"${CMAKE_CURRENT_LIST_DIR}/btc/profile/esp/include"
"${CMAKE_CURRENT_LIST_DIR}/hci_log/include"
"${CMAKE_CURRENT_LIST_DIR}/ble_log/include"
"${CMAKE_CURRENT_LIST_DIR}/ble_log/deprecated/include"
PARENT_SCOPE
)
return()
endif()
if(NOT CONFIG_BT_ENABLED)
return()
endif()
list(APPEND bt_common_srcs
"${CMAKE_CURRENT_LIST_DIR}/btc/core/btc_alarm.c"
"${CMAKE_CURRENT_LIST_DIR}/api/esp_blufi_api.c"
"${CMAKE_CURRENT_LIST_DIR}/hci_log/bt_hci_log.c"
"${CMAKE_CURRENT_LIST_DIR}/btc/core/btc_manage.c"
"${CMAKE_CURRENT_LIST_DIR}/hci_log/bt_hci_log_insights.c"
"${CMAKE_CURRENT_LIST_DIR}/btc/core/btc_task.c"
"${CMAKE_CURRENT_LIST_DIR}/btc/profile/esp/blufi/blufi_prf.c"
"${CMAKE_CURRENT_LIST_DIR}/btc/profile/esp/blufi/blufi_protocol.c"
"${CMAKE_CURRENT_LIST_DIR}/osi/alarm.c"
"${CMAKE_CURRENT_LIST_DIR}/osi/allocator.c"
"${CMAKE_CURRENT_LIST_DIR}/osi/buffer.c"
"${CMAKE_CURRENT_LIST_DIR}/osi/config.c"
"${CMAKE_CURRENT_LIST_DIR}/osi/fixed_queue.c"
"${CMAKE_CURRENT_LIST_DIR}/osi/pkt_queue.c"
"${CMAKE_CURRENT_LIST_DIR}/osi/fixed_pkt_queue.c"
"${CMAKE_CURRENT_LIST_DIR}/osi/future.c"
"${CMAKE_CURRENT_LIST_DIR}/osi/hash_functions.c"
"${CMAKE_CURRENT_LIST_DIR}/osi/hash_map.c"
"${CMAKE_CURRENT_LIST_DIR}/osi/list.c"
"${CMAKE_CURRENT_LIST_DIR}/osi/mutex.c"
"${CMAKE_CURRENT_LIST_DIR}/osi/thread.c"
"${CMAKE_CURRENT_LIST_DIR}/osi/osi.c"
"${CMAKE_CURRENT_LIST_DIR}/osi/semaphore.c"
"${CMAKE_CURRENT_LIST_DIR}/ble_log/deprecated/ble_log_spi_out.c"
)
list(APPEND bt_common_include_dirs
"${CMAKE_CURRENT_LIST_DIR}/osi/include"
"${CMAKE_CURRENT_LIST_DIR}/api/include/api"
"${CMAKE_CURRENT_LIST_DIR}/btc/profile/esp/blufi/include"
"${CMAKE_CURRENT_LIST_DIR}/btc/profile/esp/include"
"${CMAKE_CURRENT_LIST_DIR}/hci_log/include"
"${CMAKE_CURRENT_LIST_DIR}/ble_log/include"
"${CMAKE_CURRENT_LIST_DIR}/ble_log/deprecated/include"
)
list(APPEND bt_common_priv_include_dirs
"${CMAKE_CURRENT_LIST_DIR}/btc/include"
"${CMAKE_CURRENT_LIST_DIR}/include"
)
if(CONFIG_BLE_LOG_ENABLED)
list(APPEND bt_common_srcs
"${CMAKE_CURRENT_LIST_DIR}/ble_log/src/ble_log.c"
"${CMAKE_CURRENT_LIST_DIR}/ble_log/src/ble_log_lbm.c"
"${CMAKE_CURRENT_LIST_DIR}/ble_log/src/ble_log_rt.c"
"${CMAKE_CURRENT_LIST_DIR}/ble_log/src/ble_log_util.c"
)
list(APPEND bt_common_include_dirs
"${CMAKE_CURRENT_LIST_DIR}/ble_log/include"
)
list(APPEND bt_common_priv_include_dirs
"${CMAKE_CURRENT_LIST_DIR}/ble_log/src/internal_include"
"${CMAKE_CURRENT_LIST_DIR}/ble_log/src/internal_include/prph"
)
# Timestamp synchronization extension
if(CONFIG_BLE_LOG_TS_ENABLED)
list(APPEND bt_common_srcs "${CMAKE_CURRENT_LIST_DIR}/ble_log/src/ble_log_ts.c")
endif()
# Peripheral interface implementation
if(CONFIG_BLE_LOG_PRPH_DUMMY)
list(APPEND bt_common_srcs
"${CMAKE_CURRENT_LIST_DIR}/ble_log/src/prph/ble_log_prph_dummy.c"
)
elseif(CONFIG_BLE_LOG_PRPH_SPI_MASTER_DMA)
list(APPEND bt_common_srcs
"${CMAKE_CURRENT_LIST_DIR}/ble_log/src/prph/ble_log_prph_spi_master_dma.c"
)
elseif(CONFIG_BLE_LOG_PRPH_UART_DMA)
list(APPEND bt_common_srcs
"${CMAKE_CURRENT_LIST_DIR}/ble_log/src/prph/ble_log_prph_uart_dma.c"
)
endif()
endif()
# 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_NIMBLE_CRYPTO_STACK_MBEDTLS)
list(APPEND bt_common_include_dirs
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/include"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/port"
)
list(APPEND bt_common_srcs
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/src/utils.c"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/src/sha256.c"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/src/ecc.c"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/src/ctr_prng.c"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/src/ctr_mode.c"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/src/aes_decrypt.c"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/src/aes_encrypt.c"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/src/ccm_mode.c"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/src/ecc_dsa.c"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/src/cmac_mode.c"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/src/ecc_dh.c"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/src/hmac_prng.c"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/src/ecc_platform_specific.c"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/src/hmac.c"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/src/cbc_mode.c"
"${CMAKE_CURRENT_LIST_DIR}/tinycrypt/port/esp_tinycrypt_port.c"
)
endif()
# Export the variables to the parent scope
set(bt_common_srcs "${bt_common_srcs}" PARENT_SCOPE)
set(bt_common_include_dirs "${bt_common_include_dirs}" PARENT_SCOPE)
set(bt_common_priv_include_dirs "${bt_common_priv_include_dirs}" PARENT_SCOPE)
+15
View File
@@ -6,6 +6,21 @@ config BT_ALARM_MAX_NUM
This option decides the maximum number of alarms which
could be used by Bluetooth host.
config BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT
bool "Allow BLE connection interval below Bluetooth Core Spec minimum (disable host check)"
depends on BT_BLE_ENABLED || BT_NIMBLE_ENABLED
default n
help
When enabled, BLE host-side validation accepts connection interval
values below the Bluetooth Core Specification minimum of 0x0006
(7.5 ms), down to non-zero values. The BLE controller still enforces
what is actually supported in hardware and firmware.
End users should NOT set this option directly. In typical IDF builds it
follows the active Controller integration when that Controller supports
this mode; use the Controller's own configuration instead of toggling
this host symbol manually.
choice BT_SMP_CRYPTO_STACK
prompt "SMP cryptographic stack"
depends on (BT_BLE_SMP_ENABLE || BT_SMP_ENABLE || BT_NIMBLE_SECURITY_ENABLE || BT_LE_SECURITY_ENABLE)
+9 -2
View File
@@ -7,6 +7,14 @@ config BLE_LOG_ENABLED
Enable BT Log Async Output
if BLE_LOG_ENABLED
config BLE_LOG_LBM_AUTO_FLUSH
bool "Enable automatic BLE Log LBM buffer flush"
default n
help
Periodically flush partially-filled BLE Log LBM transport buffers
that remain pending, reducing latency for low-volume or
intermittent logging.
config BLE_LOG_TASK_STACK_SIZE
int "Stack size for BLE Log Task"
default 1024 if IDF_TARGET_ARCH_RISCV
@@ -17,8 +25,7 @@ if BLE_LOG_ENABLED
config BLE_LOG_LBM_TRANS_BUF_SIZE
int "Total buffer memory per common LBM (bytes)"
default 512 if BT_BLUEDROID_ENABLED
default 1024 if BT_NIMBLE_ENABLED
default 2048
help
Total buffer memory allocated for each common pool log buffer
manager (LBM). This memory is divided equally among internal
+11 -4
View File
@@ -80,7 +80,7 @@ void app_main() {
uint8_t data[] = {0x01, 0x02, 0x03, 0x04};
ble_log_write_hex(BLE_LOG_SRC_CUSTOM, data, sizeof(data));
// Force flush buffers
// End session and flush buffers
ble_log_flush();
// Cleanup resources
@@ -178,9 +178,15 @@ Write hexadecimal log data.
#### `void ble_log_flush(void)`
Force flush all buffers and send pending logs immediately.
End the current logging session and flush pending logs immediately.
**Note**: This operation is blocking and will pause module operation until all buffers are cleared.
This API temporarily suspends ordinary log writes, waits for in-progress
writers to exit, emits a final statistics internal frame, flushes pending
transport buffers, resets statistics, and then restores the enable state that
was in effect before the call.
**Note**: This operation is blocking. If BLE Log was enabled before the call,
it remains enabled after the flush completes.
#### `void ble_log_dump_to_console(void)`
@@ -272,7 +278,7 @@ void example_basic_logging() {
uint8_t host_data[] = {0x02, 0x00, 0x20, 0x0B, 0x00, 0x07, 0x00, 0x04, 0x00, 0x10, 0x01, 0x00, 0xFF, 0xFF, 0x00, 0x28};
ble_log_write_hex(BLE_LOG_SRC_HOST, host_data, sizeof(host_data));
// Force send
// End session and flush buffers
ble_log_flush();
// Cleanup
@@ -334,6 +340,7 @@ void example_performance_test() {
ble_log_write_hex(BLE_LOG_SRC_CUSTOM, test_data, sizeof(test_data));
}
// End session and flush buffers
ble_log_flush();
uint32_t end_time = esp_timer_get_time();
@@ -132,6 +132,12 @@ if(LOG_COMPRESSED_MODULE)
string(REPLACE ";" "|" MODULE_CODE_PATH "${LOG_COMPRESSED_MODULE_CODE_PATH}")
set(MATCH_PATTERN "(${MODULE_CODE_PATH}).+\\.c")
foreach(src ${srcs})
# Normalize absolute paths to relative paths (relative to CODE_BASE_PATH)
# so that pattern matching works and .compressed_srcs/ has a clean layout
if(IS_ABSOLUTE "${src}")
get_filename_component(src "${src}" ABSOLUTE)
file(RELATIVE_PATH src "${CODE_BASE_PATH}" "${src}")
endif()
if(src MATCHES ${MATCH_PATTERN})
set(dest "${LOG_COMPRESSED_SRCS_DIR}/${src}")
file(WRITE "${dest}" "")
@@ -699,9 +699,15 @@ class LogCompressor:
compressed_file_cnt = 0
total_cnt = 0
for src in srcs:
if pattern.match(src):
src_path = self.code_base_path / src
dest_path = self.bt_compressed_srcs_path / src
# Convert absolute paths to relative (to code_base_path) for pattern matching
src_for_match = src
try:
src_for_match = str(Path(src).relative_to(self.code_base_path))
except ValueError:
pass # Not under code_base_path, keep as-is
if pattern.match(src_for_match):
src_path = self.code_base_path / src_for_match
dest_path = self.bt_compressed_srcs_path / src_for_match
temp_path = f'{dest_path}.tmp'
total_cnt += 1
# Skip if already processed
+25 -1
View File
@@ -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
*/
@@ -13,12 +13,22 @@
#include "ble_log_lbm.h"
#include "ble_log_prph.h"
#include "ble_log_util.h"
#include "esp_log.h"
#include "esp_system.h"
#if CONFIG_BLE_LOG_TS_ENABLED
#include "ble_log_ts.h"
#endif /* CONFIG_BLE_LOG_TS_ENABLED */
/* VARIABLE */
#define TAG "ble_log"
BLE_LOG_STATIC bool ble_log_inited = false;
BLE_LOG_STATIC bool shutdown_handler_registered = false;
BLE_LOG_STATIC void ble_log_shutdown_handler(void)
{
ble_log_flush();
}
/* INTERFACE */
bool ble_log_init(void)
@@ -53,6 +63,12 @@ bool ble_log_init(void)
/* Initialization done */
ble_log_inited = true;
ble_log_enable(true);
esp_err_t ret = esp_register_shutdown_handler(ble_log_shutdown_handler);
if (ret == ESP_OK) {
shutdown_handler_registered = true;
} else {
ESP_LOGW(TAG, "Register shutdown handler failed, ret = 0x%x", ret);
}
/* Write initialization done log */
ble_log_info_t ble_log_info = {
@@ -69,6 +85,14 @@ exit:
void ble_log_deinit(void)
{
if (shutdown_handler_registered) {
esp_err_t ret = esp_unregister_shutdown_handler(ble_log_shutdown_handler);
if (ret == ESP_OK) {
shutdown_handler_registered = false;
} else {
ESP_LOGW(TAG, "Unregister shutdown handler failed, ret = 0x%x", ret);
}
}
ble_log_enable(false);
ble_log_inited = false;
+170 -80
View File
@@ -11,15 +11,20 @@
#include "ble_log.h"
#include "ble_log_lbm.h"
#include "ble_log_rt.h"
#include "esp_log.h"
#if CONFIG_SOC_ESP_NIMBLE_CONTROLLER
#include "os/os_mbuf.h"
#endif /* CONFIG_SOC_ESP_NIMBLE_CONTROLLER */
/* VARIABLE */
#define TAG "ble_log"
#define BLE_LOG_LBM_WAIT_TIMEOUT_MS (1000)
BLE_LOG_STATIC volatile uint32_t lbm_ref_count = 0;
BLE_LOG_STATIC bool lbm_inited = false;
BLE_LOG_STATIC bool lbm_enabled = false;
BLE_LOG_STATIC volatile bool flush_in_progress = false;
BLE_LOG_STATIC ble_log_lbm_ctx_t *lbm_ctx = NULL;
BLE_LOG_STATIC ble_log_stat_mgr_t *stat_mgr_ctx[BLE_LOG_SRC_MAX] = {0};
@@ -30,10 +35,14 @@ bool ble_log_lbm_acquire_trans(size_t log_len, ble_log_lbm_t **out_lbm,
BLE_LOG_STATIC void ble_log_lbm_release(ble_log_lbm_t *lbm);
BLE_LOG_STATIC
ble_log_prph_trans_t **ble_log_lbm_get_trans(ble_log_lbm_t *lbm, size_t log_len);
BLE_LOG_STATIC bool ble_log_lbm_flush_all_trans(void);
BLE_LOG_STATIC void ble_log_lbm_reset_stats(void);
BLE_LOG_STATIC
void ble_log_lbm_write_trans(ble_log_prph_trans_t **trans, ble_log_src_t src_code,
const uint8_t *addr, uint16_t len,
const uint8_t *addr_append, uint16_t len_append, bool omdata);
BLE_LOG_STATIC
bool ble_log_write_hex_core(ble_log_src_t src_code, const uint8_t *addr, size_t len);
#if BLE_LOG_UART_REDIR_ENABLED
BLE_LOG_STATIC
void ble_log_lbm_stream_seal(ble_log_prph_trans_t **trans, ble_log_src_t src_code);
@@ -110,6 +119,66 @@ void ble_log_lbm_release(ble_log_lbm_t *lbm)
}
}
BLE_LOG_STATIC bool ble_log_lbm_flush_all_trans(void)
{
ble_log_lbm_t *lbm;
ble_log_prph_trans_t **trans;
bool in_progress;
TickType_t start_tick = xTaskGetTickCount();
/* Queue transports with logs */
for (int i = 0; i < BLE_LOG_LBM_CNT; i++) {
lbm = &(lbm_ctx->lbm_pool[i]);
int trans_idx = lbm->trans_idx;
for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) {
trans = &(lbm->trans[trans_idx]);
if (!__atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE) &&
(*trans)->pos) {
ble_log_rt_queue_trans(trans);
}
trans_idx = (trans_idx + 1) & (BLE_LOG_TRANS_BUF_CNT - 1);
}
}
/* Wait for transportation to finish */
do {
in_progress = false;
for (int i = 0; i < BLE_LOG_LBM_CNT; i++) {
lbm = &(lbm_ctx->lbm_pool[i]);
for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) {
trans = &(lbm->trans[j]);
in_progress |= __atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE);
}
}
if (in_progress) {
if ((xTaskGetTickCount() - start_tick) >=
pdMS_TO_TICKS(BLE_LOG_LBM_WAIT_TIMEOUT_MS)) {
ESP_LOGE(TAG, "Timed out waiting for BLE Log transports");
return false;
}
vTaskDelay(1);
}
} while (in_progress);
return true;
}
BLE_LOG_STATIC void ble_log_lbm_reset_stats(void)
{
ble_log_lbm_t *lbm;
for (int i = 0; i < BLE_LOG_SRC_MAX; i++) {
BLE_LOG_MEMSET(stat_mgr_ctx[i], 0, sizeof(ble_log_stat_mgr_t));
}
for (int i = 0; i < BLE_LOG_LBM_CNT; i++) {
lbm = &(lbm_ctx->lbm_pool[i]);
__atomic_store_n(&lbm->trans_inflight, 0, __ATOMIC_RELAXED);
__atomic_store_n(&lbm->trans_inflight_peak, 0, __ATOMIC_RELAXED);
}
ble_log_prph_reset_util_counters();
}
BLE_LOG_IRAM_ATTR BLE_LOG_STATIC
void ble_log_lbm_write_trans(ble_log_prph_trans_t **trans, ble_log_src_t src_code,
const uint8_t *addr, uint16_t len,
@@ -203,6 +272,35 @@ void ble_log_stat_mgr_update(ble_log_src_t src_code, uint32_t len, bool lost)
}
}
BLE_LOG_IRAM_ATTR BLE_LOG_STATIC
bool ble_log_write_hex_core(ble_log_src_t src_code, const uint8_t *addr, size_t len)
{
/* Get transport from the best available pool */
size_t payload_len = len + sizeof(uint32_t);
ble_log_lbm_t *lbm;
ble_log_prph_trans_t **trans;
if (!ble_log_lbm_acquire_trans(payload_len, &lbm, &trans)) {
goto failed;
}
/* Write transport */
uint32_t os_ts = pdTICKS_TO_MS(BLE_LOG_IN_ISR()?
xTaskGetTickCountFromISR():
xTaskGetTickCount());
ble_log_lbm_write_trans(trans, src_code, (const uint8_t *)&os_ts,
sizeof(uint32_t), addr, len, false);
/* Release */
ble_log_lbm_release(lbm);
return true;
failed:
if (lbm_inited) {
ble_log_stat_mgr_update(src_code, payload_len, true);
}
return false;
}
/* -------------------------- */
/* INTERNAL INTERFACE */
/* -------------------------- */
@@ -289,10 +387,15 @@ void ble_log_lbm_deinit(void)
lbm_enabled = false;
/* Disable module and wait for all references to be released */
uint32_t time_waited = 0;
TickType_t start_tick = xTaskGetTickCount();
while (__atomic_load_n(&lbm_ref_count, __ATOMIC_ACQUIRE) > 0) {
vTaskDelay(pdMS_TO_TICKS(1));
BLE_LOG_ASSERT(time_waited++ < 1000);
if ((xTaskGetTickCount() - start_tick) >=
pdMS_TO_TICKS(BLE_LOG_LBM_WAIT_TIMEOUT_MS)) {
ESP_LOGE(TAG, "Timed out waiting for BLE Log references during deinit");
}
BLE_LOG_ASSERT((xTaskGetTickCount() - start_tick) <
pdMS_TO_TICKS(BLE_LOG_LBM_WAIT_TIMEOUT_MS));
vTaskDelay(1);
}
/* Release statistic manager context */
@@ -501,6 +604,33 @@ deref:
BLE_LOG_REF_COUNT_RELEASE(&lbm_ref_count);
}
void ble_log_write_final_stat(void)
{
BLE_LOG_REF_COUNT_ACQUIRE(&lbm_ref_count);
if (!lbm_inited) {
goto deref;
}
ble_log_final_stat_t final_stat;
final_stat.int_src_code = BLE_LOG_INT_SRC_FINAL_STAT;
final_stat.src_cnt = BLE_LOG_SRC_MAX;
BLE_LOG_ENTER_CRITICAL();
for (int i = 0; i < BLE_LOG_SRC_MAX; i++) {
ble_log_final_stat_entry_t *entry = &final_stat.entries[i];
entry->src_code = i;
BLE_LOG_MEMCPY(&entry->written_frame_cnt,
&stat_mgr_ctx[i]->written_frame_cnt,
4 * sizeof(uint32_t));
}
BLE_LOG_EXIT_CRITICAL();
ble_log_write_internal((const uint8_t *)&final_stat, sizeof(final_stat));
deref:
BLE_LOG_REF_COUNT_RELEASE(&lbm_ref_count);
}
/* ------------------------ */
/* PUBLIC INTERFACE */
/* ------------------------ */
@@ -518,7 +648,6 @@ void ble_log_flush(void)
/* Prevent concurrent flush — two concurrent callers would deadlock on
* the ref_count spin-wait (both hold a ref, both wait for ref_count <= 1).
* Second caller returns immediately instead of deadlocking. */
static volatile bool flush_in_progress = false;
if (__atomic_test_and_set(&flush_in_progress, __ATOMIC_ACQUIRE)) {
return;
}
@@ -527,8 +656,6 @@ void ble_log_flush(void)
if (!lbm_inited) {
goto deref;
}
/* Write enhanced statistics before module disable */
ble_log_write_enh_stat();
ble_log_write_buf_util();
@@ -541,64 +668,32 @@ void ble_log_flush(void)
/* Disable module and wait for all other references to release */
bool lbm_enabled_copy = lbm_enabled;
lbm_enabled = false;
uint32_t time_waited = 0;
TickType_t start_tick = xTaskGetTickCount();
while (__atomic_load_n(&lbm_ref_count, __ATOMIC_ACQUIRE) > 1) {
vTaskDelay(pdMS_TO_TICKS(1));
BLE_LOG_ASSERT(time_waited++ < 1000);
}
/* Queue transports with logs */
ble_log_lbm_t *lbm;
ble_log_prph_trans_t **trans;
/* Flush pools */
for (int i = 0; i < BLE_LOG_LBM_CNT; i++) {
lbm = &(lbm_ctx->lbm_pool[i]);
int trans_idx = lbm->trans_idx;
for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) {
trans = &(lbm->trans[trans_idx]);
if (!__atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE) &&
(*trans)->pos) {
ble_log_rt_queue_trans(trans);
}
trans_idx = (trans_idx + 1) & (BLE_LOG_TRANS_BUF_CNT - 1);
if ((xTaskGetTickCount() - start_tick) >=
pdMS_TO_TICKS(BLE_LOG_LBM_WAIT_TIMEOUT_MS)) {
ESP_LOGE(TAG, "Timed out waiting for BLE Log writers");
goto fail;
}
vTaskDelay(1);
}
/* Wait for transportation to finish */
time_waited = 0;
bool in_progress;
do {
in_progress = false;
for (int i = 0; i < BLE_LOG_LBM_CNT; i++) {
lbm = &(lbm_ctx->lbm_pool[i]);
for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) {
trans = &(lbm->trans[j]);
in_progress |= __atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE);
}
}
if (in_progress) {
vTaskDelay(pdMS_TO_TICKS(1));
BLE_LOG_ASSERT(time_waited++ < 1000);
}
} while (in_progress);
/* Reset statistics manager after all operations complete */
for (int i = 0; i < BLE_LOG_SRC_MAX; i++) {
BLE_LOG_MEMSET(stat_mgr_ctx[i], 0, sizeof(ble_log_stat_mgr_t));
if (!ble_log_lbm_flush_all_trans()) {
goto fail;
}
for (int i = 0; i < BLE_LOG_LBM_CNT; i++) {
lbm = &(lbm_ctx->lbm_pool[i]);
__atomic_store_n(&lbm->trans_inflight, 0, __ATOMIC_RELAXED);
__atomic_store_n(&lbm->trans_inflight_peak, 0, __ATOMIC_RELAXED);
}
ble_log_prph_reset_util_counters();
ble_log_write_final_stat();
/* Resume enable status */
if (!ble_log_lbm_flush_all_trans()) {
goto fail;
}
ble_log_lbm_reset_stats();
fail:
/* Resume enable status after a completed or failed flush. */
lbm_enabled = lbm_enabled_copy;
deref:
BLE_LOG_REF_COUNT_RELEASE(&lbm_ref_count);
__atomic_clear(&flush_in_progress, __ATOMIC_RELEASE);
@@ -607,38 +702,33 @@ deref:
BLE_LOG_IRAM_ATTR
bool ble_log_write_hex(ble_log_src_t src_code, const uint8_t *addr, size_t len)
{
bool ret = false;
BLE_LOG_REF_COUNT_ACQUIRE(&lbm_ref_count);
if (!lbm_enabled) {
goto exit;
}
/* Get transport from the best available pool */
size_t payload_len = len + sizeof(uint32_t);
ble_log_lbm_t *lbm;
ble_log_prph_trans_t **trans;
if (!ble_log_lbm_acquire_trans(payload_len, &lbm, &trans)) {
goto failed;
}
/* Write transport */
uint32_t os_ts = pdTICKS_TO_MS(BLE_LOG_IN_ISR()?
xTaskGetTickCountFromISR():
xTaskGetTickCount());
ble_log_lbm_write_trans(trans, src_code, (const uint8_t *)&os_ts,
sizeof(uint32_t), addr, len, false);
/* Release */
ble_log_lbm_release(lbm);
BLE_LOG_REF_COUNT_RELEASE(&lbm_ref_count);
return true;
failed:
if (lbm_inited) {
ble_log_stat_mgr_update(src_code, payload_len, true);
}
ret = ble_log_write_hex_core(src_code, addr, len);
exit:
BLE_LOG_REF_COUNT_RELEASE(&lbm_ref_count);
return false;
return ret;
}
BLE_LOG_IRAM_ATTR
bool ble_log_write_internal(const uint8_t *addr, size_t len)
{
bool ret = false;
BLE_LOG_REF_COUNT_ACQUIRE(&lbm_ref_count);
if (!lbm_inited) {
goto exit;
}
ret = ble_log_write_hex_core(BLE_LOG_SRC_INTERNAL, addr, len);
exit:
BLE_LOG_REF_COUNT_RELEASE(&lbm_ref_count);
return ret;
}
#if CONFIG_BLE_LOG_LL_ENABLED
@@ -13,6 +13,7 @@
/* ---------------- */
/* Includes */
/* ---------------- */
#include "ble_log.h"
#include "ble_log_prph.h"
#include "freertos/FreeRTOS.h"
@@ -174,6 +175,25 @@ typedef struct {
uint32_t lost_bytes_cnt;
} __attribute__((packed)) ble_log_enh_stat_t;
/* -------------------------------- */
/* Final Statistics Defines */
/* -------------------------------- */
typedef struct {
uint8_t src_code;
uint32_t written_frame_cnt;
uint32_t lost_frame_cnt;
uint32_t written_bytes_cnt;
uint32_t lost_bytes_cnt;
} __attribute__((packed)) ble_log_final_stat_entry_t;
typedef struct {
uint8_t int_src_code;
uint8_t src_cnt;
ble_log_final_stat_entry_t entries[BLE_LOG_SRC_MAX];
} __attribute__((packed)) ble_log_final_stat_t;
#define BLE_LOG_FINAL_STAT_LEN sizeof(ble_log_final_stat_t)
/* -------------------------------------- */
/* Log Statistics Manager Context */
/* -------------------------------------- */
@@ -220,6 +240,8 @@ _Static_assert(CONFIG_BLE_LOG_LBM_LL_TRANS_BUF_SIZE % BLE_LOG_TRANS_BUF_CNT == 0
#endif
_Static_assert(CONFIG_BLE_LOG_LBM_TRANS_BUF_SIZE / BLE_LOG_TRANS_BUF_CNT >= BLE_LOG_FRAME_OVERHEAD,
"Common LBM per-buffer size too small for a single frame");
_Static_assert(BLE_LOG_TRANS_SIZE >= BLE_LOG_FINAL_STAT_LEN + sizeof(uint32_t) + BLE_LOG_FRAME_OVERHEAD,
"Common LBM per-buffer size too small for final statistics frame");
_Static_assert((BLE_LOG_TRANS_BUF_CNT & (BLE_LOG_TRANS_BUF_CNT - 1)) == 0,
"BLE_LOG_TRANS_BUF_CNT must be a power of 2");
_Static_assert(1 + BLE_LOG_LBM_ATOMIC_TASK_CNT <= 16,
@@ -235,6 +257,8 @@ _Static_assert(BLE_LOG_TRANS_BUF_CNT <= 255,
bool ble_log_lbm_init(void);
void ble_log_lbm_deinit(void);
void ble_log_lbm_enable(bool enable);
bool ble_log_write_internal(const uint8_t *addr, size_t len);
void ble_log_write_final_stat(void);
void ble_log_write_enh_stat(void);
void ble_log_write_buf_util(void);
#if BLE_LOG_UART_REDIR_ENABLED
@@ -144,6 +144,7 @@ typedef enum {
BLE_LOG_INT_SRC_INFO,
BLE_LOG_INT_SRC_FLUSH,
BLE_LOG_INT_SRC_BUF_UTIL,
BLE_LOG_INT_SRC_FINAL_STAT,
BLE_LOG_INT_SRC_MAX,
} ble_log_int_src_t;
@@ -20,6 +20,12 @@
#define BLE_LOG_SPI_DMA_ALIGN_BYTES (4U)
#define BLE_LOG_SPI_ALIGN_LOG_PERIOD (256U)
#if CONFIG_SPI_MASTER_ISR_IN_IRAM
#define BLE_LOG_SPI_MASTER_DMA_CB_ATTR BLE_LOG_IRAM_ATTR
#else
#define BLE_LOG_SPI_MASTER_DMA_CB_ATTR
#endif
/* VARIABLE */
BLE_LOG_STATIC bool prph_inited = false;
BLE_LOG_STATIC spi_device_handle_t dev_handle = NULL;
@@ -30,7 +36,7 @@ BLE_LOG_STATIC void spi_master_dma_tx_done_cb(spi_transaction_t *spi_trans);
BLE_LOG_STATIC void spi_master_dma_pre_tx_cb(spi_transaction_t *spi_trans);
/* PRIVATE FUNCTION */
BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void spi_master_dma_tx_done_cb(spi_transaction_t *spi_trans)
BLE_LOG_SPI_MASTER_DMA_CB_ATTR BLE_LOG_STATIC void spi_master_dma_tx_done_cb(spi_transaction_t *spi_trans)
{
/* SPI slave performance issue workaround */
last_tx_done_ts = esp_timer_get_time();
@@ -43,7 +49,7 @@ BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void spi_master_dma_tx_done_cb(spi_transaction_
__atomic_store_n(&trans->prph_owned, false, __ATOMIC_RELEASE);
}
BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void spi_master_dma_pre_tx_cb(spi_transaction_t *spi_trans)
BLE_LOG_SPI_MASTER_DMA_CB_ATTR BLE_LOG_STATIC void spi_master_dma_pre_tx_cb(spi_transaction_t *spi_trans)
{
/* SPI slave performance issue workaround */
while ((esp_timer_get_time() - last_tx_done_ts) < BLE_LOG_SPI_TRANS_ITVL_MIN_US) {}
+4 -1
View File
@@ -353,7 +353,10 @@ bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg
memcpy(lmsg, msg, sizeof(btc_msg_t));
if (arg) {
memset(lmsg->arg, 0x00, arg_len); //important, avoid arg which have no length
/* memcpy below covers exactly arg_len bytes, which is the full size of
* the destination buffer (it was sized as sizeof(btc_msg_t) + arg_len),
* so a prior memset would be redundant. Deep-copy callbacks must only
* read fields that were written by the caller-supplied arg. */
memcpy(lmsg->arg, arg, arg_len);
if (copy_func) {
copy_func(lmsg, lmsg->arg, arg);
+10
View File
@@ -40,6 +40,16 @@ static const char s_hex_to_char_mapping[16] = {
static bt_hci_log_t g_bt_hci_log_data_ctl = {0};
static bt_hci_log_t g_bt_hci_log_adv_ctl = {0};
uint8_t bt_hci_log_h4_type_to_data_type(uint8_t h4_type)
{
switch (h4_type) {
case 0x05:
return HCI_LOG_DATA_TYPE_ISO_DATA;
default:
return h4_type;
}
}
esp_err_t bt_hci_log_init(void)
{
uint8_t *g_bt_hci_log_data_buffer = NULL;
@@ -0,0 +1,90 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
#include "esp_timer.h"
#include "bt_ble_insights.h"
#include "bt_common.h"
#include "hci_log/bt_hci_log.h"
#if (BT_HCI_LOG_INCLUDED == TRUE) && BT_HCI_INSIGHTS_INCLUDED
static uint8_t s_hci_log_seq_num = 0;
static portMUX_TYPE s_hci_log_mux = portMUX_INITIALIZER_UNLOCKED;
#define HCI_LOG_INSIGHTS_LINE_SIZE 128U
#define HCI_LOG_INSIGHTS_TS_LEN 8U
static const char *bt_hci_log_insights_label(uint8_t data_type)
{
switch (data_type) {
case HCI_LOG_DATA_TYPE_COMMAND:
return "C";
case HCI_LOG_DATA_TYPE_H2C_ACL:
return "H";
case HCI_LOG_DATA_TYPE_SCO:
return "S";
case HCI_LOG_DATA_TYPE_EVENT:
return "E";
case HCI_LOG_DATA_TYPE_ADV:
return "ADV";
case HCI_LOG_DATA_TYPE_C2H_ACL:
return "D";
case HCI_LOG_DATA_TYPE_ISO_DATA:
return "I";
default:
return NULL;
}
}
void bt_hci_log_record_insights(uint8_t data_type, const uint8_t *data, uint16_t data_len)
{
const char *label = bt_hci_log_insights_label(data_type);
char line[HCI_LOG_INSIGHTS_LINE_SIZE];
uint8_t ts_bytes[HCI_LOG_INSIGHTS_TS_LEN];
uint64_t timestamp;
uint8_t seq_num;
int offset;
if (!BT_BLE_INSIGHTS_AVAILABLE || label == NULL || data == NULL || data_len == 0) {
return;
}
portENTER_CRITICAL(&s_hci_log_mux);
seq_num = ++s_hci_log_seq_num;
portEXIT_CRITICAL(&s_hci_log_mux);
timestamp = esp_timer_get_time();
memcpy(ts_bytes, &timestamp, sizeof(ts_bytes));
offset = snprintf(line, sizeof(line), "%02x %s:", (unsigned int)seq_num, label);
if (offset < 0 || (size_t)offset >= sizeof(line) - 1) {
return;
}
for (size_t i = 0; i < sizeof(ts_bytes) && offset <= (int)sizeof(line) - 3; i++) {
offset += snprintf(&line[offset], sizeof(line) - offset, "%02x", ts_bytes[i]);
}
if (offset < 0 || (size_t)offset >= sizeof(line) - 1) {
return;
}
line[offset++] = ' ';
line[offset] = '\0';
for (uint16_t i = 0; i < data_len && offset <= (int)sizeof(line) - 3; i++) {
offset += snprintf(&line[offset], sizeof(line) - offset, "%02X", data[i]);
}
ble_insights_log(line);
}
#endif
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -102,6 +102,17 @@ esp_err_t bt_hci_log_record_hci_data(uint8_t data_type, uint8_t *data, uint16_t
*/
esp_err_t bt_hci_log_record_hci_adv(uint8_t data_type, uint8_t *data, uint8_t data_len);
/**
*
* @brief Convert HCI H4 packet type to HCI log data type.
*
* @param h4_type : HCI H4 packet type byte
*
* @return corresponding HCI log data type
*
*/
uint8_t bt_hci_log_h4_type_to_data_type(uint8_t h4_type);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,21 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BT_BLE_INSIGHTS_H__
#define __BT_BLE_INSIGHTS_H__
#if __has_include("ble_insights.h")
#include "ble_insights.h"
#define BT_BLE_INSIGHTS_AVAILABLE 1
#else
#define BT_BLE_INSIGHTS_AVAILABLE 0
static inline void ble_insights_log(const char *log)
{
(void)log;
}
#endif
#endif /* __BT_BLE_INSIGHTS_H__ */
+14 -3
View File
@@ -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
*/
@@ -100,6 +100,13 @@
#define BT_HCI_LOG_INCLUDED FALSE
#endif
// HCI INSIGHTS LOG
#if UC_BT_HCI_LOG_INSIGHTS_ENABLE
#define BT_HCI_INSIGHTS_INCLUDED UC_BT_HCI_LOG_INSIGHTS_ENABLE
#else
#define BT_HCI_INSIGHTS_INCLUDED FALSE
#endif
// HCI LOG TO SPI
#if UC_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
#define BT_BLE_LOG_SPI_OUT_HCI_ENABLED UC_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
@@ -117,10 +124,10 @@
#if UC_BT_HCI_LOG_DATA_BUFFER_SIZE
#define HCI_LOG_DATA_BUFFER_SIZE UC_BT_HCI_LOG_DATA_BUFFER_SIZE
#else
#define HCI_BUFFER_SIZE (5)
#define HCI_LOG_DATA_BUFFER_SIZE (5)
#endif
#if UC_BT_HCI_ADV_BUFFER_SIZE
#if UC_BT_HCI_LOG_ADV_BUFFER_SIZE
#define HCI_LOG_ADV_BUFFER_SIZE UC_BT_HCI_LOG_ADV_BUFFER_SIZE
#else
#define HCI_LOG_ADV_BUFFER_SIZE (5)
@@ -277,4 +284,8 @@ typedef struct {
#define BD_ADDR_LEN 6 /* Device address length */
typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */
#if (BT_HCI_LOG_INCLUDED == TRUE) && BT_HCI_INSIGHTS_INCLUDED
void bt_hci_log_record_insights(uint8_t data_type, const uint8_t *data, uint16_t data_len);
#endif
#endif /* _BT_COMMON_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
*/
@@ -176,4 +176,12 @@
#define UC_BT_HCI_LOG_ADV_BUFFER_SIZE (5)
#endif
// HCI LOG INSIGHTS
#ifdef CONFIG_BT_HCI_LOG_INSIGHTS_ENABLE
#define UC_BT_HCI_LOG_INSIGHTS_ENABLE TRUE
#else
#define UC_BT_HCI_LOG_INSIGHTS_ENABLE FALSE
#endif
#endif /* __BT_USER_CONFIG_H__ */
+133
View File
@@ -0,0 +1,133 @@
# Function to register the libraries for the BT controller
function(register_bt_ctrl_libs)
# TODO: The coex will use controller library even if CONFIG_BT_CONTROLLER_ENABLED=n which is not correct.
if(CONFIG_IDF_TARGET_ESP32)
add_prebuilt_library(bt_btdm_app "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/lib_esp32/esp32/libbtdm_app.a")
target_link_libraries(${COMPONENT_LIB} PRIVATE bt_btdm_app)
target_link_options(${COMPONENT_LIB} INTERFACE "SHELL:-u ld_include_hli_vectors_bt")
endif()
if(NOT CONFIG_BT_CONTROLLER_ENABLED)
return()
endif()
if(CONFIG_IDF_TARGET_ESP32C3)
if(CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY)
set(lib_name "btdm_app_flash")
else()
set(lib_name "btdm_app")
endif()
add_prebuilt_library(bt_btdm_app
"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/lib_esp32c3_family/esp32c3/lib${lib_name}.a")
target_link_libraries(${COMPONENT_LIB} PRIVATE bt_btdm_app)
elseif(CONFIG_IDF_TARGET_ESP32S3)
if(CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY)
set(lib_name "btdm_app_flash")
else()
set(lib_name "btdm_app")
endif()
add_prebuilt_library(bt_btdm_app
"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/lib_esp32c3_family/esp32s3/lib${lib_name}.a")
target_link_libraries(${COMPONENT_LIB} PRIVATE bt_btdm_app)
elseif(NOT CONFIG_IDF_TARGET_ESP32)
set(lib_path "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/lib_${TARGET_SRC_NAME}/${TARGET_SRC_NAME}-bt-lib")
# BLE controller library
if(NOT CONFIG_BT_DUAL_MODE_ARCH OR CONFIG_BT_CTRL_BLE_ENABLE)
if(EXISTS "${lib_path}/libble_app.a")
if(CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY AND EXISTS "${lib_path}/libble_app_flash.a")
add_prebuilt_library(libble_app "${lib_path}/libble_app_flash.a" REQUIRES esp_phy bt)
else()
add_prebuilt_library(libble_app "${lib_path}/libble_app.a" REQUIRES esp_phy bt)
endif()
else()
if(CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY AND EXISTS "${lib_path}/${idf_target}/libble_app_flash.a")
add_prebuilt_library(libble_app "${lib_path}/${idf_target}/libble_app_flash.a" REQUIRES esp_phy bt)
else()
add_prebuilt_library(libble_app "${lib_path}/${idf_target}/libble_app.a" REQUIRES esp_phy bt)
endif()
endif()
target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app)
endif()
# BREDR controller library
if(CONFIG_BT_CTRL_BREDR_ENABLE)
if(EXISTS "${lib_path}/libbredr_app.a")
add_prebuilt_library(libbredr_app "${lib_path}/libbredr_app.a" REQUIRES esp_phy bt)
else()
add_prebuilt_library(libbredr_app "${lib_path}/${idf_target}/libbredr_app.a" REQUIRES esp_phy bt)
endif()
target_link_libraries(${COMPONENT_LIB} PRIVATE libbredr_app)
endif()
# BTDM common library
if(CONFIG_BT_DUAL_MODE_ARCH)
if(EXISTS "${lib_path}/libbtdm_common.a")
add_prebuilt_library(libbtdm_common "${lib_path}/libbtdm_common.a" esp_phy bt)
else()
add_prebuilt_library(libbtdm_common "${lib_path}/${idf_target}/libbtdm_common.a" esp_phy bt)
endif()
target_link_libraries(${COMPONENT_LIB} PRIVATE libbtdm_common)
endif()
endif()
# Used to dump logs in the panic handler
if(CONFIG_BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE)
target_link_options(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=esp_panic_handler")
endif()
endfunction()
set(bt_ctrl_srcs "" PARENT_SCOPE)
set(bt_ctrl_include_dirs "" PARENT_SCOPE)
set(bt_ctrl_ldscripts "${ldscripts}")
set(bt_ctrl_ldscripts "${bt_ctrl_ldscripts}" PARENT_SCOPE)
# API headers that are used in the docs are also compiled
# even if CONFIG_BT_ENABLED=n as long as CONFIG_IDF_DOC_BUILD=y
if(CONFIG_IDF_DOC_BUILD AND CONFIG_SOC_BT_SUPPORTED)
get_filename_component(
_bt_ctrl_absolute_include_dir
"${CMAKE_CURRENT_LIST_DIR}/../include/${TARGET_SRC_NAME}/include"
ABSOLUTE
)
set(bt_ctrl_include_dirs "${_bt_ctrl_absolute_include_dir}" PARENT_SCOPE)
return()
endif()
if(NOT CONFIG_BT_CONTROLLER_ENABLED)
return()
endif()
# Get all the .c files in the TARGET_SRC_NAME directory
file(GLOB_RECURSE _CTRL_SRCS "${TARGET_SRC_NAME}/*.c")
list(APPEND bt_ctrl_srcs ${_CTRL_SRCS})
list(APPEND bt_ctrl_include_dirs "${CMAKE_CURRENT_LIST_DIR}/../include/${TARGET_SRC_NAME}/include")
# TODO: Move this to a separate file for the controller and the host
if(CONFIG_SOC_ESP_NIMBLE_CONTROLLER AND NOT CONFIG_BT_NIMBLE_ENABLED)
list(APPEND bt_ctrl_srcs
"${CMAKE_CURRENT_LIST_DIR}/../host/nimble/port/src/esp_nimble_mem.c"
)
list(APPEND bt_ctrl_include_dirs
"${CMAKE_CURRENT_LIST_DIR}/../host/nimble/port/include"
)
endif()
# Add the linker scripts
if(CONFIG_IDF_TARGET_ESP32)
list(APPEND bt_ctrl_srcs "${CMAKE_CURRENT_LIST_DIR}/esp32/hli_vectors.S"
"${CMAKE_CURRENT_LIST_DIR}/esp32/hli_api.c")
list(APPEND bt_ctrl_ldscripts "${CMAKE_CURRENT_LIST_DIR}/linker_rw_bt_controller.lf")
elseif(CONFIG_IDF_TARGET_ESP32C3)
list(APPEND bt_ctrl_ldscripts "${CMAKE_CURRENT_LIST_DIR}/linker_rw_bt_controller.lf")
elseif(CONFIG_IDF_TARGET_ESP32S3)
list(APPEND bt_ctrl_ldscripts "${CMAKE_CURRENT_LIST_DIR}/linker_rw_bt_controller.lf")
elseif(CONFIG_IDF_TARGET_ESP32C2)
set(bt_ctrl_ldscripts "${CMAKE_CURRENT_LIST_DIR}/linker_esp32c2.lf")
elseif(CONFIG_BT_DUAL_MODE_ARCH)
list(APPEND bt_ctrl_ldscripts "${CMAKE_CURRENT_LIST_DIR}/linker_esp_btdm_controller.lf")
else()
list(APPEND bt_ctrl_ldscripts "${CMAKE_CURRENT_LIST_DIR}/linker_esp_ble_controller.lf")
endif()
# Export the variables to the parent scope
set(bt_ctrl_srcs "${bt_ctrl_srcs}" PARENT_SCOPE)
set(bt_ctrl_include_dirs "${bt_ctrl_include_dirs}" PARENT_SCOPE)
set(bt_ctrl_ldscripts "${bt_ctrl_ldscripts}" PARENT_SCOPE)
+2 -2
View File
@@ -46,7 +46,7 @@ _l4_save_ctx:
xt_highint4:
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
#if CONFIG_ESP_INT_WDT && CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
/*
Here, Timer2 is used to count a little time(50us).
The subsequent dram0 write operation is blocked due to live lock, which will
@@ -96,7 +96,7 @@ xt_highint4:
rsr a2, EPC1
s32i a2, a0, 24
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
#if CONFIG_ESP_INT_WDT && CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
movi a0, 0
xsr a0, XT_REG_INTENABLE /* disable all interrupts */
movi a2, ~(1<<16)
+2
View File
@@ -456,6 +456,8 @@ void r_ble_lll_conn_event_delete_and_reschedule(void){}
void r_ble_lll_conn_event_delete_and_reschedule_eco4(void){}
void r_ble_ll_utils_verify_aa(void){}
void r_ble_ll_utils_verify_aa_eco4(void){}
int r_ble_lll_conn_process_rx_data_after_halt(void){return 0;}
int r_ble_lll_conn_process_rx_data_after_halt_eco4(void){return 0;}
#endif // !DEFAULT_BT_LE_ROLE_PERIPHERAL
#if !DEFAULT_BT_LE_ROLE_CENTROL && !DEFAULT_BT_LE_ROLE_PERIPHERAL
+13 -7
View File
@@ -2,6 +2,15 @@ config BT_CTRL_MODE_EFF
int
default 1
config BT_CTRL_CHECK_CONFIG_EFF
int
default 1
help
Marker that controller Kconfig is active (always set in sdkconfig).
Must not be unset in normal IDF builds. Controller-only integrations
that do not export this symbol rely on esp_bt.h to apply compile-time
defaults for missing BLE feature CONFIG_* names.
config BT_CTRL_BLE_MAX_ACT
int "BLE Max Instances"
default 6
@@ -566,7 +575,7 @@ config BT_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS
config BT_CTRL_BLE_MIN_CONN_INTERVAL_ENABLE
bool "Allow BLE connection interval below the spec minimum"
default y
select BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT if BT_BLUEDROID_ENABLED
select BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT if BT_BLUEDROID_ENABLED || BT_NIMBLE_ENABLED
help
Enabling this option allows the BLE controller to use a connection interval
smaller than the Bluetooth Core specification minimum of 7.5 ms. On
@@ -581,12 +590,9 @@ config BT_CTRL_BLE_MIN_CONN_INTERVAL_ENABLE
This option is enabled by default. Disable it to stay compliant with the BLE
specification (minimum connection interval 7.5 ms).
Host stack: When Bluedroid is the BLE host, enabling this option also selects
BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT so the host accepts connection
intervals below the spec minimum. NimBLE host does not provide equivalent
support yet; it is planned for a future release. Until then, use Bluedroid
if you need coordinated host and controller behavior for sub-minimum
intervals.
Host stack: Enabling this option also selects
BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT so the active BLE host accepts
connection intervals below the spec minimum.
menu "Controller debug log Options (Experimental)"
config BT_CTRL_LE_LOG_EN
+5
View File
@@ -1867,6 +1867,11 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
ESP_LOGI(BT_LOG_TAG, "BT controller compile version [%s]", btdm_controller_get_compile_version());
#ifndef CONFIG_BT_CTRL_CHECK_CONFIG_EFF
ESP_LOGW(BT_LOG_TAG, "CONFIG_BT_CTRL_CHECK_CONFIG_EFF is not defined; "
"using compile-time default BLE controller feature options");
#endif
#if (CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY)
ESP_LOGI(BT_LOG_TAG,"Put all controller code in flash");
#endif
+221
View File
@@ -0,0 +1,221 @@
function(register_ble_mesh_libs)
if(NOT CONFIG_BLE_MESH)
return()
endif()
if(CONFIG_BLE_MESH_V11_SUPPORT)
add_prebuilt_library(ble_mesh "esp_ble_mesh/lib/lib/${idf_target}/libble_mesh.a")
target_link_libraries(${COMPONENT_LIB} PRIVATE ble_mesh)
endif()
endfunction()
set(ble_mesh_srcs "" PARENT_SCOPE)
set(ble_mesh_include_dirs "" PARENT_SCOPE)
# API headers that are used in the docs are also compiled
# even if CONFIG_BT_ENABLED=n as long as CONFIG_IDF_DOC_BUILD=y
if(CONFIG_IDF_DOC_BUILD)
set(ble_mesh_include_dirs
"${CMAKE_CURRENT_LIST_DIR}/common/include"
"${CMAKE_CURRENT_LIST_DIR}/core"
"${CMAKE_CURRENT_LIST_DIR}/core/include"
"${CMAKE_CURRENT_LIST_DIR}/core/storage"
"${CMAKE_CURRENT_LIST_DIR}/btc/include"
"${CMAKE_CURRENT_LIST_DIR}/models/common/include"
"${CMAKE_CURRENT_LIST_DIR}/models/client/include"
"${CMAKE_CURRENT_LIST_DIR}/models/server/include"
"${CMAKE_CURRENT_LIST_DIR}/api/core/include"
"${CMAKE_CURRENT_LIST_DIR}/api/models/include"
"${CMAKE_CURRENT_LIST_DIR}/api"
# BLE Mesh v1.1 headers
"${CMAKE_CURRENT_LIST_DIR}/lib/include"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/core/include"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/models/include"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/btc/include"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/include"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/dfu"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/mbt"
PARENT_SCOPE
)
return()
endif()
if(NOT CONFIG_BLE_MESH)
return()
endif()
if(CONFIG_BLE_MESH_USE_UNIFIED_CRYPTO)
message(WARNING "This configuration path is deprecated and will be removed"
"in a future version. Please use the corresponding Kconfig"
"options under $IDF_PATH/components/bt/common/Kconfig.")
endif()
list(APPEND ble_mesh_srcs
"${CMAKE_CURRENT_LIST_DIR}/api/core/esp_ble_mesh_ble_api.c"
"${CMAKE_CURRENT_LIST_DIR}/api/core/esp_ble_mesh_common_api.c"
"${CMAKE_CURRENT_LIST_DIR}/api/core/esp_ble_mesh_local_data_operation_api.c"
"${CMAKE_CURRENT_LIST_DIR}/api/core/esp_ble_mesh_low_power_api.c"
"${CMAKE_CURRENT_LIST_DIR}/api/core/esp_ble_mesh_networking_api.c"
"${CMAKE_CURRENT_LIST_DIR}/api/core/esp_ble_mesh_provisioning_api.c"
"${CMAKE_CURRENT_LIST_DIR}/api/core/esp_ble_mesh_proxy_api.c"
"${CMAKE_CURRENT_LIST_DIR}/api/models/esp_ble_mesh_config_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/api/models/esp_ble_mesh_generic_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/api/models/esp_ble_mesh_health_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/api/models/esp_ble_mesh_lighting_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/api/models/esp_ble_mesh_sensor_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/api/models/esp_ble_mesh_time_scene_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/btc/btc_ble_mesh_ble.c"
"${CMAKE_CURRENT_LIST_DIR}/btc/btc_ble_mesh_config_model.c"
"${CMAKE_CURRENT_LIST_DIR}/btc/btc_ble_mesh_generic_model.c"
"${CMAKE_CURRENT_LIST_DIR}/btc/btc_ble_mesh_health_model.c"
"${CMAKE_CURRENT_LIST_DIR}/btc/btc_ble_mesh_lighting_model.c"
"${CMAKE_CURRENT_LIST_DIR}/btc/btc_ble_mesh_prov.c"
"${CMAKE_CURRENT_LIST_DIR}/btc/btc_ble_mesh_sensor_model.c"
"${CMAKE_CURRENT_LIST_DIR}/btc/btc_ble_mesh_time_scene_model.c"
"${CMAKE_CURRENT_LIST_DIR}/common/atomic.c"
"${CMAKE_CURRENT_LIST_DIR}/common/buf.c"
"${CMAKE_CURRENT_LIST_DIR}/common/common.c"
"${CMAKE_CURRENT_LIST_DIR}/common/kernel.c"
"${CMAKE_CURRENT_LIST_DIR}/common/mutex.c"
"${CMAKE_CURRENT_LIST_DIR}/common/queue.c"
"${CMAKE_CURRENT_LIST_DIR}/common/timer.c"
"${CMAKE_CURRENT_LIST_DIR}/common/utils.c"
"${CMAKE_CURRENT_LIST_DIR}/core/storage/settings_nvs.c"
"${CMAKE_CURRENT_LIST_DIR}/core/storage/settings_uid.c"
"${CMAKE_CURRENT_LIST_DIR}/core/storage/settings.c"
"${CMAKE_CURRENT_LIST_DIR}/core/access.c"
"${CMAKE_CURRENT_LIST_DIR}/core/adv_common.c"
"${CMAKE_CURRENT_LIST_DIR}/core/beacon.c"
"${CMAKE_CURRENT_LIST_DIR}/core/cfg_cli.c"
"${CMAKE_CURRENT_LIST_DIR}/core/cfg_srv.c"
"${CMAKE_CURRENT_LIST_DIR}/core/crypto.c"
"${CMAKE_CURRENT_LIST_DIR}/core/fast_prov.c"
"${CMAKE_CURRENT_LIST_DIR}/core/friend.c"
"${CMAKE_CURRENT_LIST_DIR}/core/health_cli.c"
"${CMAKE_CURRENT_LIST_DIR}/core/health_srv.c"
"${CMAKE_CURRENT_LIST_DIR}/core/heartbeat.c"
"${CMAKE_CURRENT_LIST_DIR}/core/local.c"
"${CMAKE_CURRENT_LIST_DIR}/core/lpn.c"
"${CMAKE_CURRENT_LIST_DIR}/core/main.c"
"${CMAKE_CURRENT_LIST_DIR}/core/net.c"
"${CMAKE_CURRENT_LIST_DIR}/core/prov_common.c"
"${CMAKE_CURRENT_LIST_DIR}/core/prov_node.c"
"${CMAKE_CURRENT_LIST_DIR}/core/prov_pvnr.c"
"${CMAKE_CURRENT_LIST_DIR}/core/proxy_client.c"
"${CMAKE_CURRENT_LIST_DIR}/core/proxy_server.c"
"${CMAKE_CURRENT_LIST_DIR}/core/pvnr_mgmt.c"
"${CMAKE_CURRENT_LIST_DIR}/core/rpl.c"
"${CMAKE_CURRENT_LIST_DIR}/core/scan.c"
"${CMAKE_CURRENT_LIST_DIR}/core/test.c"
"${CMAKE_CURRENT_LIST_DIR}/models/common/device_property.c"
"${CMAKE_CURRENT_LIST_DIR}/models/common/model_common.c"
"${CMAKE_CURRENT_LIST_DIR}/models/client/client_common.c"
"${CMAKE_CURRENT_LIST_DIR}/models/client/generic_client.c"
"${CMAKE_CURRENT_LIST_DIR}/models/client/lighting_client.c"
"${CMAKE_CURRENT_LIST_DIR}/models/client/sensor_client.c"
"${CMAKE_CURRENT_LIST_DIR}/models/client/time_scene_client.c"
"${CMAKE_CURRENT_LIST_DIR}/models/server/generic_server.c"
"${CMAKE_CURRENT_LIST_DIR}/models/server/lighting_server.c"
"${CMAKE_CURRENT_LIST_DIR}/models/server/sensor_server.c"
"${CMAKE_CURRENT_LIST_DIR}/models/server/server_common.c"
"${CMAKE_CURRENT_LIST_DIR}/models/server/state_binding.c"
"${CMAKE_CURRENT_LIST_DIR}/models/server/state_transition.c"
"${CMAKE_CURRENT_LIST_DIR}/models/server/time_scene_server.c"
)
if(CONFIG_BLE_MESH_SUPPORT_MULTI_ADV)
list(APPEND ble_mesh_srcs "${CMAKE_CURRENT_LIST_DIR}/core/ext_adv.c")
else()
list(APPEND ble_mesh_srcs "${CMAKE_CURRENT_LIST_DIR}/core/adv.c")
endif()
if(CONFIG_BLE_MESH_SUPPORT_BLE_ADV)
list(APPEND ble_mesh_srcs "${CMAKE_CURRENT_LIST_DIR}/core/ble_adv.c")
endif()
# Select crypto implementation based on config
if(CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT)
list(APPEND ble_mesh_srcs "${CMAKE_CURRENT_LIST_DIR}/common/crypto_tc.c")
elseif(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS)
if(CONFIG_MBEDTLS_VER_4_X_SUPPORT)
list(APPEND ble_mesh_srcs "${CMAKE_CURRENT_LIST_DIR}/common/crypto_psa.c")
else()
list(APPEND ble_mesh_srcs "${CMAKE_CURRENT_LIST_DIR}/common/crypto_mbedtls.c")
endif()
endif()
list(APPEND ble_mesh_include_dirs
"${CMAKE_CURRENT_LIST_DIR}/common/include"
"${CMAKE_CURRENT_LIST_DIR}/core"
"${CMAKE_CURRENT_LIST_DIR}/core/include"
"${CMAKE_CURRENT_LIST_DIR}/core/storage"
"${CMAKE_CURRENT_LIST_DIR}/btc/include"
"${CMAKE_CURRENT_LIST_DIR}/models/common/include"
"${CMAKE_CURRENT_LIST_DIR}/models/client/include"
"${CMAKE_CURRENT_LIST_DIR}/models/server/include"
"${CMAKE_CURRENT_LIST_DIR}/api/core/include"
"${CMAKE_CURRENT_LIST_DIR}/api/models/include"
"${CMAKE_CURRENT_LIST_DIR}/api"
)
if(CONFIG_BLE_MESH_V11_SUPPORT)
list(APPEND ble_mesh_include_dirs
"${CMAKE_CURRENT_LIST_DIR}/lib/include"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/core/include"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/models/include"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/btc/include"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/include"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/dfu"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/mbt"
)
list(APPEND ble_mesh_srcs
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/core/esp_ble_mesh_agg_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/core/esp_ble_mesh_brc_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/core/esp_ble_mesh_cm_data_api.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/core/esp_ble_mesh_df_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/core/esp_ble_mesh_lcd_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/core/esp_ble_mesh_odp_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/core/esp_ble_mesh_prb_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/core/esp_ble_mesh_rpr_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/core/esp_ble_mesh_sar_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/core/esp_ble_mesh_srpl_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/models/esp_ble_mesh_mbt_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/models/esp_ble_mesh_dfu_model_api.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/api/models/esp_ble_mesh_dfu_slot_api.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/btc/btc_ble_mesh_agg_model.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/btc/btc_ble_mesh_brc_model.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/btc/btc_ble_mesh_df_model.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/btc/btc_ble_mesh_dfu_model.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/btc/btc_ble_mesh_dfu_slot.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/btc/btc_ble_mesh_lcd_model.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/btc/btc_ble_mesh_mbt_model.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/btc/btc_ble_mesh_odp_model.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/btc/btc_ble_mesh_prb_model.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/btc/btc_ble_mesh_rpr_model.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/btc/btc_ble_mesh_sar_model.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/btc/btc_ble_mesh_srpl_model.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/mbt/blob_srv.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/mbt/blob_cli.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/dfu/dfu_cli.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/dfu/dfu_srv.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/dfu/dfu_slot.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/dfu/dfu_metadata.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/dfu/dfd_srv.c"
"${CMAKE_CURRENT_LIST_DIR}/v1.1/dfu/dfd_cli.c"
"${CMAKE_CURRENT_LIST_DIR}/lib/ext.c"
)
if(CONFIG_BLE_MESH_SAR_ENHANCEMENT)
list(APPEND ble_mesh_srcs "${CMAKE_CURRENT_LIST_DIR}/core/transport.enh.c")
else()
list(APPEND ble_mesh_srcs "${CMAKE_CURRENT_LIST_DIR}/core/transport.c")
endif()
else()
list(APPEND ble_mesh_srcs "${CMAKE_CURRENT_LIST_DIR}/core/transport.c")
endif()
# Export the variables to the parent scope
set(ble_mesh_srcs "${ble_mesh_srcs}" PARENT_SCOPE)
set(ble_mesh_include_dirs "${ble_mesh_include_dirs}" PARENT_SCOPE)
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -75,6 +75,13 @@ esp_err_t esp_ble_mesh_start_ble_scanning(esp_ble_mesh_ble_scan_param_t *param)
btc_ble_mesh_ble_args_t arg = {0};
btc_msg_t msg = {0};
/* Note:
* Currently the function is only used to enable reporting
* non-mesh advertising packets to the application layer,
* and the input parameter will not be used for now.
*/
ARG_UNUSED(param);
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -131,8 +131,10 @@ esp_err_t esp_ble_mesh_model_unsubscribe_group_addr(uint16_t element_addr, uint1
esp_err_t esp_ble_mesh_enable_directed_forwarding(uint16_t net_idx, bool directed_forwarding,
bool directed_forwarding_relay)
{
return btc_ble_mesh_enable_directed_forwarding(net_idx, directed_forwarding,
directed_forwarding_relay);
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_ble_mesh_enable_directed_forwarding(net_idx, directed_forwarding,
directed_forwarding_relay) == 0 ? ESP_OK : ESP_FAIL);
}
#endif /* CONFIG_BLE_MESH_DF_SRV */
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -30,6 +30,35 @@ static esp_err_t ble_mesh_model_send_msg(esp_ble_mesh_model_t *model,
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
/* When data is NULL, it is mandatory to set length to 0 to prevent users from misinterpreting parameters. */
if (data == NULL) {
length = 0;
}
/* Compute op_len from opcode before length validation */
if (opcode < 0x100) {
op_len = 1;
} else if (opcode < 0x10000) {
op_len = 2;
} else {
op_len = 3;
}
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
/* When "send_rel" is true and "send_szmic" is 1, 8-octets TransMIC will
* be used, otherwise 4-octets TransMIC will be used.
*/
mic_len = (model->pub->send_rel && model->pub->send_szmic) ?
ESP_BLE_MESH_MIC_LONG : ESP_BLE_MESH_MIC_SHORT;
} else {
/* When the message is tagged with the send-segmented tag and "send_szmic"
* is 1, 8-octets TransMIC will be used, otherwise 4-octets TransMIC will
* be used.
*/
mic_len = ((ctx->send_tag & ESP_BLE_MESH_TAG_SEND_SEGMENTED) && ctx->send_szmic) ?
ESP_BLE_MESH_MIC_LONG : ESP_BLE_MESH_MIC_SHORT;
}
if (ctx) {
if (ctx->addr == ESP_BLE_MESH_ADDR_UNASSIGNED) {
BT_ERR("Invalid destination address 0x0000");
@@ -63,6 +92,7 @@ static esp_err_t ble_mesh_model_send_msg(esp_ble_mesh_model_t *model,
ctx->enh.long_pkt_cfg != ESP_BLE_MESH_LONG_PACKET_PREFER)) {
BT_ERR("Invalid long packet configuration %d (expected FORCE=1 or PREFER=2)",
ctx->enh.long_pkt_cfg);
return ESP_ERR_INVALID_ARG;
}
if (ctx->enh.long_pkt_cfg_used && (op_len + length + mic_len > ESP_BLE_MESH_EXT_SDU_MAX_LEN)) {
@@ -82,19 +112,6 @@ static esp_err_t ble_mesh_model_send_msg(esp_ble_mesh_model_t *model,
return ESP_ERR_INVALID_ARG;
}
/* When data is NULL, it is mandatory to set length to 0 to prevent users from misinterpreting parameters. */
if (data == NULL) {
length = 0;
}
if (opcode < 0x100) {
op_len = 1;
} else if (opcode < 0x10000) {
op_len = 2;
} else {
op_len = 3;
}
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
if (op_len + length > model->pub->msg->size) {
BT_ERR("Too small publication msg size %d", model->pub->msg->size);
@@ -102,31 +119,20 @@ static esp_err_t ble_mesh_model_send_msg(esp_ble_mesh_model_t *model,
}
}
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
/* When "send_rel" is true and "send_szmic" is 1, 8-octets TransMIC will
* be used, otherwise 4-octets TransMIC will be used.
*/
mic_len = (model->pub->send_rel && model->pub->send_szmic) ?
ESP_BLE_MESH_MIC_LONG : ESP_BLE_MESH_MIC_SHORT;
} else {
/* When the message is tagged with the send-segmented tag and "send_szmic"
* is 1, 8-octets TransMIC will be used, otherwise 4-octets TransMIC will
* be used.
*/
mic_len = ((ctx->send_tag & ESP_BLE_MESH_TAG_SEND_SEGMENTED) && ctx->send_szmic) ?
ESP_BLE_MESH_MIC_LONG : ESP_BLE_MESH_MIC_SHORT;
}
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
bt_mesh_model_msg_init(model->pub->msg, opcode);
net_buf_simple_add_mem(model->pub->msg, data, length);
if (length > 0) {
net_buf_simple_add_mem(model->pub->msg, data, length);
}
} else {
msg_data = (uint8_t *)bt_mesh_calloc(op_len + length);
if (msg_data == NULL) {
return ESP_ERR_NO_MEM;
}
esp_ble_mesh_model_msg_opcode_init(msg_data, opcode);
memcpy(msg_data + op_len, data, length);
if (length > 0) {
memcpy(msg_data + op_len, data, length);
}
}
msg.sig = BTC_SIG_API_CALL;
@@ -693,6 +699,7 @@ esp_err_t esp_ble_mesh_provisioner_open_settings_with_uid(const char *uid)
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_OPEN_SETTINGS_WITH_UID;
memset(arg.open_settings_with_uid.uid, 0, sizeof(arg.open_settings_with_uid.uid));
strncpy(arg.open_settings_with_uid.uid, uid, ESP_BLE_MESH_SETTINGS_UID_SIZE);
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
@@ -736,6 +743,7 @@ esp_err_t esp_ble_mesh_provisioner_close_settings_with_uid(const char *uid, bool
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_CLOSE_SETTINGS_WITH_UID;
memset(arg.close_settings_with_uid.uid, 0, sizeof(arg.close_settings_with_uid.uid));
strncpy(arg.close_settings_with_uid.uid, uid, ESP_BLE_MESH_SETTINGS_UID_SIZE);
arg.close_settings_with_uid.erase = erase;
@@ -779,6 +787,7 @@ esp_err_t esp_ble_mesh_provisioner_delete_settings_with_uid(const char *uid)
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DELETE_SETTINGS_WITH_UID;
memset(arg.delete_settings_with_uid.uid, 0, sizeof(arg.delete_settings_with_uid.uid));
strncpy(arg.delete_settings_with_uid.uid, uid, ESP_BLE_MESH_SETTINGS_UID_SIZE);
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL)
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -44,7 +44,7 @@ static bool prov_bearers_valid(esp_ble_mesh_prov_bearer_t bearers)
esp_err_t esp_ble_mesh_node_prov_enable(esp_ble_mesh_prov_bearer_t bearers)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_ble_mesh_prov_args_t arg;
btc_msg_t msg = {0};
if (prov_bearers_valid(bearers) == false) {
@@ -200,7 +200,7 @@ esp_err_t esp_ble_mesh_provisioner_input_string(const char *string, uint8_t link
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
if (!string || strlen(string) > ESP_BLE_MESH_PROV_OUTPUT_OOB_MAX_LEN ||
if (!string || strlen(string) > ESP_BLE_MESH_PROV_INPUT_OOB_MAX_LEN ||
link_idx >= MAX_PROV_LINK_IDX) {
return ESP_ERR_INVALID_ARG;
}
@@ -482,7 +482,10 @@ esp_err_t esp_ble_mesh_set_fast_prov_info(esp_ble_mesh_fast_prov_info_t *fast_pr
btc_msg_t msg = {0};
if (fast_prov_info == NULL || (fast_prov_info->offset +
fast_prov_info->match_len > ESP_BLE_MESH_OCTET16_LEN)) {
fast_prov_info->match_len > ESP_BLE_MESH_OCTET16_LEN) ||
!ESP_BLE_MESH_ADDR_IS_UNICAST(fast_prov_info->unicast_min) ||
!ESP_BLE_MESH_ADDR_IS_UNICAST(fast_prov_info->unicast_max) ||
fast_prov_info->unicast_min > fast_prov_info->unicast_max) {
return ESP_ERR_INVALID_ARG;
}
@@ -224,7 +224,7 @@ esp_err_t esp_ble_mesh_proxy_client_directed_proxy_set(uint8_t conn_handle, uint
#endif /* CONFIG_BLE_MESH_DF_CLI */
#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX
esp_err_t esp_ble_mesh_proxy_client_send_solic_pdu(uint8_t net_idx, uint16_t ssrc, uint16_t dst)
esp_err_t esp_ble_mesh_proxy_client_send_solic_pdu(uint16_t net_idx, uint16_t ssrc, uint16_t dst)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
@@ -161,7 +161,7 @@ esp_err_t esp_ble_mesh_proxy_client_directed_proxy_set(uint8_t conn_handle, uint
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_client_send_solic_pdu(uint8_t net_idx, uint16_t ssrc, uint16_t dst);
esp_err_t esp_ble_mesh_proxy_client_send_solic_pdu(uint16_t net_idx, uint16_t ssrc, uint16_t dst);
#ifdef __cplusplus
}
@@ -14,6 +14,10 @@
#if CONFIG_BLE_MESH_CFG_CLI
esp_err_t esp_ble_mesh_register_config_client_callback(esp_ble_mesh_cfg_client_cb_t callback)
{
if (callback == NULL) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_CONFIG_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
@@ -14,6 +14,10 @@
#if CONFIG_BLE_MESH_GENERIC_CLIENT
esp_err_t esp_ble_mesh_register_generic_client_callback(esp_ble_mesh_generic_client_cb_t callback)
{
if (callback == NULL) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_GENERIC_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -14,6 +14,10 @@
#if CONFIG_BLE_MESH_HEALTH_CLI
esp_err_t esp_ble_mesh_register_health_client_callback(esp_ble_mesh_health_client_cb_t callback)
{
if (callback == NULL) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_HEALTH_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
@@ -29,7 +33,9 @@ esp_err_t esp_ble_mesh_health_client_get_state(esp_ble_mesh_client_common_param_
params->ctx.net_idx == ESP_BLE_MESH_KEY_UNUSED ||
params->ctx.app_idx == ESP_BLE_MESH_KEY_UNUSED ||
params->ctx.addr == ESP_BLE_MESH_ADDR_UNASSIGNED ||
(params->opcode == ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_GET && get_state == NULL)) {
((params->opcode == ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_GET ||
params->opcode == ESP_BLE_MESH_MODEL_OP_ATTENTION_GET ||
params->opcode == ESP_BLE_MESH_MODEL_OP_HEALTH_PERIOD_GET) && get_state == NULL)) {
return ESP_ERR_INVALID_ARG;
}
@@ -14,6 +14,10 @@
#if CONFIG_BLE_MESH_LIGHTING_CLIENT
esp_err_t esp_ble_mesh_register_light_client_callback(esp_ble_mesh_light_client_cb_t callback)
{
if (callback == NULL) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_LIGHTING_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
@@ -14,6 +14,10 @@
#if CONFIG_BLE_MESH_SENSOR_CLI
esp_err_t esp_ble_mesh_register_sensor_client_callback(esp_ble_mesh_sensor_client_cb_t callback)
{
if (callback == NULL) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_SENSOR_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
@@ -495,7 +495,8 @@ esp_err_t esp_ble_mesh_register_generic_client_callback(esp_ble_mesh_generic_cli
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] get_state: Pointer to generic get message value.
* Shall not be set to NULL.
* Shall not be set to NULL when the opcode requires
* parameters (property-related GET operations).
*
* @return ESP_OK on success or error code otherwise.
*
@@ -551,7 +551,8 @@ esp_err_t esp_ble_mesh_register_light_client_callback(esp_ble_mesh_light_client_
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] get_state: Pointer of light get message value.
* Shall not be set to NULL.
* Shall not be set to NULL when the opcode requires
* parameters (e.g., ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_GET).
*
* @return ESP_OK on success or error code otherwise.
*
@@ -38,6 +38,7 @@ static void btc_ble_mesh_ble_copy_req_data(btc_msg_t *msg, void *p_dst, void *p_
p_src_data->scan_ble_adv_pkt.length);
} else {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
p_dst_data->scan_ble_adv_pkt.length = 0;
}
}
break;
@@ -248,6 +248,7 @@ static void btc_ble_mesh_config_client_copy_req_data(btc_msg_t *msg, void *p_des
break;
}
}
__attribute__((fallthrough));
case ESP_BLE_MESH_CFG_CLIENT_TIMEOUT_EVT:
break;
default:
@@ -300,6 +301,7 @@ static void btc_ble_mesh_config_client_free_req_data(btc_msg_t *msg)
break;
}
}
__attribute__((fallthrough));
case ESP_BLE_MESH_CFG_CLIENT_TIMEOUT_EVT:
if (arg->params) {
bt_mesh_free(arg->params);
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -54,7 +54,7 @@ void btc_ble_mesh_generic_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, voi
dst->generic_client_get_state.get_state = (esp_ble_mesh_generic_client_get_state_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_generic_client_get_state_t));
if (dst->generic_client_get_state.get_state) {
memcpy(dst->generic_client_get_state.get_state, src->generic_client_get_state.get_state,
sizeof(esp_ble_mesh_generic_client_get_state_t));
sizeof(esp_ble_mesh_generic_client_get_state_t));
} else {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
/* Free the previously allocated resources */
@@ -146,6 +146,11 @@ void btc_ble_mesh_generic_client_arg_deep_free(btc_msg_t *msg)
}
arg = (btc_ble_mesh_generic_client_args_t *)(msg->arg);
/**
* msg->arg is guaranteed to be non-NULL by btc_transfer_context
*/
ESP_ASSUME_NONNULL(arg);
switch (msg->act) {
case BTC_BLE_MESH_ACT_GENERIC_CLIENT_GET_STATE:
@@ -334,6 +339,7 @@ static void btc_ble_mesh_generic_client_copy_req_data(btc_msg_t *msg, void *p_de
break;
}
}
__attribute__((fallthrough));
case ESP_BLE_MESH_GENERIC_CLIENT_TIMEOUT_EVT:
break;
default:
@@ -393,6 +399,7 @@ static void btc_ble_mesh_generic_client_free_req_data(btc_msg_t *msg)
break;
}
}
__attribute__((fallthrough));
case ESP_BLE_MESH_GENERIC_CLIENT_TIMEOUT_EVT:
if (arg->params) {
bt_mesh_free(arg->params);
@@ -53,7 +53,7 @@ void btc_ble_mesh_health_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void
dst->health_client_get_state.get_state = (esp_ble_mesh_health_client_get_state_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_health_client_get_state_t));
if (dst->health_client_get_state.get_state) {
memcpy(dst->health_client_get_state.get_state, src->health_client_get_state.get_state,
sizeof(esp_ble_mesh_health_client_get_state_t));
sizeof(esp_ble_mesh_health_client_get_state_t));
} else {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
/* Free the previously allocated resources */
@@ -192,6 +192,7 @@ static void btc_ble_mesh_health_client_copy_req_data(btc_msg_t *msg, void *p_des
break;
}
}
__attribute__((fallthrough));
case ESP_BLE_MESH_HEALTH_CLIENT_TIMEOUT_EVT:
break;
default:
@@ -229,6 +230,7 @@ static void btc_ble_mesh_health_client_free_req_data(btc_msg_t *msg)
break;
}
}
__attribute__((fallthrough));
case ESP_BLE_MESH_HEALTH_CLIENT_TIMEOUT_EVT:
if (arg->params) {
bt_mesh_free(arg->params);
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -176,6 +176,7 @@ static void btc_ble_mesh_lighting_client_copy_req_data(btc_msg_t *msg, void *p_d
break;
}
}
__attribute__((fallthrough));
case ESP_BLE_MESH_LIGHT_CLIENT_TIMEOUT_EVT:
break;
default:
@@ -209,6 +210,7 @@ static void btc_ble_mesh_lighting_client_free_req_data(btc_msg_t *msg)
break;
}
}
__attribute__((fallthrough));
case ESP_BLE_MESH_LIGHT_CLIENT_TIMEOUT_EVT:
if (arg->params) {
bt_mesh_free(arg->params);
@@ -458,13 +460,13 @@ static void btc_ble_mesh_lighting_server_free_req_data(btc_msg_t *msg)
switch (msg->act) {
case ESP_BLE_MESH_LIGHTING_SERVER_STATE_CHANGE_EVT:
if (arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET ||
arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK) {
arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK) {
bt_mesh_free_buf(arg->value.state_change.lc_property_set.property_value);
}
break;
case ESP_BLE_MESH_LIGHTING_SERVER_RECV_SET_MSG_EVT:
if (arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET ||
arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK) {
arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK) {
bt_mesh_free_buf(arg->value.set.lc_property.property_value);
}
break;
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -208,7 +208,7 @@ static void btc_ble_mesh_prov_copy_req_data(btc_msg_t *msg, void *p_dest, void *
#if CONFIG_BLE_MESH_CERT_BASED_PROV
case ESP_BLE_MESH_PROVISIONER_RECV_PROV_RECORDS_LIST_EVT:
if (p_src_data->recv_provisioner_records_list.msg &&
p_src_data->recv_provisioner_records_list.len) {
p_src_data->recv_provisioner_records_list.len) {
p_dest_data->recv_provisioner_records_list.msg = (uint8_t *)bt_mesh_calloc(p_src_data->recv_provisioner_records_list.len);
if (!p_dest_data->recv_provisioner_records_list.msg) {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
@@ -222,7 +222,7 @@ static void btc_ble_mesh_prov_copy_req_data(btc_msg_t *msg, void *p_dest, void *
break;
case ESP_BLE_MESH_PROVISIONER_PROV_RECORD_RECV_COMP_EVT:
if (p_src_data->provisioner_prov_record_recv_comp.record &&
p_src_data->provisioner_prov_record_recv_comp.total_len) {
p_src_data->provisioner_prov_record_recv_comp.total_len) {
p_dest_data->provisioner_prov_record_recv_comp.record = bt_mesh_calloc(p_src_data->provisioner_prov_record_recv_comp.total_len);
if (!p_dest_data->provisioner_prov_record_recv_comp.record) {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
@@ -263,10 +263,11 @@ static void btc_ble_mesh_prov_free_req_data(btc_msg_t *msg)
bt_mesh_free(arg->provisioner_prov_record_recv_comp.record);
}
break;
#else /* CONFIG_BLE_MESH_CERT_BASED_PROV */
ARG_UNUSED(arg);
#endif /* CONFIG_BLE_MESH_CERT_BASED_PROV */
default:
#if !CONFIG_BLE_MESH_CERT_BASED_PROV
ARG_UNUSED(arg);
#endif /* !CONFIG_BLE_MESH_CERT_BASED_PROV */
break;
}
}
@@ -381,7 +382,7 @@ static void btc_ble_mesh_model_copy_req_data(btc_msg_t *msg, void *p_dest, void
}
if (p_src_data->model_operation.msg &&
p_src_data->model_operation.length) {
p_src_data->model_operation.length) {
p_dest_data->model_operation.msg = (uint8_t *)bt_mesh_calloc(p_src_data->model_operation.length);
if (!p_dest_data->model_operation.msg) {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
@@ -412,7 +413,7 @@ static void btc_ble_mesh_model_copy_req_data(btc_msg_t *msg, void *p_dest, void
}
if (p_src_data->client_recv_publish_msg.msg &&
p_src_data->client_recv_publish_msg.length) {
p_src_data->client_recv_publish_msg.length) {
p_dest_data->client_recv_publish_msg.msg = (uint8_t *)bt_mesh_calloc(p_src_data->client_recv_publish_msg.length);
if (!p_dest_data->client_recv_publish_msg.msg) {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
@@ -530,6 +531,14 @@ static void btc_ble_mesh_server_model_op_cb(struct bt_mesh_model *model,
{
esp_ble_mesh_model_cb_param_t mesh_param = {0};
/**
* model,ctx and buf is guaranteed to be non-NULL
* by bt_mesh_model_recv in access.c
*/
ESP_ASSUME_NONNULL(model);
ESP_ASSUME_NONNULL(ctx);
ESP_ASSUME_NONNULL(buf);
mesh_param.model_operation.opcode = ctx->recv_op;
mesh_param.model_operation.model = (esp_ble_mesh_model_t *)model;
mesh_param.model_operation.ctx = (esp_ble_mesh_msg_ctx_t *)ctx;
@@ -707,7 +716,7 @@ static int btc_ble_mesh_output_string_cb(const char *str)
memset(mesh_param.node_prov_output_str.string, 0, sizeof(mesh_param.node_prov_output_str.string));
strncpy(mesh_param.node_prov_output_str.string, str,
MIN(strlen(str), sizeof(mesh_param.node_prov_output_str.string)));
MIN(strlen(str), sizeof(mesh_param.node_prov_output_str.string) - 1));
ret = btc_ble_mesh_prov_callback(&mesh_param, ESP_BLE_MESH_NODE_PROV_OUTPUT_STRING_EVT);
return (ret == BT_STATUS_SUCCESS) ? 0 : -1;
@@ -797,7 +806,7 @@ static void btc_ble_mesh_provisioner_recv_unprov_adv_pkt_cb(const uint8_t addr[6
esp_ble_mesh_prov_cb_param_t mesh_param = {0};
if (addr == NULL || dev_uuid == NULL ||
(bearer != BLE_MESH_PROV_ADV && bearer != BLE_MESH_PROV_GATT)) {
(bearer != BLE_MESH_PROV_ADV && bearer != BLE_MESH_PROV_GATT)) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
@@ -850,6 +859,17 @@ static int btc_ble_mesh_provisioner_prov_output_cb(uint8_t method, bt_mesh_input
mesh_param.provisioner_prov_output.size = size;
mesh_param.provisioner_prov_output.link_idx = link_idx;
if (act == BLE_MESH_ENTER_STRING) {
/**
* data is guaranteed to be non-NULL by `prov_auth` in `prov_pvnr.c`
*/
ESP_ASSUME_NONNULL(data);
/**
* The size of the string should be less than or equal to 8 bytes,
* which is defined in the Bluetooth Mesh Profile Specification 5.4.1.3.
* Moreover, the size used here has been verified by the protocol stack
* and is legitimate, so it will definitely not cause a string out-of-bounds
* issue.
*/
strncpy(mesh_param.provisioner_prov_output.string, (char *)data, size);
} else {
mesh_param.provisioner_prov_output.number = sys_get_le32((uint8_t *)data);
@@ -1160,7 +1180,10 @@ int btc_ble_mesh_client_model_init(esp_ble_mesh_model_t *model)
return -EINVAL;
}
__ASSERT(model && model->op, "Invalid parameter");
if (!model || !model->op) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
esp_ble_mesh_model_op_t *op = model->op;
while (op && op->opcode != 0) {
op->param_cb = (esp_ble_mesh_cb_t)btc_ble_mesh_client_model_op_cb;
@@ -2351,7 +2374,7 @@ static void btc_ble_mesh_model_op_set(esp_ble_mesh_model_t *model)
model->pub->update = (esp_ble_mesh_cb_t)btc_ble_mesh_model_publish_update;
}
break;
#endif /* CONFIG_BLE_MESH_DFD_SRV */
#endif /* CONFIG_BLE_MESH_DFD_CLI */
default:
goto set_vnd_op;
}
@@ -2390,6 +2413,7 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
esp_ble_mesh_model_t *sig_model = &elem->sig_models[j];
if (sig_model->op && BLE_MESH_MODEL_OP_LEN(sig_model->op->opcode) == 3) {
/* Opcode of SIG model must be 1 or 2 bytes. */
xSemaphoreGive(arg->mesh_init.semaphore);
btc_ble_mesh_prov_register_complete_cb(-EINVAL);
return;
}
@@ -2400,6 +2424,7 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
esp_ble_mesh_model_t *vnd_model = &elem->vnd_models[k];
if (vnd_model->op && BLE_MESH_MODEL_OP_LEN(vnd_model->op->opcode) < 3) {
/* Opcode of vendor model must be 3 bytes. */
xSemaphoreGive(arg->mesh_init.semaphore);
btc_ble_mesh_prov_register_complete_cb(-EINVAL);
return;
}
@@ -2588,9 +2613,9 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
act = ESP_BLE_MESH_PROVISIONER_PROV_DEV_WITH_ADDR_COMP_EVT;
param.provisioner_prov_dev_with_addr_comp.err_code =
bt_mesh_provisioner_prov_device_with_addr(arg->provisioner_prov_dev_with_addr.uuid,
arg->provisioner_prov_dev_with_addr.addr, arg->provisioner_prov_dev_with_addr.addr_type,
arg->provisioner_prov_dev_with_addr.bearer, arg->provisioner_prov_dev_with_addr.oob_info,
arg->provisioner_prov_dev_with_addr.unicast_addr);
arg->provisioner_prov_dev_with_addr.addr, arg->provisioner_prov_dev_with_addr.addr_type,
arg->provisioner_prov_dev_with_addr.bearer, arg->provisioner_prov_dev_with_addr.oob_info,
arg->provisioner_prov_dev_with_addr.unicast_addr);
break;
case BTC_BLE_MESH_ACT_PROVISIONER_DEV_DEL: {
struct bt_mesh_device_delete del_dev = {0};
@@ -2608,9 +2633,9 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
act = ESP_BLE_MESH_PROVISIONER_SET_DEV_UUID_MATCH_COMP_EVT;
param.provisioner_set_dev_uuid_match_comp.err_code =
bt_mesh_provisioner_set_dev_uuid_match(arg->set_dev_uuid_match.offset,
arg->set_dev_uuid_match.match_len,
arg->set_dev_uuid_match.match_val,
arg->set_dev_uuid_match.prov_after_match);
arg->set_dev_uuid_match.match_len,
arg->set_dev_uuid_match.match_val,
arg->set_dev_uuid_match.prov_after_match);
break;
case BTC_BLE_MESH_ACT_PROVISIONER_SET_PROV_DATA_INFO: {
struct bt_mesh_prov_data_info info = {0};
@@ -2653,7 +2678,7 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
act = ESP_BLE_MESH_PROVISIONER_ADD_LOCAL_APP_KEY_COMP_EVT;
param.provisioner_add_app_key_comp.err_code =
bt_mesh_provisioner_local_app_key_add(app_key, arg->add_local_app_key.net_idx,
&arg->add_local_app_key.app_idx);
&arg->add_local_app_key.app_idx);
param.provisioner_add_app_key_comp.net_idx = arg->add_local_app_key.net_idx;
param.provisioner_add_app_key_comp.app_idx = arg->add_local_app_key.app_idx;
break;
@@ -2664,7 +2689,7 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
param.provisioner_update_app_key_comp.app_idx = arg->update_local_app_key.app_idx;
param.provisioner_update_app_key_comp.err_code =
bt_mesh_provisioner_local_app_key_update(arg->update_local_app_key.app_key,
arg->update_local_app_key.net_idx, arg->update_local_app_key.app_idx);
arg->update_local_app_key.net_idx, arg->update_local_app_key.app_idx);
break;
case BTC_BLE_MESH_ACT_PROVISIONER_BIND_LOCAL_MOD_APP:
act = ESP_BLE_MESH_PROVISIONER_BIND_APP_KEY_TO_MODEL_COMP_EVT;
@@ -2674,9 +2699,9 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
param.provisioner_bind_app_key_to_model_comp.model_id = arg->local_mod_app_bind.model_id;
param.provisioner_bind_app_key_to_model_comp.err_code =
bt_mesh_provisioner_bind_local_model_app_idx(arg->local_mod_app_bind.elem_addr,
arg->local_mod_app_bind.model_id,
arg->local_mod_app_bind.cid,
arg->local_mod_app_bind.app_idx);
arg->local_mod_app_bind.model_id,
arg->local_mod_app_bind.cid,
arg->local_mod_app_bind.app_idx);
break;
case BTC_BLE_MESH_ACT_PROVISIONER_ADD_LOCAL_NET_KEY: {
const uint8_t *net_key = NULL;
@@ -2695,14 +2720,14 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
param.provisioner_update_net_key_comp.net_idx = arg->update_local_net_key.net_idx;
param.provisioner_update_net_key_comp.err_code =
bt_mesh_provisioner_local_net_key_update(arg->update_local_net_key.net_key,
arg->update_local_net_key.net_idx);
arg->update_local_net_key.net_idx);
break;
case BTC_BLE_MESH_ACT_PROVISIONER_STORE_NODE_COMP_DATA:
act = ESP_BLE_MESH_PROVISIONER_STORE_NODE_COMP_DATA_COMP_EVT;
param.provisioner_store_node_comp_data_comp.addr = arg->store_node_comp_data.unicast_addr;
param.provisioner_store_node_comp_data_comp.err_code =
bt_mesh_provisioner_store_node_comp_data(arg->store_node_comp_data.unicast_addr,
arg->store_node_comp_data.data, arg->store_node_comp_data.length);
arg->store_node_comp_data.data, arg->store_node_comp_data.length);
break;
case BTC_BLE_MESH_ACT_PROVISIONER_DELETE_NODE_WITH_UUID:
act = ESP_BLE_MESH_PROVISIONER_DELETE_NODE_WITH_UUID_COMP_EVT;
@@ -2794,11 +2819,11 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
break;
#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */
#if CONFIG_BLE_MESH_CERT_BASED_PROV
extern int bt_mesh_provisioner_send_prov_records_get(uint16_t link_idx);
extern int bt_mesh_provisioner_send_prov_record_req(uint16_t link_idx, uint16_t record_id,
uint16_t frag_offset, uint16_t max_size);
extern int bt_mesh_provisioner_send_prov_invite(uint16_t link_idx);
extern int bt_mesh_provisioner_send_link_close(uint16_t link_idx);
extern int bt_mesh_provisioner_send_prov_records_get(uint16_t link_idx);
extern int bt_mesh_provisioner_send_prov_record_req(uint16_t link_idx, uint16_t record_id,
uint16_t frag_offset, uint16_t max_size);
extern int bt_mesh_provisioner_send_prov_invite(uint16_t link_idx);
extern int bt_mesh_provisioner_send_link_close(uint16_t link_idx);
case BTC_BLE_MESH_ACT_PROVISIONER_SEND_PROV_RECORDS_GET:
act = ESP_BLE_MESH_PROVISIONER_SEND_PROV_RECORDS_GET_EVT;
@@ -2837,13 +2862,13 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
act = ESP_BLE_MESH_SET_FAST_PROV_INFO_COMP_EVT;
param.set_fast_prov_info_comp.status_unicast =
bt_mesh_set_fast_prov_unicast_addr_range(arg->set_fast_prov_info.unicast_min,
arg->set_fast_prov_info.unicast_max);
arg->set_fast_prov_info.unicast_max);
param.set_fast_prov_info_comp.status_net_idx =
bt_mesh_set_fast_prov_net_idx(arg->set_fast_prov_info.net_idx);
param.set_fast_prov_info_comp.status_match =
bt_mesh_provisioner_set_dev_uuid_match(arg->set_fast_prov_info.offset,
arg->set_fast_prov_info.match_len,
arg->set_fast_prov_info.match_val, false);
arg->set_fast_prov_info.match_len,
arg->set_fast_prov_info.match_val, false);
break;
case BTC_BLE_MESH_ACT_SET_FAST_PROV_ACTION:
act = ESP_BLE_MESH_SET_FAST_PROV_ACTION_COMP_EVT;
@@ -3039,11 +3064,18 @@ void btc_ble_mesh_model_call_handler(btc_msg_t *msg)
break;
}
case BTC_BLE_MESH_ACT_SERVER_MODEL_SEND: {
assert(arg->model_send.model);
assert(arg->model_send.ctx);
if (arg->model_send.length) {
assert(arg->model_send.data);
}
/**
* model,ctx and data is guaranteed to be non-NULL
* by esp_ble_mesh_server_model_send_msg in esp_ble_mesh_networking_api.c
*/
ESP_ASSUME_NONNULL(arg->model_send.model);
ESP_ASSUME_NONNULL(arg->model_send.ctx);
ESP_ASSUME_NONNULL(arg->model_send.data);
/**
* length is guaranteed to be greater than 0 (opcode length + payload length)
* by ble_mesh_model_send_msg in esp_ble_mesh_networking_api.c
*/
ESP_ASSUME_NONNULL(arg->model_send.length);
/* arg->model_send.length contains opcode & payload, plus extra 4-bytes TransMIC */
struct net_buf_simple *buf = bt_mesh_alloc_buf(arg->model_send.length + BLE_MESH_MIC_SHORT);
@@ -3109,7 +3141,7 @@ void btc_ble_mesh_model_call_handler(btc_msg_t *msg)
(struct bt_mesh_model *)arg->model_update_state.model, arg->model_update_state.type,
(bt_mesh_server_state_value_t *)arg->model_update_state.value);
btc_ble_mesh_server_model_update_state_comp_cb(arg->model_update_state.model,
arg->model_update_state.type, err);
arg->model_update_state.type, err);
break;
#endif /* CONFIG_BLE_MESH_SERVER_MODEL */
default:
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -86,7 +86,6 @@ void btc_ble_mesh_sensor_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void
length = src->sensor_client_get_state.get_state->series_get.raw_value_x1->len;
dst->sensor_client_get_state.get_state->series_get.raw_value_x1 = bt_mesh_alloc_buf(length);
if (!dst->sensor_client_get_state.get_state->series_get.raw_value_x1) {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
/* Free the previously allocated resources */
bt_mesh_free(dst->sensor_client_get_state.params);
@@ -103,7 +102,6 @@ void btc_ble_mesh_sensor_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void
length = src->sensor_client_get_state.get_state->series_get.raw_value_x2->len;
dst->sensor_client_get_state.get_state->series_get.raw_value_x2 = bt_mesh_alloc_buf(length);
if (!dst->sensor_client_get_state.get_state->series_get.raw_value_x2) {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
/* Free the previously allocated resources */
if (dst->sensor_client_get_state.get_state->series_get.raw_value_x1) {
@@ -499,6 +497,7 @@ static void btc_ble_mesh_sensor_client_copy_req_data(btc_msg_t *msg, void *p_des
break;
}
}
__attribute__((fallthrough));
case ESP_BLE_MESH_SENSOR_CLIENT_TIMEOUT_EVT:
break;
default:
@@ -557,6 +556,7 @@ static void btc_ble_mesh_sensor_client_free_req_data(btc_msg_t *msg)
break;
}
}
__attribute__((fallthrough));
case ESP_BLE_MESH_SENSOR_CLIENT_TIMEOUT_EVT:
if (arg->params) {
bt_mesh_free(arg->params);
@@ -759,6 +759,7 @@ static void btc_ble_mesh_sensor_server_copy_req_data(btc_msg_t *msg, void *p_des
p_dest_data->value.state_change.sensor_cadence_set.trigger_delta_up = bt_mesh_alloc_buf(length);
if (p_dest_data->value.state_change.sensor_cadence_set.trigger_delta_up == NULL) {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
/* The allocated memory will be released by btc_ble_mesh_sensor_server_free_req_data */
return;
}
net_buf_simple_add_mem(p_dest_data->value.state_change.sensor_cadence_set.trigger_delta_up,
@@ -770,6 +771,7 @@ static void btc_ble_mesh_sensor_server_copy_req_data(btc_msg_t *msg, void *p_des
p_dest_data->value.state_change.sensor_cadence_set.fast_cadence_low = bt_mesh_alloc_buf(length);
if (p_dest_data->value.state_change.sensor_cadence_set.fast_cadence_low == NULL) {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
/* The allocated memory will be released by btc_ble_mesh_sensor_server_free_req_data */
return;
}
net_buf_simple_add_mem(p_dest_data->value.state_change.sensor_cadence_set.fast_cadence_low,
@@ -781,6 +783,7 @@ static void btc_ble_mesh_sensor_server_copy_req_data(btc_msg_t *msg, void *p_des
p_dest_data->value.state_change.sensor_cadence_set.fast_cadence_high = bt_mesh_alloc_buf(length);
if (p_dest_data->value.state_change.sensor_cadence_set.fast_cadence_high == NULL) {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
/* The allocated memory will be released by btc_ble_mesh_sensor_server_free_req_data */
return;
}
net_buf_simple_add_mem(p_dest_data->value.state_change.sensor_cadence_set.fast_cadence_high,
@@ -877,7 +880,7 @@ static void btc_ble_mesh_sensor_server_free_req_data(btc_msg_t *msg)
switch (msg->act) {
case ESP_BLE_MESH_SENSOR_SERVER_STATE_CHANGE_EVT:
if (arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET ||
arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET_UNACK) {
arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET_UNACK) {
bt_mesh_free_buf(arg->value.state_change.sensor_cadence_set.trigger_delta_down);
bt_mesh_free_buf(arg->value.state_change.sensor_cadence_set.trigger_delta_up);
bt_mesh_free_buf(arg->value.state_change.sensor_cadence_set.fast_cadence_low);
@@ -896,7 +899,7 @@ static void btc_ble_mesh_sensor_server_free_req_data(btc_msg_t *msg)
break;
case ESP_BLE_MESH_SENSOR_SERVER_RECV_SET_MSG_EVT:
if (arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET ||
arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET_UNACK) {
arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET_UNACK) {
bt_mesh_free_buf(arg->value.set.sensor_cadence.cadence);
} else if (arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET ||
arg->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET_UNACK) {
@@ -176,6 +176,7 @@ static void btc_ble_mesh_time_scene_client_copy_req_data(btc_msg_t *msg, void *p
break;
}
}
__attribute__((fallthrough));
case ESP_BLE_MESH_TIME_SCENE_CLIENT_TIMEOUT_EVT:
break;
default:
@@ -210,6 +211,7 @@ static void btc_ble_mesh_time_scene_client_free_req_data(btc_msg_t *msg)
break;
}
}
__attribute__((fallthrough));
case ESP_BLE_MESH_TIME_SCENE_CLIENT_TIMEOUT_EVT:
if (arg->params) {
bt_mesh_free(arg->params);
+21 -13
View File
@@ -13,7 +13,7 @@
/*
* SPDX-FileCopyrightText: 2016 Intel Corporation
* SPDX-FileCopyrightText: 2011-2014 Wind River Systems, Inc.
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -24,20 +24,28 @@
#ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN
/**
*
* @brief Atomic get primitive
*
* @param target memory location to read from
*
* This routine provides the atomic get primitive to atomically read
* a value from <target>. It simply does an ordinary load. Note that <target>
* is expected to be aligned to a 4-byte boundary.
*
* @return The value read from <target>
*/
*
* @brief Atomic get primitive
*
* @param target memory location to read from
*
* This routine provides the atomic get primitive to atomically read
* a value from <target>. It simply does an ordinary load. Note that <target>
* is expected to be aligned to a 4-byte boundary.
*
* @return The value read from <target>
*/
bt_mesh_atomic_val_t bt_mesh_atomic_get(const bt_mesh_atomic_t *target)
{
return *target;
bt_mesh_atomic_val_t ret;
bt_mesh_atomic_lock();
ret = *target;
bt_mesh_atomic_unlock();
return ret;
}
/**
+33 -15
View File
@@ -1,6 +1,6 @@
/*
* SPDX-FileCopyrightText: 2015 Intel Corporation
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -378,6 +378,8 @@ void net_buf_reset(struct net_buf *buf)
void net_buf_simple_init_with_data(struct net_buf_simple *buf,
void *data, size_t size)
{
NET_BUF_ASSERT(size <= UINT16_MAX);
buf->__buf = data;
buf->data = data;
buf->size = size;
@@ -388,6 +390,7 @@ void net_buf_simple_reserve(struct net_buf_simple *buf, size_t reserve)
{
NET_BUF_ASSERT(buf);
NET_BUF_ASSERT(buf->len == 0U);
NET_BUF_ASSERT(reserve <= buf->size);
NET_BUF_DBG("buf %p reserve %zu", buf, reserve);
buf->data = buf->__buf + reserve;
@@ -416,18 +419,16 @@ struct net_buf *net_buf_slist_get(sys_slist_t *list)
NET_BUF_ASSERT(list);
bt_mesh_list_lock();
buf = (void *)sys_slist_get(list);
bt_mesh_list_unlock();
buf = (void *)sys_slist_get(list);
if (!buf) {
bt_mesh_list_unlock();
return NULL;
}
/* Get any fragments belonging to this buffer */
for (frag = buf; (frag->flags & NET_BUF_FRAGS); frag = frag->frags) {
bt_mesh_list_lock();
frag->frags = (void *)sys_slist_get(list);
bt_mesh_list_unlock();
NET_BUF_ASSERT(frag->frags);
@@ -435,6 +436,8 @@ struct net_buf *net_buf_slist_get(sys_slist_t *list)
frag->flags &= ~NET_BUF_FRAGS;
}
bt_mesh_list_unlock();
/* Mark the end of the fragment list */
frag->frags = NULL;
@@ -447,7 +450,10 @@ struct net_buf *net_buf_ref(struct net_buf *buf)
NET_BUF_DBG("buf %p (old) ref %u pool %p", buf, buf->ref, buf->pool);
bt_mesh_buf_lock();
buf->ref++;
bt_mesh_buf_unlock();
return buf;
}
@@ -459,6 +465,8 @@ void net_buf_unref(struct net_buf *buf)
{
NET_BUF_ASSERT(buf);
bt_mesh_buf_lock();
while (buf) {
struct net_buf *frags = buf->frags;
struct net_buf_pool *pool = NULL;
@@ -467,6 +475,7 @@ void net_buf_unref(struct net_buf *buf)
if (!buf->ref) {
NET_BUF_ERR("%s():%d: buf %p double free", func, line,
buf);
bt_mesh_buf_unlock();
return;
}
#endif
@@ -475,6 +484,7 @@ void net_buf_unref(struct net_buf *buf)
/* Changed by Espressif. Add !buf->ref to avoid minus 0 */
if (!buf->ref || --buf->ref > 0) {
bt_mesh_buf_unlock();
return;
}
@@ -496,6 +506,8 @@ void net_buf_unref(struct net_buf *buf)
buf = frags;
}
bt_mesh_buf_unlock();
}
static uint8_t *fixed_data_alloc(struct net_buf *buf, size_t *size, int32_t timeout)
@@ -525,6 +537,10 @@ static uint8_t *data_alloc(struct net_buf *buf, size_t *size, int32_t timeout)
return pool->alloc->cb->alloc(buf, size, timeout);
}
/**
* When using this function, Must ensure that the lock for
* buf->pool has been acquired; otherwise, race conditions may occur.
*/
#if CONFIG_BLE_MESH_NET_BUF_LOG
struct net_buf *net_buf_alloc_len_debug(struct net_buf_pool *pool, size_t size,
int32_t timeout, const char *func, int line)
@@ -541,11 +557,6 @@ struct net_buf *net_buf_alloc_len(struct net_buf_pool *pool, size_t size,
NET_BUF_DBG("Alloc, pool %p, uninit_count %d, buf_count %d",
pool, pool->uninit_count, pool->buf_count);
/* We need to lock interrupts temporarily to prevent race conditions
* when accessing pool->uninit_count.
*/
bt_mesh_buf_lock();
/* If there are uninitialized buffers we're guaranteed to succeed
* with the allocation one way or another.
*/
@@ -554,14 +565,11 @@ struct net_buf *net_buf_alloc_len(struct net_buf_pool *pool, size_t size,
for (i = pool->buf_count; i > 0; i--) {
buf = pool_get_uninit(pool, i);
if (!buf->ref) {
bt_mesh_buf_unlock();
goto success;
}
}
}
bt_mesh_buf_unlock();
NET_BUF_ERR("Out of free buffer, pool %p", pool);
return NULL;
@@ -600,15 +608,25 @@ struct net_buf *net_buf_alloc_fixed_debug(struct net_buf_pool *pool,
int line)
{
const struct net_buf_pool_fixed *fixed = pool->alloc->alloc_data;
struct net_buf *buf = NULL;
return net_buf_alloc_len_debug(pool, fixed->data_size, timeout, func, line);
bt_mesh_buf_lock();
buf = net_buf_alloc_len_debug(pool, fixed->data_size, timeout, func, line);
bt_mesh_buf_unlock();
return buf;
}
#else
struct net_buf *net_buf_alloc_fixed(struct net_buf_pool *pool, int32_t timeout)
{
const struct net_buf_pool_fixed *fixed = pool->alloc->alloc_data;
struct net_buf *buf = NULL;
return net_buf_alloc_len(pool, fixed->data_size, timeout);
bt_mesh_buf_lock();
buf = net_buf_alloc_len(pool, fixed->data_size, timeout);
bt_mesh_buf_unlock();
return buf;
}
#endif
@@ -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
*/
@@ -112,10 +112,14 @@ int bt_mesh_ccm_encrypt_raw_key(const uint8_t key[16], uint8_t nonce[13],
uint8_t *enc_data, size_t mic_size)
{
struct bt_mesh_key mesh_key;
int ret;
memcpy(mesh_key.key, key, 16);
return bt_mesh_ccm_encrypt(&mesh_key, nonce, plaintext, len, aad, aad_len,
enc_data, mic_size);
ret = bt_mesh_ccm_encrypt(&mesh_key, nonce, plaintext, len, aad, aad_len,
enc_data, mic_size);
mbedtls_platform_zeroize(&mesh_key, sizeof(mesh_key));
return ret;
}
int bt_mesh_ccm_decrypt_raw_key(const uint8_t key[16], uint8_t nonce[13],
@@ -124,10 +128,14 @@ int bt_mesh_ccm_decrypt_raw_key(const uint8_t key[16], uint8_t nonce[13],
uint8_t *plaintext, size_t mic_size)
{
struct bt_mesh_key mesh_key;
int ret;
memcpy(mesh_key.key, key, 16);
return bt_mesh_ccm_decrypt(&mesh_key, nonce, enc_data, len, aad, aad_len,
plaintext, mic_size);
ret = bt_mesh_ccm_decrypt(&mesh_key, nonce, enc_data, len, aad, aad_len,
plaintext, mic_size);
mbedtls_platform_zeroize(&mesh_key, sizeof(mesh_key));
return ret;
}
int bt_mesh_aes_cmac_mesh_key(const struct bt_mesh_key *key,
@@ -230,6 +238,10 @@ int bt_mesh_pub_key_gen(void)
dh_pair.is_ready = false;
do {
/**
* For now, there is no need to consider the security
* of the private key generated by the random function.
*/
err = bt_mesh_rand(dh_pair.private_key, sizeof(dh_pair.private_key));
if (err) {
BT_ERR("Failed to generate random private key");
@@ -360,12 +372,12 @@ bool bt_mesh_check_public_key_raw(const uint8_t key[64])
goto cleanup;
}
ret = mbedtls_mpi_read_binary(&Q.MBEDTLS_PRIVATE(X), dh_pair.public_key, 32);
ret = mbedtls_mpi_read_binary(&Q.MBEDTLS_PRIVATE(X), key, 32);
if (ret != 0) {
goto cleanup;
}
ret = mbedtls_mpi_read_binary(&Q.MBEDTLS_PRIVATE(Y), dh_pair.public_key + 32, 32);
ret = mbedtls_mpi_read_binary(&Q.MBEDTLS_PRIVATE(Y), key + 32, 32);
if (ret != 0) {
goto cleanup;
}
@@ -409,12 +421,12 @@ int bt_mesh_dhkey_gen_raw(const uint8_t *pub_key, const uint8_t *priv_key,
}
/* Load public key point */
ret = mbedtls_mpi_read_binary(&Q.MBEDTLS_PRIVATE(X), dh_pair.public_key, 32);
ret = mbedtls_mpi_read_binary(&Q.MBEDTLS_PRIVATE(X), pub_key, 32);
if (ret != 0) {
goto cleanup;
}
ret = mbedtls_mpi_read_binary(&Q.MBEDTLS_PRIVATE(Y), dh_pair.public_key + 32, 32);
ret = mbedtls_mpi_read_binary(&Q.MBEDTLS_PRIVATE(Y), pub_key + 32, 32);
if (ret != 0) {
goto cleanup;
}
+34 -12
View File
@@ -1,6 +1,6 @@
/*
* SPDX-FileCopyrightText: 2023 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -292,6 +292,7 @@ int bt_mesh_pub_key_gen(void)
uint8_t private_key[PRIV_KEY_SIZE];
size_t key_len;
int err;
int ret = 0;
/* Destroy any existing key */
if (dh_pair.priv_key_id != PSA_KEY_ID_NULL) {
@@ -300,15 +301,26 @@ int bt_mesh_pub_key_gen(void)
}
dh_pair.is_ready = false;
/* Generate a random private key (in little-endian format for storage) */
/* Generate a random private key and let PSA validate the range.
* For NIST P-256, the private key scalar d must satisfy: 1 <= d < n.
* PSA will return PSA_ERROR_INVALID_ARGUMENT if the key is out of range.
*/
#define MAX_KEY_GEN_RETRIES 10
int retries = 0;
do {
err = bt_mesh_rand(private_key, sizeof(private_key));
if (err) {
BT_ERR("Failed to generate random private key");
return err;
ret = err;
goto cleanup;
}
/* Ensure the private key is valid (non-zero first bytes in BE) */
} while (private_key[0] == 0 && private_key[1] == 0);
if (++retries > MAX_KEY_GEN_RETRIES) {
BT_ERR("Exceeded maximum key generation retries");
ret = -EIO;
goto cleanup;
}
/* Minimal check for obviously invalid keys (all zeros in MSB region) */
} while (private_key[0] == 0 && private_key[1] == 0 && private_key[2] == 0 && private_key[3] == 0);
/* Configure key attributes for ECDH with P-256 */
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
@@ -323,7 +335,8 @@ int bt_mesh_pub_key_gen(void)
if (status != PSA_SUCCESS) {
BT_ERR("PSA import private key failed: %d", status);
psa_reset_key_attributes(&key_attributes);
return -EIO;
ret = -EIO;
goto cleanup;
}
/* Export public key (PSA computes it from the private key) */
@@ -334,13 +347,20 @@ int bt_mesh_pub_key_gen(void)
psa_destroy_key(dh_pair.priv_key_id);
dh_pair.priv_key_id = PSA_KEY_ID_NULL;
psa_reset_key_attributes(&key_attributes);
return -EIO;
ret = -EIO;
goto cleanup;
}
dh_pair.is_ready = true;
psa_reset_key_attributes(&key_attributes);
return 0;
cleanup:
/* Securely clear private key from stack to prevent key leakage */
memset(private_key, 0, sizeof(private_key));
/* Memory barrier to prevent compiler from optimizing out the memset */
__asm__ __volatile__("" : : "r"(private_key) : "memory");
return ret;
}
const uint8_t *bt_mesh_pub_key_get_raw(void)
@@ -360,6 +380,8 @@ void bt_mesh_set_private_key_raw(const uint8_t pri_key[32])
psa_status_t status;
size_t key_len;
BT_DBG("Privkey:%s", bt_hex(pri_key, PRIV_KEY_SIZE));
/* Destroy any existing key */
if (dh_pair.priv_key_id != PSA_KEY_ID_NULL) {
psa_destroy_key(dh_pair.priv_key_id);
@@ -393,7 +415,6 @@ void bt_mesh_set_private_key_raw(const uint8_t pri_key[32])
}
BT_DBG("Pubkey:%s", bt_hex(&dh_pair.public_key[1], PUB_KEY_SIZE));
BT_DBG("Privkey:%s", bt_hex(pri_key, PRIV_KEY_SIZE));
dh_pair.is_ready = true;
psa_reset_key_attributes(&attributes);
}
@@ -407,7 +428,7 @@ bool bt_mesh_check_public_key_raw(const uint8_t key[64])
/* PSA requires 0x04 prefix for uncompressed point */
pub_be[0] = 0x04;
/* Convert from little-endian to big-endian */
/* Copy X and Y coordinates (already in big-endian format) */
memcpy(&pub_be[1], key, 32);
memcpy(&pub_be[33], key + 32, 32);
@@ -587,15 +608,16 @@ void bt_mesh_key_assign(struct bt_mesh_key *dst, const struct bt_mesh_key *src)
int bt_mesh_key_destroy(const struct bt_mesh_key *key)
{
psa_status_t status;
psa_key_id_t key_id = key->key;
status = psa_destroy_key(key->key);
status = psa_destroy_key(key_id);
if (status != PSA_SUCCESS) {
BT_ERR("PSA destroy key failed: %d", status);
return -EIO;
}
#if CONFIG_BT_SETTINGS
return keyid_free(key->key);
return keyid_free(key_id);
#else
return 0;
#endif
@@ -72,8 +72,8 @@ int bt_mesh_ccm_encrypt(const struct bt_mesh_key *key, uint8_t nonce[13],
return -EIO;
}
if (tc_ccm_generation_encryption(enc_data, len + mic_size, aad, aad_len,
plaintext, len, &ccm) == TC_CRYPTO_FAIL) {
if (tc_ccm_generation_encryption(enc_data, (unsigned int)(len + mic_size), aad, (unsigned int)aad_len,
plaintext, (unsigned int)len, &ccm) == TC_CRYPTO_FAIL) {
return -EIO;
}
@@ -168,7 +168,7 @@ extern bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh
#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
static inline bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val)
{
return __atomic_compare_exchange_n(target, &excepted, &new_val, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return __atomic_compare_exchange_n(target, &excepted, new_val, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
}
#else
extern bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val);
@@ -50,7 +50,9 @@ void bt_mesh_atomic_lock(void);
void bt_mesh_atomic_unlock(void);
void bt_mesh_mutex_init(void);
#if CONFIG_BLE_MESH_DEINIT
void bt_mesh_mutex_deinit(void);
#endif /* CONFIG_BLE_MESH_DEINIT */
#ifdef __cplusplus
}
@@ -41,6 +41,13 @@ extern "C" {
#define INT_TO_POINTER(x) ((void *) (x))
#endif
#ifndef ESP_ASSUME_NONNULL
/**
* @brief Assume pointer parameters are non-null unless explicitly marked otherwise.
*/
#define ESP_ASSUME_NONNULL(ptr)
#endif
/* Evaluates to 0 if cond is true-ish; compile error otherwise */
#ifndef ZERO_OR_COMPILE_ERROR
#define ZERO_OR_COMPILE_ERROR(cond) ((int) sizeof(char[1 - 2 * !(cond)]) - 1)
+6 -2
View File
@@ -1,14 +1,18 @@
/*
* SPDX-FileCopyrightText: 2016 Intel Corporation
* SPDX-FileCopyrightText: 2016 Wind River Systems, Inc.
* SPDX-FileContributor: 2020-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2020-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "mesh/timer.h"
#include "mesh/kernel.h"
void k_sleep(int32_t duration)
{
vTaskDelay(duration / portTICK_PERIOD_MS);
if (duration < 0 && duration != K_FOREVER) {
duration = 0;
}
vTaskDelay((duration == K_FOREVER) ? portMAX_DELAY : (duration / portTICK_PERIOD_MS));
}
+37 -18
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -64,6 +64,8 @@ void bt_mesh_mutex_lock(bt_mesh_mutex_t *mutex)
if (mutex->mutex) {
xSemaphoreTake(mutex->mutex, portMAX_DELAY);
} else {
BT_ERR("Lock, no mutex");
}
}
@@ -76,6 +78,8 @@ void bt_mesh_mutex_unlock(bt_mesh_mutex_t *mutex)
if (mutex->mutex) {
xSemaphoreGive(mutex->mutex);
} else {
BT_ERR("Unlock, no mutex");
}
}
@@ -120,6 +124,8 @@ void bt_mesh_r_mutex_lock(bt_mesh_mutex_t *mutex)
if (mutex->mutex) {
xSemaphoreTakeRecursive(mutex->mutex, portMAX_DELAY);
} else {
BT_ERR("Lock, no recursive mutex");
}
}
@@ -132,6 +138,8 @@ void bt_mesh_r_mutex_unlock(bt_mesh_mutex_t *mutex)
if (mutex->mutex) {
xSemaphoreGiveRecursive(mutex->mutex);
} else {
BT_ERR("Unlock, no recursive mutex");
}
}
@@ -152,6 +160,11 @@ void bt_mesh_c_semaphore_create(bt_mesh_mutex_t *mutex, int max, int init)
return;
}
if (max <= 0 || init < 0 || init > max) {
BT_ERR("Create, invalid semaphore parameters (max=%d, init=%d)", max, init);
return;
}
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
mutex->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
@@ -175,7 +188,11 @@ void bt_mesh_c_semaphore_take(bt_mesh_mutex_t *mutex, uint32_t timeout)
}
if (mutex->mutex) {
xSemaphoreTake(mutex->mutex, timeout / portTICK_PERIOD_MS);
if (xSemaphoreTake(mutex->mutex, timeout / portTICK_PERIOD_MS) != pdTRUE) {
BT_ERR("Failed to take semaphore");
}
} else {
BT_ERR("Lock, no semaphore");
}
}
@@ -188,63 +205,65 @@ void bt_mesh_c_semaphore_give(bt_mesh_mutex_t *mutex)
if (mutex->mutex) {
xSemaphoreGive(mutex->mutex);
} else {
BT_ERR("Unlock, no semaphore");
}
}
void bt_mesh_alarm_lock(void)
{
bt_mesh_mutex_lock(&alarm_lock);
bt_mesh_r_mutex_lock(&alarm_lock);
}
void bt_mesh_alarm_unlock(void)
{
bt_mesh_mutex_unlock(&alarm_lock);
bt_mesh_r_mutex_unlock(&alarm_lock);
}
void bt_mesh_list_lock(void)
{
bt_mesh_mutex_lock(&list_lock);
bt_mesh_r_mutex_lock(&list_lock);
}
void bt_mesh_list_unlock(void)
{
bt_mesh_mutex_unlock(&list_lock);
bt_mesh_r_mutex_unlock(&list_lock);
}
void bt_mesh_buf_lock(void)
{
bt_mesh_mutex_lock(&buf_lock);
bt_mesh_r_mutex_lock(&buf_lock);
}
void bt_mesh_buf_unlock(void)
{
bt_mesh_mutex_unlock(&buf_lock);
bt_mesh_r_mutex_unlock(&buf_lock);
}
void bt_mesh_atomic_lock(void)
{
bt_mesh_mutex_lock(&atomic_lock);
bt_mesh_r_mutex_lock(&atomic_lock);
}
void bt_mesh_atomic_unlock(void)
{
bt_mesh_mutex_unlock(&atomic_lock);
bt_mesh_r_mutex_unlock(&atomic_lock);
}
void bt_mesh_mutex_init(void)
{
bt_mesh_mutex_create(&alarm_lock);
bt_mesh_mutex_create(&list_lock);
bt_mesh_mutex_create(&buf_lock);
bt_mesh_mutex_create(&atomic_lock);
bt_mesh_r_mutex_create(&alarm_lock);
bt_mesh_r_mutex_create(&list_lock);
bt_mesh_r_mutex_create(&buf_lock);
bt_mesh_r_mutex_create(&atomic_lock);
}
#if CONFIG_BLE_MESH_DEINIT
void bt_mesh_mutex_deinit(void)
{
bt_mesh_mutex_free(&alarm_lock);
bt_mesh_mutex_free(&list_lock);
bt_mesh_mutex_free(&buf_lock);
bt_mesh_mutex_free(&atomic_lock);
bt_mesh_r_mutex_free(&alarm_lock);
bt_mesh_r_mutex_free(&list_lock);
bt_mesh_r_mutex_free(&buf_lock);
bt_mesh_r_mutex_free(&atomic_lock);
}
#endif /* CONFIG_BLE_MESH_DEINIT */
+1 -1
View File
@@ -35,7 +35,7 @@ int bt_mesh_queue_init(bt_mesh_queue_t *queue, uint16_t queue_size, uint8_t item
int bt_mesh_queue_deinit(bt_mesh_queue_t *queue)
{
__ASSERT(queue, "Invalid queue init parameters");
__ASSERT(queue && queue->handle, "Invalid queue deinit parameters");
vQueueDelete(queue->handle);
queue->handle = NULL;
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
+1 -1
View File
@@ -135,7 +135,7 @@ int k_delayed_work_submit(struct k_delayed_work *work, int32_t delay)
}
/* If delay is 0, call the corresponding timeout handler. */
if (delay == 0) {
if (delay <= 0) {
k_work_submit(&work->work);
return 0;
}
+13 -1
View File
@@ -16,7 +16,10 @@
const char *bt_hex(const void *buf, size_t len)
{
static const char hex[] = "0123456789abcdef";
static char hexbufs[2][129];
/* WARNING: Buffer count limits concurrent bt_hex() calls in a single
* expression or across threads. Increase if more simultaneous calls needed.
*/
static char hexbufs[4][129];
static uint8_t curbuf;
const uint8_t *b = buf;
char *str = NULL;
@@ -25,6 +28,11 @@ const char *bt_hex(const void *buf, size_t len)
str = hexbufs[curbuf++];
curbuf %= ARRAY_SIZE(hexbufs);
if (buf == NULL) {
str[0] = '\0';
return str;
}
len = MIN(len, (sizeof(hexbufs[0]) - 1) / 2);
for (i = 0; i < len; i++) {
@@ -39,6 +47,10 @@ const char *bt_hex(const void *buf, size_t len)
void mem_rcopy(uint8_t *dst, uint8_t const *src, uint16_t len)
{
if (dst == NULL || src == NULL || len == 0) {
return;
}
src += len;
while (len--) {
*dst++ = *--src;
+81 -9
View File
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -141,6 +141,11 @@ static int32_t next_period(struct bt_mesh_model *mod)
return 0;
}
if (pub->period_start == 0) {
BT_ERR("PubFailed,TryPubInNxtPeriod");
return period;
}
elapsed = k_uptime_get_32() - pub->period_start;
BT_INFO("Elapsed %u Period %u", elapsed, period);
@@ -244,6 +249,13 @@ static int publish_retransmit(struct bt_mesh_model *mod)
/* Tag with send-segmented */
ctx.send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
}
#if CONFIG_BLE_MESH_LONG_PACKET
if ((pub->msg->len <= MIN(BLE_MESH_EXT_TX_SDU_MAX, BLE_MESH_EXT_SDU_MAX_LEN) - BLE_MESH_MIC_SHORT) &&
(pub->msg->len > MIN(BLE_MESH_TX_SDU_MAX, BLE_MESH_SDU_MAX_LEN) - BLE_MESH_MIC_SHORT)) {
ctx.enh.long_pkt_cfg_used = true;
ctx.enh.long_pkt_cfg = BLE_MESH_LONG_PACKET_PREFER;
}
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Dst 0x%04x",
ctx.net_idx, ctx.app_idx, ctx.addr);
@@ -316,13 +328,16 @@ static void mod_publish(struct k_work *work)
* In the event, users can update the context of the publish message
* which will be published in the next period.
*/
if (pub->update && pub->update(pub->mod)) {
/* Cancel this publish attempt. */
BT_ERR("Update failed, skipping publish (err %d)", err);
if (pub->update) {
err = pub->update(pub->mod);
if (err) {
/* Cancel this publish attempt. */
BT_ERR("Update failed, skipping publish (err %d)", err);
pub->period_start = k_uptime_get_32();
publish_retransmit_end(err, pub);
return;
pub->period_start = k_uptime_get_32();
publish_retransmit_end(err, pub);
return;
}
}
err = bt_mesh_model_publish(pub->mod);
@@ -335,6 +350,16 @@ struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod)
{
BT_DBG("ModelElem, ElemIdx %u", mod->elem_idx);
if (!comp_0) {
BT_ERR("comp_0 not initialized");
return NULL;
}
if (mod->elem_idx >= comp_0->elem_count) {
BT_ERR("Invalid element index %u", mod->elem_idx);
return NULL;
}
return &comp_0->elem[mod->elem_idx];
}
@@ -428,7 +453,7 @@ int bt_mesh_comp_register(const struct bt_mesh_comp *comp)
BT_DBG("CompRegister, ElemCount %u", comp->elem_count);
/* There must be at least one element */
if (!comp->elem_count) {
if (!comp->elem_count || comp->elem_count > BLE_MESH_MODEL_MAX_ELEM_COUNT) {
return -EINVAL;
}
@@ -504,6 +529,20 @@ void bt_mesh_comp_provision(uint16_t addr)
{
int i;
if (!comp_0) {
BT_ERR("comp_0 not initialized");
return;
}
/* Validate unicast address range: addr must be valid (0x0001-0x7FFF) and
* addr + elem_count - 1 must not exceed 0x7FFF (unicast address upper bound).
*/
if (!BLE_MESH_ADDR_IS_UNICAST(addr) ||
(uint32_t)addr + comp_0->elem_count - 1 > 0x7FFF) {
BT_ERR("Address range overflow: addr 0x%04x, elem_count %u", addr, comp_0->elem_count);
return;
}
dev_primary_addr = addr;
BT_INFO("CompProvision, PrimaryAddr 0x%04x ElemCount %u", addr, comp_0->elem_count);
@@ -585,6 +624,11 @@ struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr)
BT_DBG("ElemFind, Addr 0x%04x", addr);
if (!comp_0) {
BT_ERR("comp_0 not initialized");
return NULL;
}
if (BLE_MESH_ADDR_IS_UNICAST(addr)) {
index = (addr - comp_0->elem[0].addr);
if (index < comp_0->elem_count) {
@@ -609,6 +653,11 @@ bool bt_mesh_has_addr(uint16_t addr)
{
uint16_t index;
if (!comp_0) {
BT_ERR("comp_0 not initialized");
return false;
}
if (BLE_MESH_ADDR_IS_UNICAST(addr)) {
return bt_mesh_elem_find(addr) != NULL;
}
@@ -626,6 +675,11 @@ bool bt_mesh_has_addr(uint16_t addr)
uint8_t bt_mesh_elem_count(void)
{
if (!comp_0) {
BT_ERR("comp_0 not initialized");
return 0;
}
BT_DBG("ElemCount %u", comp_0->elem_count);
return comp_0->elem_count;
@@ -797,6 +851,11 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
rx->ctx.app_idx, rx->ctx.addr, rx->ctx.recv_dst);
BT_INFO("Len %u: %s", buf->len, bt_hex(buf->data, buf->len));
if (!comp_0) {
BT_ERR("comp_0 not initialized");
return;
}
if (get_opcode(buf, &opcode, true) < 0) {
BT_WARN("Unable to decode OpCode");
return;
@@ -911,7 +970,7 @@ static bool ready_to_send(uint16_t dst)
if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en()) {
if (bt_mesh_provisioner_check_msg_dst(dst) == false &&
bt_mesh_elem_find(dst) == false) {
bt_mesh_elem_find(dst) == NULL) {
BT_ERR("Failed to find Dst 0x%04x", dst);
return false;
}
@@ -1205,10 +1264,22 @@ int bt_mesh_model_publish(struct bt_mesh_model *model)
return -EADDRNOTAVAIL;
}
#if CONFIG_BLE_MESH_LONG_PACKET
if (pub->msg->len + BLE_MESH_MIC_SHORT > MIN(BLE_MESH_EXT_TX_SDU_MAX, BLE_MESH_EXT_SDU_MAX_LEN)) {
BT_ERR("Message does not fit extended maximum SDU size");
return -EMSGSIZE;
}
if ((pub->msg->len <= MIN(BLE_MESH_EXT_TX_SDU_MAX, BLE_MESH_EXT_SDU_MAX_LEN) - BLE_MESH_MIC_SHORT) &&
(pub->msg->len > MIN(BLE_MESH_TX_SDU_MAX, BLE_MESH_SDU_MAX_LEN) - BLE_MESH_MIC_SHORT)) {
tx.ctx->enh.long_pkt_cfg_used = true;
tx.ctx->enh.long_pkt_cfg = BLE_MESH_LONG_PACKET_PREFER;
}
#else
if (pub->msg->len + BLE_MESH_MIC_SHORT > MIN(BLE_MESH_TX_SDU_MAX, BLE_MESH_SDU_MAX_LEN)) {
BT_ERR("Message does not fit maximum SDU size");
return -EMSGSIZE;
}
#endif
if (pub->count) {
BT_WARN("Clearing publish retransmit timer");
@@ -1245,6 +1316,7 @@ int bt_mesh_model_publish(struct bt_mesh_model *model)
bt_mesh_model_pub_use_directed(&tx, pub->directed_pub_policy);
#endif /* CONFIG_BLE_MESH_DF_SRV */
pub->period_start = 0;
pub->count = BLE_MESH_PUB_TRANSMIT_COUNT(pub->retransmit);
BT_INFO("PubCount %u PubInterval %u",
+2
View File
@@ -15,6 +15,8 @@
extern "C" {
#endif
#define BLE_MESH_MODEL_MAX_ELEM_COUNT 255
/* bt_mesh_model.flags */
enum {
BLE_MESH_MOD_BIND_PENDING = BIT(0),
+2 -2
View File
@@ -144,7 +144,7 @@ static int adv_send(struct net_buf *buf)
struct bt_mesh_ble_adv_data data = {0};
struct bt_mesh_ble_adv_tx *tx = cb_data;
if (tx == NULL) {
if (tx == NULL || tx->buf == NULL) {
BT_ERR("Invalid adv user data");
net_buf_unref(buf);
return -EINVAL;
@@ -217,7 +217,7 @@ static QueueHandle_t relay_adv_handle_get(void)
adv_type = bt_mesh_adv_types_mgmt_get(BLE_MESH_ADV_RELAY_DATA);
if (adv_type->adv_q == NULL) {
if (adv_type == NULL || adv_type->adv_q == NULL) {
BT_DBG("HandleNotFound");
return NULL;
}
+2 -1
View File
@@ -216,6 +216,7 @@ int bt_mesh_adv_inst_deinit(enum bt_mesh_adv_inst_type inst_type)
static struct bt_mesh_adv *adv_alloc(int id, enum bt_mesh_adv_type type)
{
BT_DBG("AdvAlloc, ID %d", id);
assert(id >= 0 && id < CONFIG_BLE_MESH_ADV_BUF_COUNT);
init_adv_with_defaults(&adv_pool[id], type);
return &adv_pool[id];
}
@@ -700,7 +701,7 @@ void bt_mesh_relay_adv_init(void)
&relay_adv_buf_pool, &relay_adv_alloc);
#if CONFIG_BLE_MESH_EXT_ADV
bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_RELAY_DATA, &relay_adv_queue,
&ext_adv_buf_pool, &ext_relay_adv_alloc);
&ext_relay_adv_buf_pool, &ext_relay_adv_alloc);
#if CONFIG_BLE_MESH_LONG_PACKET && CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT
bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_LONG_RELAY_DATA, &relay_adv_queue,
&ext_long_relay_adv_buf_pool, ext_long_relay_adv_alloc);
+13 -11
View File
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -225,13 +225,14 @@ static int secure_beacon_send(void)
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_ADV)
static int unprovisioned_beacon_send(void)
{
const struct bt_mesh_prov *prov = bt_mesh_prov_get();
uint8_t uri_hash[16] = {0};
struct net_buf *buf = NULL;
uint16_t oob_info = 0U;
BT_DBG("UnprovisionedBeaconSend");
if (bt_mesh_prov_get() == NULL) {
if (prov == NULL) {
BT_ERR("No provisioning context provided");
return -EINVAL;
}
@@ -243,13 +244,13 @@ static int unprovisioned_beacon_send(void)
}
net_buf_add_u8(buf, BEACON_TYPE_UNPROVISIONED);
net_buf_add_mem(buf, bt_mesh_prov_get()->uuid, 16);
net_buf_add_mem(buf, prov->uuid, 16);
if (bt_mesh_prov_get()->uri &&
bt_mesh_s1(bt_mesh_prov_get()->uri, uri_hash) == 0) {
oob_info = bt_mesh_prov_get()->oob_info | BLE_MESH_PROV_OOB_URI;
if (prov->uri &&
bt_mesh_s1(prov->uri, uri_hash) == 0) {
oob_info = prov->oob_info | BLE_MESH_PROV_OOB_URI;
} else {
oob_info = bt_mesh_prov_get()->oob_info;
oob_info = prov->oob_info;
}
net_buf_add_be16(buf, oob_info);
@@ -258,7 +259,7 @@ static int unprovisioned_beacon_send(void)
bt_mesh_adv_send(buf, UNPROV_XMIT, NULL, NULL);
net_buf_unref(buf);
if (bt_mesh_prov_get()->uri) {
if (prov->uri) {
size_t len = 0;
buf = bt_mesh_adv_create(BLE_MESH_ADV_URI, K_NO_WAIT);
@@ -267,14 +268,14 @@ static int unprovisioned_beacon_send(void)
return -ENOBUFS;
}
len = strlen(bt_mesh_prov_get()->uri);
len = strlen(prov->uri);
BT_DBG("URI %u: %s", len, bt_mesh_prov_get()->uri);
BT_DBG("URI %u: %s", len, prov->uri);
if (net_buf_tailroom(buf) < len) {
BT_WARN("Too long URI to fit advertising data");
} else {
net_buf_add_mem(buf, bt_mesh_prov_get()->uri, len);
net_buf_add_mem(buf, prov->uri, len);
bt_mesh_adv_send(buf, UNPROV_XMIT, NULL, NULL);
}
@@ -561,6 +562,7 @@ void bt_mesh_beacon_init(void)
/* private beacon init */
if (bt_mesh_private_beacon_timer_init()) {
BT_ERR("Failed to create a mpb_timer");
k_delayed_work_free(&snb_timer);
return;
}
#endif /* CONFIG_BLE_MESH_PRB_SRV */
@@ -455,7 +455,7 @@ void ble_mesh_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
break;
case BTA_DM_BLE_5_GAP_EXT_SCAN_STOP_COMPLETE_EVT:
if (params->scan_stop.status != BTM_SUCCESS) {
BT_ERR("BTM_BLE_5_GAP_EXT_SCAN_START_COMPLETE_EVT Failed");
BT_ERR("BTA_DM_BLE_5_GAP_EXT_SCAN_STOP_COMPLETE_EVT Failed");
}
break;
default:
@@ -571,7 +571,7 @@ static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
if (interval == 0 ||
interval < window) {
BT_ERR("invalid scan param itvl %d win %d", interval, window);
return EINVAL;
return -EINVAL;
}
ext_scan_params.own_addr_type = BLE_MESH_ADDR_PUBLIC;
@@ -970,11 +970,19 @@ int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
if (data && param->adv_type != BLE_MESH_ADV_DIRECT_IND &&
param->adv_type != BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
if (data->adv_data_len) {
if (data->adv_data_len > sizeof(set.data)) {
BT_ERR("adv_data_len %u exceeds buffer size %zu", data->adv_data_len, sizeof(set.data));
return -EINVAL;
}
set.len = data->adv_data_len;
memcpy(set.data, data->adv_data, data->adv_data_len);
BTA_DmBleGapConfigExtAdvDataRaw(false, inst_id, set.len, set.data);
}
if (data->scan_rsp_data_len && param->adv_type != BLE_MESH_ADV_NONCONN_IND) {
if (data->scan_rsp_data_len > sizeof(set.data)) {
BT_ERR("scan_rsp_data_len %u exceeds buffer size %zu", data->scan_rsp_data_len, sizeof(set.data));
return -EINVAL;
}
set.len = data->scan_rsp_data_len;
memcpy(set.data, data->scan_rsp_data, data->scan_rsp_data_len);
BTA_DmBleGapConfigExtAdvDataRaw(true, inst_id, set.len, set.data);
@@ -1608,6 +1616,10 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc)
break;
}
case BLE_MESH_UUID_GATT_CHRC_VAL: {
if (i + 1 >= svc->attr_count) {
BT_ERR("Characteristic declaration at index %d missing value attribute", i);
goto cleanup;
}
gatts_future_mesh = future_new();
struct bt_mesh_gatt_char *gatts_chrc = (struct bt_mesh_gatt_char *)svc->attrs[i].user_data;
bta_uuid_to_bt_mesh_uuid(&bta_uuid, gatts_chrc->uuid);
@@ -2315,7 +2327,11 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
}
break;
case BTA_GATTC_CLOSE_EVT:
bta_gattc_clcb_dealloc_by_conn_id(p_data->close.conn_id);
/* CLCB lifetime is owned by BTA: bta_gattc_close() deallocates the
* CLCB right after invoking this synchronous callback. Calling
* bta_gattc_clcb_dealloc_by_conn_id() here would be a redundant
* double-dealloc (currently a no-op only because of NULL checks in
* bta_gattc_clcb_dealloc()). Keep this branch as a pure notification. */
BT_DBG("BTA_GATTC_CLOSE_EVT");
break;
case BTA_GATTC_CONNECT_EVT: {
+7 -1
View File
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -759,6 +759,12 @@ int bt_mesh_cfg_ttl_set(bt_mesh_client_common_param_t *param, uint8_t val)
{
BT_DBG("TTLSet, Val 0x%02x", val);
/* Per BLE Mesh spec, TTL 0x01 is prohibited and 0x80-0xFF are reserved */
if (val == 0x01 || val > 0x7F) {
BT_ERR("Invalid TTL value 0x%02x", val);
return -EINVAL;
}
return send_msg_with_u8(param, OP_DEFAULT_TTL_SET, val);
}
+7 -2
View File
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -911,6 +911,7 @@ static void default_ttl_set(struct bt_mesh_model *model,
}
} else {
BT_WARN("Prohibited Default TTL value 0x%02x", buf->data[0]);
return;
}
bt_mesh_model_msg_init(&msg, OP_DEFAULT_TTL_STATUS);
@@ -1348,7 +1349,7 @@ static struct label *va_find(const uint8_t *label_uuid,
for (i = 0; i < ARRAY_SIZE(labels); i++) {
if (labels[i].ref == 0) {
if (free_slot != NULL) {
if (free_slot != NULL && *free_slot == NULL) {
*free_slot = &labels[i];
}
continue;
@@ -1370,6 +1371,9 @@ uint8_t va_add(uint8_t *label_uuid, uint16_t *addr)
update = va_find(label_uuid, &free_slot);
if (update) {
if (update->ref == UINT16_MAX) {
return STATUS_INSUFF_RESOURCES;
}
update->ref++;
va_store(update);
@@ -2590,6 +2594,7 @@ static void net_key_update(struct bt_mesh_model *model,
switch (sub->kr_phase) {
case BLE_MESH_KR_NORMAL:
if (!memcmp(buf->data, sub->keys[0].net, 16)) {
send_net_key_status(model, ctx, idx, STATUS_SUCCESS);
return;
}
break;
+8 -3
View File
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -28,14 +28,19 @@
int bt_mesh_k1(const uint8_t *ikm, size_t ikm_len, const uint8_t salt[16],
const char *info, uint8_t okm[16])
{
uint8_t t[16] = {0};
int err = 0;
err = bt_mesh_aes_cmac_one(salt, ikm, ikm_len, okm);
err = bt_mesh_aes_cmac_one(salt, ikm, ikm_len, t);
if (err < 0) {
memset(t, 0, sizeof(t));
return err;
}
return bt_mesh_aes_cmac_one(okm, info, strlen(info), okm);
err = bt_mesh_aes_cmac_one(t, info, strlen(info), okm);
memset(t, 0, sizeof(t));
return err;
}
int bt_mesh_k2(const uint8_t n[16], const uint8_t *p, size_t p_len,
+1 -1
View File
@@ -24,7 +24,7 @@ extern "C" {
/* bt_mesh_aes_cmac_one is defined as inline in mesh/crypto.h */
static inline bool bt_mesh_s1(const char *m, uint8_t salt[16])
static inline int bt_mesh_s1(const char *m, uint8_t salt[16])
{
const uint8_t zero[16] = { 0 };
+20 -15
View File
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -30,7 +30,7 @@
static struct bt_mesh_adv_inst *adv_insts;
static int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration)
static int adv_send(struct bt_mesh_adv_inst *inst, int32_t *adv_duration)
{
struct net_buf *buf = inst->sending_buf;
const struct bt_mesh_send_cb *cb = BLE_MESH_ADV(buf)->cb;
@@ -57,9 +57,10 @@ static int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration)
case BLE_MESH_ADV_EXT_LONG_DATA:
case BLE_MESH_ADV_EXT_LONG_RELAY_DATA:
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
{
is_ext_adv = true;
}
{
is_ext_adv = true;
}
__attribute__((fallthrough));
#endif /* CONFIG_BLE_MESH_EXT_ADV */
case BLE_MESH_ADV_PROV:
case BLE_MESH_ADV_DATA:
@@ -195,7 +196,7 @@ static int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration)
return err;
}
*adv_duration = duration;
*adv_duration = (int32_t)duration;
BT_DBG("Advertising started. %u ms", duration);
return 0;
@@ -264,12 +265,12 @@ static int find_valid_msg_from_queue(bt_mesh_queue_t *msg_queue, bt_mesh_msg_t *
return 0;
}
static int activate_idle_adv_instance(uint32_t *update_evts, uint16_t *min_duration)
static int activate_idle_adv_instance(uint32_t *update_evts, int32_t *min_duration)
{
uint16_t cur_min_duration = K_FOREVER;
int32_t cur_min_duration = K_FOREVER;
enum bt_mesh_adv_type adv_type = 0;
bt_mesh_queue_t *msg_queue = NULL;
uint16_t duration = K_FOREVER;
int32_t duration = K_FOREVER;
bt_mesh_msg_t msg = {0};
uint32_t spt_mask = 0;
uint32_t evts = 0;
@@ -389,13 +390,17 @@ static uint32_t received_adv_evts_handle(uint32_t recv_evts)
} else
#endif
{
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);
if (adv_insts[i].sending_buf == NULL) {
BT_WARN("sending_buf is NULL for inst %d, skipping", i);
} else {
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);
bt_mesh_adv_buf_ref_debug(__func__, adv_insts[i].sending_buf, 4U, BLE_MESH_BUF_REF_SMALL);
net_buf_unref(adv_insts[i].sending_buf);
adv_insts[i].sending_buf = NULL;
net_buf_unref(adv_insts[i].sending_buf);
adv_insts[i].sending_buf = NULL;
}
}
adv_insts[i].busy = false;
@@ -407,7 +412,7 @@ static uint32_t received_adv_evts_handle(uint32_t recv_evts)
static void adv_thread(void *p)
{
uint16_t adv_duration = K_FOREVER;
int32_t adv_duration = K_FOREVER;
uint32_t recv_evts = 0;
uint32_t wait_evts = 0;
+9 -7
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -62,7 +62,8 @@ struct bt_mesh_subnet *bt_mesh_fast_prov_subnet_get(uint16_t net_idx)
for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
sub = &bt_mesh.sub[i];
if (sub->net_idx == net_idx) {
if (sub->net_idx != BLE_MESH_KEY_UNUSED &&
sub->net_idx == net_idx) {
BT_DBG("NodeSub");
return sub;
}
@@ -194,6 +195,12 @@ uint8_t bt_mesh_set_fast_prov_action(uint8_t action)
}
if (action == ACTION_ENTER) {
/* Perform validation before state mutation */
if (bt_mesh_provisioner_set_primary_elem_addr(bt_mesh_primary_addr()) < 0) {
BT_ERR("SetPrimaryElemAddrFail");
return 0x01;
}
if (bt_mesh_secure_beacon_get() == BLE_MESH_SECURE_BEACON_ENABLED) {
bt_mesh_secure_beacon_disable();
}
@@ -201,11 +208,6 @@ uint8_t bt_mesh_set_fast_prov_action(uint8_t action)
if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) {
bt_mesh_proxy_client_prov_enable();
}
if (bt_mesh_provisioner_set_primary_elem_addr(bt_mesh_primary_addr()) < 0) {
BT_ERR("SetPrimaryElemAddrFail");
return 0x01;
}
bt_mesh_provisioner_set_prov_bearer(BLE_MESH_PROV_ADV, false);
bt_mesh_provisioner_fast_prov_enable(true);
bt_mesh_atomic_or(bt_mesh.flags, BIT(BLE_MESH_PROVISIONER) | BIT(BLE_MESH_VALID_PROV));
+1 -1
View File
@@ -994,7 +994,7 @@ int bt_mesh_friend_clear_cfm(struct bt_mesh_net_rx *rx,
frnd = find_clear(rx->ctx.addr);
if (!frnd) {
BT_WARN("No pending clear procedure for 0x%02x", rx->ctx.addr);
BT_WARN("No pending clear procedure for 0x%04x", rx->ctx.addr);
return 0;
}
+1 -1
View File
@@ -270,7 +270,7 @@ int bt_mesh_health_fault_test(bt_mesh_client_common_param_t *param,
{
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_TEST, 3);
BT_DBG("HealthFaultTest, CID 0x%04x TestID 0x%04x NeedAck %u", cid, test_id, need_ack);
BT_DBG("HealthFaultTest, CID 0x%04x TestID 0x%02x NeedAck %u", cid, test_id, need_ack);
bt_mesh_model_msg_init(&msg, need_ack ? OP_HEALTH_FAULT_TEST : OP_HEALTH_FAULT_TEST_UNREL);
net_buf_simple_add_u8(&msg, test_id);
+7 -6
View File
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -418,6 +418,7 @@ static int health_pub_update(struct bt_mesh_model *model)
int bt_mesh_fault_update(struct bt_mesh_elem *elem)
{
struct bt_mesh_model *model = NULL;
int err = 0;
BT_DBG("FaultUpdate");
@@ -439,7 +440,10 @@ int bt_mesh_fault_update(struct bt_mesh_elem *elem)
return 0;
}
health_pub_update(model);
err = health_pub_update(model);
if (err) {
return err;
}
return bt_mesh_model_publish(model);
}
@@ -449,10 +453,6 @@ static void attention_off(struct k_work *work)
struct bt_mesh_health_srv *srv = CONTAINER_OF(work,
struct bt_mesh_health_srv,
attn_timer.work);
if (!srv) {
BT_ERR("No Health Server context provided");
return;
}
BT_DBG("AttentionOff");
@@ -532,6 +532,7 @@ static int health_srv_deinit(struct bt_mesh_model *model)
model->pub->update = NULL;
k_delayed_work_free(&srv->attn_timer);
srv->attn_timer_start = false;
if (bt_mesh_model_in_primary(model)) {
health_srv = NULL;
+37 -15
View File
@@ -1,6 +1,6 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -77,28 +77,50 @@ void bt_mesh_heartbeat_send(void)
uint8_t init_ttl;
uint16_t feat;
} hb;
struct bt_mesh_msg_ctx ctx = {
.net_idx = cfg->hb_pub.net_idx,
.app_idx = BLE_MESH_KEY_UNUSED,
.addr = cfg->hb_pub.dst,
.send_ttl = cfg->hb_pub.ttl,
.send_cred = BLE_MESH_FLOODING_CRED,
};
struct bt_mesh_net_tx tx = {
.sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx),
.ctx = &ctx,
.src = bt_mesh_model_elem(cfg->model)->addr,
.xmit = bt_mesh_net_transmit_get(),
};
struct bt_mesh_msg_ctx ctx = {0};
struct bt_mesh_net_tx tx = {0};
struct bt_mesh_elem *elem = NULL;
uint16_t feat = 0U;
BT_DBG("HeartbeatSend, Dst 0x%04x", cfg->hb_pub.dst);
if (cfg == NULL) {
BT_WARN("No configuration server context available");
return;
}
if (cfg->model == NULL) {
BT_ERR("Configuration server model is NULL");
return;
}
/* Do nothing if heartbeat publication is not enabled */
if (cfg->hb_pub.dst == BLE_MESH_ADDR_UNASSIGNED) {
return;
}
elem = bt_mesh_model_elem(cfg->model);
if (elem == NULL) {
BT_ERR("Failed to get element for heartbeat");
return;
}
ctx.net_idx = cfg->hb_pub.net_idx;
ctx.app_idx = BLE_MESH_KEY_UNUSED;
ctx.addr = cfg->hb_pub.dst;
ctx.send_ttl = cfg->hb_pub.ttl;
ctx.send_cred = BLE_MESH_FLOODING_CRED;
tx.sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx);
if (tx.sub == NULL) {
BT_ERR("No subnet found for heartbeat publication (net_idx 0x%04x)", cfg->hb_pub.net_idx);
return;
}
tx.ctx = &ctx;
tx.src = elem->addr;
tx.xmit = bt_mesh_net_transmit_get();
BT_DBG("HeartbeatSend, Dst 0x%04x", cfg->hb_pub.dst);
hb.init_ttl = cfg->hb_pub.ttl;
if (bt_mesh_relay_get() == BLE_MESH_RELAY_ENABLED) {
+2 -2
View File
@@ -16,8 +16,8 @@
extern "C" {
#endif
int bt_mesh_model_subscribe_group_addr(uint16_t elem_addr, uint16_t mod_id,
uint16_t cid, uint16_t group_addr);
int bt_mesh_model_subscribe_group_addr(uint16_t elem_addr, uint16_t cid,
uint16_t mod_id, uint16_t group_addr);
int bt_mesh_model_unsubscribe_group_addr(uint16_t elem_addr, uint16_t cid,
uint16_t mod_id, uint16_t group_addr);
+12 -5
View File
@@ -283,7 +283,7 @@ static void clear_friendship(bool force, bool disable)
*/
lpn->groups_changed = 1U;
if (cfg->hb_pub.feat & BLE_MESH_FEAT_LOW_POWER) {
if (cfg && (cfg->hb_pub.feat & BLE_MESH_FEAT_LOW_POWER)) {
bt_mesh_heartbeat_send();
}
@@ -335,6 +335,11 @@ static const struct bt_mesh_send_cb friend_req_sent_cb = {
static int send_friend_req(struct bt_mesh_lpn *lpn)
{
const struct bt_mesh_comp *comp = bt_mesh_comp_get();
if (!comp) {
BT_ERR("Invalid composition data");
return -EINVAL;
}
struct bt_mesh_msg_ctx ctx = {
.net_idx = bt_mesh.sub[0].net_idx,
.app_idx = BLE_MESH_KEY_UNUSED,
@@ -710,6 +715,8 @@ static inline int group_popcount(bt_mesh_atomic_t *target)
for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) {
count += popcount(bt_mesh_atomic_get(&target[i]));
}
return count;
#else /* CONFIG_BLE_MESH_LPN_GROUPS > 32 */
return popcount(bt_mesh_atomic_get(target));
#endif /* CONFIG_BLE_MESH_LPN_GROUPS > 32 */
@@ -1086,7 +1093,7 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx,
BT_INFO("Friendship established with 0x%04x", lpn->frnd);
if (cfg->hb_pub.feat & BLE_MESH_FEAT_LOW_POWER) {
if (cfg && (cfg->hb_pub.feat & BLE_MESH_FEAT_LOW_POWER)) {
bt_mesh_heartbeat_send();
}
@@ -1122,10 +1129,10 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx,
bt_mesh_net_iv_update(iv_index, BLE_MESH_IV_UPDATE(msg->flags));
if (lpn->groups_changed) {
sub_update(TRANS_CTL_OP_FRIEND_SUB_ADD);
sub_update(TRANS_CTL_OP_FRIEND_SUB_REM);
bool sent = sub_update(TRANS_CTL_OP_FRIEND_SUB_ADD);
sent = (sent || sub_update(TRANS_CTL_OP_FRIEND_SUB_REM));
if (!lpn->sent_req) {
if (!lpn->sent_req && !sent) {
lpn->groups_changed = 0U;
}
}
+7 -8
View File
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -641,13 +641,12 @@ bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, uint8_t new_kr, bool new_key)
/* Ignore */
break;
}
/* Upon receiving a Secure Network beacon with the KR flag set
* to 0 using the new NetKey in Phase 1, the node shall
* immediately transition to Phase 3, which effectively skips
* Phase 2.
*
* Intentional fall-through.
*/
/* Upon receiving a Secure Network beacon with the KR flag set
* to 0 using the new NetKey in Phase 1, the node shall
* immediately transition to Phase 3, which effectively skips
* Phase 2.
*/
__attribute__((fallthrough));
case BLE_MESH_KR_PHASE_2:
BT_INFO("KrPhase 0x%02x -> Normal", sub->kr_phase);
@@ -1,7 +1,7 @@
/*
* SPDX-FileCopyrightText: 2017 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2015-2016 Intel Corporation
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -88,7 +88,7 @@ static inline bool bt_mesh_is_ble_adv_running();
static bool g_host_init = false;
#if CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_USE_BLE_50
#if CONFIG_BLE_MESH_NODE
static void bt_mesh_gatts_conn_init(void)
{
int i;
@@ -118,7 +118,7 @@ static int bt_mesh_find_conn_idx(uint16_t conn_handle)
}
return -ENODEV;
}
#endif /* CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_USE_BLE_50 */
#endif /* CONFIG_BLE_MESH_NODE */
int bt_mesh_host_init(void)
{
@@ -322,9 +322,10 @@ static int chr_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
uint16_t uuid16 = 0;
int i = (int)arg; /* service index */
struct bt_mesh_conn *conn = &bt_mesh_gattc_info[i].conn;
const ble_uuid_any_t *uuid = &chr->uuid;
const ble_uuid_any_t *uuid = NULL;
if (chr) {
uuid = &chr->uuid;
uuid16 = (uint16_t) BLE_UUID16(uuid)->value;
}
@@ -698,10 +699,9 @@ report_to_user:
bt_mesh_gattc_info[i].wr_desc_done = false;
break;
}
if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
goto transfer_to_user;
}
}
if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
goto transfer_to_user;
}
} else {
goto transfer_to_user;
@@ -748,7 +748,10 @@ report_to_user:
}
conn = &bt_mesh_gattc_info[i].conn;
ble_gap_conn_find(event->notify_rx.conn_handle, &conn_desc);
if (ble_gap_conn_find(event->notify_rx.conn_handle, &conn_desc) != 0) {
BT_ERR("Failed to find connection for notify handler");
return 0;
}
if (bt_mesh_gattc_info[i].data_out_handle != event->notify_rx.attr_handle) {
/* Data isn't populated yet */
@@ -829,6 +832,8 @@ void *bt_mesh_nimble_gap_cb_get(void)
static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window, uint8_t filter_dup)
{
int rc;
#if CONFIG_BLE_MESH_USE_BLE_50
uncoded_disc_params.itvl = (window ? interval : 0);
uncoded_disc_params.window = window;
@@ -839,9 +844,13 @@ static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
coded_disc_params.passive = (scan_type == BLE_MESH_SCAN_PASSIVE);
uncoded_disc_params.passive = (scan_type == BLE_MESH_SCAN_PASSIVE);
ble_gap_ext_disc(BLE_OWN_ADDR_PUBLIC, 0, 0, filter_dup, 0, 0,
uncoded_disc_params.itvl ? &uncoded_disc_params : NULL,
coded_disc_params.itvl ? &coded_disc_params : NULL, disc_cb, NULL);
rc = ble_gap_ext_disc(BLE_OWN_ADDR_PUBLIC, 0, 0, filter_dup, 0, 0,
uncoded_disc_params.itvl ? &uncoded_disc_params : NULL,
coded_disc_params.itvl ? &coded_disc_params : NULL, disc_cb, NULL);
if (rc != 0) {
BT_ERR("Failed to start extended discovery (err %d)", rc);
return rc;
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
scan_param.filter_duplicates = filter_dup;
scan_param.itvl = interval;
@@ -852,7 +861,11 @@ static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
} else {
scan_param.passive = 0;
}
ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &scan_param, disc_cb, NULL);
rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &scan_param, disc_cb, NULL);
if (rc != 0) {
BT_ERR("Failed to start discovery (err %d)", rc);
return rc;
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#if BLE_MESH_DEV
@@ -880,10 +893,14 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
MODLOG_DFLT(INFO, "connection %s; status=%d ",
event->connect.status == 0 ? "established" : "failed",
event->connect.status);
if (event->connect.status == 0) {
rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
assert(rc == 0);
if (event->connect.status != 0) {
return 0;
}
rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
assert(rc == 0);
MODLOG_DFLT(INFO, "\n");
#if BLE_MESH_DEV
/* When connection is created, advertising will be stopped automatically. */
@@ -904,9 +921,7 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
#endif
if (bt_mesh_gatts_conn_cb != NULL && bt_mesh_gatts_conn_cb->connected != NULL) {
int index = 0;
#if CONFIG_BLE_MESH_USE_BLE_50
index = bt_mesh_find_free_conn_idx();
int index = bt_mesh_find_free_conn_idx();
if (index != -ENOMEM) {
bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->connect.conn_handle);
(bt_mesh_gatts_conn_cb->connected)(&bt_mesh_gatts_conn[index], 0);
@@ -914,13 +929,6 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
BT_ERR("No space for new connection");
ble_gap_terminate(event->connect.conn_handle, BLE_ERR_CONN_LIMIT);
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
index = BLE_MESH_GATT_GET_CONN_ID(event->connect.conn_handle);
if (index < BLE_MESH_MAX_CONN) {
bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->connect.conn_handle);
(bt_mesh_gatts_conn_cb->connected)(&bt_mesh_gatts_conn[index], 0);
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
memcpy(bt_mesh_gatts_addr, desc.peer_id_addr.val, BLE_MESH_ADDR_LEN);
/* This is for EspBleMesh Android app. When it tries to connect with the
* device at the first time and it fails due to some reason. And after
@@ -940,22 +948,13 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
bt_mesh_atomic_test_and_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
#endif
if (bt_mesh_gatts_conn_cb != NULL && bt_mesh_gatts_conn_cb->disconnected != NULL) {
int index = 0;
#if CONFIG_BLE_MESH_USE_BLE_50
index = bt_mesh_find_conn_idx(BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle));
int index = bt_mesh_find_conn_idx(BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle));
if (index != -ENODEV) {
bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle);
(bt_mesh_gatts_conn_cb->disconnected)(&bt_mesh_gatts_conn[index], event->disconnect.reason);
} else {
BT_ERR("No device");
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
index = BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle);
if (index < BLE_MESH_MAX_CONN) {
bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle);
(bt_mesh_gatts_conn_cb->disconnected)(&bt_mesh_gatts_conn[index], event->disconnect.reason);
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
bt_mesh_gatts_conn[index].handle = BT_MESH_GATTS_CONN_UNUSED;
memset(bt_mesh_gatts_addr, 0x0, BLE_MESH_ADDR_LEN);
}
@@ -1035,19 +1034,11 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
uint16_t len = 0;
uint16_t ccc_val = 0;
#if CONFIG_BLE_MESH_USE_BLE_50
index = bt_mesh_find_conn_idx(BLE_MESH_GATT_GET_CONN_ID(event->subscribe.conn_handle));
if (index == -ENODEV) {
BT_ERR("Couldn't find conn %d", event->subscribe.conn_handle);
return 0;
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
index = BLE_MESH_GATT_GET_CONN_ID(event->subscribe.conn_handle);
if (index >= BLE_MESH_MAX_CONN) {
BT_ERR("InvConnIdx[%d]", index);
return 0;
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
if (event->subscribe.prev_notify != event->subscribe.cur_notify) {
ccc_val = event->subscribe.cur_notify;
@@ -1224,6 +1215,7 @@ int bt_le_ext_adv_start(const uint8_t inst_id,
err = os_mbuf_append(data, buf, buf_len);
if (err) {
bt_mesh_free(buf);
os_mbuf_free_chain(data);
BT_ERR("Append ad data to os buf failed %d", err);
return -EINVAL;
}
@@ -1236,19 +1228,22 @@ int bt_le_ext_adv_start(const uint8_t inst_id,
buf = bt_mesh_calloc(sd_len * BLE_HS_ADV_MAX_SZ);
if (!buf) {
BT_ERR("ad buffer alloc failed");
os_mbuf_free_chain(data);
return -ENOMEM;
}
err = set_ad(sd, sd_len, buf, &buf_len);
if (err) {
bt_mesh_free(buf);
os_mbuf_free_chain(data);
BT_ERR("SetScanRspDataFail[%d]", err);
return err;
}
scan_rsp = os_msys_get_pkthdr(buf_len, 0);
if (!data) {
if (!scan_rsp) {
bt_mesh_free(buf);
os_mbuf_free_chain(data);
BT_ERR("os buf get failed");
return -ENOBUFS;
}
@@ -1256,6 +1251,8 @@ int bt_le_ext_adv_start(const uint8_t inst_id,
err = os_mbuf_append(scan_rsp, buf, buf_len);
if (err) {
bt_mesh_free(buf);
os_mbuf_free_chain(data);
os_mbuf_free_chain(scan_rsp);
BT_ERR("Append ad data to os buf failed %d", err);
return -EINVAL;
}
@@ -1315,6 +1312,10 @@ int bt_le_ext_adv_start(const uint8_t inst_id,
err = ble_gap_ext_adv_remove(inst_id);
if (err != 0 && err != BLE_HS_EALREADY) {
BT_ERR("Advertising rm failed: err %d", err);
os_mbuf_free_chain(data);
if (scan_rsp) {
os_mbuf_free_chain(scan_rsp);
}
return err;
}
}
@@ -1322,6 +1323,10 @@ int bt_le_ext_adv_start(const uint8_t inst_id,
err = ble_gap_ext_adv_configure(inst_id, &adv_params, NULL, gap_event_cb, NULL);
if (err != 0) {
BT_ERR("Advertising config failed: err %d", err);
os_mbuf_free_chain(data);
if (scan_rsp) {
os_mbuf_free_chain(scan_rsp);
}
return err;
}
@@ -1331,6 +1336,9 @@ int bt_le_ext_adv_start(const uint8_t inst_id,
err = ble_gap_ext_adv_set_data(inst_id, data);
if (err != 0) {
BT_ERR("Advertising set failed: err %d", err);
if (scan_rsp) {
os_mbuf_free_chain(scan_rsp);
}
return err;
}
@@ -1604,6 +1612,7 @@ int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
if (os_mbuf_append(data, adv_data->adv_data, adv_data->adv_data_len)) {
BT_ERR("Append data failed");
os_mbuf_free_chain(data);
return -EINVAL;
}
@@ -1622,6 +1631,7 @@ int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
if (os_mbuf_append(data, adv_data->scan_rsp_data, adv_data->scan_rsp_data_len)) {
BT_ERR("Append data failed");
os_mbuf_free_chain(data);
return -EINVAL;
}
err = ble_gap_ext_adv_rsp_set_data(inst_id, data);
@@ -2420,23 +2430,25 @@ static int proxy_char_access_cb(uint16_t conn_handle, uint16_t attr_handle,
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR || ctxt->op == BLE_GATT_ACCESS_OP_WRITE_DSC) {
struct bt_mesh_gatt_attr *attr = bt_mesh_gatts_find_attr_by_handle(attr_handle);
int index = 0;
uint16_t len = 0;
ssize_t len = 0;
#if CONFIG_BLE_MESH_USE_BLE_50
index = bt_mesh_find_conn_idx(BLE_MESH_GATT_GET_CONN_ID(conn_handle));
index = bt_mesh_find_conn_idx(BLE_MESH_GATT_GET_CONN_ID(conn_handle));
if (index == -ENODEV) {
BT_ERR("Unknown conn handle");
return 0;
}
#else
index = BLE_MESH_GATT_GET_CONN_ID(conn_handle);
#endif
BT_DBG("write, handle %d, len %d, data %s", attr_handle,
ctxt->om->om_len,
bt_hex(ctxt->om->om_data, ctxt->om->om_len));
if (attr != NULL && attr->write != NULL) {
if (OS_MBUF_IS_PKTHDR(ctxt->om) && OS_MBUF_PKTLEN(ctxt->om) > ctxt->om->om_len) {
/* Handle fragmented mbuf chain: either linearize or return error */
BT_ERR("Fragmented mbuf not supported");
return BLE_ATT_ERR_UNLIKELY;
}
if ((len = attr->write(&bt_mesh_gatts_conn[index], attr,
ctxt->om->om_data,
ctxt->om->om_len,
@@ -2554,9 +2566,7 @@ void bt_mesh_gatt_init(void)
ble_gatts_svc_set_visibility(prov_svc_start_handle, 1);
ble_gatts_svc_set_visibility(proxy_svc_start_handle, 0);
#if CONFIG_BLE_MESH_USE_BLE_50
bt_mesh_gatts_conn_init();
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
init = true;
}
#endif /* CONFIG_BLE_MESH_NODE */
@@ -2596,6 +2606,7 @@ void bt_mesh_gatt_init(void)
ble_gatts_svc_set_visibility(prov_svc_start_handle, 1);
ble_gatts_svc_set_visibility(proxy_svc_start_handle, 0);
bt_mesh_gatts_conn_init();
init = true;
}
#endif /* CONFIG_BLE_MESH_NODE */
+31 -9
View File
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -103,6 +103,14 @@ static const struct {
bool bt_mesh_prov_pdu_check(uint8_t type, uint16_t length, uint8_t *reason)
{
if (type >= ARRAY_SIZE(prov_pdu)) {
BT_ERR("Invalid PDU type 0x%02x", type);
if (reason) {
*reason = PROV_ERR_NVAL_PDU;
}
return false;
}
if (prov_pdu[type].length != length) {
#if CONFIG_BLE_MESH_CERT_BASED_PROV
if ((type == PROV_REC_LIST || type == PROV_REC_RSP) &&
@@ -224,12 +232,21 @@ bool bt_mesh_gen_prov_start(struct bt_mesh_prov_link *link,
return false;
}
if (START_LAST_SEG(rx->gpc) > 0 && link->rx.buf->len <= 20) {
BT_ERR("Too small total length for multi-segment PDU");
if (close) {
*close = true;
if (START_LAST_SEG(rx->gpc) > 0) {
/* For multi-segment PDUs, validate that total length is consistent
* with the claimed segment count to prevent underflow in
* bt_mesh_gen_prov_cont() when computing expect_len.
* Minimum length = first segment (20) + (last_seg - 1) * full continuation (23) + 1
*/
uint16_t min_len = 20 + 23 * (START_LAST_SEG(rx->gpc) - 1) + 1;
if (link->rx.buf->len < min_len) {
BT_ERR("Total length %u too small for %u segments (min %u)",
link->rx.buf->len, START_LAST_SEG(rx->gpc) + 1, min_len);
if (close) {
*close = true;
}
return false;
}
return false;
}
link->rx.seg = (1 << (START_LAST_SEG(rx->gpc) + 1)) - 1;
@@ -375,7 +392,7 @@ static void free_segments(struct bt_mesh_prov_link *link)
struct net_buf *buf = link->tx.buf[i];
if (!buf) {
break;
continue;
}
link->tx.buf[i] = NULL;
@@ -536,6 +553,8 @@ static void send_reliable(struct bt_mesh_prov_link *link, uint8_t xmit)
{
link->tx.start = k_uptime_get();
bt_mesh_mutex_lock(&link->buf_lock);
for (size_t i = 0; i < ARRAY_SIZE(link->tx.buf); i++) {
struct net_buf *buf = link->tx.buf[i];
@@ -549,6 +568,8 @@ static void send_reliable(struct bt_mesh_prov_link *link, uint8_t xmit)
bt_mesh_adv_send(buf, xmit, &buf_sent_cb, link);
}
}
bt_mesh_mutex_unlock(&link->buf_lock);
}
int bt_mesh_prov_bearer_ctl_send(struct bt_mesh_prov_link *link, uint8_t op,
@@ -737,6 +758,7 @@ int bt_mesh_prov_send(struct bt_mesh_prov_link *link, struct net_buf_simple *buf
return bt_mesh_prov_send_adv(link, buf);
#endif /* CONFIG_BLE_MESH_PB_ADV */
/* Shall not reach here. */
return 0;
/* Shall not reach here - no provisioning bearer is enabled */
BT_ERR("No provisioning bearer available");
return -ENOTSUP;
}
+14 -5
View File
@@ -124,7 +124,7 @@ static void reset_adv_link(struct bt_mesh_prov_link *link, uint8_t reason)
{
ARG_UNUSED(link);
BT_INFO("ResetAdvLink:%08x", link->link_id);
BT_INFO("ResetAdvLink:%08x", prov_link.link_id);
bt_mesh_prov_clear_tx(&prov_link, true);
if (bt_mesh_prov_get()->link_close) {
@@ -285,6 +285,11 @@ static int prov_auth(uint8_t method, uint8_t action, uint8_t size)
return -EINVAL;
}
if (bt_mesh_prov_get()->static_val == NULL) {
BT_ERR("Static OOB value not set");
return -EINVAL;
}
if (bt_mesh_prov_get()->static_val_len > auth_size) {
memcpy(prov_link.auth, bt_mesh_prov_get()->static_val, auth_size);
} else {
@@ -306,7 +311,7 @@ static int prov_auth(uint8_t method, uint8_t action, uint8_t size)
return -EINVAL;
}
if (size > bt_mesh_prov_get()->output_size) {
if (size == 0 || size > bt_mesh_prov_get()->output_size) {
return -EINVAL;
}
@@ -599,7 +604,7 @@ int bt_mesh_input_string(const char *str)
}
(void)memset(prov_link.auth, 0, sizeof(prov_link.auth));
(void)memcpy(prov_link.auth, str, bt_mesh_prov_get()->input_size);
(void)memcpy(prov_link.auth, str, MIN(strlen(str), bt_mesh_prov_get()->input_size));
send_input_complete();
@@ -631,11 +636,13 @@ static void send_pub_key(void)
if (bt_mesh_dh_key_gen(buf.data, dhkey)) {
BT_ERR("Unable to generate DHKey");
(void)memset(dhkey, 0, sizeof(dhkey));
close_link(PROV_ERR_UNEXP_ERR);
return;
}
memcpy(prov_link.dhkey, dhkey, 32);
(void)memset(dhkey, 0, sizeof(dhkey));
BT_DBG("DHkey: %s", bt_hex(prov_link.dhkey, 32));
@@ -643,6 +650,7 @@ static void send_pub_key(void)
if (bt_mesh_pub_key_copy(pub_key)) {
BT_ERR("No public key available");
(void)memset(pub_key, 0, sizeof(pub_key));
close_link(PROV_ERR_UNEXP_ERR);
return;
}
@@ -654,6 +662,7 @@ static void send_pub_key(void)
/* Public key is already in big-endian format from bt_mesh_pub_key_copy() */
memcpy(net_buf_simple_add(&buf, 32), pub_key, 32);
memcpy(net_buf_simple_add(&buf, 32), &pub_key[32], 32);
(void)memset(pub_key, 0, sizeof(pub_key));
memcpy(&prov_link.conf_inputs[81], &buf.data[1], 64);
@@ -1187,7 +1196,7 @@ static void prov_msg_recv(void)
uint8_t type = 0;
if (bt_mesh_atomic_test_bit(prov_link.flags, LINK_INVALID)) {
BT_WARN("Unexpected msg 0x%02x on invalidated link", type);
BT_WARN("Unexpected msg on invalidated link");
close_link(PROV_ERR_UNEXP_PDU);
return;
}
@@ -1196,7 +1205,7 @@ static void prov_msg_recv(void)
* should be ignored.
*/
if (bt_mesh_atomic_test_bit(prov_link.flags, LINK_CLOSING)) {
BT_WARN("Link is closing, unexpected msg 0x%02x", type);
BT_WARN("Link is closing, unexpected msg received");
return;
}
+7 -6
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -655,7 +655,7 @@ start:
#endif /* CONFIG_BLE_MESH_PB_GATT */
/* Shall not reach here. */
return 0;
return -EINVAL;
}
int bt_mesh_provisioner_prov_device_with_addr(const uint8_t uuid[16], const uint8_t addr[6],
@@ -754,7 +754,7 @@ int bt_mesh_provisioner_prov_device_with_addr(const uint8_t uuid[16], const uint
#endif /* CONFIG_BLE_MESH_PB_GATT */
/* Shall not reach here. */
return 0;
return -EINVAL;
}
int bt_mesh_provisioner_delete_device(struct bt_mesh_device_delete *del_dev)
@@ -2487,7 +2487,7 @@ static void prov_msg_recv(struct bt_mesh_prov_link *link)
* should be ignored.
*/
if (bt_mesh_atomic_test_bit(link->flags, LINK_CLOSING)) {
BT_WARN("Link is closing, unexpected msg 0x%02x", type);
BT_WARN("Link is closing, ignoring received PDU");
return;
}
@@ -3165,7 +3165,7 @@ int bt_mesh_rpr_cli_pdu_recv(struct bt_mesh_prov_link *link, uint8_t type,
return -EINVAL;
}
if (type != link->expect) {
if (type != PROV_FAILED && type != link->expect) {
BT_ERR("PB-Remote, unexpected msg 0x%02x != 0x%02x", type, link->expect);
return -EINVAL;
}
@@ -3188,7 +3188,8 @@ int bt_mesh_rpr_cli_pdu_send(struct bt_mesh_prov_link *link, uint8_t type)
send_confirm(link);
break;
default:
break;
BT_WARN("Unsupported RPR CLI PDU type 0x%02x", type);
return -EINVAL;
}
return 0;
+22 -8
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -80,7 +80,7 @@ static void proxy_sar_timeout(struct k_work *work)
BT_WARN("ProxySARTimeout");
server = CONTAINER_OF(work, struct bt_mesh_proxy_server, sar_timer.work);
if (!server || !server->conn) {
if (!server->conn) {
BT_ERR("InvalidProxyServerParam");
return;
}
@@ -429,6 +429,10 @@ int bt_mesh_proxy_client_segment_send(struct bt_mesh_conn *conn, uint8_t type,
net_buf_simple_push_u8(msg, BLE_MESH_PROXY_PDU_HDR(BLE_MESH_PROXY_SAR_FIRST, type));
err = proxy_send(conn, msg->data, mtu);
/* Note:
* Even if proxy_send() failed, do not return early here in order to
* keep the msg in a consistent final state.
*/
net_buf_simple_pull(msg, mtu);
while (msg->len) {
@@ -440,6 +444,10 @@ int bt_mesh_proxy_client_segment_send(struct bt_mesh_conn *conn, uint8_t type,
net_buf_simple_push_u8(msg, BLE_MESH_PROXY_PDU_HDR(BLE_MESH_PROXY_SAR_CONT, type));
err = proxy_send(conn, msg->data, mtu);
/* Note:
* Even if proxy_send() failed, do not return early here in order to
* keep the msg in a consistent final state.
*/
net_buf_simple_pull(msg, mtu);
}
@@ -449,10 +457,16 @@ int bt_mesh_proxy_client_segment_send(struct bt_mesh_conn *conn, uint8_t type,
int bt_mesh_proxy_client_send(struct bt_mesh_conn *conn, uint8_t type,
struct net_buf_simple *msg)
{
struct bt_mesh_proxy_server *server = find_server(conn);
struct bt_mesh_proxy_server *server = NULL;
if (conn == NULL) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
BT_DBG("ProxyClientSend, ConnHandle 0x%04x Type %u", conn->handle, type);
server = find_server(conn);
if (!server) {
BT_ERR("No Proxy Server object found");
return -ENOTCONN;
@@ -645,8 +659,8 @@ int bt_mesh_proxy_client_prov_disable(void)
struct bt_mesh_proxy_server *server = &servers[i];
if (server->conn && server->conn_type == CLI_PROV) {
bt_mesh_gattc_disconnect(server->conn);
server->conn_type = CLI_NONE;
bt_mesh_gattc_disconnect(server->conn);
}
}
@@ -728,7 +742,7 @@ int bt_mesh_proxy_client_gatt_enable(void)
BT_DBG("ProxyClientGattEnable");
for (i = 0; i < ARRAY_SIZE(servers); i++) {
if (servers[i].conn) {
if (servers[i].conn && servers[i].conn_type == CLI_NONE) {
servers[i].conn_type = CLI_PROXY;
}
}
@@ -758,8 +772,8 @@ int bt_mesh_proxy_client_gatt_disable(void)
struct bt_mesh_proxy_server *server = &servers[i];
if (server->conn && server->conn_type == CLI_PROXY) {
bt_mesh_gattc_disconnect(server->conn);
server->conn_type = CLI_NONE;
bt_mesh_gattc_disconnect(server->conn);
}
}
@@ -1127,13 +1141,13 @@ static int send_proxy_cfg(struct bt_mesh_conn *conn, uint16_t net_idx, struct bt
case BLE_MESH_PROXY_CFG_FILTER_ADD:
for (uint16_t i = 0U; i < cfg->add.addr_num; i++) {
net_buf_simple_add_le16(buf, cfg->add.addr[i]);
net_buf_simple_add_be16(buf, cfg->add.addr[i]);
}
break;
case BLE_MESH_PROXY_CFG_FILTER_REMOVE:
for (uint16_t i = 0U; i < cfg->remove.addr_num; i++) {
net_buf_simple_add_le16(buf, cfg->remove.addr[i]);
net_buf_simple_add_be16(buf, cfg->remove.addr[i]);
}
break;
+16 -16
View File
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -182,7 +182,7 @@ static void proxy_sar_timeout(struct k_work *work)
BT_WARN("ProxySARTimeout");
client = CONTAINER_OF(work, struct bt_mesh_proxy_client, sar_timer.work);
if (!client || !client->conn) {
if (!client->conn) {
BT_ERR("Invalid proxy client parameter");
return;
}
@@ -312,15 +312,12 @@ static void filter_add(struct bt_mesh_proxy_client *client,
for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
if (client->filter[i].addr == addr) {
BT_INFO("client addr 0x%04x already added", addr);
return;
}
}
for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
if (client->filter[i].addr == addr) {
BT_INFO("client addr 0x%04x already added", addr);
return;
}
if (client->filter[i].addr == BLE_MESH_ADDR_UNASSIGNED) {
BT_INFO("Add client or filter addr 0x%04x", addr);
client->filter[i].addr = addr;
@@ -514,7 +511,7 @@ static void proxy_send_beacons(struct k_work *work)
{
struct bt_mesh_proxy_client *client = CONTAINER_OF(work,
struct bt_mesh_proxy_client,
send_beacons);;
send_beacons);
int i;
BT_DBG("ProxySendBeacons");
@@ -1484,10 +1481,10 @@ int bt_mesh_proxy_server_segment_send(struct bt_mesh_conn *conn, uint8_t type,
net_buf_simple_push_u8(msg, BLE_MESH_PROXY_PDU_HDR(BLE_MESH_PROXY_SAR_FIRST, type));
err = proxy_send(conn, msg->data, mtu);
if (err) {
BT_ERR("ProxyServerSendFail %d", err);
return err;
}
/* Note:
* Even if proxy_send() failed, do not return early here in order to
* keep the msg in a consistent final state.
*/
net_buf_simple_pull(msg, mtu);
while (msg->len) {
@@ -1498,14 +1495,14 @@ int bt_mesh_proxy_server_segment_send(struct bt_mesh_conn *conn, uint8_t type,
net_buf_simple_push_u8(msg, BLE_MESH_PROXY_PDU_HDR(BLE_MESH_PROXY_SAR_CONT, type));
err = proxy_send(conn, msg->data, mtu);
if (err) {
BT_ERR("ProxyServerSendFail %d", err);
return err;
}
/* Note:
* Even if proxy_send() failed, do not return early here in order to
* keep the msg in a consistent final state.
*/
net_buf_simple_pull(msg, mtu);
}
return 0;
return err;
}
int bt_mesh_proxy_server_send(struct bt_mesh_conn *conn, uint8_t type,
@@ -2241,6 +2238,9 @@ int bt_mesh_proxy_server_deinit(void)
k_delayed_work_free(&client->sar_timer);
memset(client, 0, sizeof(struct bt_mesh_proxy_client));
#if CONFIG_BLE_MESH_PROXY_PRIVACY
client->proxy_privacy = BLE_MESH_PROXY_PRIVACY_DISABLED;
#endif /* CONFIG_BLE_MESH_PROXY_PRIVACY */
}
#if CONFIG_BLE_MESH_GATT_PROXY_SERVER && CONFIG_BLE_MESH_PRB_SRV
+6 -5
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -378,11 +378,7 @@ static int provisioner_remove_node(uint16_t index, bool erase)
/* Reset corresponding transport info when removing the node */
for (i = 0; i < node->element_num; i++) {
bt_mesh_rx_reset_single(node->unicast_addr + i);
}
for (i = 0; i < node->element_num; i++) {
bt_mesh_tx_reset_single(node->unicast_addr + i);
}
for (i = 0; i < node->element_num; i++) {
bt_mesh_rpl_reset_single(node->unicast_addr + i, erase);
}
@@ -544,6 +540,11 @@ int bt_mesh_provisioner_delete_node_with_dev_addr(const bt_mesh_addr_t *addr)
{
int i;
if (addr == NULL) {
BT_ERR("Invalid device address");
return -EINVAL;
}
bt_mesh_provisioner_lock();
for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {

Some files were not shown because too many files have changed in this diff Show More