From 4dfb8568e7226c605c8a022539733db122f98134 Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Fri, 21 Aug 2026 22:35:46 +0800 Subject: [PATCH] feat(ble_log): report build, lib and chip versions in a version info frame Replace the 2-byte BLE Log info record with a 58-byte version info frame (BLE_LOG_VERSION 5 -> 6; the abandoned branch that claimed the version-6 slot frees it, so the overall bump stays 5 -> 6): - idf build commit (12 bytes), injected at build time by register_ble_log_idf_commit() next to the other register_* helpers; the git probe is only trusted when the IDF tree itself is a repo/worktree, since rev-parse walks up parent directories - controller, btdm_common, BLE Mesh and BLE Audio lib commits (10 bytes each, zero-padded), every getter guarded by the exact condition that links its lib, so configs without the lib leave the field zero (no link errors) - chip model and revision from esp_chip_info() at runtime Lib strings are copied NUL-safely instead of assuming a fixed hash length; the mesh commit is the substring after the last space of bt_mesh_v11_commit_str. Frame layout is pinned by a static assert. Verified on target: esp32, esp32c3, esp32c5 and esp32h4 boards (the h4 run covers controller + btdm_common + mesh in one build); the audio-enabled build is blocked by pre-existing esp_ble_audio compile errors on this base (audio symbol verified with nm instead). --- components/bt/CMakeLists.txt | 1 + components/bt/common/CMakeLists.txt | 29 ++++++++ components/bt/common/ble_log/src/ble_log_rt.c | 73 ++++++++++++++++++- .../src/internal_include/ble_log_util.h | 18 ++++- 4 files changed, 116 insertions(+), 5 deletions(-) diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index b96558323f8..dcd7fe6347e 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -119,6 +119,7 @@ if(CONFIG_BT_ENABLED) target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable) target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") + register_ble_log_idf_commit() register_bt_ctrl_libs() set_bluedroid_host_compile_flags() set_nimble_host_compile_flags() diff --git a/components/bt/common/CMakeLists.txt b/components/bt/common/CMakeLists.txt index 5e0f062eecf..1bb4376bca8 100644 --- a/components/bt/common/CMakeLists.txt +++ b/components/bt/common/CMakeLists.txt @@ -66,6 +66,35 @@ function(wrap_uart_log_tx_interface) endif() endfunction() +# Inject the ESP-IDF build commit into the bt component as a private compile +# definition (BLE_LOG_IDF_COMMIT), reported later in the BLE Log version info +# frame. Does nothing when the commit cannot be determined. +function(register_ble_log_idf_commit) + idf_build_get_property(idf_path IDF_PATH) + # "git rev-parse" walks up parent dirs; only trust it when the IDF tree + # itself is a repo/worktree. Release trees have no .git and must leave + # BLE_LOG_IDF_COMMIT undefined instead of picking up an enclosing repo. + if(NOT EXISTS "${idf_path}/.git") + return() + endif() + execute_process( + COMMAND "${GIT_EXECUTABLE}" rev-parse HEAD + WORKING_DIRECTORY "${idf_path}" + RESULT_VARIABLE ble_log_git_result + OUTPUT_VARIABLE ble_log_idf_commit + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + string(LENGTH "${ble_log_idf_commit}" ble_log_idf_commit_len) + # Take the first 12 chars of the full hash; --short=N may return a longer + # ambiguous abbreviation, so never rely on abbreviated output + if(ble_log_git_result EQUAL 0 AND ble_log_idf_commit_len EQUAL 40) + string(SUBSTRING "${ble_log_idf_commit}" 0 12 ble_log_idf_commit) + target_compile_definitions(${COMPONENT_LIB} PRIVATE + "BLE_LOG_IDF_COMMIT=\"${ble_log_idf_commit}\"") + endif() +endfunction() + set(bt_common_srcs "" PARENT_SCOPE) set(bt_common_include_dirs "" PARENT_SCOPE) set(bt_common_priv_include_dirs "" PARENT_SCOPE) diff --git a/components/bt/common/ble_log/src/ble_log_rt.c b/components/bt/common/ble_log/src/ble_log_rt.c index 7aaac49c4eb..a425034b6ed 100644 --- a/components/bt/common/ble_log/src/ble_log_rt.c +++ b/components/bt/common/ble_log/src/ble_log_rt.c @@ -14,10 +14,39 @@ #include "ble_log_lbm.h" #include "esp_log.h" +#include "esp_chip_info.h" /* MACRO */ #define TAG "ble_log_rt" +#if CONFIG_BT_CONTROLLER_ENABLED +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 +extern const char *btdm_controller_get_compile_version(void); +#define BLE_LOG_CONTROLLER_GET_COMMIT() btdm_controller_get_compile_version() +#elif !CONFIG_BT_DUAL_MODE_ARCH || CONFIG_BT_CTRL_BLE_ENABLE +/* BR/EDR-only dual-mode builds do not link the BLE controller lib */ +extern char *ble_controller_get_compile_version(void); +#define BLE_LOG_CONTROLLER_GET_COMMIT() ble_controller_get_compile_version() +#endif +#if CONFIG_BT_DUAL_MODE_ARCH +/* BTDM common lib (dual-mode arch only) */ +extern const char *r_btdm_get_compile_version(void); +#define BLE_LOG_BTDM_COMMON_GET_COMMIT() r_btdm_get_compile_version() +#endif +#endif + +#if CONFIG_BLE_MESH && CONFIG_BLE_MESH_V11_SUPPORT +/* "Bluetooth Mesh v1.1 commit: " */ +extern const char bt_mesh_v11_commit_str[]; +#endif + +#if CONFIG_BT_AUDIO && CONFIG_SOC_BLE_AUDIO_SUPPORTED +extern const char *lib_audio_commit_get(void); +#endif + +_Static_assert(sizeof(ble_log_version_info_t) == 58, + "Unexpected BLE Log version info frame size"); + /* VARIABLE */ BLE_LOG_STATIC BLE_LOG_DRAM_ATTR uint32_t rt_inited = 0; BLE_LOG_STATIC BLE_LOG_DRAM_ATTR volatile uint32_t rt_ref_count = 0; @@ -35,6 +64,12 @@ BLE_LOG_STATIC void ble_log_rt_ts_trigger(void *arg); #endif /* CONFIG_BLE_LOG_TS_ENABLED */ /* PRIVATE FUNCTION */ +/* Copies a NUL-terminated commit string into a fixed-width zero-padded field */ +BLE_LOG_STATIC void ble_log_commit_copy(uint8_t *dst, const char *src, size_t len) +{ + BLE_LOG_MEMCPY(dst, src, strnlen(src, len)); +} + BLE_LOG_STATIC void ble_log_rt_task(void *pvParameters) { (void)pvParameters; @@ -56,12 +91,42 @@ BLE_LOG_STATIC void ble_log_rt_task(void *pvParameters) } last_hook_os_ts = curr_os_ts; - /* Write BLE Log info log */ - ble_log_info_t ble_log_info = { - .int_src_code = BLE_LOG_INT_SRC_INFO, + /* Write version info: BLE Log version, idf commit (build-time), + * linked-in BLE lib commits, chip model/revision (efuse, runtime-only). + * Libs absent from the build leave their fields zero. */ + ble_log_version_info_t version_info = { + .int_src_code = BLE_LOG_INT_SRC_VERSION_INFO, .version = BLE_LOG_VERSION, }; - ble_log_write_hex(BLE_LOG_SRC_INTERNAL, (const uint8_t *)&ble_log_info, sizeof(ble_log_info_t)); +#ifdef BLE_LOG_IDF_COMMIT + BLE_LOG_MEMCPY(version_info.idf_commit, BLE_LOG_IDF_COMMIT, BLE_LOG_IDF_COMMIT_LEN); +#endif +#if CONFIG_BT_CONTROLLER_ENABLED && defined(BLE_LOG_CONTROLLER_GET_COMMIT) + ble_log_commit_copy(version_info.controller_commit, BLE_LOG_CONTROLLER_GET_COMMIT(), + BLE_LOG_LIB_COMMIT_LEN); +#endif +#if CONFIG_BT_CONTROLLER_ENABLED && defined(BLE_LOG_BTDM_COMMON_GET_COMMIT) + ble_log_commit_copy(version_info.btdm_common_commit, BLE_LOG_BTDM_COMMON_GET_COMMIT(), + BLE_LOG_LIB_COMMIT_LEN); +#endif +#if CONFIG_BLE_MESH && CONFIG_BLE_MESH_V11_SUPPORT + /* The hash is the substring after the last space of the lib string */ + const char *mesh_commit = strrchr(bt_mesh_v11_commit_str, ' '); + if (mesh_commit) { + ble_log_commit_copy(version_info.mesh_commit, mesh_commit + 1, + BLE_LOG_LIB_COMMIT_LEN); + } +#endif +#if CONFIG_BT_AUDIO && CONFIG_SOC_BLE_AUDIO_SUPPORTED + ble_log_commit_copy(version_info.audio_commit, lib_audio_commit_get(), + BLE_LOG_LIB_COMMIT_LEN); +#endif + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + version_info.chip_model = (uint16_t)chip_info.model; + version_info.chip_revision = chip_info.revision; + ble_log_write_hex(BLE_LOG_SRC_INTERNAL, (const uint8_t *)&version_info, + sizeof(version_info)); ble_log_write_enh_stat(); ble_log_write_buf_util(); diff --git a/components/bt/common/ble_log/src/internal_include/ble_log_util.h b/components/bt/common/ble_log/src/internal_include/ble_log_util.h index f3a99fa8645..1ce2dbb719a 100644 --- a/components/bt/common/ble_log/src/internal_include/ble_log_util.h +++ b/components/bt/common/ble_log/src/internal_include/ble_log_util.h @@ -91,7 +91,10 @@ void ble_log_cas_release(volatile bool *cas_lock) __atomic_store_n(cas_lock, false, __ATOMIC_RELEASE); } -#define BLE_LOG_VERSION (5) +#define BLE_LOG_VERSION (6) +#define BLE_LOG_IDF_COMMIT_LEN (12) +/* Lib commit hashes are at most 10 hex chars; zero-padded when shorter */ +#define BLE_LOG_LIB_COMMIT_LEN (10) /* TYPEDEF */ typedef enum { @@ -102,6 +105,7 @@ typedef enum { BLE_LOG_INT_SRC_FLUSH, BLE_LOG_INT_SRC_BUF_UTIL, BLE_LOG_INT_SRC_FINAL_STAT, + BLE_LOG_INT_SRC_VERSION_INFO, BLE_LOG_INT_SRC_MAX, } ble_log_int_src_t; @@ -110,6 +114,18 @@ typedef struct { uint8_t version; } __attribute__((packed)) ble_log_info_t; +typedef struct { + uint8_t int_src_code; + uint8_t version; + uint8_t idf_commit[BLE_LOG_IDF_COMMIT_LEN]; + uint8_t controller_commit[BLE_LOG_LIB_COMMIT_LEN]; + uint8_t btdm_common_commit[BLE_LOG_LIB_COMMIT_LEN]; + uint8_t mesh_commit[BLE_LOG_LIB_COMMIT_LEN]; + uint8_t audio_commit[BLE_LOG_LIB_COMMIT_LEN]; + uint16_t chip_model; + uint16_t chip_revision; +} __attribute__((packed)) ble_log_version_info_t; + /* INTERFACE */ uint32_t ble_log_fast_checksum(const uint8_t *data, size_t len);