diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 77f4919d025..e85501734c0 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -983,7 +983,7 @@ set(bt_priv_requires ) if(CONFIG_BLE_COMPRESSED_LOG_ENABLE) - set(BT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}") + set(CODE_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}") # When log compression is enabled, selected logs are replaced # by auto-generated macros that emit pre-encoded data. # This eliminates the original format strings, reducing firmware size and diff --git a/components/bt/common/ble_log/extension/log_compression/CMakeLists.txt b/components/bt/common/ble_log/extension/log_compression/CMakeLists.txt index 967b0e9b8ec..15ae73550ac 100644 --- a/components/bt/common/ble_log/extension/log_compression/CMakeLists.txt +++ b/components/bt/common/ble_log/extension/log_compression/CMakeLists.txt @@ -1,6 +1,6 @@ - set(LOG_COMPRESSED_MODULE "") set(LOG_COMPRESSED_MODULE_CODE_PATH "") +set(BT_ROOT_PATH $ENV{IDF_PATH}/components/bt) set(LOG_COMPRESSED_SRCS_DIR "${CMAKE_BINARY_DIR}/ble_log/.compressed_srcs") # default config value for ble mesh module @@ -17,32 +17,62 @@ set(BLE_HOST_TAGS_PRESERVE "") if(CONFIG_BLE_MESH_COMPRESSED_LOG_ENABLE) list(APPEND LOG_COMPRESSED_MODULE "BLE_MESH") - if(NOT EXISTS "${CMAKE_BINARY_DIR}/ble_log/include/mesh_log_index.h") - file(WRITE "${CMAKE_BINARY_DIR}/ble_log/include/mesh_log_index.h" "") - endif() - list(APPEND LOG_COMPRESSED_MODULE_CODE_PATH "esp_ble_mesh") # update config file set(BLE_MESH_CODE_PATH "esp_ble_mesh") set(BLE_MESH_LOG_INDEX_HEADER "mesh_log_index.h") + set(BLE_MESH_LOG_SCRIPT_PATH + "${CMAKE_CURRENT_LIST_DIR}/scripts/module_scripts/ble_mesh/make_mesh_log_macro.py") # update BLE_MESH_TAGS and BLE_MESH_TAGS_PRESERVE include(${CMAKE_CURRENT_LIST_DIR}/cmake/ble_mesh_log_tags.cmake) - + if(NOT EXISTS "${CMAKE_BINARY_DIR}/ble_log/include/${BLE_MESH_LOG_INDEX_HEADER}") + file(WRITE "${CMAKE_BINARY_DIR}/ble_log/include/${BLE_MESH_LOG_INDEX_HEADER}" "") + endif() + list(APPEND LOG_COMPRESSED_MODULE_CODE_PATH ${BLE_MESH_CODE_PATH}) endif() + if(CONFIG_BLE_HOST_COMPRESSED_LOG_ENABLE AND CONFIG_BT_BLUEDROID_ENABLED) list(APPEND LOG_COMPRESSED_MODULE "BLE_HOST") - list(APPEND LOG_COMPRESSED_MODULE_CODE_PATH "host/bluedroid/stack") - if(NOT EXISTS "${CMAKE_BINARY_DIR}/ble_log/include/host_log_index.h") - file(WRITE "${CMAKE_BINARY_DIR}/ble_log/include/host_log_index.h" "") - endif() + # update config file set(HOST_CODE_PATH "host/bluedroid/stack") set(HOST_LOG_INDEX_HEADER "host_log_index.h") + set(BLE_HOST_LOG_SCRIPT_PATH + "${CMAKE_CURRENT_LIST_DIR}/scripts/module_scripts/bluedroid/make_bluedroid_log_macro.py") + include(${CMAKE_CURRENT_LIST_DIR}/cmake/ble_host_bluedroid_tags.cmake) + if(NOT EXISTS "${CMAKE_BINARY_DIR}/ble_log/include/${HOST_LOG_INDEX_HEADER}") + file(WRITE "${CMAKE_BINARY_DIR}/ble_log/include/${HOST_LOG_INDEX_HEADER}" "") + endif() + list(APPEND LOG_COMPRESSED_MODULE_CODE_PATH ${HOST_CODE_PATH}) endif() + +if(BLE_COMPRESSED_LIB_LOG_BUILD) + if(NOT (BLE_COMPRESSED_LIB_NAME AND BLE_COMPRESSED_LIB_CODE_DIR AND BLE_COMPRESSED_LIB_LOG_TAGS)) + message(FATAL_ERROR "Invalid settings") + else() + message("Building compressed log for ${BLE_COMPRESSED_LIB_NAME}") + endif() + list(APPEND LOG_COMPRESSED_MODULE ${BLE_COMPRESSED_LIB_NAME}) + if(NOT EXISTS "${CMAKE_BINARY_DIR}/ble_log/include/${BLE_COMPRESSED_LIB_LOG_INDEX_HEADER}") + file(WRITE "${CMAKE_BINARY_DIR}/ble_log/include/${BLE_COMPRESSED_LIB_LOG_INDEX_HEADER}" "") + endif() + list(APPEND LOG_COMPRESSED_MODULE_CODE_PATH ${BLE_COMPRESSED_LIB_CODE_DIR}) + + string(REPLACE ";" "," BLE_COMPRESSED_LIB_CODE_DIR "${BLE_COMPRESSED_LIB_CODE_DIR}") + string(REPLACE ";" "," BLE_COMPRESSED_LIB_LOG_TAGS "${BLE_COMPRESSED_LIB_LOG_TAGS}") + string(REPLACE ";" "," BLE_COMPRESSED_LIB_LOG_TAGS_PRESERVE "${BLE_COMPRESSED_LIB_LOG_TAGS_PRESERVE}") +else() + set(BLE_COMPRESSED_LIB_NAME "placeholder") +endif() + + if(LOG_COMPRESSED_MODULE) - list(APPEND srcs "common/ble_log/extension/log_compression/ble_log_compression.c") - list(APPEND include_dirs "${CMAKE_BINARY_DIR}/ble_log/include") + # When building the library, ble_log_compression.c and its dependencies are not needed + if(NOT BLE_COMPRESSED_LIB_LOG_BUILD) + list(APPEND srcs "common/ble_log/extension/log_compression/ble_log_compression.c") + list(APPEND include_dirs "${CMAKE_BINARY_DIR}/ble_log/include") + endif() if(NOT CMAKE_VERSION VERSION_LESS 3.15.0) set(Python3_FIND_STRATEGY LOCATION) find_package(Python3 COMPONENTS Interpreter) @@ -111,19 +141,39 @@ if(LOG_COMPRESSED_MODULE) "host/nimble/nimble/nimble/host/store/config/src") endif() - add_custom_target(ble_log_compression ALL - COMMAND ${BLE_PYTHON_EXECUTABLE} ${PYTHON_SCRIPT} - compress - --compressed_srcs_path "${LOG_COMPRESSED_SRCS_DIR}" - --build_path "${CMAKE_BINARY_DIR}" - --module "'${LOG_COMPRESSED_MODULE}'" - --bt_path "${BT_ROOT_PATH}" - --srcs "'${compressed_srcs}'" - DEPENDS ${compressed_srcs_with_abs_path} ${PYTHON_SCRIPT} - COMMENT "Log compression is being performed, please wait..." - WORKING_DIRECTORY ${BT_ROOT_PATH} - USES_TERMINAL - ) + if(BLE_COMPRESSED_LIB_LOG_BUILD) + execute_process(COMMAND ${BLE_PYTHON_EXECUTABLE} ${PYTHON_SCRIPT} + compress + --compressed_srcs_path "${LOG_COMPRESSED_SRCS_DIR}" + --build_path "${CMAKE_BINARY_DIR}" + --module "${LOG_COMPRESSED_MODULE}" + --code_base_path "${CODE_BASE_PATH}" + --srcs "${compressed_srcs}" + RESULT_VARIABLE result + OUTPUT_VARIABLE out + ERROR_VARIABLE err) + if(NOT ${result} EQUAL 0) + message(WARNING "${err}") + message(WARNING "Exit this log compression due to failure of compression") + set(LOG_COMPRESS_INCLUDE_DIRS ${include_dirs} PARENT_SCOPE) + set(LOG_COMPRESSION_TARGET "" PARENT_SCOPE) + return() + endif() + else() + add_custom_target(ble_log_compression ALL + COMMAND ${BLE_PYTHON_EXECUTABLE} ${PYTHON_SCRIPT} + compress + --compressed_srcs_path "${LOG_COMPRESSED_SRCS_DIR}" + --build_path "${CMAKE_BINARY_DIR}" + --module "'${LOG_COMPRESSED_MODULE}'" + --code_base_path "${CODE_BASE_PATH}" + --srcs "'${compressed_srcs}'" + DEPENDS ${compressed_srcs_with_abs_path} ${PYTHON_SCRIPT} + COMMENT "Log compression is being performed, please wait..." + WORKING_DIRECTORY ${BT_ROOT_PATH} + USES_TERMINAL + ) + endif() function(add_flags_if_in_list file file_list compile_flags) set(PROCESSED OFF PARENT_SCOPE) @@ -190,7 +240,10 @@ if(LOG_COMPRESSED_MODULE) set(LOG_COMPRESSION_TARGET ble_log_compression PARENT_SCOPE) # set(LOG_COMPRESSION_TARGET "" PARENT_SCOPE) set(LOG_COMPRESS_SRCS "${compressed_srcs_with_abs_path};${uncompressed_srcs}" PARENT_SCOPE) - list(APPEND include_dirs "common/ble_log/extension/log_compression/include") + if(NOT BLE_COMPRESSED_LIB_LOG_BUILD) + list(APPEND include_dirs "common/ble_log/extension/log_compression/include") + endif() + list(APPEND include_dirs "${CMAKE_BINARY_DIR}/ble_log/include") set(LOG_COMPRESS_INCLUDE_DIRS ${include_dirs} PARENT_SCOPE) else() set(LOG_COMPRESSION_TARGET "" PARENT_SCOPE) diff --git a/components/bt/common/ble_log/extension/log_compression/scripts/ble_log_compress.py b/components/bt/common/ble_log/extension/log_compression/scripts/ble_log_compress.py index cb4e40bd577..2398036d8c7 100644 --- a/components/bt/common/ble_log/extension/log_compression/scripts/ble_log_compress.py +++ b/components/bt/common/ble_log/extension/log_compression/scripts/ble_log_compress.py @@ -19,6 +19,7 @@ This script processes Bluetooth source files to compress logging statements. import argparse import enum +import importlib.util import logging import os import re @@ -33,6 +34,7 @@ from typing import Dict from typing import List from typing import Tuple from typing import Union +from typing import cast import tree_sitter_c as tsc import yaml @@ -72,10 +74,16 @@ CLANG_PARSER: Union[Parser, None] = None SOURCE_ENUM_MAP = { 'BLE_HOST': 0, 'BLE_MESH': 1, + 'BLE_MESH_LIB': 2, } # Functions that require hex formatting -HEX_FUNCTIONS = ['bt_hex'] # Used in Mesh and Audio modules +HEX_FUNCTIONS = { + # func_name: (arg_cnt, buf_idx, buf_len) + # Negative buf_len indicates constant buffer size + 'bt_hex': (2, 0, 1), # Used in Mesh and Audio modules + 'MAC2STR': (1, 0, -6), # Used in Bluedroid Host +} # C keywords to exclude from function names C_KEYWORDS = { @@ -119,15 +127,6 @@ LINE_MACROS = { '__LINE__', } -BLUEDROID_LOG_MODE_LEVEL_GET = { - 'BTM': 'btm_cb.trace_level', - 'L2CAP': 'l2cb.l2cap_trace_level', - 'GAP': 'gap_cb.trace_level', - 'GATT': 'gatt_cb.trace_level', - 'SMP': 'smp_cb.trace_level', - 'APPL': 'appl_trace_level', -} - class ARG_SIZE_TYPE(enum.IntEnum): U32 = 0 @@ -174,11 +173,12 @@ class LogCompressor: """Main class for BLE log compression.""" def __init__(self) -> None: - self.bt_component_path = Path() + self.code_base_path = Path() self.build_dir = Path() self.bt_compressed_srcs_path = Path() self.config: dict[str, Any] = {} self.module_info: dict[str, Any] = {} + self.module_mod: dict[str, Any] = {} def init_parser(self) -> Parser: """Initialize tree-sitter parser for C.""" @@ -371,15 +371,20 @@ class LogCompressor: if ( arg_node.type == 'call_expression' and arg_node.child_by_field_name('function') - and arg_node.child_by_field_name('function').text.decode('utf-8') in HEX_FUNCTIONS + and arg_node.child_by_field_name('function').text.decode('utf-8') in HEX_FUNCTIONS.keys() ): # Extract arguments of the hex function + hex_func_name = arg_node.child_by_field_name('function').text.decode('utf-8') hex_args = arg_node.child_by_field_name('arguments') - if hex_args and hex_args.named_child_count >= 2: - buf_node = hex_args.named_children[0] - len_node = hex_args.named_children[1] + hex_func_info = HEX_FUNCTIONS[hex_func_name] + if hex_args and hex_args.named_child_count == hex_func_info[0]: + buf_node = hex_args.named_children[hex_func_info[1]].text.decode('utf-8') + if hex_func_info[2] < 0: + len_node = abs(hex_func_info[2]) + else: + len_node = hex_args.named_children[hex_func_info[2]].text.decode('utf-8') token_list = list(token) - token_list[6] = f'@hex_func@{buf_node.text.decode("utf-8")}@{len_node.text.decode("utf-8")}' + token_list[6] = f'@hex_func@{buf_node}@{len_node}' tokens[tokens_tuple_map[i]] = tuple(token_list) log_info['argu_tokens'] = tokens @@ -419,7 +424,7 @@ class LogCompressor: if ( node.type == 'call_expression' and node.child_by_field_name('function') - and node.child_by_field_name('function').text.decode('utf-8') in HEX_FUNCTIONS + and node.child_by_field_name('function').text.decode('utf-8') in HEX_FUNCTIONS.keys() ): return True @@ -462,53 +467,6 @@ class LogCompressor: if not log_idx: return '' - def generate_mesh_log_prefix(source: str, tag: str, print_statm: str) -> str: - level = tag.split('_')[-1] - mod = tag.split('_')[0] - if level == 'ERR': - level = 'ERROR' - log_level = 'BLE_MESH_LOG_LEVEL_ERROR' - elif level == 'WARN': - level = 'WARN' - log_level = 'BLE_MESH_LOG_LEVEL_WARN' - elif level == 'INFO': - level = 'INFO' - log_level = 'BLE_MESH_LOG_LEVEL_INFO' - elif level == 'DBG': - level = 'DEBUG' - log_level = 'BLE_MESH_LOG_LEVEL_DEBUG' - else: - LOGGER.error(f'Invalid log level {level}') - return '' - if mod == 'NET': - used_log_levl = 'BLE_MESH_NET_BUF_LOG_LEVEL' - used_log_mod = 'BLE_MESH_NET_BUF' - else: - used_log_levl = 'BLE_MESH_LOG_LEVEL' - used_log_mod = 'BLE_MESH' - return ( - f'{{do {{ if (({used_log_levl} >= {log_level}) &&' - f' BLE_MESH_LOG_LEVEL_CHECK({used_log_mod}, {level})) {print_statm};}} while (0);}}\\\n' - ) - - def generate_bluedroid_log_prefix(source: str, tag: str, print_statm: str) -> str: - tag_info = tag.split('_') - mod = tag_info[0] - - return ( - f'{{if ({BLUEDROID_LOG_MODE_LEVEL_GET[mod]} >= BT_TRACE_LEVEL_{tag_info[-1]} &&' - f' BT_LOG_LEVEL_CHECK({mod}, {tag_info[-1]})) {print_statm};}}\\\n' - ) - - def generate_log_lvl_prefix(source: str, tag: str, print_statm: str) -> str: - if source == 'BLE_MESH': - return ' ' + generate_mesh_log_prefix(source, tag, print_statm) - elif source == 'BLE_HOST': # only bluedroid host supported for now - return ' ' + generate_bluedroid_log_prefix(source, tag, print_statm) - else: - LOGGER.error(f'Unknown source {source}') - return '' - source_value = SOURCE_ENUM_MAP.get(source.upper()) if source_value is None: raise ValueError(f'Invalid source: {source}') @@ -551,41 +509,22 @@ class LogCompressor: else: sizes.append(f'{int(ARG_SIZE_TYPE.U32)}') - if arg_count > 0: - size_str = ', '.join(sizes) - arg_str = ', '.join(arguments).replace('\n', '') - macro += generate_log_lvl_prefix( - source, - tag, - (f'BLE_LOG_COMPRESSED_HEX_PRINT({source_value}, {log_idx}, {arg_count}, {size_str}, {arg_str})'), - ) + stmt = self.module_mod[source].gen_compressed_stmt( + log_idx, + source_value, + tag, + log_info['arguments'][0], + [{'name': arg, 'size_type': size_type} for arg, size_type in zip(arguments, sizes)], + [ + { + 'buffer': hex_str.split('@')[2], + 'length': hex_str.split('@')[3], + } + for hex_str in hex_func + ], + ) + macro += cast(str, stmt) - for idx, item in enumerate(hex_func): - # hex_func format: @hex_func@buf@len - parts = item.split('@') - if len(parts) >= 4: - buf = parts[2] - buf_len = parts[3] - macro += generate_log_lvl_prefix( - source, - tag, - (f'BLE_LOG_COMPRESSED_HEX_PRINT_BUF({source_value}, {log_idx}, {idx}, {buf}, {buf_len})'), - ) - else: - macro += generate_log_lvl_prefix( - source, tag, f'BLE_LOG_COMPRESSED_HEX_PRINT_WITH_ZERO_ARGUMENTS({source_value}, {log_idx})' - ) - for idx, item in enumerate(hex_func): - # hex_func format: @hex_func@buf@len - parts = item.split('@') - if len(parts) >= 4: - buf = parts[2] - buf_len = parts[3] - macro += generate_log_lvl_prefix( - source, - tag, - (f'BLE_LOG_COMPRESSED_HEX_PRINT_BUF({source_value}, {log_idx}, {idx}, {buf}, {buf_len})'), - ) if ( 'tags_with_preserve' in self.module_info[source] and tag in self.module_info[source]['tags_with_preserve'] @@ -593,8 +532,7 @@ class LogCompressor: macro += f' {tag}(fmt, ##__VA_ARGS__);\\\n' else: # Non-hexified log - print_fmt = print_fmt or 'NULL' - macro += f' BLE_LOG_COMPRESSED_PRINT({source_value}, {log_idx}, "{print_fmt}", ##__VA_ARGS__); \\\n' + raise ValueError('Hexify convert failed') macro += '}\n' return macro @@ -716,7 +654,7 @@ class LogCompressor: total_cnt = 0 for src in srcs: if pattern.match(src): - src_path = self.bt_component_path / src + src_path = self.code_base_path / src dest_path = self.bt_compressed_srcs_path / src temp_path = f'{dest_path}.tmp' total_cnt += 1 @@ -754,7 +692,7 @@ class LogCompressor: module: Module name macros: List of (log_id, macro_definition) """ - # header_path = self.bt_component_path / self.module_info[module]['log_index_path'] + # header_path = self.code_base_path / self.module_info[module]['log_index_path'] header_path = self.build_dir / Path('ble_log') / Path('include') / self.module_info[module]['log_index_file'] # Create directory if needed header_path.parent.mkdir(parents=True, exist_ok=True) @@ -764,8 +702,7 @@ class LogCompressor: return elif update_state == self.db_manager.SOURCE_LOG_UPDATE_FULL: # Header template - header_content = ( - textwrap.dedent(f""" + header_content = textwrap.dedent(f""" /* * SPDX-FileCopyrightText: {datetime.now().year} Espressif Systems (Shanghai) CO LTD * @@ -778,22 +715,11 @@ class LogCompressor: #include #include - // Compression function declarations - extern int ble_log_compressed_hex_print - (uint32_t source, uint32_t log_index, size_t args_size_cnt, ...); - extern int ble_log_compressed_hex_print_buf - (uint8_t source, uint32_t log_index, uint8_t buf_idx, const uint8_t *buf, size_t len); - - // Compression macros - #define BLE_LOG_COMPRESSED_HEX_PRINT(source, log_index, args_cnt, ...) \\ - ble_log_compressed_hex_print(source, log_index, args_cnt, ##__VA_ARGS__) - #define BLE_LOG_COMPRESSED_HEX_PRINT_BUF(source, log_index, buf_idx, buf, len) \\ - ble_log_compressed_hex_print_buf(source, log_index, buf_idx, (const uint8_t *)buf, len) - #define BLE_LOG_COMPRESSED_HEX_PRINT_WITH_ZERO_ARGUMENTS(source, log_index) \\ - ble_log_compressed_hex_print(source, log_index, 0) """).strip() - + '\n\n' - ) + + header_content += self.module_mod[module].gen_header_head() + header_content += '\n\n' + # Add sorted macros for log_id, macro_def in sorted(macros, key=lambda x: x[0]): header_content += macro_def + '\n' @@ -852,6 +778,14 @@ class LogCompressor: for module in module_names: if module in modules: self.module_info[module] = modules[module] + module_script_path = self.module_info[module]['script'] + spec = self.module_mod[module] = importlib.util.spec_from_file_location(module, module_script_path) + if spec and spec.loader: + self.module_mod[module] = importlib.util.module_from_spec(spec) + spec.loader.exec_module(self.module_mod[module]) + else: + LOGGER.error(f"Failed to load module '{module}' script") + raise ImportError(' Failed to load module script') print(f'Found module {module} for compression\n', flush=True, end='', file=sys.stdout) else: LOGGER.warning(f"Skipping module '{module}' - config not found") @@ -863,7 +797,7 @@ class LogCompressor: compress_parser = subparsers.add_parser('compress') compress_parser.add_argument('--srcs', required=True, help='Semicolon-separated source file paths') - compress_parser.add_argument('--bt_path', required=True, help='Bluetooth component root path') + compress_parser.add_argument('--code_base_path', required=True, help='Component base path') compress_parser.add_argument('--module', required=True, help='Semicolon-separated module names') compress_parser.add_argument('--build_path', required=True, help='Build output directory') compress_parser.add_argument('--compressed_srcs_path', required=True, help='Directory for processed sources') @@ -871,7 +805,7 @@ class LogCompressor: args = parser.parse_args() # Setup paths - self.bt_component_path = Path(args.bt_path) + self.code_base_path = Path(args.code_base_path) self.build_dir = Path(args.build_path) self.bt_compressed_srcs_path = Path(args.compressed_srcs_path) @@ -947,7 +881,7 @@ class LogCompressor: # Mark files as processed for module, info in self.module_info.items(): for temp_path in info['files_to_process']: - src_path = self.bt_component_path / os.path.relpath(temp_path[:-4], self.bt_compressed_srcs_path) + src_path = self.code_base_path / os.path.relpath(temp_path[:-4], self.bt_compressed_srcs_path) db_manager.mark_file_processed(module, src_path, temp_path) for root, _, files in os.walk(self.bt_compressed_srcs_path): for name in files: diff --git a/components/bt/common/ble_log/extension/log_compression/scripts/configs/module_info.yml.in b/components/bt/common/ble_log/extension/log_compression/scripts/configs/module_info.yml.in index 853dcd47486..5201f57503a 100644 --- a/components/bt/common/ble_log/extension/log_compression/scripts/configs/module_info.yml.in +++ b/components/bt/common/ble_log/extension/log_compression/scripts/configs/module_info.yml.in @@ -6,6 +6,7 @@ log_config: description: "BLE Mesh" code_path: [@BLE_MESH_CODE_PATH@] log_index_file: @BLE_MESH_LOG_INDEX_HEADER@ + script: @BLE_MESH_LOG_SCRIPT_PATH@ tags: [@BLE_MESH_TAGS@] tags_with_preserve: [@BLE_MESH_TAGS_PRESERVE@] @@ -13,5 +14,14 @@ log_config: description: "BLE Host" code_path: [@HOST_CODE_PATH@] log_index_file: @HOST_LOG_INDEX_HEADER@ + script: @BLE_HOST_LOG_SCRIPT_PATH@ tags: [@BLE_HOST_TAGS@] tags_with_preserve: [@BLE_HOST_TAGS_PRESERVE@] + + @BLE_COMPRESSED_LIB_NAME@: + description: "@BLE_COMPRESSED_LIB_DESC@" + code_path: [@BLE_COMPRESSED_LIB_CODE_DIR@] + log_index_file: @BLE_COMPRESSED_LIB_LOG_INDEX_HEADER@ + script: @BLE_COMPRESSED_LIB_LOG_SCRIPT_PATH@ + tags: [@BLE_COMPRESSED_LIB_LOG_TAGS@] + tags_with_preserve: [@BLE_COMPRESSED_LIB_LOG_TAGS_PRESERVE@] diff --git a/components/bt/common/ble_log/extension/log_compression/scripts/inttypes_map.py b/components/bt/common/ble_log/extension/log_compression/scripts/inttypes_map.py index 9e95a18cffe..44f193ac226 100644 --- a/components/bt/common/ble_log/extension/log_compression/scripts/inttypes_map.py +++ b/components/bt/common/ble_log/extension/log_compression/scripts/inttypes_map.py @@ -163,4 +163,5 @@ TYPES_MACRO_MAP = { 'SCNoPTR': __PRIPTR_PREFIX + 'o', 'SCNuPTR': __PRIPTR_PREFIX + 'u', 'SCNxPTR': __PRIPTR_PREFIX + 'x', + 'MACSTR': '%s', } diff --git a/components/bt/common/ble_log/extension/log_compression/scripts/module_scripts/ble_mesh/make_mesh_log_macro.py b/components/bt/common/ble_log/extension/log_compression/scripts/module_scripts/ble_mesh/make_mesh_log_macro.py new file mode 100644 index 00000000000..791de5f8abb --- /dev/null +++ b/components/bt/common/ble_log/extension/log_compression/scripts/module_scripts/ble_mesh/make_mesh_log_macro.py @@ -0,0 +1,71 @@ +# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +import textwrap + + +def generate_mesh_log_prefix(tag: str, print_statm: str) -> str: + level = tag.split('_')[-1] + mod = tag.split('_')[0] + if level == 'ERR': + level = 'ERROR' + log_level = 'BLE_MESH_LOG_LEVEL_ERROR' + elif level == 'WARN': + level = 'WARN' + log_level = 'BLE_MESH_LOG_LEVEL_WARN' + elif level == 'INFO': + level = 'INFO' + log_level = 'BLE_MESH_LOG_LEVEL_INFO' + elif level == 'DBG': + level = 'DEBUG' + log_level = 'BLE_MESH_LOG_LEVEL_DEBUG' + else: + return '' + if mod == 'NET': + used_log_levl = 'BLE_MESH_NET_BUF_LOG_LEVEL' + used_log_mod = 'BLE_MESH_NET_BUF' + else: + used_log_levl = 'BLE_MESH_LOG_LEVEL' + used_log_mod = 'BLE_MESH' + return ( + f'{{do {{ if (({used_log_levl} >= {log_level}) &&' + f' BLE_MESH_LOG_LEVEL_CHECK({used_log_mod}, {level})) {print_statm};}} while (0);}}\\\n' + ) + + +def gen_header_head() -> str: + head = textwrap.dedent(""" + // Compression function declarations + extern int ble_log_compressed_hex_print + (uint8_t source, uint32_t log_index, size_t args_size_cnt, ...); + extern int ble_log_compressed_hex_print_buf + (uint8_t source, uint32_t log_index, uint8_t buf_idx, const uint8_t *buf, size_t len); + """) + return head + + +def gen_compressed_stmt( + log_index: int, module_id: int, func_name: str, fmt: str, args: list[dict], buffer_args: list[dict] +) -> str: + if len(args) == 0: + stmt = f' ble_log_compressed_hex_print({module_id}, {log_index}, 0);' + for idx, buffer_arg in enumerate(buffer_args): + stmt += '\\\n' + stmt += ( + f' ble_log_compressed_hex_print_buf(' + f'{module_id}, {log_index}, {idx}, ' + f'(const uint8_t *){buffer_arg["buffer"]}, {buffer_arg["length"]});' + ) + stmt += '\\\n' + return ' ' + generate_mesh_log_prefix(func_name, stmt) + size_str = ', '.join([arg['size_type'] for arg in args]) + args_str = ', '.join([arg['name'] for arg in args]).replace('\n', '') + stmt = f' ble_log_compressed_hex_print({module_id}, {log_index}, {len(args)}, {size_str}, {args_str});' + for idx, buffer_arg in enumerate(buffer_args): + stmt += '\\\n' + stmt += ( + f' ble_log_compressed_hex_print_buf(' + f'{module_id}, {log_index}, {idx}, ' + f'(const uint8_t *){buffer_arg["buffer"]}, {buffer_arg["length"]});' + ) + stmt += '\\\n' + return ' ' + generate_mesh_log_prefix(func_name, stmt) diff --git a/components/bt/common/ble_log/extension/log_compression/scripts/module_scripts/bluedroid/make_bluedroid_log_macro.py b/components/bt/common/ble_log/extension/log_compression/scripts/module_scripts/bluedroid/make_bluedroid_log_macro.py new file mode 100644 index 00000000000..72be38c081a --- /dev/null +++ b/components/bt/common/ble_log/extension/log_compression/scripts/module_scripts/bluedroid/make_bluedroid_log_macro.py @@ -0,0 +1,61 @@ +# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +import textwrap + +BLUEDROID_LOG_MODE_LEVEL_GET = { + 'BTM': 'btm_cb.trace_level', + 'L2CAP': 'l2cb.l2cap_trace_level', + 'GAP': 'gap_cb.trace_level', + 'GATT': 'gatt_cb.trace_level', + 'SMP': 'smp_cb.trace_level', + 'APPL': 'appl_trace_level', +} + + +def generate_bluedroid_log_prefix(tag: str, print_statm: str) -> str: + tag_info = tag.split('_') + mod = tag_info[0] + + return ( + f'{{if ({BLUEDROID_LOG_MODE_LEVEL_GET[mod]} >= BT_TRACE_LEVEL_{tag_info[-1]} &&' + f' BT_LOG_LEVEL_CHECK({mod}, {tag_info[-1]})) {print_statm};}}\\\n' + ) + + +def gen_header_head() -> str: + head = textwrap.dedent(""" + // Compression function declarations + extern int ble_log_compressed_hex_print + (uint8_t source, uint32_t log_index, size_t args_size_cnt, ...); + extern int ble_log_compressed_hex_print_buf + (uint8_t source, uint32_t log_index, uint8_t buf_idx, const uint8_t *buf, size_t len); + """) + return head + + +def gen_compressed_stmt( + log_index: int, module_id: int, func_name: str, fmt: str, args: list[dict], buffer_args: list[dict] +) -> str: + if len(args) == 0: + stmt = f' ble_log_compressed_hex_print({module_id},{log_index}, 0);' + for idx, buffer_arg in enumerate(buffer_args): + stmt += '\\\n' + stmt += ( + f' ble_log_compressed_hex_print_buf(' + f'{module_id}, {log_index}, {idx}, ' + f'(const uint8_t *){buffer_arg["buffer"]}, {buffer_arg["length"]});' + ) + stmt += '\\\n' + return ' ' + generate_bluedroid_log_prefix(func_name, stmt) + size_str = ', '.join([arg['size_type'] for arg in args]) + args_str = ', '.join([arg['name'] for arg in args]).replace('\n', '') + stmt = f' ble_log_compressed_hex_print({module_id},{log_index}, {len(args)}, {size_str}, {args_str});' + for idx, buffer_arg in enumerate(buffer_args): + stmt += '\\\n' + stmt += ( + f' ble_log_compressed_hex_print_buf(' + f'{module_id}, {log_index}, {idx}, ' + f'(const uint8_t *){buffer_arg["buffer"]}, {buffer_arg["length"]});' + ) + stmt += '\\\n' + return ' ' + generate_bluedroid_log_prefix(func_name, stmt)