diff --git a/components/app_trace/port/port_uart.c b/components/app_trace/port/port_uart.c index 053f235cdbf8..43dd60c8a7f5 100644 --- a/components/app_trace/port/port_uart.c +++ b/components/app_trace/port/port_uart.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -288,10 +288,9 @@ static esp_err_t esp_apptrace_uart_up_buffer_put(esp_apptrace_uart_data_t *hw_da static void esp_apptrace_uart_down_buffer_config(esp_apptrace_uart_data_t *hw_data, uint8_t *buf, uint32_t size) { - hw_data->down_buffer = (uint8_t *)malloc(size); - if (hw_data->down_buffer == NULL){ - assert(false && "Failed to allocate apptrace uart down buffer!"); - } + assert(buf != NULL && "Down buffer cannot be NULL"); + + hw_data->down_buffer = buf; hw_data->down_buffer_size = size; } diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 3858836f3077..aab4b401abfe 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -633,19 +633,17 @@ if(CONFIG_BT_ENABLED) "esp_ble_mesh/v1.1/btc/btc_ble_mesh_sar_model.c" "esp_ble_mesh/v1.1/btc/btc_ble_mesh_srpl_model.c" "esp_ble_mesh/lib/ext.c") + if(CONFIG_BLE_MESH_SAR_ENHANCEMENT) list(APPEND srcs "esp_ble_mesh/core/transport.enh.c") else() list(APPEND srcs "esp_ble_mesh/core/transport.c") endif() else() - list(APPEND srcs - "esp_ble_mesh/core/transport.c") + list(APPEND srcs "esp_ble_mesh/core/transport.c") endif() endif() - - if(CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT) list(APPEND srcs "porting/npl/freertos/src/npl_os_freertos.c" @@ -952,7 +950,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 967b0e9b8eca..15ae73550ace 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 da1f4493b68d..c48e067db836 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 @@ -15,6 +15,7 @@ """ import argparse import enum +import importlib.util import logging import os import re @@ -25,6 +26,7 @@ from datetime import datetime from pathlib import Path from typing import Any +from typing import cast from typing import Dict from typing import List from typing import Tuple @@ -68,10 +70,16 @@ 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 = { @@ -115,15 +123,6 @@ '__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 @@ -170,11 +169,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.""" @@ -367,15 +367,20 @@ def _process_log_node(self, node: Node, function_boundaries: list[tuple[str, int 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 @@ -415,7 +420,7 @@ def _can_be_hexified(self, token: tuple[int, int, str, str, str, str, str], node 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 @@ -458,53 +463,6 @@ def generate_compressed_macro( 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}') @@ -547,41 +505,22 @@ def generate_log_lvl_prefix(source: str, tag: str, print_statm: str) -> str: 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'] @@ -589,8 +528,7 @@ def generate_log_lvl_prefix(source: str, tag: str, print_statm: str) -> str: 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 @@ -712,7 +650,7 @@ def prepare_source_files(self, srcs: list[str]) -> None: 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 @@ -750,7 +688,7 @@ def generate_log_index_header(self, module: str, macros: list[tuple[int, str]]) 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) @@ -760,8 +698,7 @@ def generate_log_index_header(self, module: str, macros: list[tuple[int, str]]) 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 * @@ -774,22 +711,11 @@ def generate_log_index_header(self, module: str, macros: list[tuple[int, str]]) #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' @@ -848,6 +774,14 @@ def load_config(self, config_path: str, module_names: list[str]) -> None: 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") @@ -859,7 +793,7 @@ def main(self) -> int: 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') @@ -867,7 +801,7 @@ def main(self) -> int: 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) @@ -943,7 +877,7 @@ def main(self) -> int: # 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 853dcd474865..5201f57503a9 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 9e95a18cffef..44f193ac226f 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 @@ '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 000000000000..791de5f8abb7 --- /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 000000000000..72be38c081af --- /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) diff --git a/components/bt/common/ble_log/src/ble_log_lbm.c b/components/bt/common/ble_log/src/ble_log_lbm.c index 5078f2bad7dc..9b8626d1ad77 100644 --- a/components/bt/common/ble_log/src/ble_log_lbm.c +++ b/components/bt/common/ble_log/src/ble_log_lbm.c @@ -421,6 +421,7 @@ void ble_log_flush(void) BLE_LOG_REF_COUNT_RELEASE(&lbm_ref_count); } +BLE_LOG_IRAM_ATTR bool ble_log_write_hex(ble_log_src_t src_code, const uint8_t *addr, size_t len) { BLE_LOG_REF_COUNT_ACQUIRE(&lbm_ref_count); diff --git a/components/bt/common/ble_log/src/internal_include/ble_log_ts.h b/components/bt/common/ble_log/src/internal_include/ble_log_ts.h index 11e74e1508e5..5e0864b25874 100644 --- a/components/bt/common/ble_log/src/internal_include/ble_log_ts.h +++ b/components/bt/common/ble_log/src/internal_include/ble_log_ts.h @@ -29,10 +29,10 @@ extern uint32_t r_ble_lll_timer_current_tick_get(void); #elif defined(CONFIG_IDF_TARGET_ESP32C2) extern uint32_t r_os_cputime_get32(void); #define BLE_LOG_GET_LC_TS r_os_cputime_get32() -/* Legacy BLE Controller (Wait for support) */ -// #elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) -// extern uint32_t lld_read_clock_us(void); -// #define BLE_LOG_GET_LC_TS lld_read_clock_us() +/* Legacy BLE Controller */ +#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) +extern uint32_t lld_read_clock_us(void); +#define BLE_LOG_GET_LC_TS lld_read_clock_us() #else /* Other targets */ #define BLE_LOG_GET_LC_TS 0 #endif /* BLE targets */ diff --git a/components/bt/controller/esp32h2/Kconfig.in b/components/bt/controller/esp32h2/Kconfig.in index 00ae776c2d78..679f7c286456 100644 --- a/components/bt/controller/esp32h2/Kconfig.in +++ b/components/bt/controller/esp32h2/Kconfig.in @@ -573,7 +573,7 @@ config BT_LE_LL_PEER_SCA config BT_LE_MAX_CONNECTIONS int "Maximum number of concurrent connections" depends on !BT_NIMBLE_ENABLED - range 1 35 + range 1 70 default 3 help Defines maximum number of concurrent BLE connections. For ESP32, user diff --git a/components/bt/controller/lib_esp32 b/components/bt/controller/lib_esp32 index 06dc466733e3..05e9c75b8977 160000 --- a/components/bt/controller/lib_esp32 +++ b/components/bt/controller/lib_esp32 @@ -1 +1 @@ -Subproject commit 06dc466733e3e8738c6c638615e6f04e52ca1aa7 +Subproject commit 05e9c75b8977a3767c5cf5afedcd4c7f8c0f5f62 diff --git a/components/bt/esp_ble_mesh/core/access.c b/components/bt/esp_ble_mesh/core/access.c index 3791add9e34f..a616928b0d97 100644 --- a/components/bt/esp_ble_mesh/core/access.c +++ b/components/bt/esp_ble_mesh/core/access.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -25,7 +25,7 @@ #if CONFIG_BLE_MESH_V11_SUPPORT #include "mesh_v1.1/utils.h" -#endif +#endif /* CONFIG_BLE_MESH_V11_SUPPORT */ #define BLE_MESH_SDU_MAX_LEN 384 @@ -45,6 +45,8 @@ void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod, { int i, j; + BT_DBG("ModelForeach"); + if (comp_0 == NULL) { BT_ERR("Invalid device composition"); return; @@ -53,15 +55,21 @@ void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod, for (i = 0; i < comp_0->elem_count; i++) { struct bt_mesh_elem *elem = &comp_0->elem[i]; + BT_DBG("Element %u", i); + for (j = 0; j < elem->model_count; j++) { struct bt_mesh_model *model = &elem->models[j]; + BT_DBG("ID 0x%04x", model->id); + func(model, elem, false, i == 0, user_data); } for (j = 0; j < elem->vnd_model_count; j++) { struct bt_mesh_model *model = &elem->vnd_models[j]; + BT_DBG("ID 0x%04x CID 0x%04x", model->vnd.id, model->vnd.company); + func(model, elem, true, i == 0, user_data); } } @@ -71,6 +79,8 @@ int32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod) { int period = 0; + BT_DBG("ModelPubPeriodGet"); + if (!mod->pub) { BT_ERR("Model has no publication support"); return 0; @@ -98,6 +108,9 @@ int32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod) return 0; } + BT_DBG("Period %ld FastPeriod %u PeriodDiv %u", + period, mod->pub->fast_period, mod->pub->period_div); + if (mod->pub->fast_period) { return period >> mod->pub->period_div; } @@ -110,19 +123,22 @@ static int32_t next_period(struct bt_mesh_model *mod) struct bt_mesh_model_pub *pub = mod->pub; uint32_t elapsed = 0U, period = 0U; + BT_DBG("NextPeriod"); + if (!pub) { BT_ERR("Model has no publication support"); - return -ENOTSUP; + return 0; } period = bt_mesh_model_pub_period_get(mod); if (!period) { + BT_DBG("PeriodZero"); return 0; } elapsed = k_uptime_get_32() - pub->period_start; - BT_INFO("Publishing took %ums", elapsed); + BT_INFO("Elapsed %u Period %u", elapsed, period); if (elapsed >= period) { BT_WARN("Publication sending took longer than the period"); @@ -138,7 +154,7 @@ static void publish_sent(int err, void *user_data) struct bt_mesh_model *mod = user_data; int32_t delay = 0; - BT_DBG("err %d", err); + BT_DBG("PublishSent, Err %d", err); if (!mod->pub) { BT_ERR("Model has no publication support"); @@ -151,8 +167,9 @@ static void publish_sent(int err, void *user_data) delay = next_period(mod); } + BT_DBG("PubCount %u PubDelay %ld", mod->pub->count, delay); + if (delay) { - BT_INFO("Publishing next time in %dms", delay); k_delayed_work_submit(&mod->pub->timer, delay); } } @@ -162,6 +179,8 @@ static void publish_start(uint16_t duration, int err, void *user_data) struct bt_mesh_model *mod = user_data; struct bt_mesh_model_pub *pub = mod->pub; + BT_DBG("PublishStart, Err %d", err); + if (err) { BT_ERR("Failed to publish: err %d", err); return; @@ -191,6 +210,8 @@ static int publish_retransmit(struct bt_mesh_model *mod) }; int err = 0; + BT_DBG("PublishRetransmit"); + if (!pub || !pub->msg) { BT_ERR("Model has no publication support"); return -ENOTSUP; @@ -219,9 +240,14 @@ static int publish_retransmit(struct bt_mesh_model *mod) ctx.send_tag |= BLE_MESH_TAG_SEND_SEGMENTED; } + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Dst 0x%04x", + ctx.net_idx, ctx.app_idx, ctx.addr); + BT_DBG("TTL %u SendCred %u SendRel %u PubCount %u", + ctx.send_ttl, ctx.send_cred, pub->send_rel, pub->count); + #if CONFIG_BLE_MESH_DF_SRV bt_mesh_model_pub_use_directed(&tx, pub->directed_pub_policy); -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ sdu = bt_mesh_alloc_buf(pub->msg->len + BLE_MESH_MIC_LONG); if (!sdu) { @@ -241,8 +267,11 @@ static int publish_retransmit(struct bt_mesh_model *mod) static void publish_retransmit_end(int err, struct bt_mesh_model_pub *pub) { + BT_DBG("PublishRetransmitEnd, Err %d", err); + /* Cancel all retransmits for this publish attempt */ pub->count = 0U; + /* Make sure the publish timer gets reset */ publish_sent(err, pub->mod); } @@ -256,7 +285,8 @@ static void mod_publish(struct k_work *work) int err = 0; period_ms = bt_mesh_model_pub_period_get(pub->mod); - BT_INFO("Publish period %u ms", period_ms); + + BT_INFO("ModPublish, Period %u", period_ms); if (pub->count) { err = publish_retransmit(pub->mod); @@ -284,6 +314,7 @@ static void mod_publish(struct k_work *work) if (pub->update && pub->update(pub->mod)) { /* 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; @@ -297,6 +328,8 @@ static void mod_publish(struct k_work *work) struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod) { + BT_DBG("ModelElem, ElemIdx %u", mod->elem_idx); + return &comp_0->elem[mod->elem_idx]; } @@ -304,6 +337,8 @@ struct bt_mesh_model *bt_mesh_model_get(bool vnd, uint8_t elem_idx, uint8_t mod_ { struct bt_mesh_elem *elem = NULL; + BT_DBG("ModelGet, ElemIdx %u ModIdx %u Vnd %u", elem_idx, mod_idx, vnd); + if (!comp_0) { BT_ERR("comp_0 not initialized"); return NULL; @@ -339,6 +374,8 @@ static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, int *err = user_data; int i; + BT_DBG("ModInit, Vnd %u Primary %u", vnd, primary); + if (!user_data) { BT_ERR("Invalid model init user data"); return; @@ -368,6 +405,8 @@ static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, mod->model_idx = mod - elem->models; } + BT_DBG("ElemIdx %u ModelIdx %u", mod->elem_idx, mod->model_idx); + if (vnd) { return; } @@ -381,6 +420,8 @@ int bt_mesh_comp_register(const struct bt_mesh_comp *comp) { int err = 0; + BT_DBG("CompRegister, ElemCount %u", comp->elem_count); + /* There must be at least one element */ if (!comp->elem_count) { return -EINVAL; @@ -400,6 +441,8 @@ static void mod_deinit(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, int *err = user_data; int i; + BT_DBG("ModDeinit, Vnd %u Primary %u", vnd, primary); + if (!user_data) { BT_ERR("Invalid model deinit user data"); return; @@ -438,6 +481,8 @@ int bt_mesh_comp_deregister(void) { int err = 0; + BT_DBG("CompDeregister"); + if (comp_0 == NULL) { return -EINVAL; } @@ -456,25 +501,29 @@ void bt_mesh_comp_provision(uint16_t addr) dev_primary_addr = addr; - BT_INFO("Primary address 0x%04x, element count %u", addr, comp_0->elem_count); + BT_INFO("CompProvision, PrimaryAddr 0x%04x ElemCount %u", addr, comp_0->elem_count); for (i = 0; i < comp_0->elem_count; i++) { struct bt_mesh_elem *elem = &comp_0->elem[i]; elem->addr = addr++; - BT_DBG("addr 0x%04x mod_count %u vnd_mod_count %u", + BT_DBG("ElemAddr 0x%04x ModCount %u VndModCount %u", elem->addr, elem->model_count, elem->vnd_model_count); } } void bt_mesh_comp_unprovision(void) { + BT_DBG("CompUnprovision"); + dev_primary_addr = BLE_MESH_ADDR_UNASSIGNED; } uint16_t bt_mesh_primary_addr(void) { + BT_DBG("PrimaryAddr 0x%04x", dev_primary_addr); + return dev_primary_addr; } @@ -482,12 +531,16 @@ uint16_t *bt_mesh_model_find_group(struct bt_mesh_model *mod, uint16_t addr) { int i; + BT_DBG("ModelFindGroup, Addr 0x%04x", addr); + for (i = 0; i < ARRAY_SIZE(mod->groups); i++) { if (mod->groups[i] == addr) { + BT_DBG("ModGroupFound"); return &mod->groups[i]; } } + BT_DBG("ModGroupNotFound"); return NULL; } @@ -498,6 +551,8 @@ static struct bt_mesh_model *bt_mesh_elem_find_group(struct bt_mesh_elem *elem, uint16_t *match = NULL; int i; + BT_DBG("ElemFindGroup, Addr 0x%04x", group_addr); + for (i = 0; i < elem->model_count; i++) { model = &elem->models[i]; @@ -523,6 +578,8 @@ struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr) { uint16_t index = 0U; + BT_DBG("ElemFind, Addr 0x%04x", addr); + if (BLE_MESH_ADDR_IS_UNICAST(addr)) { index = (addr - comp_0->elem[0].addr); if (index < comp_0->elem_count) { @@ -545,6 +602,8 @@ struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr) uint8_t bt_mesh_elem_count(void) { + BT_DBG("ElemCount %u", comp_0->elem_count); + return comp_0->elem_count; } @@ -552,6 +611,8 @@ static bool model_has_key(struct bt_mesh_model *mod, uint16_t key) { int i; + BT_DBG("ModelHasKey, AppIdx 0x%04x", key); + for (i = 0; i < ARRAY_SIZE(mod->keys); i++) { if (mod->keys[i] == key) { return true; @@ -565,6 +626,8 @@ static bool model_has_dst(struct bt_mesh_model *model, struct bt_mesh_subnet *sub, uint16_t dst) { + BT_DBG("ModelHasDst, Dst 0x%04x", dst); + if (BLE_MESH_ADDR_IS_UNICAST(dst)) { return (comp_0->elem[model->elem_idx].addr == dst); } @@ -583,6 +646,8 @@ static const struct bt_mesh_model_op *find_op(struct bt_mesh_model *models, { int i; + BT_DBG("FindOp, ModelCount %u Opcode 0x%08lx", model_count, opcode); + for (i = 0; i < model_count; i++) { const struct bt_mesh_model_op *op; @@ -601,6 +666,8 @@ static const struct bt_mesh_model_op *find_op(struct bt_mesh_model *models, static int get_opcode(struct net_buf_simple *buf, uint32_t *opcode, bool pull_buf) { + BT_DBG("GetOpCode, PullBuf %u", pull_buf); + switch (buf->data[0] >> 6) { case 0x00: case 0x01: @@ -646,6 +713,8 @@ static int get_opcode(struct net_buf_simple *buf, uint32_t *opcode, bool pull_bu int bt_mesh_get_opcode(struct net_buf_simple *buf, uint32_t *opcode, bool pull_buf) { + BT_DBG("GetOpCode"); + if (buf == NULL || buf->len == 0 || opcode == NULL) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; @@ -656,6 +725,8 @@ int bt_mesh_get_opcode(struct net_buf_simple *buf, bool bt_mesh_fixed_group_match(uint16_t addr) { + BT_DBG("FixedGroupMatch, Addr 0x%04x", addr); + /* Check for fixed group addresses */ switch (addr) { case BLE_MESH_ADDR_ALL_NODES: @@ -677,12 +748,14 @@ bool bt_mesh_fixed_direct_match(struct bt_mesh_subnet *sub, uint16_t addr) * shall be processed by the primary element of all nodes that * have directed forwarding functionality enabled. */ + BT_DBG("FixedDirectMatch, Addr 0x%04x", addr); + #if CONFIG_BLE_MESH_DF_SRV if (addr == BLE_MESH_ADDR_DIRECTS && sub && sub->directed_forwarding == BLE_MESH_DIRECTED_FORWARDING_ENABLED) { return true; } -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ return false; } @@ -695,16 +768,17 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) uint8_t count = 0U; int i; - BT_INFO("recv, app_idx 0x%04x src 0x%04x dst 0x%04x", rx->ctx.app_idx, - rx->ctx.addr, rx->ctx.recv_dst); - BT_INFO("recv, len %u: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_INFO("ModelRecv"); + BT_INFO("AppIdx 0x%04x Src 0x%04x Dst 0x%04x", + 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 (get_opcode(buf, &opcode, true) < 0) { BT_WARN("Unable to decode OpCode"); return; } - BT_DBG("OpCode 0x%08x", opcode); + BT_DBG("OpCode 0x%08lx RecvCred %u", opcode, rx->ctx.recv_cred); for (i = 0; i < comp_0->elem_count; i++) { struct bt_mesh_elem *elem = &comp_0->elem[i]; @@ -729,10 +803,12 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) } if (!model_has_key(model, rx->ctx.app_idx)) { + BT_DBG("ModelNotHasKey"); continue; } if (!model_has_dst(model, rx->sub, rx->ctx.recv_dst)) { + BT_DBG("ModelNotHasDst"); continue; } @@ -776,6 +852,8 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) void bt_mesh_model_msg_init(struct net_buf_simple *msg, uint32_t opcode) { + BT_DBG("ModelMsgInit, OpCode 0x%08lx", opcode); + net_buf_simple_init(msg, 0); switch (BLE_MESH_MODEL_OP_LEN(opcode)) { @@ -801,6 +879,8 @@ void bt_mesh_model_msg_init(struct net_buf_simple *msg, uint32_t opcode) static bool ready_to_send(uint16_t dst) { + BT_DBG("IsReadyToSend, Dst 0x%04x", dst); + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { return true; } @@ -808,7 +888,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_ERR("Failed to find DST 0x%04x", dst); + BT_ERR("Failed to find Dst 0x%04x", dst); return false; } return true; @@ -820,15 +900,19 @@ static bool ready_to_send(uint16_t dst) #if !CONFIG_BLE_MESH_V11_SUPPORT static bool use_friend_cred(uint16_t net_idx, uint16_t dst) { + BT_DBG("IsFrndCredUsed, NetIdx 0x%04x Dst 0x%04x", net_idx, dst); + /* Currently LPN only supports using NetKey in bt_mesh.sub[0] */ if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) && net_idx == 0 && bt_mesh_lpn_match(dst)) { + BT_DBG("LPNMatch"); return true; } if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && bt_mesh_friend_match(net_idx, dst)) { + BT_DBG("FrndMatch"); return true; } @@ -843,6 +927,9 @@ bool bt_mesh_valid_security_cred(struct bt_mesh_net_tx *tx) * If not, later a better security credentials could be * chosen for the message. */ + BT_DBG("IsValidSecCred, NetIdx 0x%04x Tag 0x%02x Cred %u", + tx->ctx->net_idx, tx->ctx->send_tag, tx->ctx->send_cred); + if (!bt_mesh_tag_immutable_cred(tx->ctx->send_tag)) { return true; } @@ -871,22 +958,27 @@ void bt_mesh_choose_better_security_cred(struct bt_mesh_net_tx *tx) net_idx = tx->ctx->net_idx; addr = tx->ctx->addr; + BT_DBG("ChooseBetterSecCred"); + BT_DBG("NetIdx 0x%04x Dst 0x%04x Tag 0x%02x Cred %u", + net_idx, addr, send_tag, send_cred); + /* If the message is tagged with immutable-credentials, * then the security credentials shall not be changed. */ if (bt_mesh_tag_immutable_cred(send_tag)) { + BT_DBG("ImmutableCred"); return; } if (send_cred > BLE_MESH_FRIENDSHIP_CRED) { - BT_INFO("Use managed flooding security credentials"); + BT_INFO("UseFloodingSecCred"); tx->ctx->send_cred = BLE_MESH_FLOODING_CRED; return; } if (send_cred == BLE_MESH_FRIENDSHIP_CRED) { if (!use_friend_cred(net_idx, addr)) { - BT_INFO("Use managed flooding security credentials"); + BT_INFO("UseFloodingSecCred"); tx->ctx->send_cred = BLE_MESH_FLOODING_CRED; tx->ctx->send_tag = send_tag | BLE_MESH_TAG_IMMUTABLE_CRED; } else { @@ -911,14 +1003,13 @@ void bt_mesh_choose_better_security_cred(struct bt_mesh_net_tx *tx) if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && BLE_MESH_ADDR_IS_UNICAST(addr) && bt_mesh_friend_match(net_idx, addr)) { - BT_INFO("Use friendship security credentials"); + BT_INFO("UseFrndSecCred"); tx->ctx->send_cred = BLE_MESH_FRIENDSHIP_CRED; tx->ctx->send_tag = send_tag | BLE_MESH_TAG_IMMUTABLE_CRED; return; } - /** - * Spec 3.7.3.1 + /* Spec 3.7.3.1 * The Low power node in friendship should use friendship security * material. * @@ -938,11 +1029,12 @@ void bt_mesh_choose_better_security_cred(struct bt_mesh_net_tx *tx) if (BLE_MESH_ADDR_IS_UNICAST(addr) && bt_mesh.lpn.frnd == addr && !bt_mesh_tag_immutable_cred(send_tag)) { + BT_INFO("UseFrndSecCred"); tx->ctx->send_cred = BLE_MESH_FRIENDSHIP_CRED; tx->ctx->send_tag = send_tag | BLE_MESH_TAG_IMMUTABLE_CRED; return; } -#endif +#endif /* CONFIG_BLE_MESH_LOW_POWER */ } #endif /* !CONFIG_BLE_MESH_V11_SUPPORT */ @@ -953,9 +1045,10 @@ static int model_send(struct bt_mesh_model *model, { int err = 0; - BT_INFO("send, app_idx 0x%04x src 0x%04x dst 0x%04x", - tx->ctx->app_idx, tx->src, tx->ctx->addr); - BT_INFO("send, len %u: %s", msg->len, bt_hex(msg->data, msg->len)); + BT_INFO("ModelSend"); + BT_INFO("AppIdx 0x%04x Src 0x%04x Dst 0x%04x TTL %u", + tx->ctx->app_idx, tx->src, tx->ctx->addr, tx->ctx->send_ttl); + BT_INFO("Len %u: %s", msg->len, bt_hex(msg->data, msg->len)); if (ready_to_send(tx->ctx->addr) == false) { BT_ERR("Not ready to send"); @@ -994,7 +1087,7 @@ static int model_send(struct bt_mesh_model *model, #if CONFIG_BLE_MESH_DF_SRV bt_mesh_is_directed_path_needed(tx); -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ return err; } @@ -1006,9 +1099,11 @@ int bt_mesh_model_send_implicit(struct bt_mesh_model *model, { struct bt_mesh_subnet *sub = NULL; + BT_DBG("ModelSendImplicit"); + sub = bt_mesh_subnet_get(ctx->net_idx); if (!sub) { - BT_ERR("Send, NetKey 0x%04x not found", ctx->net_idx); + BT_ERR("NetIdx 0x%04x not found", ctx->net_idx); return -EADDRNOTAVAIL; } @@ -1029,9 +1124,11 @@ int bt_mesh_model_send(struct bt_mesh_model *model, { struct bt_mesh_subnet *sub = NULL; + BT_DBG("ModelSend, NetIdx 0x%04x", ctx->net_idx); + sub = bt_mesh_subnet_get(ctx->net_idx); if (!sub) { - BT_ERR("Send, NetKey 0x%04x not found", ctx->net_idx); + BT_ERR("NetIdx 0x%04x not found", ctx->net_idx); return -EADDRNOTAVAIL; } @@ -1058,6 +1155,8 @@ int bt_mesh_model_publish(struct bt_mesh_model *model) }; int err = 0; + BT_DBG("ModelPublish"); + if (!pub || !pub->msg) { BT_ERR("Model has no publication support"); return -ENOTSUP; @@ -1106,12 +1205,12 @@ int bt_mesh_model_publish(struct bt_mesh_model *model) #if CONFIG_BLE_MESH_DF_SRV bt_mesh_model_pub_use_directed(&tx, pub->directed_pub_policy); -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ pub->count = BLE_MESH_PUB_TRANSMIT_COUNT(pub->retransmit); - BT_INFO("Publish Retransmit Count %u Interval %ums", pub->count, - BLE_MESH_PUB_TRANSMIT_INT(pub->retransmit)); + BT_INFO("PubCount %u PubInterval %u", + pub->count, BLE_MESH_PUB_TRANSMIT_INT(pub->retransmit)); sdu = bt_mesh_alloc_buf(pub->msg->len + BLE_MESH_MIC_LONG); if (!sdu) { @@ -1135,6 +1234,8 @@ struct bt_mesh_model *bt_mesh_model_find_vnd(struct bt_mesh_elem *elem, { int i; + BT_DBG("ModelFindVnd, ID 0x%04x CID 0x%04x", id, company); + for (i = 0; i < elem->vnd_model_count; i++) { if (elem->vnd_models[i].vnd.company == company && elem->vnd_models[i].vnd.id == id) { @@ -1149,6 +1250,8 @@ struct bt_mesh_model *bt_mesh_model_find(struct bt_mesh_elem *elem, uint16_t id) { int i; + BT_DBG("ModelFind, ID 0x%04x", id); + for (i = 0; i < elem->model_count; i++) { if (elem->models[i].id == id) { return &elem->models[i]; @@ -1160,6 +1263,8 @@ struct bt_mesh_model *bt_mesh_model_find(struct bt_mesh_elem *elem, uint16_t id) const struct bt_mesh_comp *bt_mesh_comp_get(void) { + BT_DBG("CompGet %p", comp_0); + return comp_0; } @@ -1177,6 +1282,8 @@ const uint8_t *bt_mesh_dev_key_get(uint16_t dst) key = bt_mesh_provisioner_dev_key_get(dst); } + BT_DBG("Dst 0x%04x DevKey %s", dst, key ? bt_hex(key, 16) : ""); + return key; } @@ -1188,20 +1295,22 @@ size_t bt_mesh_rx_netkey_size(void) if (bt_mesh_is_provisioned()) { size = ARRAY_SIZE(bt_mesh.sub); } -#endif +#endif /* CONFIG_BLE_MESH_NODE && !CONFIG_BLE_MESH_PROVISIONER */ #if !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER if (bt_mesh_is_provisioner_en()) { size = ARRAY_SIZE(bt_mesh.p_sub); } -#endif +#endif /* !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER */ #if CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER size = ARRAY_SIZE(bt_mesh.sub); if (bt_mesh_is_provisioner_en()) { size += ARRAY_SIZE(bt_mesh.p_sub); } -#endif +#endif /* CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER */ + + BT_DBG("RxNetKeySize %u", size); return size; } @@ -1214,13 +1323,13 @@ struct bt_mesh_subnet *bt_mesh_rx_netkey_get(size_t index) if (bt_mesh_is_provisioned()) { sub = &bt_mesh.sub[index]; } -#endif +#endif /* CONFIG_BLE_MESH_NODE && !CONFIG_BLE_MESH_PROVISIONER */ #if !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER if (bt_mesh_is_provisioner_en()) { sub = bt_mesh.p_sub[index]; } -#endif +#endif /* !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER */ #if CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER if (index < ARRAY_SIZE(bt_mesh.sub)) { @@ -1228,7 +1337,10 @@ struct bt_mesh_subnet *bt_mesh_rx_netkey_get(size_t index) } else { sub = bt_mesh.p_sub[index - ARRAY_SIZE(bt_mesh.sub)]; } -#endif +#endif /* CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER */ + + BT_DBG("RxNetKeyGet, Index %u NetIdx 0x%04x", + index, sub ? sub->net_idx : BLE_MESH_KEY_ANY); return sub; } @@ -1252,7 +1364,7 @@ size_t bt_mesh_rx_devkey_size(void) if (bt_mesh_is_provisioner_en()) { size = 1; } -#endif +#endif /* !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER */ #if CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER size = 1; @@ -1264,7 +1376,9 @@ size_t bt_mesh_rx_devkey_size(void) if (bt_mesh_is_provisioner_en()) { size += 1; } -#endif +#endif /* CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER */ + + BT_DBG("RxDevKeySize %u", size); return size; } @@ -1281,13 +1395,13 @@ const uint8_t *bt_mesh_rx_devkey_get(size_t index, uint16_t src) key = bt_mesh.dev_key_ca; } } -#endif +#endif /* CONFIG_BLE_MESH_NODE && !CONFIG_BLE_MESH_PROVISIONER */ #if !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER if (bt_mesh_is_provisioner_en()) { key = bt_mesh_provisioner_dev_key_get(src); } -#endif +#endif /* !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER */ #if CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER if (index == 0) { @@ -1305,11 +1419,13 @@ const uint8_t *bt_mesh_rx_devkey_get(size_t index, uint16_t src) */ key = bt_mesh.dev_key_ca; } else -#endif +#endif /* CONFIG_BLE_MESH_RPR_SRV */ { key = bt_mesh_provisioner_dev_key_get(src); } -#endif +#endif /* CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER */ + + BT_DBG("RxDevKeyGet, Index %u Src 0x%04x", index, src); return key; } @@ -1322,20 +1438,22 @@ size_t bt_mesh_rx_appkey_size(void) if (bt_mesh_is_provisioned()) { size = ARRAY_SIZE(bt_mesh.app_keys); } -#endif +#endif /* CONFIG_BLE_MESH_NODE && !CONFIG_BLE_MESH_PROVISIONER */ #if !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER if (bt_mesh_is_provisioner_en()) { size = ARRAY_SIZE(bt_mesh.p_app_keys); } -#endif +#endif /* !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER */ #if CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER size = ARRAY_SIZE(bt_mesh.app_keys); if (bt_mesh_is_provisioner_en()) { size += ARRAY_SIZE(bt_mesh.p_app_keys); } -#endif +#endif /* CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER */ + + BT_DBG("RxAppKeySize %u", size); return size; } @@ -1348,13 +1466,13 @@ struct bt_mesh_app_key *bt_mesh_rx_appkey_get(size_t index) if (bt_mesh_is_provisioned()) { key = &bt_mesh.app_keys[index]; } -#endif +#endif /* CONFIG_BLE_MESH_NODE && !CONFIG_BLE_MESH_PROVISIONER */ #if !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER if (bt_mesh_is_provisioner_en()) { key = bt_mesh.p_app_keys[index]; } -#endif +#endif /* !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER */ #if CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER if (index < ARRAY_SIZE(bt_mesh.app_keys)) { @@ -1362,7 +1480,87 @@ struct bt_mesh_app_key *bt_mesh_rx_appkey_get(size_t index) } else { key = bt_mesh.p_app_keys[index - ARRAY_SIZE(bt_mesh.app_keys)]; } -#endif +#endif /* CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER */ + + BT_DBG("RxAppKeyGet, Index %u AppIdx 0x%04x", + index, key ? key->app_idx : BLE_MESH_KEY_ANY); return key; } + +struct bt_mesh_app_key *bt_mesh_app_key_get(uint16_t app_idx) +{ + BT_DBG("AppKeyGet, AppIdx 0x%04x", app_idx); + + if (bt_mesh_is_provisioned()) { +#if CONFIG_BLE_MESH_NODE + if (!IS_ENABLED(CONFIG_BLE_MESH_FAST_PROV)) { + for (int i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { + if (bt_mesh.app_keys[i].net_idx != BLE_MESH_KEY_UNUSED && + bt_mesh.app_keys[i].app_idx == app_idx) { + BT_DBG("NodeAppKey"); + return &bt_mesh.app_keys[i]; + } + } + } else { + BT_DBG("FastProvAppKey"); + return bt_mesh_fast_prov_app_key_find(app_idx); + } +#endif /* CONFIG_BLE_MESH_NODE */ + } else if (bt_mesh_is_provisioner_en()) { +#if CONFIG_BLE_MESH_PROVISIONER + for (int i = 0; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) { + if (bt_mesh.p_app_keys[i] && + bt_mesh.p_app_keys[i]->net_idx != BLE_MESH_KEY_UNUSED && + bt_mesh.p_app_keys[i]->app_idx == app_idx) { + BT_DBG("PvnrAppKey"); + return bt_mesh.p_app_keys[i]; + } + } +#endif /* CONFIG_BLE_MESH_PROVISIONER */ + } + + return NULL; +} + +int bt_mesh_upper_key_get(const struct bt_mesh_subnet *subnet, uint16_t app_idx, + const uint8_t **key, uint8_t *aid, uint16_t dst) +{ + struct bt_mesh_app_key *app_key = NULL; + + BT_DBG("UpperKeyGet, AppIdx 0x%04x Dst 0x%04x", app_idx, dst); + + if (app_idx == BLE_MESH_KEY_DEV) { + *key = bt_mesh_dev_key_get(dst); + if (!*key) { + BT_ERR("DevKeyNotFound 0x%04x", dst); + return -EINVAL; + } + + *aid = 0U; + return 0; + } + + if (!subnet) { + BT_ERR("InvalidSubnet"); + return -EINVAL; + } + + app_key = bt_mesh_app_key_get(app_idx); + if (!app_key) { + BT_ERR("AppKeyNotFound 0x%04x", app_idx); + return -ENOENT; + } + + if (subnet->kr_phase == BLE_MESH_KR_PHASE_2 && app_key->updated) { + BT_DBG("NewAppKey"); + *key = app_key->keys[1].val; + *aid = app_key->keys[1].id; + } else { + BT_DBG("OldAppKey"); + *key = app_key->keys[0].val; + *aid = app_key->keys[0].id; + } + + return 0; +} diff --git a/components/bt/esp_ble_mesh/core/adv.c b/components/bt/esp_ble_mesh/core/adv.c index 22323ca3404e..5f58c2058b33 100644 --- a/components/bt/esp_ble_mesh/core/adv.c +++ b/components/bt/esp_ble_mesh/core/adv.c @@ -166,8 +166,8 @@ static inline int adv_send(struct net_buf *buf) struct bt_mesh_adv_data ad = {0}; int err = 0; - BT_DBG("type %u len %u: %s", BLE_MESH_ADV(buf)->type, - buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("LegacyAdvSend, Type %u", BLE_MESH_ADV(buf)->type); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); #if CONFIG_BLE_MESH_SUPPORT_BLE_ADV if (BLE_MESH_ADV(buf)->type != BLE_MESH_ADV_BLE) { @@ -192,13 +192,14 @@ static inline int adv_send(struct net_buf *buf) #if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX if (BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_PROXY_SOLIC) { bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL); + struct bt_mesh_adv_data solic_ad[2] = { BLE_MESH_ADV_DATA_BYTES(BLE_MESH_DATA_UUID16_ALL, 0x59, 0x18), BLE_MESH_ADV_DATA(BLE_MESH_DATA_SVC_DATA16, buf->data, buf->len), }; err = bt_le_adv_start(¶m, solic_ad, ARRAY_SIZE(solic_ad), NULL, 0); } else -#endif +#endif /* CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX */ { bt_mesh_adv_buf_ref_debug(__func__, buf, 4U, BLE_MESH_BUF_REF_SMALL); err = bt_le_adv_start(¶m, &ad, 1, NULL, 0); @@ -215,8 +216,8 @@ static inline int adv_send(struct net_buf *buf) } BT_DBG("interval %dms, duration %dms, period %dms, count %d", - ADV_SCAN_INT(tx->param.interval), tx->param.duration, - tx->param.period, tx->param.count); + ADV_SCAN_INT(tx->param.interval), tx->param.duration, + tx->param.period, tx->param.count); data.adv_data_len = tx->buf->data[0]; if (data.adv_data_len) { @@ -235,6 +236,7 @@ static inline int adv_send(struct net_buf *buf) #endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */ net_buf_unref(buf); + adv_send_start(duration, err, cb, cb_data); if (err) { BT_ERR("Start advertising failed: err %d", err); @@ -264,24 +266,33 @@ static inline TickType_t K_WAIT(int32_t val) static void adv_thread(void *p) { #if CONFIG_BLE_MESH_RELAY_ADV_BUF + QueueHandle_t relay_adv_handle = NULL; QueueSetMemberHandle_t handle = NULL; -#endif - bt_mesh_msg_t msg = {0}; +#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */ struct net_buf **buf = NULL; + bt_mesh_msg_t msg = {0}; + +#if CONFIG_BLE_MESH_RELAY_ADV_BUF + relay_adv_handle = relay_adv_handle_get(); + assert(relay_adv_handle); +#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */ buf = (struct net_buf **)(&msg.arg); - BT_DBG("%s, starts", __func__); + BT_DBG("LegacyAdvThread"); while (1) { *buf = NULL; + #if !CONFIG_BLE_MESH_RELAY_ADV_BUF #if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \ CONFIG_BLE_MESH_GATT_PROXY_SERVER xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT); while (!(*buf)) { int32_t timeout = 0; + BT_DBG("Mesh Proxy Advertising start"); + timeout = bt_mesh_proxy_server_adv_start(); BT_DBG("Mesh Proxy Advertising up to %d ms", timeout); xQueueReceive(adv_queue.handle, &msg, K_WAIT(timeout)); @@ -304,12 +315,17 @@ static void adv_thread(void *p) } else { while (!(*buf)) { int32_t timeout = 0; + BT_DBG("Mesh Proxy Advertising start"); + timeout = bt_mesh_proxy_server_adv_start(); BT_DBG("Mesh Proxy Advertising up to %d ms", timeout); + handle = xQueueSelectFromSet(mesh_queue_set, K_WAIT(timeout)); + BT_DBG("Mesh Proxy Advertising stop"); bt_mesh_proxy_server_adv_stop(); + if (handle) { if (uxQueueMessagesWaiting(adv_queue.handle)) { xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT); @@ -319,7 +335,7 @@ static void adv_thread(void *p) } } } -#else +#else /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */ handle = xQueueSelectFromSet(mesh_queue_set, portMAX_DELAY); if (handle) { if (uxQueueMessagesWaiting(adv_queue.handle)) { @@ -347,6 +363,7 @@ static void adv_thread(void *p) * BLE_MESH_RELAY_TIME_INTERVAL, this relay packet will not be sent. */ BT_INFO("Ignore relay packet"); + net_buf_unref(*buf); } else { if (adv_send(*buf)) { @@ -359,6 +376,8 @@ static void adv_thread(void *p) net_buf_unref(*buf); } + BT_DBG("Yield"); + /* Give other threads a chance to run */ taskYIELD(); } @@ -509,6 +528,8 @@ void bt_mesh_adv_update(void) .arg = NULL, }; + BT_DBG("LegacyAdvUpdate"); + bt_mesh_task_post(&msg, K_NO_WAIT, false); } diff --git a/components/bt/esp_ble_mesh/core/adv.h b/components/bt/esp_ble_mesh/core/adv.h index 369d3cef3d0e..e249eed1b179 100644 --- a/components/bt/esp_ble_mesh/core/adv.h +++ b/components/bt/esp_ble_mesh/core/adv.h @@ -94,6 +94,7 @@ uint16_t bt_mesh_get_stored_relay_count(void); void bt_mesh_adv_update(void); void bt_mesh_adv_init(void); + void bt_mesh_adv_deinit(void); #if CONFIG_BLE_MESH_SUPPORT_BLE_ADV diff --git a/components/bt/esp_ble_mesh/core/adv_common.c b/components/bt/esp_ble_mesh/core/adv_common.c new file mode 100644 index 000000000000..ff4e50ac1c8d --- /dev/null +++ b/components/bt/esp_ble_mesh/core/adv_common.c @@ -0,0 +1,951 @@ +/* Bluetooth Mesh */ + +/* + * SPDX-FileCopyrightText: 2017 Intel Corporation + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include "adv_common.h" +#include "net.h" +#include "ble_adv.h" + +NET_BUF_POOL_DEFINE(adv_buf_pool, CONFIG_BLE_MESH_ADV_BUF_COUNT, + BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL); + +static struct bt_mesh_adv adv_pool[CONFIG_BLE_MESH_ADV_BUF_COUNT]; + +static struct bt_mesh_adv_queue adv_queue; + +#if CONFIG_BLE_MESH_RELAY_ADV_BUF +NET_BUF_POOL_DEFINE(relay_adv_buf_pool, CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT, + BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL); + +static struct bt_mesh_adv relay_adv_pool[CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT]; +struct bt_mesh_adv_queue relay_adv_queue; + +#define BLE_MESH_RELAY_TIME_INTERVAL K_SECONDS(6) +#define BLE_MESH_MAX_TIME_INTERVAL 0xFFFFFFFF +#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */ + +static bt_mesh_mutex_t adv_buf_alloc_lock; +#if CONFIG_BLE_MESH_EXT_ADV +NET_BUF_POOL_DEFINE(ext_adv_buf_pool, CONFIG_BLE_MESH_EXT_ADV_BUF_COUNT, + BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL); +static bt_mesh_ext_adv_t ext_adv_pool[CONFIG_BLE_MESH_EXT_ADV_BUF_COUNT]; +#if CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT +NET_BUF_POOL_DEFINE(ext_relay_adv_buf_pool, CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT, + BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL); +static bt_mesh_ext_adv_t ext_relay_adv_pool[CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT]; +#endif /* CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT */ +#if CONFIG_BLE_MESH_LONG_PACKET +NET_BUF_POOL_DEFINE(ext_long_adv_buf_pool, CONFIG_BLE_MESH_LONG_PACKET_TX_SEG_CNT, + CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN, BLE_MESH_ADV_USER_DATA_SIZE, NULL); +static bt_mesh_ext_adv_t ext_long_adv_pool[CONFIG_BLE_MESH_LONG_PACKET_TX_SEG_CNT]; +#if CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT +NET_BUF_POOL_DEFINE(ext_long_relay_adv_buf_pool, CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT, + CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN, BLE_MESH_ADV_USER_DATA_SIZE, NULL); +static bt_mesh_ext_adv_t ext_long_relay_adv_pool[CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT]; +#endif /* CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT */ +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ + +static inline void init_adv_with_defaults(struct bt_mesh_adv *adv, + enum bt_mesh_adv_type type) +{ + memset(adv, 0, sizeof(struct bt_mesh_adv)); + adv->type = type; + adv->adv_itvl = BLE_MESH_ADV_ITVL_DEFAULT; + adv->adv_cnt = BLE_MESH_ADV_CNT_DEFAULT; + adv->channel_map = BLE_MESH_ADV_CHAN_DEFAULT; +} + +#if CONFIG_BLE_MESH_FRIEND +/* We reserve one extra buffer for each friendship, since we need to be able + * to resend the last sent PDU, which sits separately outside of the queue. + */ +#define FRIEND_BUF_COUNT ((CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE + 1) * \ + CONFIG_BLE_MESH_FRIEND_LPN_COUNT) + +NET_BUF_POOL_FIXED_DEFINE(friend_buf_pool, FRIEND_BUF_COUNT, + BLE_MESH_ADV_DATA_SIZE, NULL); + +static bt_mesh_friend_adv_t frnd_adv_pool[FRIEND_BUF_COUNT]; +#endif /* CONFIG_BLE_MESH_FRIEND */ + +struct bt_mesh_adv_task { + TaskHandle_t handle; +#if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \ + (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \ + CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY) + StaticTask_t *task; + StackType_t *stack; +#endif +}; + +static struct bt_mesh_adv_task adv_task; + +static struct bt_mesh_adv_type_manager adv_types[BLE_MESH_ADV_TYPES_NUM]; + +#if CONFIG_BLE_MESH_USE_BLE_50 +static struct bt_mesh_adv_inst adv_insts[] = { + [BLE_MESH_ADV_INST] = { + .id = CONFIG_BLE_MESH_ADV_INST_ID, +#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV + .busy = false, +#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */ + }, +#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV +#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \ + CONFIG_BLE_MESH_GATT_PROXY_SERVER + [BLE_MESH_ADV_PROXY_INST] = { + .id = CONFIG_BLE_MESH_PROXY_ADV_INST_ID, + .busy = false, + }, +#endif +#if CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE + [BLE_MESH_RELAY_ADV_INST] = { + .id = CONFIG_BLE_MESH_RELAY_ADV_INST_ID, + .busy = false, + }, +#endif /* CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE */ +#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE + [BLE_MESH_BLE_ADV_INST] = { + .id = CONFIG_BLE_MESH_BLE_ADV_INST_ID, + .busy = false, + }, +#endif /* CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE */ +#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */ +}; + +static struct bt_mesh_adv_inst *find_adv_inst_with_inst_id(uint8_t id) +{ + BT_DBG("FindAdvInstWithID, InstID %u", id); + + for (int i = 0; i < ARRAY_SIZE(adv_insts); i++) { + if (adv_insts[i].id == id) { + return &adv_insts[i]; + } + } + + BT_WARN("NotFoundAdvInst, InstID %u", id); + return NULL; +} + +struct bt_mesh_adv_inst *bt_mesh_get_adv_insts_set(void) +{ + return adv_insts; +} + +bool bt_mesh_is_adv_inst_used(uint8_t inst_id) +{ + BT_DBG("IsAdvInstUsed, InstID %u", inst_id); + + return (find_adv_inst_with_inst_id(inst_id) != NULL); +} + +int bt_mesh_adv_inst_init(enum bt_mesh_adv_inst_type inst_type, uint8_t inst_id) +{ + BT_DBG("AdvInstInit, InstType %u InstID %u", inst_type, inst_id); + + if (inst_type >= BLE_MESH_ADV_INST_TYPES_NUM) { + BT_ERR("InvalidAdvInstType %u", inst_type); + return -EINVAL; + } + + if (inst_id == BLE_MESH_ADV_INST_UNUSED) { + BT_ERR("UnusedAdvInstID"); + return -EINVAL; + } + + adv_insts[inst_type].id = inst_id; + + return 0; +} + +int bt_mesh_adv_inst_deinit(enum bt_mesh_adv_inst_type inst_type) +{ + BT_DBG("AdvInstDeinit, InstType %u", inst_type); + + if (inst_type >= BLE_MESH_ADV_INST_TYPES_NUM) { + BT_ERR("Invalid adv inst type %d", inst_type); + return -EINVAL; + } + + BT_DBG("InstID %u", adv_insts[inst_type].id); + + bt_le_ext_adv_stop(adv_insts[inst_type].id); + + adv_insts[inst_type].id = BLE_MESH_ADV_INST_UNUSED; +#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV + adv_insts[inst_type].spt_mask = 0; +#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */ + + return 0; +} +#endif /* CONFIG_BLE_MESH_USE_BLE_50 */ + +static struct bt_mesh_adv *adv_alloc(int id, enum bt_mesh_adv_type type) +{ + BT_DBG("AdvAlloc, ID %d", id); + init_adv_with_defaults(&adv_pool[id], type); + return &adv_pool[id]; +} + +#if CONFIG_BLE_MESH_EXT_ADV +struct bt_mesh_adv *ext_adv_alloc(int id, enum bt_mesh_adv_type type) +{ + init_adv_with_defaults(&ext_adv_pool[id].adv, type); + ext_adv_pool[id].primary_phy = BLE_MESH_ADV_PRI_PHY_DEFAULT; + ext_adv_pool[id].secondary_phy = BLE_MESH_ADV_SEC_PHY_DEFAULT; + ext_adv_pool[id].include_tx_power = BLE_MESH_TX_POWER_INCLUDE_DEFAULT; + ext_adv_pool[id].tx_power = BLE_MESH_TX_POWER_DEFAULT; + return &ext_adv_pool[id].adv; +} +#if CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT +struct bt_mesh_adv *ext_relay_adv_alloc(int id, enum bt_mesh_adv_type type) +{ + init_adv_with_defaults(&ext_relay_adv_pool[id].adv, type); + ext_relay_adv_pool[id].primary_phy = BLE_MESH_ADV_PRI_PHY_DEFAULT; + ext_relay_adv_pool[id].secondary_phy = BLE_MESH_ADV_SEC_PHY_DEFAULT; + ext_relay_adv_pool[id].include_tx_power = BLE_MESH_TX_POWER_INCLUDE_DEFAULT; + ext_relay_adv_pool[id].tx_power = BLE_MESH_TX_POWER_DEFAULT; + return &ext_relay_adv_pool[id].adv; +} +#endif /* CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ + +#if CONFIG_BLE_MESH_LONG_PACKET +struct bt_mesh_adv *ext_long_adv_alloc(int id, enum bt_mesh_adv_type type) +{ + init_adv_with_defaults(&ext_long_adv_pool[id].adv, type); + ext_long_adv_pool[id].primary_phy = BLE_MESH_ADV_PRI_PHY_DEFAULT; + ext_long_adv_pool[id].secondary_phy = BLE_MESH_ADV_SEC_PHY_DEFAULT; + ext_long_adv_pool[id].include_tx_power = BLE_MESH_TX_POWER_INCLUDE_DEFAULT; + ext_long_adv_pool[id].tx_power = BLE_MESH_TX_POWER_DEFAULT; + return &ext_long_adv_pool[id].adv; +} +#if CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT +struct bt_mesh_adv *ext_long_relay_adv_alloc(int id, enum bt_mesh_adv_type type) +{ + init_adv_with_defaults(&ext_long_relay_adv_pool[id].adv, type); + ext_long_relay_adv_pool[id].primary_phy = BLE_MESH_ADV_PRI_PHY_DEFAULT; + ext_long_relay_adv_pool[id].secondary_phy = BLE_MESH_ADV_SEC_PHY_DEFAULT; + ext_long_relay_adv_pool[id].include_tx_power = BLE_MESH_TX_POWER_INCLUDE_DEFAULT; + ext_long_relay_adv_pool[id].tx_power = BLE_MESH_TX_POWER_DEFAULT; + return &ext_long_relay_adv_pool[id].adv; +} +#endif /* CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT */ +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ + +struct bt_mesh_adv_type_manager *bt_mesh_adv_types_mgmt_get(enum bt_mesh_adv_type adv_type) +{ + BT_DBG("AdvTypeMgmtGet, AdvType %u", adv_type); + + return &adv_types[adv_type]; +} + +void bt_mesh_adv_buf_ref_debug(const char *func, struct net_buf *buf, + uint8_t ref_cmp, bt_mesh_buf_ref_flag_t flag) +{ + if (buf == NULL || func == NULL || flag >= BLE_MESH_BUF_REF_MAX) { + BT_ERR("%s, Invalid parameter", __func__); + return; + } + + BT_DBG("AdvBufRefDebug, BufRef %u RefCmp %u", buf->ref, ref_cmp); + + switch (flag) { + case BLE_MESH_BUF_REF_EQUAL: + if (buf->ref != ref_cmp) { + BT_ERR("Unexpected ref %d in %s, expect to equal to %d", buf->ref, func, ref_cmp); + } + break; + case BLE_MESH_BUF_REF_SMALL: + if (buf->ref >= ref_cmp) { + BT_ERR("Unexpected ref %d in %s, expect to smaller than %d", buf->ref, func, ref_cmp); + } + break; + default: + break; + } +} + +#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV +void bt_mesh_adv_inst_type_add(enum bt_mesh_adv_inst_type inst_type, + enum bt_mesh_adv_type adv_type) +{ + BT_DBG("AdvInstTypeAdd, InstType %u AdvType %u", inst_type, adv_type); + + if (inst_type >= BLE_MESH_ADV_INST_TYPES_NUM) { + BT_ERR("Invalid adv inst type %d", inst_type); + return; + } + + if (adv_type >= BLE_MESH_ADV_TYPES_NUM) { + BT_ERR("Invalid adv type %d", adv_type); + return; + } + + adv_insts[inst_type].spt_mask |= BIT(adv_type); +} + +void bt_mesh_adv_inst_type_rem(enum bt_mesh_adv_inst_type inst_type, + enum bt_mesh_adv_type adv_type) +{ + BT_DBG("AdvInstTypeRem, InstType %u AdvType %u", inst_type, adv_type); + + if (inst_type >= BLE_MESH_ADV_INST_TYPES_NUM) { + BT_ERR("Invalid adv inst type %d", inst_type); + return; + } + + if (adv_type >= BLE_MESH_ADV_TYPES_NUM) { + BT_ERR("Invalid adv type %d", adv_type); + return; + } + + adv_insts[inst_type].spt_mask &= ~BIT(adv_type); +} + +void bt_mesh_adv_inst_type_clear(enum bt_mesh_adv_inst_type inst_type, + enum bt_mesh_adv_type adv_type) +{ + BT_DBG("AdvInstTypeClear, InstType %u AdvType %u", inst_type, adv_type); + + if (inst_type >= BLE_MESH_ADV_INST_TYPES_NUM) { + BT_ERR("Invalid adv inst type %d", inst_type); + return; + } + + if (adv_type >= BLE_MESH_ADV_TYPES_NUM) { + BT_ERR("Invalid adv type %d", adv_type); + return; + } + + adv_insts[inst_type].spt_mask = 0; +} +#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */ + +int bt_mesh_adv_queue_init(struct bt_mesh_adv_queue *adv_queue, uint16_t queue_size, + bt_mesh_adv_queue_send_cb_t cb) +{ + BT_DBG("AdvQueueInit, QueueSize %u", queue_size); + + if (!adv_queue || !queue_size || !cb) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + bt_mesh_queue_init(&adv_queue->q, queue_size, sizeof(bt_mesh_msg_t)); + adv_queue->send = cb; + + return 0; +} + +int bt_mesh_adv_queue_deinit(struct bt_mesh_adv_queue *adv_queue) +{ + BT_DBG("AdvQueueDeinit"); + + if (!adv_queue) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + bt_mesh_queue_deinit(&adv_queue->q); + adv_queue->send = NULL; + + return 0; +} + +void bt_mesh_adv_type_init(enum bt_mesh_adv_type adv_type, + struct bt_mesh_adv_queue *adv_queue, + struct net_buf_pool *buf_pool, + bt_mesh_pool_allocator_t adv_alloc) +{ + BT_DBG("AdvTypeInit, AdvType %u", adv_type); + + if (adv_type >= BLE_MESH_ADV_TYPES_NUM) { + BT_ERR("%s, Invalid adv type %d", __func__, adv_type); + return; + } + + if (!adv_queue || !buf_pool || !adv_alloc) { + BT_ERR("%s, Invalid parameter", __func__); + return; + } + + adv_types[adv_type].adv_q = adv_queue; + adv_types[adv_type].pool = buf_pool; + adv_types[adv_type].pool_allocator = adv_alloc; +} + +void bt_mesh_adv_type_deinit(enum bt_mesh_adv_type adv_type) +{ + BT_DBG("AdvTypeDeinit, AdvType %u", adv_type); + + if (adv_type >= BLE_MESH_ADV_TYPES_NUM) { + BT_ERR("%s, Invalid adv type %d", __func__, adv_type); + return; + } + + adv_types[adv_type].adv_q = NULL; + adv_types[adv_type].pool = NULL; + adv_types[adv_type].pool_allocator = NULL; +} + +#if CONFIG_BLE_MESH_USE_BLE_50 +int bt_mesh_adv_task_wakeup(uint32_t evt) +{ + BT_DBG("AdvTypeWakeup, Evt 0x%08lx", evt); + + xTaskNotify(adv_task.handle, evt, eSetBits); + return 0; +} + +bool bt_mesh_adv_task_wait(uint32_t wait_bits, uint32_t timeout, uint32_t *notify) +{ + BT_DBG("AdvTypeWait, WaitBits 0x%08lx Timeout %lu", wait_bits, timeout); + + return (xTaskNotifyWait(wait_bits, UINT32_MAX, notify, K_WAIT(timeout)) == pdTRUE); +} +#else /* CONFIG_BLE_MESH_USE_BLE_50 */ +bool bt_mesh_adv_task_wait(uint32_t timeout) +{ + BT_DBG("AdvTypeWait, Timeout %lu", timeout); + + vTaskDelay(K_WAIT(timeout)); + return true; +} +#endif /* CONFIG_BLE_MESH_USE_BLE_50 */ + +uint16_t bt_mesh_pdu_duration(uint8_t xmit) +{ + uint16_t duration = 0U; + uint16_t adv_int = 0U; + + adv_int = MAX(ADV_ITVL_MIN, BLE_MESH_TRANSMIT_INT(xmit)); + duration = (BLE_MESH_TRANSMIT_COUNT(xmit) + 1) * (adv_int + 10); + + BT_DBG("PDUDuration %u", duration); + + return duration; +} + +struct net_buf *bt_mesh_adv_create_from_pool(enum bt_mesh_adv_type type, int32_t timeout) +{ + struct bt_mesh_adv *adv = NULL; + struct net_buf *buf = NULL; + + BT_DBG("AdvCreateFromPool, Type %u", type); + + if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_SUSPENDED)) { + BT_WARN("Refusing to allocate buffer while suspended"); + return NULL; + } + + if (type >= BLE_MESH_ADV_TYPES_NUM) { + BT_ERR("%s, Invalid adv type %u", __func__, type); + return NULL; + } + + if (adv_types[type].pool == NULL || adv_types[type].pool_allocator == NULL) { + BT_ERR("Uninitialized adv type %d", type); + return NULL; + } + + bt_mesh_r_mutex_lock(&adv_buf_alloc_lock); + + buf = net_buf_alloc(adv_types[type].pool, timeout); + if (!buf) { + BT_WARN("net buf alloc failed"); + bt_mesh_r_mutex_unlock(&adv_buf_alloc_lock); + return NULL; + } + + BT_DBG("Pool %p BufCount %u UinitCount %u BufID %d Ref %u", + adv_types[type].pool, adv_types[type].pool->buf_count, + adv_types[type].pool->uninit_count, net_buf_id(buf), + buf->ref); + + adv = adv_types[type].pool_allocator(net_buf_id(buf), type); + BLE_MESH_ADV(buf) = adv; + bt_mesh_r_mutex_unlock(&adv_buf_alloc_lock); + + return buf; +} + +void bt_mesh_unref_buf_from_pool(struct net_buf_pool *pool) +{ + BT_DBG("UnrefBufFromPool"); + + if (pool == NULL) { + BT_ERR("%s, Invalid parameter", __func__); + return; + } + + for (int i = 0; i < pool->buf_count; i++) { + struct net_buf *buf = &pool->__bufs[i]; + + BT_DBG("%u: Buf %p Ref %u", i, buf, buf->ref); + + if (buf->ref > 1U) { + buf->ref = 1U; + } + net_buf_unref(buf); + } +} + +void bt_mesh_unref_buf(bt_mesh_msg_t *msg) +{ + struct net_buf *buf = msg->arg; + + BT_DBG("UnRefBuf %p", buf); + + if (buf) { + BT_DBG("Ref %u", buf->ref); + + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 0); + + if (buf->ref > 1U) { + buf->ref = 1U; + } + net_buf_unref(buf); + } +} + +void bt_mesh_generic_adv_send(struct net_buf *buf, uint8_t xmit, + const struct bt_mesh_send_cb *cb, + void *cb_data, uint16_t src, + uint16_t dst, bool front) +{ + bt_mesh_msg_t msg = { + .relay = false, /* useless flag in multi-instance mode */ + }; + + BT_DBG("GenericAdvSend"); + BT_DBG("Src 0x%04x Dst 0x%04x Type 0x%02x", + src, dst, BLE_MESH_ADV(buf)->type); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); + + BLE_MESH_ADV(buf)->cb = cb; + BLE_MESH_ADV(buf)->cb_data = cb_data; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1); + BLE_MESH_ADV(buf)->xmit = xmit; + + bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL); + + msg.arg = (void *)net_buf_ref(buf); + +#if CONFIG_BLE_MESH_RELAY_ADV_BUF + if (BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_RELAY_DATA) { + msg.relay = true; + msg.src = src; + msg.dst = dst; + msg.timestamp = k_uptime_get_32(); + + BT_DBG("RelayAdvData, Timestamp %lu", msg.timestamp); + } +#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */ + + assert(adv_types[BLE_MESH_ADV(buf)->type].adv_q); + assert(adv_types[BLE_MESH_ADV(buf)->type].adv_q->send); + + adv_types[BLE_MESH_ADV(buf)->type].adv_q->send(&msg, portMAX_DELAY, front); + +#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV + bt_mesh_adv_task_wakeup(ADV_TASK_PKT_SEND_EVT); +#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */ +} + +struct bt_mesh_adv_queue *bt_mesh_adv_queue_get(void) +{ + return &adv_queue; +} + +void bt_mesh_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front) +{ + BT_DBG("TaskPost, Front %u", front); + + if (adv_queue.q.handle == NULL) { + BT_ERR("Invalid adv queue"); + return; + } + + if (front) { + if (xQueueSendToFront(adv_queue.q.handle, msg, timeout) != pdTRUE) { + BT_ERR("Failed to send item to adv queue front"); + bt_mesh_unref_buf(msg); + } + } else { + if (xQueueSend(adv_queue.q.handle, msg, timeout) != pdTRUE) { + BT_ERR("Failed to send item to adv queue back"); + bt_mesh_unref_buf(msg); + } + } +} + +#if CONFIG_BLE_MESH_RELAY_ADV_BUF +bool bt_mesh_ignore_relay_packet(uint32_t timestamp) +{ + uint32_t now = k_uptime_get_32(); + uint32_t interval = 0U; + + if (now >= timestamp) { + interval = now - timestamp; + } else { + interval = BLE_MESH_MAX_TIME_INTERVAL - (timestamp - now) + 1; + } + + BT_DBG("IgnoreRelayPacket"); + BT_DBG("Now %lu Timestamp %lu Interval %lu", now, timestamp, interval); + + return ((interval >= BLE_MESH_RELAY_TIME_INTERVAL) ? true : false); +} + +static struct bt_mesh_adv *relay_adv_alloc(int id, enum bt_mesh_adv_type type) +{ + BT_DBG("RelayAdvAlloc, ID %d", id); + memset(&relay_adv_pool[id], 0, sizeof(struct bt_mesh_adv)); + init_adv_with_defaults(&relay_adv_pool[id], type); + return &relay_adv_pool[id]; +} + +static void bt_mesh_relay_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front) +{ + bt_mesh_msg_t old_msg = {0}; + + BT_DBG("RelayTaskPost, Front %u", front); + + if (relay_adv_queue.q.handle == NULL) { + BT_ERR("Invalid relay queue"); + return; + } + + if (xQueueSend(relay_adv_queue.q.handle, msg, timeout) == pdTRUE) { + return; + } + + /* If failed to send packet to the relay queue(queue is full), we will + * remove the oldest packet in the queue and put the new one into it. + */ + if (uxQueueMessagesWaiting(relay_adv_queue.q.handle)) { + BT_INFO("Full queue, remove the oldest relay packet"); + + /* Remove the oldest relay packet from queue */ + if (xQueueReceive(relay_adv_queue.q.handle, &old_msg, K_NO_WAIT) != pdTRUE) { + BT_ERR("Failed to remove item from relay queue"); + bt_mesh_unref_buf(msg); + return; + } + + /* Unref buf used for the oldest relay packet */ + bt_mesh_unref_buf(&old_msg); + + /* Send the latest relay packet to queue */ + if (xQueueSend(relay_adv_queue.q.handle, msg, K_NO_WAIT) != pdTRUE) { + BT_ERR("Failed to send item to relay queue"); + bt_mesh_unref_buf(msg); + return; + } + } else { + BT_WARN("Empty queue, but failed to send the relay packet"); + bt_mesh_unref_buf(msg); + } +} + +uint16_t bt_mesh_get_stored_relay_count(void) +{ + uint16_t count = (uint16_t)uxQueueMessagesWaiting(relay_adv_queue.q.handle); + + BT_DBG("StoredRelayCount %u", count); + + return count; +} + +void bt_mesh_relay_adv_init(void) +{ + BT_DBG("RelayAdvInit"); + bt_mesh_adv_queue_init(&relay_adv_queue, bt_mesh_relay_adv_buf_count_get(), + bt_mesh_relay_task_post); + bt_mesh_adv_type_init(BLE_MESH_ADV_RELAY_DATA, &relay_adv_queue, + &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); +#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); +#endif /* CONFIG_BLE_MESH_LONG_PACKET && CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ + +#if CONFIG_BLE_MESH_USE_BLE_50 +#if CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE + bt_mesh_adv_inst_init(BLE_MESH_RELAY_ADV_INST, + CONFIG_BLE_MESH_RELAY_ADV_INST_ID); + bt_mesh_adv_inst_type_add(BLE_MESH_RELAY_ADV_INST, BLE_MESH_ADV_RELAY_DATA); + +#if CONFIG_BLE_MESH_EXT_ADV + bt_mesh_adv_inst_type_add(BLE_MESH_RELAY_ADV_INST, BLE_MESH_ADV_EXT_RELAY_DATA); +#if CONFIG_BLE_MESH_LONG_PACKET + bt_mesh_adv_inst_type_add(BLE_MESH_RELAY_ADV_INST, BLE_MESH_ADV_EXT_LONG_RELAY_DATA); +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ +#else /* CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE */ +#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV + bt_mesh_adv_inst_type_add(BLE_MESH_ADV_INST, BLE_MESH_ADV_RELAY_DATA); +#if CONFIG_BLE_MESH_EXT_ADV + bt_mesh_adv_inst_type_add(BLE_MESH_ADV_INST, BLE_MESH_ADV_EXT_RELAY_DATA); +#if CONFIG_BLE_MESH_LONG_PACKET + bt_mesh_adv_inst_type_add(BLE_MESH_ADV_INST, BLE_MESH_ADV_EXT_LONG_RELAY_DATA); +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ +#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */ +#endif /* CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE */ +#endif /* CONFIG_BLE_MESH_USE_BLE_50 */ +} + +#if CONFIG_BLE_MESH_DEINIT +void bt_mesh_relay_adv_deinit(void) +{ + BT_DBG("RelayAdvDeinit"); + + bt_mesh_adv_queue_deinit(&relay_adv_queue); + + bt_mesh_adv_type_deinit(BLE_MESH_ADV_RELAY_DATA); +#if CONFIG_BLE_MESH_EXT_ADV + bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_RELAY_DATA); +#if CONFIG_BLE_MESH_LONG_PACKET + bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_LONG_RELAY_DATA); +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ + +#if CONFIG_BLE_MESH_USE_BLE_50 +#if CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE + bt_mesh_adv_inst_type_rem(BLE_MESH_RELAY_ADV_INST, BLE_MESH_ADV_RELAY_DATA); +#if CONFIG_BLE_MESH_EXT_ADV + bt_mesh_adv_inst_type_rem(BLE_MESH_RELAY_ADV_INST, BLE_MESH_ADV_EXT_RELAY_DATA); +#if CONFIG_BLE_MESH_LONG_PACKET + bt_mesh_adv_inst_type_rem(BLE_MESH_RELAY_ADV_INST, BLE_MESH_ADV_EXT_LONG_RELAY_DATA); +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ + bt_mesh_adv_inst_deinit(BLE_MESH_RELAY_ADV_INST); +#else /* CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE */ +#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV + bt_mesh_adv_inst_type_rem(BLE_MESH_ADV_INST, BLE_MESH_ADV_RELAY_DATA); +#if CONFIG_BLE_MESH_EXT_ADV + bt_mesh_adv_inst_type_rem(BLE_MESH_ADV_INST, BLE_MESH_ADV_EXT_RELAY_DATA); +#if CONFIG_BLE_MESH_LONG_PACKET + bt_mesh_adv_inst_type_rem(BLE_MESH_ADV_INST, BLE_MESH_ADV_EXT_LONG_RELAY_DATA); +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ +#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */ +#endif /* CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE */ +#endif /* CONFIG_BLE_MESH_USE_BLE_50 */ + + bt_mesh_unref_buf_from_pool(&relay_adv_buf_pool); + memset(relay_adv_pool, 0, sizeof(relay_adv_pool)); +} +#endif /* CONFIG_BLE_MESH_DEINIT */ +#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */ + +#if CONFIG_BLE_MESH_FRIEND +static struct bt_mesh_adv *bt_mesh_frnd_adv_buf_get(int idx, enum bt_mesh_adv_type type) +{ + BT_DBG("FrndAdvBufGet, Idx %d", idx); + + memset(&frnd_adv_pool[idx].adv, 0, sizeof(struct bt_mesh_adv)); + init_adv_with_defaults(&frnd_adv_pool[idx].adv, type); + frnd_adv_pool[idx].app_idx = BLE_MESH_KEY_UNUSED; + return &frnd_adv_pool[idx].adv; +} + +void bt_mesh_frnd_adv_init(void) +{ + BT_DBG("FrndAdvInit"); + + bt_mesh_adv_type_init(BLE_MESH_ADV_FRIEND, &adv_queue, &friend_buf_pool, bt_mesh_frnd_adv_buf_get); + +#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV + bt_mesh_adv_inst_type_add(BLE_MESH_ADV_INST, BLE_MESH_ADV_FRIEND); +#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */ +} + +void bt_mesh_frnd_adv_deinit(void) +{ + BT_DBG("FrndAdvDeinit"); + + bt_mesh_adv_type_deinit(BLE_MESH_ADV_FRIEND); + +#if CONFIG_BLE_MESH_FRIEND && CONFIG_BLE_MESH_SUPPORT_MULTI_ADV + bt_mesh_adv_inst_type_rem(BLE_MESH_ADV_INST, BLE_MESH_ADV_FRIEND); +#endif /* CONFIG_BLE_MESH_FRIEND */ + + bt_mesh_unref_buf_from_pool(&friend_buf_pool); + memset(frnd_adv_pool, 0, sizeof(frnd_adv_pool)); +} +#endif /* CONFIG_BLE_MESH_FRIEND */ + +void bt_mesh_adv_task_init(void adv_thread(void *p)) +{ + BT_DBG("AdvTaskInit"); + + if (!adv_thread) { + BT_ERR("%s, Invalid parameter", __func__); + return; + } + +#if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \ + (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \ + CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY) + adv_task.task = heap_caps_calloc(1, sizeof(StaticTask_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); + assert(adv_task.task); + + adv_task.stack = heap_caps_calloc_prefer(1, BLE_MESH_ADV_TASK_STACK_SIZE * sizeof(StackType_t), + 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, + MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); + assert(adv_task.stack); + + adv_task.handle = xTaskCreateStaticPinnedToCore(adv_thread, BLE_MESH_ADV_TASK_NAME, + BLE_MESH_ADV_TASK_STACK_SIZE, NULL, + BLE_MESH_ADV_TASK_PRIO, adv_task.stack, + adv_task.task, BLE_MESH_ADV_TASK_CORE); + assert(adv_task.handle); +#else /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY */ + int ret = xTaskCreatePinnedToCore(adv_thread, BLE_MESH_ADV_TASK_NAME, BLE_MESH_ADV_TASK_STACK_SIZE, NULL, + BLE_MESH_ADV_TASK_PRIO, &adv_task.handle, BLE_MESH_ADV_TASK_CORE); +#if CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE + if (ret != pdTRUE) { + BT_ERR("xTaskCreatePinnedToCore failed, ret %d", ret); + return; + } +#else + assert(ret == pdTRUE); +#endif /* CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE */ +#endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY */ +} + +void bt_mesh_adv_common_init(void) +{ + BT_DBG("AdvCommonInit"); + + bt_mesh_r_mutex_create(&adv_buf_alloc_lock); + bt_mesh_adv_queue_init(&adv_queue, bt_mesh_adv_buf_count_get(), bt_mesh_task_post); + bt_mesh_adv_type_init(BLE_MESH_ADV_PROV, &adv_queue, &adv_buf_pool, adv_alloc); + bt_mesh_adv_type_init(BLE_MESH_ADV_DATA, &adv_queue, &adv_buf_pool, adv_alloc); + bt_mesh_adv_type_init(BLE_MESH_ADV_BEACON, &adv_queue, &adv_buf_pool, adv_alloc); + bt_mesh_adv_type_init(BLE_MESH_ADV_URI, &adv_queue, &adv_buf_pool, adv_alloc); +#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX + bt_mesh_adv_type_init(BLE_MESH_ADV_PROXY_SOLIC, &adv_queue, &adv_buf_pool, adv_alloc); +#endif /* CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX */ + +#if CONFIG_BLE_MESH_USE_BLE_50 + bt_mesh_adv_inst_init(BLE_MESH_ADV_INST, CONFIG_BLE_MESH_ADV_INST_ID); +#if CONFIG_BLE_MESH_EXT_ADV + bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_PROV, &adv_queue, &ext_adv_buf_pool, ext_adv_alloc); + bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_DATA, &adv_queue, &ext_adv_buf_pool, ext_adv_alloc); +#if !CONFIG_BLE_MESH_RELAY_ADV_BUF && CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT + bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_RELAY_DATA, &adv_queue, &ext_relay_adv_buf_pool, ext_relay_adv_alloc); +#endif +#if CONFIG_BLE_MESH_LONG_PACKET + bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_LONG_PROV, &adv_queue, &ext_long_adv_buf_pool, ext_long_adv_alloc); + bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_LONG_DATA, &adv_queue, &ext_long_adv_buf_pool, ext_long_adv_alloc); +#if !CONFIG_BLE_MESH_RELAY_ADV_BUF && CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT + bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_LONG_RELAY_DATA, &adv_queue, &ext_long_relay_adv_buf_pool, ext_long_relay_adv_alloc); +#endif /* !CONFIG_BLE_MESH_RELAY_ADV_BUF && CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT */ +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ +#endif /* CONFIG_BLE_MESH_USE_BLE_50 */ + +#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV + /* Due to the limitation of the sequence number in the network layer, + * it is not possible to use multiple advertising instances to process + * data from the same message queue when sending mesh packets. + * + * Therefore, shall to check whether there are duplicates in the queue + * buffer corresponding to each advertising instance. + */ + bt_mesh_adv_inst_type_add(BLE_MESH_ADV_INST, BLE_MESH_ADV_PROV); + bt_mesh_adv_inst_type_add(BLE_MESH_ADV_INST, BLE_MESH_ADV_DATA); + bt_mesh_adv_inst_type_add(BLE_MESH_ADV_INST, BLE_MESH_ADV_BEACON); + bt_mesh_adv_inst_type_add(BLE_MESH_ADV_INST, BLE_MESH_ADV_URI); +#if CONFIG_BLE_MESH_EXT_ADV + bt_mesh_adv_inst_type_add(BLE_MESH_ADV_INST, BLE_MESH_ADV_EXT_PROV); + bt_mesh_adv_inst_type_add(BLE_MESH_ADV_INST, BLE_MESH_ADV_EXT_DATA); +#if CONFIG_BLE_MESH_RELAY && !CONFIG_BLE_MESH_RELAY_ADV_BUF + bt_mesh_adv_inst_type_add(BLE_MESH_ADV_INST, BLE_MESH_ADV_EXT_RELAY_DATA); +#endif +#if CONFIG_BLE_MESH_LONG_PACKET + bt_mesh_adv_inst_type_add(BLE_MESH_ADV_INST, BLE_MESH_ADV_EXT_LONG_PROV); + bt_mesh_adv_inst_type_add(BLE_MESH_ADV_INST, BLE_MESH_ADV_EXT_LONG_DATA); +#if CONFIG_BLE_MESH_RELAY && !CONFIG_BLE_MESH_RELAY_ADV_BUF + bt_mesh_adv_inst_type_add(BLE_MESH_ADV_INST, BLE_MESH_ADV_EXT_LONG_RELAY_DATA); +#endif /* !CONFIG_BLE_MESH_RELAY_ADV_BUF */ +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ +#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */ +} + +#if CONFIG_BLE_MESH_DEINIT +void bt_mesh_adv_task_deinit(void) +{ + BT_DBG("AdvTaskDeinit"); + + vTaskDelete(adv_task.handle); + adv_task.handle = NULL; + +#if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \ + (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \ + CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY) + heap_caps_free(adv_task.stack); + adv_task.stack = NULL; + heap_caps_free(adv_task.task); + adv_task.task = NULL; +#endif +} + +void bt_mesh_adv_common_deinit(void) +{ + BT_DBG("AdvCommonDeinit"); + + bt_mesh_adv_type_deinit(BLE_MESH_ADV_PROV); + bt_mesh_adv_type_deinit(BLE_MESH_ADV_DATA); + bt_mesh_adv_type_deinit(BLE_MESH_ADV_BEACON); + bt_mesh_adv_type_deinit(BLE_MESH_ADV_URI); + +#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX + bt_mesh_adv_type_deinit(BLE_MESH_ADV_PROXY_SOLIC); +#endif + +#if CONFIG_BLE_MESH_EXT_ADV + bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_PROV); + bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_DATA); +#if !CONFIG_BLE_MESH_RELAY_ADV_BUF + bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_RELAY_DATA); +#endif +#if CONFIG_BLE_MESH_LONG_PACKET + bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_LONG_PROV); + bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_LONG_DATA); +#if !CONFIG_BLE_MESH_RELAY_ADV_BUF + bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_LONG_RELAY_DATA); +#endif +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ + + bt_mesh_adv_queue_deinit(&adv_queue); + +#if CONFIG_BLE_MESH_USE_BLE_50 + bt_mesh_adv_inst_deinit(BLE_MESH_ADV_INST); +#endif /* CONFIG_BLE_MESH_USE_BLE_50 */ + + bt_mesh_unref_buf_from_pool(&adv_buf_pool); + memset(adv_pool, 0, sizeof(adv_pool)); + + bt_mesh_r_mutex_free(&adv_buf_alloc_lock); +} +#endif /* CONFIG_BLE_MESH_DEINIT */ diff --git a/components/bt/esp_ble_mesh/core/adv_common.h b/components/bt/esp_ble_mesh/core/adv_common.h new file mode 100644 index 000000000000..54267ee5222d --- /dev/null +++ b/components/bt/esp_ble_mesh/core/adv_common.h @@ -0,0 +1,405 @@ +/* Bluetooth Mesh */ + +/* + * SPDX-FileCopyrightText: 2017 Intel Corporation + * SPDX-FileContributor: 2024-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ADV_COMMON_H_ +#define _ADV_COMMON_H_ + +#include "mesh/common.h" +#include "mesh/atomic.h" +#include "mesh/access.h" +#include "mesh/adapter.h" +#include "mesh/queue.h" +#include "mesh/timer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Pre-5.0 controllers enforce a minimum interval of 100ms + * whereas 5.0+ controllers can go down to 20ms. + */ +#if CONFIG_BLE_MESH_HCI_5_0 +#define ADV_ITVL_MIN 20 +#else +#define ADV_ITVL_MIN 100 +#endif + +/* Convert from ms to 0.625ms units */ +#define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5) +/* Convert from 0.625ms units to interval(ms) */ +#define ADV_SCAN_INT(val) ((val) * 5 / 8) + +/* Maximum advertising data payload for a single data type */ +#define BLE_MESH_ADV_DATA_SIZE 29 + +/* The user data is a pointer (4 bytes) to struct bt_mesh_adv */ +#define BLE_MESH_ADV_USER_DATA_SIZE 4 + +#define BLE_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf)) +#define BLE_MESH_ADV_BUSY(buf) (BLE_MESH_ADV(buf)->busy) + +#define BLE_MESH_MSG_NET_BUF(msg) ((struct net_buf *)(msg->arg)) + +#define BLE_MESH_ADV_INST_UNUSED 0xFF + +struct bt_mesh_adv { + const struct bt_mesh_send_cb *cb; + void *cb_data; + + uint8_t type; + + bt_mesh_atomic_t busy; + + uint8_t xmit; + + uint32_t adv_itvl; + uint8_t adv_cnt; + uint8_t channel_map; +}; + +#if CONFIG_BLE_MESH_USE_BLE_50 +#define EXT_ADV(buf) CONTAINER_OF(BLE_MESH_ADV(buf), bt_mesh_ext_adv_t, adv) +typedef struct { + struct bt_mesh_adv adv; + uint8_t primary_phy; + uint8_t secondary_phy; + uint8_t include_tx_power:1; + int8_t tx_power; +} bt_mesh_ext_adv_t; +#endif + +#if CONFIG_BLE_MESH_FRIEND +#define FRIEND_ADV(buf) CONTAINER_OF(BLE_MESH_ADV(buf), bt_mesh_friend_adv_t, adv) + +typedef struct { + struct bt_mesh_adv adv; + uint16_t app_idx; +} bt_mesh_friend_adv_t; +#endif /* CONFIG_BLE_MESH_FRIEND */ + +enum { +#if CONFIG_BLE_MESH_USE_BLE_50 + ADV_TASK_MESH_ADV_INST_EVT = BIT(CONFIG_BLE_MESH_ADV_INST_ID), + +#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV +#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \ + CONFIG_BLE_MESH_GATT_PROXY_SERVER + ADV_TASK_PROX_ADV_INST_EVT = BIT(CONFIG_BLE_MESH_PROXY_ADV_INST_ID), +#endif + +#if CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE + ADV_TASK_RELAY_ADV_INST_EVT = BIT(CONFIG_BLE_MESH_RELAY_ADV_INST_ID), +#endif + +#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE + ADV_TASK_BLE_ADV_INST_EVT = BIT(CONFIG_BLE_MESH_BLE_ADV_INST_ID), +#endif +#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */ + +#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \ + CONFIG_BLE_MESH_GATT_PROXY_SERVER + ADV_TASK_PROXY_ADV_UPD_EVT = BIT(30), +#endif +#endif /* CONFIG_BLE_MESH_USE_BLE_50 */ + + ADV_TASK_PKT_SEND_EVT = BIT(31), + + ADV_TASK_EVT_MAX, +}; + +uint16_t bt_mesh_pdu_duration(uint8_t xmit); + +typedef struct bt_mesh_msg { + bool relay; /* Flag indicates if the packet is a relayed one */ + void *arg; /* Pointer to the struct net_buf */ + uint16_t src; /* Source address for relay packets */ + uint16_t dst; /* Destination address for relay packets */ + uint32_t timestamp; /* Timestamp recorded when the relay packet is posted to queue */ +} bt_mesh_msg_t; + +struct bt_mesh_adv_inst { + uint8_t id; + +#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV + bool busy; + struct net_buf *sending_buf; + + /* Indicate which adv_type is supported by this instance */ + uint32_t spt_mask; +#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */ +}; + +enum bt_mesh_adv_type { + BLE_MESH_ADV_PROV, + BLE_MESH_ADV_DATA, +#if CONFIG_BLE_MESH_EXT_ADV + BLE_MESH_ADV_EXT_PROV, + BLE_MESH_ADV_EXT_DATA, + BLE_MESH_ADV_EXT_RELAY_DATA, +#if CONFIG_BLE_MESH_LONG_PACKET + BLE_MESH_ADV_EXT_LONG_PROV, + BLE_MESH_ADV_EXT_LONG_DATA, + BLE_MESH_ADV_EXT_LONG_RELAY_DATA, +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ +#if CONFIG_BLE_MESH_FRIEND + BLE_MESH_ADV_FRIEND, +#endif +#if CONFIG_BLE_MESH_RELAY_ADV_BUF + BLE_MESH_ADV_RELAY_DATA, +#endif + BLE_MESH_ADV_BEACON, + BLE_MESH_ADV_URI, +#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX + BLE_MESH_ADV_PROXY_SOLIC, +#endif +#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV + BLE_MESH_ADV_BLE, +#endif + BLE_MESH_ADV_TYPES_NUM, +}; + +typedef enum { + BLE_MESH_BUF_REF_EQUAL, + BLE_MESH_BUF_REF_SMALL, + BLE_MESH_BUF_REF_MAX, +} bt_mesh_buf_ref_flag_t; + + +static const uint8_t adv_type[] = { + [BLE_MESH_ADV_PROV] = BLE_MESH_DATA_MESH_PROV, + [BLE_MESH_ADV_DATA] = BLE_MESH_DATA_MESH_MESSAGE, +#if CONFIG_BLE_MESH_EXT_ADV + [BLE_MESH_ADV_EXT_PROV] = BLE_MESH_DATA_MESH_PROV, + [BLE_MESH_ADV_EXT_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE, + [BLE_MESH_ADV_EXT_DATA] = BLE_MESH_DATA_MESH_MESSAGE, +#if CONFIG_BLE_MESH_LONG_PACKET + [BLE_MESH_ADV_EXT_LONG_PROV] = BLE_MESH_DATA_MESH_PROV, + [BLE_MESH_ADV_EXT_LONG_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE, + [BLE_MESH_ADV_EXT_LONG_DATA] = BLE_MESH_DATA_MESH_MESSAGE, +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ +#if CONFIG_BLE_MESH_FRIEND + [BLE_MESH_ADV_FRIEND] = BLE_MESH_DATA_MESH_MESSAGE, +#endif +#if CONFIG_BLE_MESH_RELAY_ADV_BUF + [BLE_MESH_ADV_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE, +#endif + [BLE_MESH_ADV_BEACON] = BLE_MESH_DATA_MESH_BEACON, + [BLE_MESH_ADV_URI] = BLE_MESH_DATA_URI, +}; + +typedef struct bt_mesh_adv *(*bt_mesh_pool_allocator_t)(int id, enum bt_mesh_adv_type type); +typedef void (*bt_mesh_adv_queue_send_cb_t)(bt_mesh_msg_t *msg, uint32_t timeout, bool front); + +struct bt_mesh_adv_type_manager { + struct bt_mesh_adv_queue *adv_q; + struct net_buf_pool *pool; + bt_mesh_pool_allocator_t pool_allocator; +}; + +struct bt_mesh_adv_queue { + bt_mesh_queue_t q; + bt_mesh_adv_queue_send_cb_t send; +}; + +static inline TickType_t K_WAIT(int32_t val) +{ + return (val == K_FOREVER) ? portMAX_DELAY : (val / portTICK_PERIOD_MS); +} + +static inline void adv_send_start(uint16_t duration, int err, + const struct bt_mesh_send_cb *cb, + void *cb_data) +{ + if (cb && cb->start) { + cb->start(duration, err, cb_data); + } +} + +static inline void adv_send_end(int err, const struct bt_mesh_send_cb *cb, + void *cb_data) +{ + if (cb && cb->end) { + cb->end(err, cb_data); + } +} + +struct bt_mesh_adv_queue *bt_mesh_adv_queue_get(void); + +struct net_buf *bt_mesh_adv_create_from_pool(enum bt_mesh_adv_type type, int32_t timeout); + +static inline struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, int32_t timeout) +{ + return bt_mesh_adv_create_from_pool(type, timeout); +} + +void bt_mesh_adv_buf_ref_debug(const char *func, struct net_buf *buf, + uint8_t ref_cmp, bt_mesh_buf_ref_flag_t flag); + +struct bt_mesh_adv_type_manager *bt_mesh_adv_types_mgmt_get(enum bt_mesh_adv_type adv_type); + +void bt_mesh_generic_adv_send(struct net_buf *buf, uint8_t xmit, + const struct bt_mesh_send_cb *cb, + void *cb_data, uint16_t src, + uint16_t dst, bool front); + +static inline void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit, + const struct bt_mesh_send_cb *cb, + void *cb_data) +{ + bt_mesh_generic_adv_send(buf, xmit, cb, cb_data, BLE_MESH_ADDR_UNASSIGNED, BLE_MESH_ADDR_UNASSIGNED, false); +} + +void bt_mesh_unref_buf_from_pool(struct net_buf_pool *pool); + +void bt_mesh_unref_buf(bt_mesh_msg_t *msg); + +int bt_mesh_adv_queue_init(struct bt_mesh_adv_queue *adv_queue, + uint16_t queue_size, + bt_mesh_adv_queue_send_cb_t cb); + +int bt_mesh_adv_queue_deinit(struct bt_mesh_adv_queue *adv_queue); + +void bt_mesh_adv_type_init(enum bt_mesh_adv_type adv_type, + struct bt_mesh_adv_queue *adv_queue, + struct net_buf_pool *buf_pool, + bt_mesh_pool_allocator_t adv_alloc); + +void bt_mesh_adv_type_deinit(enum bt_mesh_adv_type adv_type); + +void bt_mesh_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front); + +#if CONFIG_BLE_MESH_USE_BLE_50 +struct bt_mesh_adv_inst *bt_mesh_get_adv_insts_set(void); + +bool bt_mesh_is_adv_inst_used(uint8_t inst_id); + +int bt_mesh_adv_inst_init(enum bt_mesh_adv_inst_type inst_type, uint8_t inst_id); + +int bt_mesh_adv_inst_deinit(enum bt_mesh_adv_inst_type inst_type); +#endif /* CONFIG_BLE_MESH_USE_BLE_50 */ + +#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV +void bt_mesh_adv_inst_type_add(enum bt_mesh_adv_inst_type inst_type, + enum bt_mesh_adv_type adv_type); + +void bt_mesh_adv_inst_type_rem(enum bt_mesh_adv_inst_type inst_type, + enum bt_mesh_adv_type adv_type); + +void bt_mesh_adv_inst_type_clear(enum bt_mesh_adv_inst_type inst_type, + enum bt_mesh_adv_type adv_type); +#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */ + +#if CONFIG_BLE_MESH_RELAY_ADV_BUF +static ALWAYS_INLINE +uint16_t bt_mesh_relay_adv_buf_count_get(void) +{ + uint16_t relay_adv_count = 2 + CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT; + +#if CONFIG_BLE_MESH_EXT_ADV && CONFIG_BLE_MESH_RELAY + relay_adv_count += CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT; +#endif + +#if CONFIG_BLE_MESH_LONG_PACKET && CONFIG_BLE_MESH_RELAY + relay_adv_count += CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT; +#endif + return relay_adv_count; +} + +void bt_mesh_relay_adv_init(void); + +bool bt_mesh_ignore_relay_packet(uint32_t timestamp); + +static inline void bt_mesh_relay_adv_send(struct net_buf *buf, uint8_t xmit, + uint16_t src, uint16_t dst, + const struct bt_mesh_send_cb *cb, + void *cb_data) +{ + bt_mesh_generic_adv_send(buf, xmit, cb, cb_data, src, dst, false); +}; + +uint16_t bt_mesh_get_stored_relay_count(void); + +#if CONFIG_BLE_MESH_DEINIT +void bt_mesh_relay_adv_deinit(void); +#endif +#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */ + +#if CONFIG_BLE_MESH_FRIEND +void bt_mesh_frnd_adv_init(void); + +#if CONFIG_BLE_MESH_DEINIT +void bt_mesh_frnd_adv_deinit(void); +#endif /* CONFIG_BLE_MESH_DEINIT */ +#endif /* CONFIG_BLE_MESH_FRIEND */ + +static ALWAYS_INLINE +uint16_t bt_mesh_adv_buf_count_get(void) +{ + uint16_t adv_count = 2 + CONFIG_BLE_MESH_ADV_BUF_COUNT; + +#if CONFIG_BLE_MESH_EXT_ADV + adv_count += CONFIG_BLE_MESH_EXT_ADV_BUF_COUNT; +#if !CONFIG_BLE_MESH_RELAY_ADV_BUF && CONFIG_BLE_MESH_RELAY + adv_count += CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT; +#endif /* !CONFIG_BLE_MESH_RELAY_ADV_BUF && CONFIG_BLE_MESH_RELAY */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ + +#if CONFIG_BLE_MESH_LONG_PACKET + adv_count += CONFIG_BLE_MESH_LONG_PACKET_ADV_BUF_COUNT; +#if !CONFIG_BLE_MESH_RELAY_ADV_BUF && CONFIG_BLE_MESH_RELAY + adv_count += CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT; +#endif /* !CONFIG_BLE_MESH_RELAY_ADV_BUF && CONFIG_BLE_MESH_RELAY */ +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ + +#if (CONFIG_BLE_MESH_SUPPORT_BLE_ADV && \ + !(CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE)) + adv_count += CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT; +#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */ + + return adv_count; +} + +void bt_mesh_adv_task_init(void adv_thread(void *p)); + +void bt_mesh_adv_common_init(void); + +#if CONFIG_BLE_MESH_DEINIT +void bt_mesh_adv_task_deinit(void); + +void bt_mesh_adv_common_deinit(void); +#endif + +#if CONFIG_BLE_MESH_USE_BLE_50 +int bt_mesh_adv_task_wakeup(uint32_t evt); + +bool bt_mesh_adv_task_wait(uint32_t wait_bits, TickType_t timeout, uint32_t *notify); +#else /* CONFIG_BLE_MESH_USE_BLE_50 */ +bool bt_mesh_adv_task_wait(uint32_t timeout); +#endif /* CONFIG_BLE_MESH_USE_BLE_50 */ + +#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV +static inline void bt_mesh_ble_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, + void *cb_data, bool front) +{ + bt_mesh_generic_adv_send(buf, 0, cb, cb_data, BLE_MESH_ADDR_UNASSIGNED, BLE_MESH_ADDR_UNASSIGNED, front); +} + +int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param, + const struct bt_mesh_ble_adv_data *data, uint8_t *index); + +int bt_mesh_stop_ble_advertising(uint8_t index); +#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ADV_COMMON_H_ */ diff --git a/components/bt/esp_ble_mesh/core/beacon.c b/components/bt/esp_ble_mesh/core/beacon.c index 97ec6ebd8231..e58214c0c3aa 100644 --- a/components/bt/esp_ble_mesh/core/beacon.c +++ b/components/bt/esp_ble_mesh/core/beacon.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,19 +27,19 @@ #if CONFIG_BLE_MESH_V11_SUPPORT #include "mesh_v1.1/utils.h" -#endif +#endif /* CONFIG_BLE_MESH_V11_SUPPORT */ -#if defined(CONFIG_BLE_MESH_UNPROVISIONED_BEACON_INTERVAL) +#if CONFIG_BLE_MESH_UNPROVISIONED_BEACON_INTERVAL #define UNPROV_BEACON_INTERVAL K_SECONDS(CONFIG_BLE_MESH_UNPROVISIONED_BEACON_INTERVAL) -#else +#else /* CONFIG_BLE_MESH_UNPROVISIONED_BEACON_INTERVAL */ #define UNPROV_BEACON_INTERVAL K_SECONDS(5) -#endif +#endif /* CONFIG_BLE_MESH_UNPROVISIONED_BEACON_INTERVAL */ #if CONFIG_BLE_MESH_BQB_TEST #define SECURE_BEACON_INTERVAL K_SECONDS(3) -#else +#else /* CONFIG_BLE_MESH_BQB_TEST */ #define SECURE_BEACON_INTERVAL K_SECONDS(10) -#endif +#endif /* CONFIG_BLE_MESH_BQB_TEST */ /* 3 transmissions, 20ms interval */ #define UNPROV_XMIT BLE_MESH_TRANSMIT(2, 20) @@ -58,6 +58,8 @@ struct bt_mesh_subnet *cache_check(uint8_t data[21], bool private_beacon) uint8_t *cache = NULL; int i = 0; + BT_DBG("CacheCheck, PrivateBeacon %u", private_beacon); + subnet_size = bt_mesh_rx_netkey_size(); for (i = 0; i < subnet_size; i++) { @@ -69,11 +71,12 @@ struct bt_mesh_subnet *cache_check(uint8_t data[21], bool private_beacon) #if CONFIG_BLE_MESH_PRIVATE_BEACON cache = private_beacon ? sub->mpb_cache : sub->snb_cache; -#else +#else /* CONFIG_BLE_MESH_PRIVATE_BEACON */ cache = sub->snb_cache; -#endif +#endif /* CONFIG_BLE_MESH_PRIVATE_BEACON */ if (!memcmp(cache, data, 21)) { + BT_DBG("BeaconSubFound, NetIdx 0x%04x", sub->net_idx); return sub; } } @@ -83,11 +86,13 @@ struct bt_mesh_subnet *cache_check(uint8_t data[21], bool private_beacon) void cache_add(uint8_t data[21], struct bt_mesh_subnet *sub, bool private_beacon) { + BT_DBG("CacheAdd, NetIdx 0x%04x PrivateBeacon %u", sub->net_idx, private_beacon); + #if CONFIG_BLE_MESH_PRIVATE_BEACON if (private_beacon) { memcpy(sub->mpb_cache, data, 21); } else -#endif +#endif /* CONFIG_BLE_MESH_PRIVATE_BEACON */ { memcpy(sub->snb_cache, data, 21); } @@ -98,10 +103,10 @@ static void secure_beacon_complete(int err, void *user_data) struct bt_mesh_subnet *sub = NULL; uint16_t net_idx = BLE_MESH_KEY_UNUSED; - BT_DBG("err %d", err); - net_idx = (uint16_t)NET_IDX_GET(user_data); + BT_DBG("SecureBeaconComplete, NetIdx 0x%04x Err %d", net_idx, err); + /* For node, directly updating the "beacon_sent" timestamp is fine, * since the subnet is pre-allocated. * For Provisioner, before updating the "beacon_sent" timestamp, we @@ -112,6 +117,8 @@ static void secure_beacon_complete(int err, void *user_data) sub = bt_mesh_subnet_get(net_idx); if (sub) { sub->snb_sent = k_uptime_get_32(); + + BT_DBG("SnbSent %lu", sub->snb_sent); } } @@ -121,6 +128,8 @@ void bt_mesh_secure_beacon_create(struct bt_mesh_subnet *sub, uint8_t flags = bt_mesh_net_flags(sub); struct bt_mesh_subnet_keys *keys = NULL; + BT_DBG("SecureBeaconCreate"); + net_buf_simple_add_u8(buf, BEACON_TYPE_SECURE); if (sub->kr_flag) { @@ -139,10 +148,10 @@ void bt_mesh_secure_beacon_create(struct bt_mesh_subnet *sub, net_buf_simple_add_mem(buf, sub->auth, 8); - BT_DBG("SNB: net_idx 0x%03x iv_index 0x%08x flags 0x%02x", - sub->net_idx, bt_mesh.iv_index, flags); - BT_DBG("SNB: NetID %s Auth %s", bt_hex(keys->net_id, 8), - bt_hex(sub->auth, 8)); + BT_DBG("NetIdx 0x%04x IVIndex 0x%08x Flags 0x%02x", + sub->net_idx, bt_mesh.iv_index, flags); + BT_DBG("NetID %s Auth %s", bt_hex(keys->net_id, 8), + bt_hex(sub->auth, 8)); } static int secure_beacon_send(void) @@ -154,6 +163,8 @@ static int secure_beacon_send(void) size_t subnet_size = 0U; int i = 0; + BT_DBG("SecureBeaconSend"); + subnet_size = bt_mesh_rx_netkey_size(); for (i = 0; i < subnet_size; i++) { @@ -165,6 +176,8 @@ static int secure_beacon_send(void) continue; } + BT_DBG("Now %lu SnbSent %lu SnbLast %u", now, sub->snb_sent, sub->snb_last); + time_diff = now - sub->snb_sent; if (time_diff < K_SECONDS(600) && time_diff < BEACON_THRESHOLD(sub->snb_last)) { @@ -178,9 +191,10 @@ static int secure_beacon_send(void) */ #if CONFIG_BLE_MESH_GATT_PROXY_CLIENT if (bt_mesh_proxy_client_beacon_send(sub, false)) { + BT_DBG("ProxyClientBeaconSend"); continue; } -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */ buf = bt_mesh_adv_create(BLE_MESH_ADV_BEACON, K_NO_WAIT); if (!buf) { @@ -201,6 +215,7 @@ static int secure_beacon_send(void) * updating its "snb_sent" timestamp. */ bt_mesh_adv_send(buf, SNB_XMIT, &send_cb, NET_IDX_SET(sub->net_idx)); + net_buf_unref(buf); } @@ -214,6 +229,8 @@ static int unprovisioned_beacon_send(void) struct net_buf *buf = NULL; uint16_t oob_info = 0U; + BT_DBG("UnprovisionedBeaconSend"); + if (bt_mesh_prov_get() == NULL) { BT_ERR("No provisioning context provided"); return -EINVAL; @@ -252,6 +269,8 @@ static int unprovisioned_beacon_send(void) len = strlen(bt_mesh_prov_get()->uri); + BT_DBG("URI %u: %s", len, bt_mesh_prov_get()->uri); + if (net_buf_tailroom(buf) < len) { BT_WARN("Too long URI to fit advertising data"); } else { @@ -277,6 +296,8 @@ void update_beacon_observation(bool private_beacon) size_t subnet_size = 0U; int i = 0; + BT_DBG("UpdateBeaconObservation, PrivateBeacon %u", private_beacon); + /* Observation period is 20 seconds, whereas the beacon timer * runs every 10 seconds. We process what's happened during * the window only after the second half. @@ -287,13 +308,15 @@ void update_beacon_observation(bool private_beacon) if (private_beacon) { mpb_first_half = !mpb_first_half; if (mpb_first_half) { + BT_DBG("MpbFirstHalf"); return; } } else -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ { snb_first_half = !snb_first_half; if (snb_first_half) { + BT_DBG("SnbFirstHalf"); return; } } @@ -309,11 +332,15 @@ void update_beacon_observation(bool private_beacon) #if CONFIG_BLE_MESH_PRB_SRV if (private_beacon) { + BT_DBG("NetIdx 0x%04x MpbCur %u", sub->net_idx, sub->mpb_cur); + sub->mpb_last = sub->mpb_cur; sub->mpb_cur = 0U; } else -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ { + BT_DBG("NetIdx 0x%04x SnbCur %u", sub->net_idx, sub->snb_cur); + sub->snb_last = sub->snb_cur; sub->snb_cur = 0U; } @@ -330,9 +357,12 @@ static bool ready_to_send(void) static void secure_beacon_send_timeout(struct k_work *work) { + BT_DBG("SecureBeaconSendTimeout"); + /* Don't send anything if we have an active provisioning link */ if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node() && IS_ENABLED(CONFIG_BLE_MESH_PROV) && bt_mesh_prov_active()) { + BT_DBG("ProvActive"); k_delayed_work_submit(&snb_timer, UNPROV_BEACON_INTERVAL); return; } @@ -345,11 +375,14 @@ static void secure_beacon_send_timeout(struct k_work *work) /* Only resubmit if beaconing is still enabled */ if (bt_mesh_secure_beacon_get() == BLE_MESH_SECURE_BEACON_ENABLED || bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_INITIATOR)) { + BT_DBG("Resubmit, SecureBeacon %u", bt_mesh_secure_beacon_get()); + k_delayed_work_submit(&snb_timer, SECURE_BEACON_INTERVAL); } } else { if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node()) { unprovisioned_beacon_send(); + k_delayed_work_submit(&snb_timer, UNPROV_BEACON_INTERVAL); } } @@ -365,6 +398,8 @@ static void secure_beacon_recv(struct net_buf_simple *buf) bool new_key = false; uint8_t flags = 0U; + BT_DBG("SecureBeaconRecv"); + if (buf->len != 21) { BT_ERR("Malformed secure beacon (len %u)", buf->len); return; @@ -384,7 +419,7 @@ static void secure_beacon_recv(struct net_buf_simple *buf) iv_index = net_buf_simple_pull_be32(buf); auth = buf->data; - BT_DBG("flags 0x%02x id %s iv_index 0x%08x", + BT_DBG("Flags 0x%02x NetID %s IVIndex 0x%08x", flags, bt_hex(net_id, 8), iv_index); sub = bt_mesh_subnet_find_with_snb(net_id, flags, iv_index, auth, &new_key); @@ -393,6 +428,9 @@ static void secure_beacon_recv(struct net_buf_simple *buf) return; } + BT_DBG("NetIdx 0x%04x KrPhase %u NewKey %u", + sub->net_idx, sub->kr_phase, new_key); + if (sub->kr_phase == BLE_MESH_KR_PHASE_2 && !new_key) { BT_WARN("Ignoring Phase 2 KR Update secured using old key"); return; @@ -417,8 +455,7 @@ static void secure_beacon_recv(struct net_buf_simple *buf) goto update_stats; } - BT_DBG("SNB: net_idx 0x%03x iv_index 0x%08x current iv_index 0x%08x", - sub->net_idx, iv_index, bt_mesh.iv_index); + BT_DBG("IVIndex 0x%08lx CurIVIndex 0x%08lx", iv_index, bt_mesh.iv_index); if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_INITIATOR) && (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS) == @@ -452,6 +489,7 @@ static void secure_beacon_recv(struct net_buf_simple *buf) update_stats: if (bt_mesh_secure_beacon_get() == BLE_MESH_SECURE_BEACON_ENABLED && sub->snb_cur < 0xff) { + BT_DBG("SnbCurInc %u", sub->snb_cur); sub->snb_cur++; } } @@ -460,7 +498,8 @@ void bt_mesh_beacon_recv(struct net_buf_simple *buf, int8_t rssi) { uint8_t type = 0U; - BT_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("BeaconRecv"); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); if (buf->len < 1) { BT_ERR("Too short beacon"); @@ -470,7 +509,7 @@ void bt_mesh_beacon_recv(struct net_buf_simple *buf, int8_t rssi) type = net_buf_simple_pull_u8(buf); switch (type) { case BEACON_TYPE_UNPROVISIONED: - BT_DBG("Unprovisioned device beacon received"); + BT_DBG("UnprovDevBeaconRecv, Rssi %d", rssi); if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) && @@ -480,11 +519,16 @@ void bt_mesh_beacon_recv(struct net_buf_simple *buf, int8_t rssi) #if CONFIG_BLE_MESH_RPR_SRV if (bt_mesh_is_provisioned()) { - const bt_mesh_addr_t *addr = bt_mesh_get_unprov_dev_addr(); + const bt_mesh_addr_t *addr = NULL; + + addr = bt_mesh_get_unprov_dev_addr(); + assert(addr); + bt_mesh_unprov_dev_fifo_enqueue(buf->data, addr->val, bt_mesh_get_adv_type()); + bt_mesh_rpr_srv_unprov_beacon_recv(buf, bt_mesh_get_adv_type(), addr, rssi); } -#endif +#endif /* CONFIG_BLE_MESH_RPR_SRV */ break; case BEACON_TYPE_SECURE: secure_beacon_recv(buf); @@ -493,7 +537,7 @@ void bt_mesh_beacon_recv(struct net_buf_simple *buf, int8_t rssi) case BEACON_TYPE_PRIVATE: bt_mesh_private_beacon_recv(buf); break; -#endif +#endif /* CONFIG_BLE_MESH_PRIVATE_BEACON */ default: BT_DBG("Unknown beacon type 0x%02x", type); break; @@ -514,7 +558,7 @@ void bt_mesh_beacon_init(void) BT_ERR("Failed to create a mpb_timer"); return; } -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ } #if CONFIG_BLE_MESH_DEINIT @@ -532,24 +576,28 @@ void bt_mesh_beacon_deinit(void) void bt_mesh_beacon_ivu_initiator(bool enable) { + BT_DBG("BeaconIVUInitiator, IVUInitiator %u", enable); + bt_mesh_atomic_set_bit_to(bt_mesh.flags, BLE_MESH_IVU_INITIATOR, enable); if (enable) { k_delayed_work_submit(&snb_timer, K_NO_WAIT); + #if CONFIG_BLE_MESH_PRB_SRV if (bt_mesh_private_beacon_state_get() == BLE_MESH_PRIVATE_BEACON_ENABLED) { bt_mesh_private_beacon_timer_submit(K_NO_WAIT); } -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ } else { if (bt_mesh_secure_beacon_get() == BLE_MESH_SECURE_BEACON_DISABLED) { k_delayed_work_cancel(&snb_timer); } + #if CONFIG_BLE_MESH_PRB_SRV if (bt_mesh_private_beacon_state_get() == BLE_MESH_PRIVATE_BEACON_DISABLED) { bt_mesh_private_beacon_timer_cancel(); } -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ } } @@ -558,8 +606,12 @@ void bt_mesh_secure_beacon_enable(void) size_t subnet_size = 0U; int i = 0; + BT_DBG("SecureBeaconEnable"); + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node() && !bt_mesh_is_provisioned()) { + BT_DBG("NodeNotProvisioned"); + k_delayed_work_submit(&snb_timer, K_NO_WAIT); return; } @@ -584,6 +636,9 @@ void bt_mesh_secure_beacon_enable(void) void bt_mesh_secure_beacon_disable(void) { + BT_DBG("SecureBeaconDisable, IVUInitiator %u", + bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_INITIATOR)); + if (!bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_INITIATOR)) { k_delayed_work_cancel(&snb_timer); } diff --git a/components/bt/esp_ble_mesh/core/ble_adv.c b/components/bt/esp_ble_mesh/core/ble_adv.c new file mode 100644 index 000000000000..aaaa4b429060 --- /dev/null +++ b/components/bt/esp_ble_mesh/core/ble_adv.c @@ -0,0 +1,371 @@ +/* Bluetooth Mesh */ + +/* + * SPDX-FileCopyrightText: 2017 Intel Corporation + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "ble_adv.h" +#include "mesh/common.h" +#include "mesh/buf.h" + +#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE +/* Use independent ble adv queue only if multi adv instance is used */ +static struct bt_mesh_adv_queue ble_adv_queue; +static void bt_mesh_ble_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front); +#endif + +static struct bt_mesh_adv_queue *p_ble_adv_queue; + +/* length + advertising data + length + scan response data */ +NET_BUF_POOL_DEFINE(ble_adv_buf_pool, CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT, + ((BLE_MESH_ADV_DATA_SIZE + 3) << 1), BLE_MESH_ADV_USER_DATA_SIZE, NULL); + +static struct bt_mesh_adv ble_adv_pool[CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT]; + +static struct bt_mesh_ble_adv_tx ble_adv_tx[CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT]; + +#define SEND_BLE_ADV_INFINITE 0xFFFF + +static struct bt_mesh_adv *ble_adv_alloc(int id, enum bt_mesh_adv_type type) +{ + BT_DBG("BLEAdvAlloc, ID %d", id); + memset(&ble_adv_pool[id], 0, sizeof(struct bt_mesh_adv)); + ble_adv_pool[id].type = type; + return &ble_adv_pool[id]; +} + +#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE +/* A separate post function is required only when using a separate queue */ +static void bt_mesh_ble_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front) +{ + BT_DBG("BLETaskPost, Front %u", front); + + if (p_ble_adv_queue->q.handle == NULL) { + BT_ERR("Invalid adv queue"); + return; + } + + if (front) { + if (xQueueSendToFront(p_ble_adv_queue->q.handle, msg, timeout) != pdTRUE) { + BT_ERR("Failed to send item to adv queue front"); + bt_mesh_unref_buf(msg); + } + } else { + if (xQueueSend(p_ble_adv_queue->q.handle, msg, timeout) != pdTRUE) { + BT_ERR("Failed to send item to adv queue back"); + bt_mesh_unref_buf(msg); + } + } +} +#endif + +static void ble_adv_tx_reset(struct bt_mesh_ble_adv_tx *tx, bool unref) +{ + BT_DBG("BLEAdvTxReset, Unref %u", unref); + + if (tx->buf == NULL) { + BT_DBG("NullTxBuf"); + return; + } + + if (bt_mesh_atomic_test_bit(tx->flags, TIMER_INIT)) { + k_delayed_work_free(&tx->resend); + } + bt_mesh_atomic_set(tx->flags, 0); + + memset(&tx->param, 0, sizeof(tx->param)); + + BT_DBG("Buf %p Ref %u Busy %u", + tx->buf, tx->buf->ref, + !!bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(tx->buf))); + + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(tx->buf), 0); + if (unref) { + net_buf_unref(tx->buf); + } + tx->buf = NULL; +} + +static void ble_adv_send_start(uint16_t duration, int err, void *cb_data) +{ + struct bt_mesh_ble_adv_tx *tx = cb_data; + + BT_DBG("BLEAdvSendStart, Duration %u Err %d", duration, err); + + /* If failed to send BLE adv packet, and param->count is not 0 + * which means the timer has been initialized, here we need to + * free the timer. + */ + if (err) { + ble_adv_tx_reset(tx, true); + } +} + +static void ble_adv_send_end(int err, void *cb_data) +{ + struct bt_mesh_ble_adv_tx *tx = cb_data; + + BT_DBG("BLEAdvSendEnd, Err %d", err); + + if (err) { + ble_adv_tx_reset(tx, true); + return; + } + + BT_DBG("Count %u Period %u", tx->param.count, tx->param.period); + + if (tx->param.count) { + if (tx->param.period) { + k_delayed_work_submit(&tx->resend, tx->param.period); + } else { + k_work_submit(&tx->resend.work); + } + } else { + ble_adv_tx_reset(tx, true); + } +} + +static struct bt_mesh_send_cb ble_adv_send_cb = { + .start = ble_adv_send_start, + .end = ble_adv_send_end, +}; + +static void ble_adv_resend(struct k_work *work) +{ + struct bt_mesh_ble_adv_tx *tx = CONTAINER_OF(work, struct bt_mesh_ble_adv_tx, resend.work); + bool front = false; + + BT_DBG("BLEAdvResend"); + + if (tx->buf == NULL) { + /* The advertising has been cancelled */ + BT_INFO("%s, cancelled", __func__); + return; + } + + BT_DBG("Priority %u Count %u Buf %p", tx->param.priority, tx->param.count, tx->buf); + + front = (tx->param.priority == BLE_MESH_BLE_ADV_PRIO_HIGH) ? true : false; + + bt_mesh_ble_adv_send(tx->buf, &ble_adv_send_cb, tx, front); + + if (tx->param.count == SEND_BLE_ADV_INFINITE) { + /* Send the BLE advertising packet infinitely */ + return; + } + + if (tx->param.count > 0U) { + tx->param.count--; + } +} + +int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param, + const struct bt_mesh_ble_adv_data *data, uint8_t *index) +{ + struct bt_mesh_ble_adv_tx *tx = NULL; + struct net_buf *buf = NULL; + bool front = false; + + BT_DBG("StartBLEAdv"); + + if (param == NULL || index == NULL) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + if (param->adv_type != BLE_MESH_ADV_DIRECT_IND && + (param->interval < 0x20 || param->interval > 0x4000)) { + BT_ERR("Invalid adv interval 0x%04x", param->interval); + return -EINVAL; + } + + if (param->adv_type > BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) { + BT_ERR("Invalid adv type 0x%02x", param->adv_type); + return -EINVAL; + } + + if (param->own_addr_type > BLE_MESH_ADDR_RANDOM_ID) { + BT_ERR("Invalid own addr type 0x%02x", param->own_addr_type); + return -EINVAL; + } + + if ((param->own_addr_type == BLE_MESH_ADDR_PUBLIC_ID || + param->own_addr_type == BLE_MESH_ADDR_RANDOM_ID || + param->adv_type == BLE_MESH_ADV_DIRECT_IND || + param->adv_type == BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) && + param->peer_addr_type > BLE_MESH_ADDR_RANDOM) { + BT_ERR("Invalid peer addr type 0x%02x", param->peer_addr_type); + return -EINVAL; + } + + if (data && (data->adv_data_len > 31 || data->scan_rsp_data_len > 31)) { + BT_ERR("Invalid adv data length (adv %d, scan rsp %d)", + data->adv_data_len, data->scan_rsp_data_len); + return -EINVAL; + } + + if (param->priority > BLE_MESH_BLE_ADV_PRIO_HIGH) { + BT_ERR("Invalid adv priority %d", param->priority); + return -EINVAL; + } + + if (param->duration < ADV_SCAN_INT(param->interval)) { + BT_ERR("Too small duration %dms", param->duration); + return -EINVAL; + } + + buf = bt_mesh_adv_create(BLE_MESH_ADV_BLE, K_NO_WAIT); + if (!buf) { + BT_ERR("No empty ble adv buffer"); + return -ENOBUFS; + } + + BT_DBG("AdvType 0x%02x Interval 0x%04x AddrType 0x%02x/0x%02x", + param->adv_type, param->interval, param->own_addr_type, param->peer_addr_type); + BT_DBG("DataLen %u/%u Priority %u Count %u Duration %u", + (data ? data->adv_data_len : 0), (data ? data->scan_rsp_data_len : 0), + param->priority, param->count, param->duration); + + /* Set advertising data and scan response data */ + memset(buf->data, 0, buf->size); + if (data) { + net_buf_add_u8(buf, data->adv_data_len); + if (data->adv_data_len) { + net_buf_add_mem(buf, data->adv_data, data->adv_data_len); + } + net_buf_add_u8(buf, data->scan_rsp_data_len); + if (data->scan_rsp_data_len) { + net_buf_add_mem(buf, data->scan_rsp_data, data->scan_rsp_data_len); + } + } + + *index = net_buf_id(buf); + tx = &ble_adv_tx[*index]; + tx->buf = buf; + memcpy(&tx->param, param, sizeof(tx->param)); + + front = (tx->param.priority == BLE_MESH_BLE_ADV_PRIO_HIGH) ? true : false; + bt_mesh_ble_adv_send(buf, &ble_adv_send_cb, tx, front); + + if (param->count) { + if (k_delayed_work_init(&tx->resend, ble_adv_resend)) { + /* If failed to create a timer, the BLE adv packet will be + * sent only once. Just give a warning here, and since the + * BLE adv packet can be sent, return 0 here. + */ + BT_WARN("Send BLE adv packet only once"); + + tx->param.count = 0; + net_buf_unref(buf); + return 0; + } + + bt_mesh_atomic_set_bit(tx->flags, TIMER_INIT); + } else { + /* Send the BLE advertising packet only once */ + net_buf_unref(buf); + } + + return 0; +} + +int bt_mesh_stop_ble_advertising(uint8_t index) +{ + struct bt_mesh_ble_adv_tx *tx = NULL; + bool unref = true; + + BT_DBG("StopBLEAdv, Index %u", index); + + if (index >= ARRAY_SIZE(ble_adv_tx)) { + BT_ERR("Invalid adv index %d", index); + return -EINVAL; + } + + tx = &ble_adv_tx[index]; + + if (tx->buf == NULL) { + BT_WARN("Already stopped, index %d", index); + return 0; + } + + BT_DBG("Busy %u Ref %u", + !!bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(tx->buf)), + tx->buf->ref); + + /* busy 1, ref 1; busy 1, ref 2; + * busy 0, ref 0; busy 0, ref 1; + */ + + if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(tx->buf)) && + tx->buf->ref == 1U) { + unref = false; + } + ble_adv_tx_reset(tx, unref); + + return 0; +} + +struct bt_mesh_adv_queue *bt_mesh_ble_adv_queue_get(void) +{ +#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE + bt_mesh_adv_queue_init(&ble_adv_queue, CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT, bt_mesh_ble_task_post); + return &ble_adv_queue; +#else + return bt_mesh_adv_queue_get(); +#endif +} + +void bt_mesh_ble_adv_init(void) +{ + BT_DBG("BLEAdvInit"); + p_ble_adv_queue = bt_mesh_ble_adv_queue_get(); + bt_mesh_adv_type_init(BLE_MESH_ADV_BLE, p_ble_adv_queue, &ble_adv_buf_pool, ble_adv_alloc); +#if CONFIG_BLE_MESH_USE_BLE_50 +#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE + bt_mesh_adv_inst_init(BLE_MESH_BLE_ADV_INST, CONFIG_BLE_MESH_BLE_ADV_INST_ID); + bt_mesh_adv_inst_type_add(BLE_MESH_BLE_ADV_INST, BLE_MESH_ADV_BLE); +#else /* CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE */ +#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV + bt_mesh_adv_inst_type_add(BLE_MESH_ADV_INST, BLE_MESH_ADV_BLE); +#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */ +#endif /* CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE */ +#endif /* CONFIG_BLE_MESH_USE_BLE_50 */ +} + +#if CONFIG_BLE_MESH_DEINIT +void bt_mesh_ble_adv_deinit(void) +{ + BT_DBG("BLEAdvDeinit"); + + for (int i = 0; i < ARRAY_SIZE(ble_adv_tx); i++) { + ble_adv_tx_reset(&ble_adv_tx[i], false); + } + + bt_mesh_unref_buf_from_pool(&ble_adv_buf_pool); + memset(ble_adv_pool, 0, sizeof(ble_adv_pool)); + +#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE + /* In other cases, ble_adv queue is an adv queue, + * so ble does not need to deinit separately */ + bt_mesh_adv_queue_deinit(p_ble_adv_queue); +#endif + bt_mesh_adv_type_deinit(BLE_MESH_ADV_BLE); + +#if CONFIG_BLE_MESH_USE_BLE_50 +#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE + bt_mesh_adv_inst_deinit(BLE_MESH_BLE_ADV_INST); + bt_mesh_adv_inst_type_rem(BLE_MESH_BLE_ADV_INST, BLE_MESH_ADV_BLE); +#else +#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV + bt_mesh_adv_inst_type_rem(BLE_MESH_ADV_INST, BLE_MESH_ADV_BLE); +#endif +#endif /* CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE */ +#endif /* CONFIG_BLE_MESH_USE_BLE_50 */ +} +#endif /* CONFIG_BLE_MESH_DEINIT */ diff --git a/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c b/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c index 2f3b3d351b86..6ae6b0fc23db 100644 --- a/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c +++ b/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c @@ -1010,7 +1010,7 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) svc->attrs[i].handle = char_handle - 1; svc->attrs[i + 1].handle = char_handle; BT_DBG("Add characteristic, uuid 0x%04x, handle %d, perm %d, properties %d", - BLE_MESH_UUID_16(gatts_chrc->uuid)->val, char_handle, svc->attrs[i + 1].perm, gatts_chrc->properties); + BLE_MESH_UUID_16(gatts_chrc->uuid)->val, char_handle, svc->attrs[i + 1].perm, gatts_chrc->properties); break; } case BLE_MESH_UUID_GATT_CEP_VAL: @@ -1198,7 +1198,7 @@ uint16_t bt_mesh_gattc_get_service_uuid(struct bt_mesh_conn *conn) int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, uint16_t service_uuid) { - tBTA_BLE_CONN_PARAMS conn_1m_param = {0}; + tBTA_BLE_CONN_PARAMS conn_1m_param = {0}; uint8_t zero[6] = {0}; int i; diff --git a/components/bt/esp_ble_mesh/core/cfg_cli.c b/components/bt/esp_ble_mesh/core/cfg_cli.c index 3aedd3644b8a..c0968428d2df 100644 --- a/components/bt/esp_ble_mesh/core/cfg_cli.c +++ b/components/bt/esp_ble_mesh/core/cfg_cli.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -110,6 +110,8 @@ static void cfg_client_recv_status(struct bt_mesh_model *model, struct net_buf_simple buf = {0}; uint8_t evt_type = 0xFF; + BT_DBG("CfgClientRecvStatus"); + if (!model || !ctx) { BT_ERR("%s, Invalid parameter", __func__); return; @@ -125,6 +127,8 @@ static void cfg_client_recv_status(struct bt_mesh_model *model, if (!node) { BT_DBG("Unexpected Config Status 0x%04x", ctx->recv_op); } else { + BT_DBG("OpCode 0x%08lx RecvOp 0x%08lx", node->opcode, ctx->recv_op); + switch (node->opcode) { case OP_BEACON_GET: case OP_COMP_DATA_GET: @@ -230,9 +234,10 @@ static void comp_data_status(struct bt_mesh_model *model, { struct bt_mesh_cfg_comp_data_status status = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("CompDataStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status.page = net_buf_simple_pull_u8(buf); status.comp_data = bt_mesh_alloc_buf(buf->len); @@ -252,9 +257,10 @@ static void state_status_u8(struct bt_mesh_model *model, { uint8_t status = 0U; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("StateStatusU8"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status = net_buf_simple_pull_u8(buf); @@ -265,6 +271,8 @@ static void beacon_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { + BT_DBG("BeaconStatus"); + state_status_u8(model, ctx, buf); } @@ -272,6 +280,8 @@ static void ttl_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { + BT_DBG("TTLStatus"); + state_status_u8(model, ctx, buf); } @@ -279,6 +289,8 @@ static void friend_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { + BT_DBG("FrndStatus"); + state_status_u8(model, ctx, buf); } @@ -286,6 +298,8 @@ static void gatt_proxy_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { + BT_DBG("GattProxyStatus"); + state_status_u8(model, ctx, buf); } @@ -295,9 +309,10 @@ static void relay_status(struct bt_mesh_model *model, { struct bt_mesh_cfg_relay_status status = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("RelayStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status.relay = net_buf_simple_pull_u8(buf); status.retransmit = net_buf_simple_pull_u8(buf); @@ -311,9 +326,10 @@ static void net_key_status(struct bt_mesh_model *model, { struct bt_mesh_cfg_netkey_status status = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("NetKeyStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status.status = net_buf_simple_pull_u8(buf); status.net_idx = net_buf_simple_pull_le16(buf) & 0xfff; @@ -327,9 +343,10 @@ static void app_key_status(struct bt_mesh_model *model, { struct bt_mesh_cfg_appkey_status status = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("AppKeyStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status.status = net_buf_simple_pull_u8(buf); key_idx_unpack(buf, &status.net_idx, &status.app_idx); @@ -343,9 +360,10 @@ static void mod_app_status(struct bt_mesh_model *model, { struct bt_mesh_cfg_mod_app_status status = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("ModAppStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status.status = net_buf_simple_pull_u8(buf); status.elem_addr = net_buf_simple_pull_le16(buf); @@ -366,9 +384,10 @@ static void mod_pub_status(struct bt_mesh_model *model, { struct bt_mesh_cfg_mod_pub_status status = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("ModPubStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status.status = net_buf_simple_pull_u8(buf); status.elem_addr = net_buf_simple_pull_le16(buf); @@ -395,9 +414,10 @@ static void mod_sub_status(struct bt_mesh_model *model, { struct bt_mesh_cfg_mod_sub_status status = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("ModSubStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status.status = net_buf_simple_pull_u8(buf); status.elem_addr = net_buf_simple_pull_le16(buf); @@ -418,9 +438,10 @@ static void hb_sub_status(struct bt_mesh_model *model, { struct bt_mesh_cfg_hb_sub_status status = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("HbSubStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status.status = net_buf_simple_pull_u8(buf); status.src = net_buf_simple_pull_le16(buf); @@ -439,9 +460,10 @@ static void hb_pub_status(struct bt_mesh_model *model, { struct bt_mesh_cfg_hb_pub_status status = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("HbPubStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status.status = net_buf_simple_pull_u8(buf); status.dst = net_buf_simple_pull_le16(buf); @@ -458,9 +480,10 @@ static void node_reset_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("NodeResetStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); cfg_client_recv_status(model, ctx, NULL, 0); } @@ -471,9 +494,10 @@ static void mod_sub_list(struct bt_mesh_model *model, { struct bt_mesh_cfg_mod_sub_list list = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("ModSubList"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); list.status = net_buf_simple_pull_u8(buf); list.elem_addr = net_buf_simple_pull_le16(buf); @@ -500,9 +524,10 @@ static void net_key_list(struct bt_mesh_model *model, { struct bt_mesh_cfg_net_key_list list = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("NetKeyList"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); list.net_idx = bt_mesh_alloc_buf(buf->len); if (!list.net_idx) { @@ -520,9 +545,10 @@ static void app_key_list(struct bt_mesh_model *model, { struct bt_mesh_cfg_app_key_list list = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("AppKeyList"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); list.status = net_buf_simple_pull_u8(buf); list.net_idx = net_buf_simple_pull_le16(buf); @@ -542,9 +568,10 @@ static void node_id_status(struct bt_mesh_model *model, { struct bt_mesh_cfg_node_id_status status = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("NodeIDStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status.status = net_buf_simple_pull_u8(buf); status.net_idx = net_buf_simple_pull_le16(buf); @@ -559,9 +586,10 @@ static void mod_app_list(struct bt_mesh_model *model, { struct bt_mesh_cfg_mod_app_list list = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("ModAppList"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); list.status = net_buf_simple_pull_u8(buf); list.elem_addr = net_buf_simple_pull_le16(buf); @@ -588,9 +616,10 @@ static void kr_phase_status(struct bt_mesh_model *model, { struct bt_mesh_cfg_key_refresh_status status = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("KrPhaseStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status.status = net_buf_simple_pull_u8(buf); status.net_idx = net_buf_simple_pull_le16(buf); @@ -605,9 +634,10 @@ static void lpn_pollto_status(struct bt_mesh_model *model, { struct bt_mesh_cfg_lpn_pollto_status status = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("LPNPollToStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status.lpn_addr = net_buf_simple_pull_le16(buf); status.timeout = net_buf_simple_pull_u8(buf); @@ -621,6 +651,8 @@ static void net_trans_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { + BT_DBG("NetTransStatus"); + state_status_u8(model, ctx, buf); } @@ -656,6 +688,9 @@ static int send_msg_with_none(bt_mesh_client_common_param_t *param, uint32_t op) { BLE_MESH_MODEL_BUF_DEFINE(msg, op, 0); + BT_DBG("SendMsgWithNone"); + BT_DBG("Dst 0x%04x Op 0x%08lx", param->ctx.addr, op); + bt_mesh_model_msg_init(&msg, op); return bt_mesh_client_send_msg(param, &msg, true, timeout_handler); @@ -665,6 +700,9 @@ static int send_msg_with_u8(bt_mesh_client_common_param_t *param, uint32_t op, u { BLE_MESH_MODEL_BUF_DEFINE(msg, op, 1); + BT_DBG("SendMsgWithU8"); + BT_DBG("Dst 0x%04x Op 0x%08lx Val 0x%02x", param->ctx.addr, op, val); + bt_mesh_model_msg_init(&msg, op); net_buf_simple_add_u8(&msg, val); @@ -675,6 +713,9 @@ static int send_msg_with_le16(bt_mesh_client_common_param_t *param, uint32_t op, { BLE_MESH_MODEL_BUF_DEFINE(msg, op, 2); + BT_DBG("SendMsgWithLE16"); + BT_DBG("Dst 0x%04x Op 0x%08lx Val 0x%04x", param->ctx.addr, op, val); + bt_mesh_model_msg_init(&msg, op); net_buf_simple_add_le16(&msg, val); @@ -683,55 +724,76 @@ static int send_msg_with_le16(bt_mesh_client_common_param_t *param, uint32_t op, int bt_mesh_cfg_comp_data_get(bt_mesh_client_common_param_t *param, uint8_t page) { + BT_DBG("CompDataGet, Page %u", page); + return send_msg_with_u8(param, OP_COMP_DATA_GET, page); } int bt_mesh_cfg_beacon_get(bt_mesh_client_common_param_t *param) { + BT_DBG("BeaconGet"); + return send_msg_with_none(param, OP_BEACON_GET); } int bt_mesh_cfg_beacon_set(bt_mesh_client_common_param_t *param, uint8_t val) { + BT_DBG("BeaconSet, Val 0x%02x", val); + if (val > 0x01) { BT_ERR("Invalid beacon state 0x%02x", val); return -EINVAL; } + return send_msg_with_u8(param, OP_BEACON_SET, val); } int bt_mesh_cfg_ttl_get(bt_mesh_client_common_param_t *param) { + BT_DBG("TTLGet"); + return send_msg_with_none(param, OP_DEFAULT_TTL_GET); } int bt_mesh_cfg_ttl_set(bt_mesh_client_common_param_t *param, uint8_t val) { + BT_DBG("TTLSet, Val 0x%02x", val); + return send_msg_with_u8(param, OP_DEFAULT_TTL_SET, val); } int bt_mesh_cfg_friend_get(bt_mesh_client_common_param_t *param) { + BT_DBG("FrndGet"); + return send_msg_with_none(param, OP_FRIEND_GET); } int bt_mesh_cfg_friend_set(bt_mesh_client_common_param_t *param, uint8_t val) { + BT_DBG("FrndSet, Val 0x%02x", val); + return send_msg_with_u8(param, OP_FRIEND_SET, val); } int bt_mesh_cfg_gatt_proxy_get(bt_mesh_client_common_param_t *param) { + BT_DBG("GattProxyGet"); + return send_msg_with_none(param, OP_GATT_PROXY_GET); } int bt_mesh_cfg_gatt_proxy_set(bt_mesh_client_common_param_t *param, uint8_t val) { + BT_DBG("GattProxySet, Val 0x%02x", val); + return send_msg_with_u8(param, OP_GATT_PROXY_SET, val); } int bt_mesh_cfg_relay_get(bt_mesh_client_common_param_t *param) { + BT_DBG("RelayGet"); + return send_msg_with_none(param, OP_RELAY_GET); } @@ -740,6 +802,8 @@ int bt_mesh_cfg_relay_set(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_SET, 2); + BT_DBG("RelaySet, Relay 0x%02x Retransmit 0x%02x", relay, retransmit); + bt_mesh_model_msg_init(&msg, OP_RELAY_SET); net_buf_simple_add_u8(&msg, relay); net_buf_simple_add_u8(&msg, retransmit); @@ -752,11 +816,15 @@ int bt_mesh_cfg_net_key_add(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_ADD, 18); + BT_DBG("NetKeyAdd"); + if (!net_key) { BT_ERR("Invalid NetKey"); return -EINVAL; } + BT_DBG("NetIdx 0x%04x NetKey %s", net_idx, bt_hex(net_key, 16)); + bt_mesh_model_msg_init(&msg, OP_NET_KEY_ADD); net_buf_simple_add_le16(&msg, net_idx); net_buf_simple_add_mem(&msg, net_key, 16); @@ -770,11 +838,16 @@ int bt_mesh_cfg_app_key_add(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_ADD, 19); + BT_DBG("AppKeyAdd"); + if (!app_key) { BT_ERR("Invalid AppKey"); return -EINVAL; } + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x AppKey %s", + net_idx, app_idx, bt_hex(app_key, 16)); + bt_mesh_model_msg_init(&msg, OP_APP_KEY_ADD); key_idx_pack(&msg, net_idx, app_idx); net_buf_simple_add_mem(&msg, app_key, 16); @@ -788,6 +861,10 @@ int bt_mesh_cfg_mod_app_bind(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_BIND, 8); + BT_DBG("ModAppBind"); + BT_DBG("ElemAddr 0x%04x AppIdx 0x%04x ModID 0x%04x CID 0x%04x", + elem_addr, app_idx, mod_id, cid); + bt_mesh_model_msg_init(&msg, OP_MOD_APP_BIND); net_buf_simple_add_le16(&msg, elem_addr); net_buf_simple_add_le16(&msg, app_idx); @@ -805,6 +882,10 @@ static int mod_sub(bt_mesh_client_common_param_t *param, uint32_t op, { BLE_MESH_MODEL_BUF_DEFINE(msg, op, 8); + BT_DBG("ModSub"); + BT_DBG("ElemAddr 0x%04x SubAddr 0x%04x ModID 0x%04x CID 0x%04x", + elem_addr, sub_addr, mod_id, cid); + bt_mesh_model_msg_init(&msg, op); net_buf_simple_add_le16(&msg, elem_addr); net_buf_simple_add_le16(&msg, sub_addr); @@ -820,6 +901,8 @@ int bt_mesh_cfg_mod_sub_add(bt_mesh_client_common_param_t *param, uint16_t elem_addr, uint16_t sub_addr, uint16_t mod_id, uint16_t cid) { + BT_DBG("ModSubAdd"); + return mod_sub(param, OP_MOD_SUB_ADD, elem_addr, sub_addr, mod_id, cid); } @@ -827,6 +910,8 @@ int bt_mesh_cfg_mod_sub_del(bt_mesh_client_common_param_t *param, uint16_t elem_addr, uint16_t sub_addr, uint16_t mod_id, uint16_t cid) { + BT_DBG("ModSubDel"); + return mod_sub(param, OP_MOD_SUB_DEL, elem_addr, sub_addr, mod_id, cid); } @@ -834,6 +919,8 @@ int bt_mesh_cfg_mod_sub_overwrite(bt_mesh_client_common_param_t *param, uint16_t elem_addr, uint16_t sub_addr, uint16_t mod_id, uint16_t cid) { + BT_DBG("ModSubOverwrite"); + return mod_sub(param, OP_MOD_SUB_OVERWRITE, elem_addr, sub_addr, mod_id, cid); } @@ -843,13 +930,15 @@ static int mod_sub_va(bt_mesh_client_common_param_t *param, uint32_t op, { BLE_MESH_MODEL_BUF_DEFINE(msg, op, 22); + BT_DBG("ModSubVa"); + if (!label) { BT_ERR("Invalid label uuid"); return -EINVAL; } - BT_DBG("elem_addr 0x%04x label %s", elem_addr, bt_hex(label, 16)); - BT_DBG("mod_id 0x%04x cid 0x%04x", mod_id, cid); + BT_DBG("ElemAddr 0x%04x ModID 0x%04x CID 0x%04x", elem_addr, mod_id, cid); + BT_DBG("Label %s", bt_hex(label, 16)); bt_mesh_model_msg_init(&msg, op); net_buf_simple_add_le16(&msg, elem_addr); @@ -866,6 +955,8 @@ int bt_mesh_cfg_mod_sub_va_add(bt_mesh_client_common_param_t *param, uint16_t elem_addr, const uint8_t label[16], uint16_t mod_id, uint16_t cid) { + BT_DBG("ModSubVaAdd"); + return mod_sub_va(param, OP_MOD_SUB_VA_ADD, elem_addr, label, mod_id, cid); } @@ -873,6 +964,8 @@ int bt_mesh_cfg_mod_sub_va_del(bt_mesh_client_common_param_t *param, uint16_t elem_addr, const uint8_t label[16], uint16_t mod_id, uint16_t cid) { + BT_DBG("ModSubVaDel"); + return mod_sub_va(param, OP_MOD_SUB_VA_DEL, elem_addr, label, mod_id, cid); } @@ -880,6 +973,8 @@ int bt_mesh_cfg_mod_sub_va_overwrite(bt_mesh_client_common_param_t *param, uint16_t elem_addr, const uint8_t label[16], uint16_t mod_id, uint16_t cid) { + BT_DBG("ModSubVaOverwrite"); + return mod_sub_va(param, OP_MOD_SUB_VA_OVERWRITE, elem_addr, label, mod_id, cid); } @@ -888,6 +983,9 @@ int bt_mesh_cfg_mod_pub_get(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_GET, 6); + BT_DBG("ModPubGet"); + BT_DBG("ElemAddr 0x%04x ModID 0x%04x CID 0x%04x", elem_addr, mod_id, cid); + bt_mesh_model_msg_init(&msg, OP_MOD_PUB_GET); net_buf_simple_add_le16(&msg, elem_addr); if (cid != BLE_MESH_CID_NVAL) { @@ -904,11 +1002,17 @@ int bt_mesh_cfg_mod_pub_set(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_SET, 13); + BT_DBG("ModPubSet"); + BT_DBG("ElemAddr 0x%04x ModID 0x%04x CID 0x%04x", elem_addr, mod_id, cid); + if (!pub) { BT_ERR("Invalid model pub set"); return -EINVAL; } + BT_DBG("Addr 0x%04x AppIdx 0x%04x TTL %u Period 0x%02x Transmit 0x%02x", + pub->addr, pub->app_idx, pub->ttl, pub->period, pub->transmit); + bt_mesh_model_msg_init(&msg, OP_MOD_PUB_SET); net_buf_simple_add_le16(&msg, elem_addr); net_buf_simple_add_le16(&msg, pub->addr); @@ -929,11 +1033,15 @@ int bt_mesh_cfg_hb_sub_set(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_SET, 5); + BT_DBG("HbSubSet"); + if (!sub) { BT_ERR("Invalid heartbeat sub set"); return -EINVAL; } + BT_DBG("Src 0x%04x Dst 0x%04x Period 0x%02x", sub->src, sub->dst, sub->period); + bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_SUB_SET); net_buf_simple_add_le16(&msg, sub->src); net_buf_simple_add_le16(&msg, sub->dst); @@ -944,6 +1052,8 @@ int bt_mesh_cfg_hb_sub_set(bt_mesh_client_common_param_t *param, int bt_mesh_cfg_hb_sub_get(bt_mesh_client_common_param_t *param) { + BT_DBG("HbSubGet"); + return send_msg_with_none(param, OP_HEARTBEAT_SUB_GET); } @@ -952,11 +1062,16 @@ int bt_mesh_cfg_hb_pub_set(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_SET, 9); + BT_DBG("HbPubSet"); + if (!pub) { BT_ERR("Invalid heartbeat pub set"); return -EINVAL; } + BT_DBG("Dst 0x%04x Count 0x%02x Period 0x%02x TTL %u Feat 0x%04x NetIdx 0x%04x", + pub->dst, pub->count, pub->period, pub->ttl, pub->feat, pub->net_idx); + bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_PUB_SET); net_buf_simple_add_le16(&msg, pub->dst); net_buf_simple_add_u8(&msg, pub->count); @@ -970,11 +1085,15 @@ int bt_mesh_cfg_hb_pub_set(bt_mesh_client_common_param_t *param, int bt_mesh_cfg_hb_pub_get(bt_mesh_client_common_param_t *param) { + BT_DBG("HbPubGet"); + return send_msg_with_none(param, OP_HEARTBEAT_PUB_GET); } int bt_mesh_cfg_node_reset(bt_mesh_client_common_param_t *param) { + BT_DBG("NodeReset"); + return send_msg_with_none(param, OP_NODE_RESET); } @@ -985,11 +1104,18 @@ int bt_mesh_cfg_mod_pub_va_set(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_VA_SET, 27); + BT_DBG("ModPubVaSet"); + BT_DBG("ElemAddr 0x%04x ModID 0x%04x CID 0x%04x", elem_addr, mod_id, cid); + if (!label || !pub) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; } + BT_DBG("Label %s", bt_hex(label, 16)); + BT_DBG("AppIdx 0x%04x TTL %u Period 0x%02x Transmit 0x%02x", + pub->app_idx, pub->ttl, pub->period, pub->transmit); + bt_mesh_model_msg_init(&msg, OP_MOD_PUB_VA_SET); net_buf_simple_add_le16(&msg, elem_addr); net_buf_simple_add_mem(&msg, label, 16); @@ -1010,6 +1136,9 @@ int bt_mesh_cfg_mod_sub_del_all(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_DEL_ALL, 6); + BT_DBG("ModSubDelAll"); + BT_DBG("ElemAddr 0x%04x ModID 0x%04x CID 0x%04x", elem_addr, mod_id, cid); + bt_mesh_model_msg_init(&msg, OP_MOD_SUB_DEL_ALL); net_buf_simple_add_le16(&msg, elem_addr); if (cid != BLE_MESH_CID_NVAL) { @@ -1038,12 +1167,18 @@ static int mod_sub_get(bt_mesh_client_common_param_t *param, uint32_t op, int bt_mesh_cfg_mod_sub_get(bt_mesh_client_common_param_t *param, uint16_t elem_addr, uint16_t mod_id) { + BT_DBG("ModSubGet"); + BT_DBG("ElemAddr 0x%04x ModID 0x%04x", elem_addr, mod_id); + return mod_sub_get(param, OP_MOD_SUB_GET, elem_addr, mod_id, BLE_MESH_CID_NVAL); } int bt_mesh_cfg_mod_sub_get_vnd(bt_mesh_client_common_param_t *param, uint16_t elem_addr, uint16_t mod_id, uint16_t cid) { + BT_DBG("ModSubGetVnd"); + BT_DBG("ElemAddr 0x%04x ModID 0x%04x CID 0x%04x", elem_addr, mod_id, cid); + if (cid == BLE_MESH_CID_NVAL) { BT_ERR("Invalid company id"); return -EINVAL; @@ -1056,11 +1191,15 @@ int bt_mesh_cfg_net_key_update(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_UPDATE, 18); + BT_DBG("NetKeyUpdate"); + if (!net_key) { BT_ERR("Invalid NetKey"); return -EINVAL; } + BT_DBG("NetIdx 0x%04x NetKey %s", net_idx, bt_hex(net_key, 16)); + bt_mesh_model_msg_init(&msg, OP_NET_KEY_UPDATE); net_buf_simple_add_le16(&msg, net_idx); net_buf_simple_add_mem(&msg, net_key, 16); @@ -1070,11 +1209,15 @@ int bt_mesh_cfg_net_key_update(bt_mesh_client_common_param_t *param, int bt_mesh_cfg_net_key_delete(bt_mesh_client_common_param_t *param, uint16_t net_idx) { + BT_DBG("NetKeyDelete, NetIdx 0x%04x", net_idx); + return send_msg_with_le16(param, OP_NET_KEY_DEL, net_idx); } int bt_mesh_cfg_net_key_get(bt_mesh_client_common_param_t *param) { + BT_DBG("NetKeyGet"); + return send_msg_with_none(param, OP_NET_KEY_GET); } @@ -1084,11 +1227,16 @@ int bt_mesh_cfg_app_key_update(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_UPDATE, 19); + BT_DBG("AppKeyUpdate"); + if (!app_key) { BT_ERR("Invalid AppKey"); return -EINVAL; } + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x AppKey %s", + net_idx, app_idx, bt_hex(app_key, 16)); + bt_mesh_model_msg_init(&msg, OP_APP_KEY_UPDATE); key_idx_pack(&msg, net_idx, app_idx); net_buf_simple_add_mem(&msg, app_key, 16); @@ -1101,6 +1249,8 @@ int bt_mesh_cfg_app_key_delete(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_DEL, 3); + BT_DBG("AppKeyDelete, NetIdx 0x%04x AppIdx 0x%04x", net_idx, app_idx); + bt_mesh_model_msg_init(&msg, OP_APP_KEY_DEL); key_idx_pack(&msg, net_idx, app_idx); @@ -1109,11 +1259,15 @@ int bt_mesh_cfg_app_key_delete(bt_mesh_client_common_param_t *param, int bt_mesh_cfg_app_key_get(bt_mesh_client_common_param_t *param, uint16_t net_idx) { + BT_DBG("AppKeyGet, NetIdx 0x%04x", net_idx); + return send_msg_with_le16(param, OP_APP_KEY_GET, net_idx); } int bt_mesh_cfg_node_identity_get(bt_mesh_client_common_param_t *param, uint16_t net_idx) { + BT_DBG("NodeIdentityGet, NetIdx 0x%04x", net_idx); + return send_msg_with_le16(param, OP_NODE_IDENTITY_GET, net_idx); } @@ -1122,6 +1276,8 @@ int bt_mesh_cfg_node_identity_set(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_SET, 3); + BT_DBG("NodeIdentitySet, NetIdx 0x%04x Identity 0x%02x", net_idx, identity); + if (identity > 0x02) { BT_ERR("Invalid node identity 0x%02x", identity); return -EINVAL; @@ -1140,6 +1296,10 @@ int bt_mesh_cfg_mod_app_unbind(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_UNBIND, 8); + BT_DBG("ModAppUnbind"); + BT_DBG("ElemAddr 0x%04x AppIdx 0x%04x ModID 0x%04x CID 0x%04x", + elem_addr, app_idx, mod_id, cid); + bt_mesh_model_msg_init(&msg, OP_MOD_APP_UNBIND); net_buf_simple_add_le16(&msg, elem_addr); net_buf_simple_add_le16(&msg, app_idx); @@ -1169,21 +1329,29 @@ static int mod_app_get(bt_mesh_client_common_param_t *param, uint32_t op, int bt_mesh_cfg_mod_app_get(bt_mesh_client_common_param_t *param, uint16_t elem_addr, uint16_t mod_id) { + BT_DBG("ModAppGet, ElemAddr 0x%04x ModID 0x%04x", elem_addr, mod_id); + return mod_app_get(param, OP_SIG_MOD_APP_GET, elem_addr, mod_id, BLE_MESH_CID_NVAL); } int bt_mesh_cfg_mod_app_get_vnd(bt_mesh_client_common_param_t *param, uint16_t elem_addr, uint16_t mod_id, uint16_t cid) { + BT_DBG("ModAppGetVnd"); + BT_DBG("ElemAddr 0x%04x ModID 0x%04x CID 0x%04x", elem_addr, mod_id, cid); + if (cid == BLE_MESH_CID_NVAL) { BT_ERR("Invalid company id"); return -EINVAL; } + return mod_app_get(param, OP_VND_MOD_APP_GET, elem_addr, mod_id, cid); } int bt_mesh_cfg_kr_phase_get(bt_mesh_client_common_param_t *param, uint16_t net_idx) { + BT_DBG("KrPhaseGet, NetIdx 0x%04x", net_idx); + return send_msg_with_le16(param, OP_KRP_GET, net_idx); } @@ -1192,6 +1360,8 @@ int bt_mesh_cfg_kr_phase_set(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_KRP_SET, 3); + BT_DBG("KrPhaseSet, NetIdx 0x%04x Transition 0x%02x", net_idx, transition); + if (transition > 0x03) { BT_ERR("Invalid kr phase transition 0x%02x", transition); return -EINVAL; @@ -1206,16 +1376,22 @@ int bt_mesh_cfg_kr_phase_set(bt_mesh_client_common_param_t *param, int bt_mesh_cfg_lpn_timeout_get(bt_mesh_client_common_param_t *param, uint16_t lpn_addr) { + BT_DBG("LPNTimeoutGet, LPN 0x%04x", lpn_addr); + return send_msg_with_le16(param, OP_LPN_TIMEOUT_GET, lpn_addr); } int bt_mesh_cfg_net_transmit_get(bt_mesh_client_common_param_t *param) { + BT_DBG("NetTransmitGet"); + return send_msg_with_none(param, OP_NET_TRANSMIT_GET); } int bt_mesh_cfg_net_transmit_set(bt_mesh_client_common_param_t *param, uint8_t transmit) { + BT_DBG("NetTransmitSet, Transmit 0x%02x", transmit); + return send_msg_with_u8(param, OP_NET_TRANSMIT_SET, transmit); } @@ -1224,6 +1400,8 @@ static int cfg_cli_init(struct bt_mesh_model *model) config_internal_data_t *internal = NULL; bt_mesh_config_client_t *client = NULL; + BT_DBG("CfgCliInit"); + if (!model) { BT_ERR("Invalid Configuration Client model"); return -EINVAL; @@ -1271,6 +1449,8 @@ static int cfg_cli_deinit(struct bt_mesh_model *model) { bt_mesh_config_client_t *client = NULL; + BT_DBG("CfgCliDeinit"); + if (!model) { BT_ERR("Invalid Configuration Client model"); return -EINVAL; diff --git a/components/bt/esp_ble_mesh/core/cfg_srv.c b/components/bt/esp_ble_mesh/core/cfg_srv.c index fe605939a549..d8be5f042465 100644 --- a/components/bt/esp_ble_mesh/core/cfg_srv.c +++ b/components/bt/esp_ble_mesh/core/cfg_srv.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -32,7 +32,7 @@ #if CONFIG_BLE_MESH_V11_SUPPORT #include "mesh_v1.1/utils.h" -#endif +#endif /* CONFIG_BLE_MESH_V11_SUPPORT */ #define DEFAULT_TTL 7 @@ -66,6 +66,9 @@ static uint8_t bt_mesh_comp_page_check(uint8_t page, bool largest) static inline uint16_t get_comp_elem_size(struct bt_mesh_elem *elem) { + BT_DBG("GetCompElemSize, ModelCount %u VndModelCount %u", + elem->model_count, elem->vnd_model_count); + return (4 + elem->model_count * 2 + elem->vnd_model_count * 4); } @@ -77,6 +80,8 @@ static uint16_t get_comp_data_size(const struct bt_mesh_comp *comp) size += get_comp_elem_size(&(comp->elem[i])); } + BT_DBG("GetCompDataSize, Size %u", size); + return size; } @@ -119,6 +124,7 @@ static void get_comp_data(struct net_buf_simple *buf, */ if (full_element && net_buf_simple_tailroom(buf) < get_comp_elem_size(elem)) { + BT_WARN("NoRoomForElementModelList"); return; } @@ -137,6 +143,8 @@ static void get_comp_data(struct net_buf_simple *buf, net_buf_simple_add_le16(buf, model->vnd.id); } } + + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); } static int fetch_comp_data(struct net_buf_simple *buf, @@ -155,7 +163,7 @@ static int fetch_comp_data(struct net_buf_simple *buf, if (net_buf_simple_tailroom(buf) < 10 || size - offset > net_buf_simple_tailroom(buf)) { BT_ERR("Too small buffer for comp data %d, %d, expected %d", - page, buf->size, size - offset); + page, buf->size, size - offset); return -EINVAL; } @@ -183,6 +191,9 @@ static int bt_mesh_get_comp_data(struct net_buf_simple *buf, uint8_t page, uint16_t offset, bool full_element) { + BT_DBG("FetchCompData, Page %u Offset %u FullElement %u", + page, offset, full_element); + if (page == 0) { return fetch_comp_data(buf, comp_0, page, offset, full_element); } @@ -199,9 +210,10 @@ static void comp_data_get(struct bt_mesh_model *model, struct net_buf_simple *sdu = NULL; uint8_t page = 0U; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("CompDataGet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); /* TODO: * @@ -268,14 +280,17 @@ static void comp_data_get(struct bt_mesh_model *model, } static struct bt_mesh_model *get_model(struct bt_mesh_elem *elem, - struct net_buf_simple *buf, bool *vnd) + struct net_buf_simple *buf, + bool *vnd) { uint16_t company = 0U, id = 0U; + BT_DBG("GetModel, Len %u", buf->len); + if (buf->len < 4) { id = net_buf_simple_pull_le16(buf); - BT_DBG("ID 0x%04x addr 0x%04x", id, elem->addr); + BT_DBG("ID 0x%04x ElemAddr 0x%04x", id, elem->addr); *vnd = false; @@ -285,42 +300,49 @@ static struct bt_mesh_model *get_model(struct bt_mesh_elem *elem, company = net_buf_simple_pull_le16(buf); id = net_buf_simple_pull_le16(buf); - BT_DBG("Company 0x%04x ID 0x%04x addr 0x%04x", company, id, - elem->addr); + BT_DBG("CID 0x%04x ID 0x%04x Addr 0x%04x", company, id, elem->addr); *vnd = true; return bt_mesh_model_find_vnd(elem, company, id); } -static bool mod_pub_app_key_bound(struct bt_mesh_model *model, - uint16_t app_idx) +static bool mod_pub_app_key_bound(struct bt_mesh_model *model, uint16_t app_idx) { int i; + BT_DBG("ModPubAppKeyBound, AppIdx 0x%04x", app_idx); + for (i = 0; i < ARRAY_SIZE(model->keys); i++) { if (model->keys[i] == app_idx) { return true; } } - BT_ERR("AppKey(0x%02x) not bound to this model", app_idx); + BT_ERR("AppKeyNotBound, AppIdx 0x%04x", app_idx); return false; } static uint8_t _mod_pub_set(struct bt_mesh_model *model, uint16_t pub_addr, - uint16_t app_idx, uint8_t cred_flag, uint8_t ttl, uint8_t period, - uint8_t retransmit, bool store) + uint16_t app_idx, uint8_t cred_flag, uint8_t ttl, + uint8_t period, uint8_t retransmit, bool store) { + BT_DBG("_ModPubSet"); + BT_DBG("Addr 0x%04x AppIdx 0x%04x TTL %u Period 0x%02x Retransmit 0x%02x Store %u", + pub_addr, app_idx, ttl, period, retransmit, store); + if (!model->pub) { + BT_DBG("StatusNvalPubParam"); return STATUS_NVAL_PUB_PARAM; } if (!IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) && cred_flag) { + BT_DBG("StatusFeatNotSupp"); return STATUS_FEAT_NOT_SUPP; } if (!model->pub->update && period) { + BT_DBG("StatusNvalPubParam"); return STATUS_NVAL_PUB_PARAM; } @@ -353,6 +375,7 @@ static uint8_t _mod_pub_set(struct bt_mesh_model *model, uint16_t pub_addr, */ if (!bt_mesh_app_key_get(app_idx) || !mod_pub_app_key_bound(model, app_idx)) { + BT_DBG("StatusInvalidAppKey"); return STATUS_INVALID_APPKEY; } @@ -367,7 +390,8 @@ static uint8_t _mod_pub_set(struct bt_mesh_model *model, uint16_t pub_addr, int32_t period_ms; period_ms = bt_mesh_model_pub_period_get(model); - BT_DBG("period %u ms", period_ms); + + BT_DBG("PubPeriod %ld", period_ms); if (period_ms) { k_delayed_work_submit(&model->pub->timer, period_ms); @@ -387,9 +411,10 @@ static uint8_t mod_bind(struct bt_mesh_model *model, uint16_t key_idx) { int i; - BT_DBG("model %p key_idx 0x%03x", model, key_idx); + BT_DBG("ModBind, KeyIdx 0x%04x", key_idx); if (!bt_mesh_app_key_get(key_idx)) { + BT_DBG("StatusInvalidAppKey"); return STATUS_INVALID_APPKEY; } @@ -412,6 +437,7 @@ static uint8_t mod_bind(struct bt_mesh_model *model, uint16_t key_idx) } } + BT_DBG("StatusInsuffResources"); return STATUS_INSUFF_RESOURCES; } @@ -419,9 +445,10 @@ static uint8_t mod_unbind(struct bt_mesh_model *model, uint16_t key_idx, bool st { int i; - BT_DBG("model %p key_idx 0x%03x store %u", model, key_idx, store); + BT_DBG("ModUnbind, KeyIdx 0x%04x Store %u", key_idx, store); if (!bt_mesh_app_key_get(key_idx)) { + BT_DBG("StatusInvalidAppKey"); return STATUS_INVALID_APPKEY; } @@ -449,6 +476,8 @@ struct bt_mesh_app_key *bt_mesh_app_key_alloc(uint16_t app_idx) { int i; + BT_DBG("AppKeyAlloc, AppIdx 0x%04x", app_idx); + for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { struct bt_mesh_app_key *key = &bt_mesh.app_keys[i]; @@ -457,31 +486,36 @@ struct bt_mesh_app_key *bt_mesh_app_key_alloc(uint16_t app_idx) } } + BT_ERR("AppKeyFull"); return NULL; } -static uint8_t app_key_set(uint16_t net_idx, uint16_t app_idx, const uint8_t val[16], - bool update) +static uint8_t app_key_set(uint16_t net_idx, uint16_t app_idx, + const uint8_t val[16], bool update) { struct bt_mesh_app_keys *keys = NULL; struct bt_mesh_app_key *key = NULL; struct bt_mesh_subnet *sub = NULL; - BT_DBG("net_idx 0x%04x app_idx %04x update %u val %s", + BT_DBG("AppKeySet"); + BT_DBG("NetIdx 0x%04x AppIdx %04x Update %u Val %s", net_idx, app_idx, update, bt_hex(val, 16)); sub = bt_mesh_subnet_get(net_idx); if (!sub) { + BT_DBG("StatusInvalidNetKey"); return STATUS_INVALID_NETKEY; } key = bt_mesh_app_key_get(app_idx); if (update) { if (!key) { + BT_DBG("StatusInvalidAppKey"); return STATUS_INVALID_APPKEY; } if (key->net_idx != net_idx) { + BT_DBG("StatusInvalidBinding"); return STATUS_INVALID_BINDING; } @@ -493,11 +527,13 @@ static uint8_t app_key_set(uint16_t net_idx, uint16_t app_idx, const uint8_t val * the AppKey value is different. */ if (sub->kr_phase != BLE_MESH_KR_PHASE_1) { + BT_DBG("StatusCannotUpdate"); return STATUS_CANNOT_UPDATE; } if (key->updated) { if (memcmp(keys->val, val, 16)) { + BT_DBG("StatusCannotUpdate"); return STATUS_CANNOT_UPDATE; } @@ -513,14 +549,17 @@ static uint8_t app_key_set(uint16_t net_idx, uint16_t app_idx, const uint8_t val } if (key->net_idx == net_idx) { + BT_DBG("StatusIdxAlreadyStored"); return STATUS_IDX_ALREADY_STORED; } + BT_DBG("StatusInvalidNetKey"); return STATUS_INVALID_NETKEY; } key = bt_mesh_app_key_alloc(app_idx); if (!key) { + BT_DBG("StatusInsuffResources"); return STATUS_INSUFF_RESOURCES; } @@ -532,17 +571,15 @@ static uint8_t app_key_set(uint16_t net_idx, uint16_t app_idx, const uint8_t val key->updated = false; } + BT_DBG("StatusStorageFail"); return STATUS_STORAGE_FAIL; } - BT_DBG("app_idx 0x%04x AID 0x%02x", app_idx, keys->id); - key->net_idx = net_idx; key->app_idx = app_idx; memcpy(keys->val, val, 16); if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - BT_DBG("Storing AppKey persistently"); bt_mesh_store_app_key(key); } @@ -559,14 +596,13 @@ static void app_key_add(struct bt_mesh_model *model, key_idx_unpack(buf, &key_net_idx, &key_app_idx); - BT_DBG("AppIdx 0x%04x NetIdx 0x%04x", key_app_idx, key_net_idx); + BT_DBG("AppKeyAdd, NetIdx 0x%04x AppIdx 0x%04x", key_net_idx, key_app_idx); bt_mesh_model_msg_init(&msg, OP_APP_KEY_STATUS); status = app_key_set(key_net_idx, key_app_idx, buf->data, false); - BT_DBG("status 0x%02x", status); - net_buf_simple_add_u8(&msg, status); + net_buf_simple_add_u8(&msg, status); key_idx_pack(&msg, key_net_idx, key_app_idx); if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) { @@ -594,14 +630,13 @@ static void app_key_update(struct bt_mesh_model *model, key_idx_unpack(buf, &key_net_idx, &key_app_idx); - BT_DBG("AppIdx 0x%04x NetIdx 0x%04x", key_app_idx, key_net_idx); + BT_DBG("AppKeyUpdate, NetIdx 0x%04x AppIdx 0x%04x", key_net_idx, key_app_idx); bt_mesh_model_msg_init(&msg, OP_APP_KEY_STATUS); status = app_key_set(key_net_idx, key_app_idx, buf->data, true); - BT_DBG("status 0x%02x", status); - net_buf_simple_add_u8(&msg, status); + net_buf_simple_add_u8(&msg, status); key_idx_pack(&msg, key_net_idx, key_app_idx); if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) { @@ -628,6 +663,8 @@ static void _mod_unbind(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, { struct unbind_data *data = user_data; + BT_DBG("_ModUnbind, Vnd %u Primary %u", vnd, primary); + mod_unbind(mod, data->app_idx, data->store); } @@ -635,7 +672,7 @@ void bt_mesh_app_key_del(struct bt_mesh_app_key *key, bool store) { struct unbind_data data = { .app_idx = key->app_idx, .store = store }; - BT_DBG("AppIdx 0x%03x store %u", key->app_idx, store); + BT_DBG("AppKeyDel, AppIdx 0x%04x Store %u", key->app_idx, store); bt_mesh_model_foreach(_mod_unbind, &data); @@ -658,9 +695,10 @@ static void app_key_del(struct bt_mesh_model *model, key_idx_unpack(buf, &key_net_idx, &key_app_idx); - BT_DBG("AppIdx 0x%04x NetIdx 0x%04x", key_app_idx, key_net_idx); + BT_DBG("AppkeyDel, NetIdx 0x%04x AppIdx 0x%04x", key_net_idx, key_app_idx); if (!bt_mesh_subnet_get(key_net_idx)) { + BT_DBG("StatusInvalidNetKey"); status = STATUS_INVALID_NETKEY; goto send_status; } @@ -675,11 +713,13 @@ static void app_key_del(struct bt_mesh_model *model, } if (key->net_idx != key_net_idx) { + BT_DBG("StatusInvalidBinding"); status = STATUS_INVALID_BINDING; goto send_status; } bt_mesh_app_key_del(key, true); + status = STATUS_SUCCESS; send_status: @@ -703,7 +743,7 @@ static void app_key_del(struct bt_mesh_model *model, } /* Index list length: 3 bytes for every pair and 2 bytes for an odd idx */ -#define IDX_LEN(num) (((num) / 2) * 3 + ((num) % 2) * 2) +#define IDX_LEN(num) (((num) / 2) * 3 + ((num) % 2) * 2) static void app_key_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, @@ -714,17 +754,20 @@ static void app_key_get(struct bt_mesh_model *model, uint16_t get_idx = 0U, i = 0U, prev = 0U; uint8_t status = 0U; + BT_DBG("AppkeyGet"); + get_idx = net_buf_simple_pull_le16(buf); if (get_idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", get_idx); return; } - BT_DBG("idx 0x%04x", get_idx); + BT_DBG("GetIdx 0x%04x", get_idx); bt_mesh_model_msg_init(&msg, OP_APP_KEY_LIST); if (!bt_mesh_subnet_get(get_idx)) { + BT_DBG("StatusInvalidNetKey"); status = STATUS_INVALID_NETKEY; } else { status = STATUS_SUCCESS; @@ -738,6 +781,7 @@ static void app_key_get(struct bt_mesh_model *model, } prev = BLE_MESH_KEY_UNUSED; + for (i = 0U; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { struct bt_mesh_app_key *key = &bt_mesh.app_keys[i]; @@ -770,9 +814,10 @@ static void beacon_get(struct bt_mesh_model *model, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_BEACON_STATUS, 1); - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("BeaconGet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); bt_mesh_model_msg_init(&msg, OP_BEACON_STATUS); net_buf_simple_add_u8(&msg, bt_mesh_secure_beacon_get()); @@ -789,9 +834,10 @@ static void beacon_set(struct bt_mesh_model *model, BLE_MESH_MODEL_BUF_DEFINE(msg, OP_BEACON_STATUS, 1); struct bt_mesh_cfg_srv *cfg = model->user_data; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("BeaconSet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); if (!cfg) { BT_WARN("No Configuration Server context available"); @@ -828,9 +874,10 @@ static void default_ttl_get(struct bt_mesh_model *model, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_DEFAULT_TTL_STATUS, 1); - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("DefaultTTLGet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); bt_mesh_model_msg_init(&msg, OP_DEFAULT_TTL_STATUS); net_buf_simple_add_u8(&msg, bt_mesh_default_ttl_get()); @@ -847,9 +894,10 @@ static void default_ttl_set(struct bt_mesh_model *model, BLE_MESH_MODEL_BUF_DEFINE(msg, OP_DEFAULT_TTL_STATUS, 1); struct bt_mesh_cfg_srv *cfg = model->user_data; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("DefaultTTLSet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); if (!cfg) { BT_WARN("No Configuration Server context available"); @@ -879,6 +927,8 @@ static void send_gatt_proxy_status(struct bt_mesh_model *model, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_GATT_PROXY_STATUS, 1); + BT_DBG("SendGattProxyStatus"); + bt_mesh_model_msg_init(&msg, OP_GATT_PROXY_STATUS); net_buf_simple_add_u8(&msg, bt_mesh_gatt_proxy_get()); @@ -891,9 +941,10 @@ static void gatt_proxy_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("GattProxyGet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); send_gatt_proxy_status(model, ctx); } @@ -904,9 +955,10 @@ static void gatt_proxy_set(struct bt_mesh_model *model, { struct bt_mesh_cfg_srv *cfg = model->user_data; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("GattProxySet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); if (buf->data[0] != 0x00 && buf->data[0] != 0x01) { BT_WARN("Invalid GATT Proxy value 0x%02x", buf->data[0]); @@ -923,7 +975,7 @@ static void gatt_proxy_set(struct bt_mesh_model *model, goto send_status; } - BT_DBG("GATT Proxy 0x%02x -> 0x%02x", cfg->gatt_proxy, buf->data[0]); + BT_DBG("GattProxy 0x%02x -> 0x%02x", cfg->gatt_proxy, buf->data[0]); if (cfg->gatt_proxy == buf->data[0]) { goto send_status; @@ -934,11 +986,11 @@ static void gatt_proxy_set(struct bt_mesh_model *model, #if CONFIG_BLE_MESH_PRB_SRV /* If the value of the GATT Proxy state of the node is 0x01 (see Table 4.21), * then the value of the Private GATT Proxy state shall be Disable (0x00). - */ + */ if (buf->data[0] == BLE_MESH_GATT_PROXY_ENABLED) { bt_mesh_disable_private_gatt_proxy(); } -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ #if CONFIG_BLE_MESH_DF_SRV /* If the value of the GATT Proxy state of the node is 0x00, @@ -946,7 +998,7 @@ static void gatt_proxy_set(struct bt_mesh_model *model, * directed proxy use directed default shall be 0x02. */ bt_mesh_disable_directed_proxy_state(ctx->net_idx); -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { bt_mesh_store_cfg(); @@ -966,9 +1018,10 @@ static void net_transmit_get(struct bt_mesh_model *model, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_TRANSMIT_STATUS, 1); - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("NetTransmitGet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); bt_mesh_model_msg_init(&msg, OP_NET_TRANSMIT_STATUS); net_buf_simple_add_u8(&msg, bt_mesh_net_transmit_get()); @@ -985,11 +1038,13 @@ static void net_transmit_set(struct bt_mesh_model *model, BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_TRANSMIT_STATUS, 1); struct bt_mesh_cfg_srv *cfg = model->user_data; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("NetTransmitSet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); - BT_DBG("Transmit 0x%02x (count %u interval %ums)", buf->data[0], + BT_DBG("Transmit 0x%02x Count %u Interval %u", + buf->data[0], BLE_MESH_TRANSMIT_COUNT(buf->data[0]), BLE_MESH_TRANSMIT_INT(buf->data[0])); @@ -1017,9 +1072,10 @@ static void relay_get(struct bt_mesh_model *model, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_STATUS, 2); - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("RelayGet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); bt_mesh_model_msg_init(&msg, OP_RELAY_STATUS); net_buf_simple_add_u8(&msg, bt_mesh_relay_get()); @@ -1037,9 +1093,10 @@ static void relay_set(struct bt_mesh_model *model, BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_STATUS, 2); struct bt_mesh_cfg_srv *cfg = model->user_data; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("RelaySet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); if (!cfg) { BT_WARN("No Configuration Server context available"); @@ -1050,6 +1107,7 @@ static void relay_set(struct bt_mesh_model *model, change = false; } else { change = (cfg->relay != buf->data[0]); + cfg->relay = buf->data[0]; cfg->relay_retransmit = buf->data[1]; @@ -1058,9 +1116,8 @@ static void relay_set(struct bt_mesh_model *model, } } - BT_DBG("Relay 0x%02x (%s) xmit 0x%02x (count %u interval %u)", - cfg->relay, change ? "changed" : "not changed", - cfg->relay_retransmit, + BT_DBG("Relay 0x%02x Change %u Xmit 0x%02x Count %u Interval %u", + cfg->relay, change, cfg->relay_retransmit, BLE_MESH_TRANSMIT_COUNT(cfg->relay_retransmit), BLE_MESH_TRANSMIT_INT(cfg->relay_retransmit)); @@ -1089,6 +1146,10 @@ static void send_mod_pub_status(struct bt_mesh_model *cfg_mod, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_STATUS, 14); + BT_DBG("SendModPubStatus"); + BT_DBG("ElemAddr 0x%04x PubAddr 0x%04x Vnd %u Status 0x%02x", + elem_addr, pub_addr, vnd, status); + bt_mesh_model_msg_init(&msg, OP_MOD_PUB_STATUS); net_buf_simple_add_u8(&msg, status); @@ -1129,6 +1190,8 @@ static void mod_pub_get(struct bt_mesh_model *model, uint8_t *mod_id = NULL, status = 0U; bool vnd = false; + BT_DBG("ModPubGet"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -1137,10 +1200,11 @@ static void mod_pub_get(struct bt_mesh_model *model, mod_id = buf->data; - BT_DBG("elem_addr 0x%04x", elem_addr); + BT_DBG("ElemAddr 0x%04x", elem_addr); elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); mod = NULL; vnd = (buf->len == 4U); status = STATUS_INVALID_ADDRESS; @@ -1149,11 +1213,13 @@ static void mod_pub_get(struct bt_mesh_model *model, mod = get_model(elem, buf, &vnd); if (!mod) { + BT_DBG("StatusInvalidModel"); status = STATUS_INVALID_MODEL; goto send_status; } if (!mod->pub) { + BT_DBG("StatusNvalPubParam"); status = STATUS_NVAL_PUB_PARAM; goto send_status; } @@ -1162,8 +1228,7 @@ static void mod_pub_get(struct bt_mesh_model *model, status = STATUS_SUCCESS; send_status: - send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, - status, mod_id); + send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, status, mod_id); } static void mod_pub_set(struct bt_mesh_model *model, @@ -1177,6 +1242,8 @@ static void mod_pub_set(struct bt_mesh_model *model, uint8_t *mod_id = NULL; bool vnd = false; + BT_DBG("ModPubSet"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -1198,16 +1265,18 @@ static void mod_pub_set(struct bt_mesh_model *model, retransmit = net_buf_simple_pull_u8(buf); mod_id = buf->data; - BT_DBG("elem_addr 0x%04x pub_addr 0x%04x cred_flag %u", + BT_DBG("ElemAddr 0x%04x PubAddr 0x%04x CredFlag %u", elem_addr, pub_addr, cred_flag); - BT_DBG("pub_app_idx 0x%03x, pub_ttl %u pub_period 0x%02x", + BT_DBG("PubAppIdx 0x%04x PubTTL %u PubPeriod 0x%02x", pub_app_idx, pub_ttl, pub_period); - BT_DBG("retransmit 0x%02x (count %u interval %ums)", retransmit, + BT_DBG("Retransmit 0x%02x Count %u Interval %u", + retransmit, BLE_MESH_PUB_TRANSMIT_COUNT(retransmit), BLE_MESH_PUB_TRANSMIT_INT(retransmit)); elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); mod = NULL; vnd = (buf->len == 4U); status = STATUS_INVALID_ADDRESS; @@ -1216,6 +1285,7 @@ static void mod_pub_set(struct bt_mesh_model *model, mod = get_model(elem, buf, &vnd); if (!mod) { + BT_DBG("StatusInvalidModel"); status = STATUS_INVALID_MODEL; goto send_status; } @@ -1224,8 +1294,7 @@ static void mod_pub_set(struct bt_mesh_model *model, pub_period, retransmit, true); send_status: - send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, - status, mod_id); + send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, status, mod_id); if (status == STATUS_SUCCESS && mod->pub) { bt_mesh_cfg_server_state_change_t change = {0}; @@ -1245,6 +1314,8 @@ static void mod_pub_set(struct bt_mesh_model *model, struct label *get_label(uint16_t index) { + BT_DBG("GetLabel, Index %u", index); + if (index >= ARRAY_SIZE(labels)) { return NULL; } @@ -1255,7 +1326,10 @@ struct label *get_label(uint16_t index) #if CONFIG_BLE_MESH_LABEL_COUNT > 0 static inline void va_store(struct label *store) { + BT_DBG("VaStore"); + bt_mesh_atomic_set_bit(store->flags, BLE_MESH_VA_CHANGED); + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { bt_mesh_store_label(); } @@ -1267,6 +1341,8 @@ static struct label *va_find(const uint8_t *label_uuid, struct label *match = NULL; int i; + BT_DBG("VaFind"); + if (free_slot != NULL) { *free_slot = NULL; } @@ -1291,10 +1367,14 @@ uint8_t va_add(uint8_t *label_uuid, uint16_t *addr) { struct label *update = NULL, *free_slot = NULL; + BT_DBG("VaAdd"); + update = va_find(label_uuid, &free_slot); if (update) { update->ref++; + va_store(update); + if (addr) { *addr = update->addr; } @@ -1302,10 +1382,12 @@ uint8_t va_add(uint8_t *label_uuid, uint16_t *addr) } if (!free_slot) { + BT_DBG("StatusInsuffResources"); return STATUS_INSUFF_RESOURCES; } if (bt_mesh_virtual_addr(label_uuid, addr) < 0) { + BT_DBG("StatusUnspecified"); return STATUS_UNSPECIFIED; } @@ -1321,6 +1403,8 @@ uint8_t va_del(uint8_t *label_uuid, uint16_t *addr) { struct label *update = NULL; + BT_DBG("VaDel"); + update = va_find(label_uuid, NULL); if (update) { update->ref--; @@ -1337,6 +1421,7 @@ uint8_t va_del(uint8_t *label_uuid, uint16_t *addr) *addr = BLE_MESH_ADDR_UNASSIGNED; } + BT_DBG("StatusCannotRemove"); return STATUS_CANNOT_REMOVE; } @@ -1346,6 +1431,8 @@ static size_t mod_sub_list_clear(struct bt_mesh_model *mod) size_t clear_count = 0U; int i; + BT_DBG("ModSubListClear"); + /* Unref stored labels related to this model */ for (i = 0, clear_count = 0; i < ARRAY_SIZE(mod->groups); i++) { if (!BLE_MESH_ADDR_IS_VIRTUAL(mod->groups[i])) { @@ -1365,10 +1452,12 @@ static size_t mod_sub_list_clear(struct bt_mesh_model *mod) if (label_uuid) { va_del(label_uuid, NULL); } else { - BT_ERR("Label UUID not found"); + BT_ERR("LabelUUIDNotFound"); } } + BT_DBG("ClearCount %u", clear_count); + return clear_count; } @@ -1384,6 +1473,8 @@ static void mod_pub_va_set(struct bt_mesh_model *model, uint8_t *mod_id = NULL; bool vnd = false; + BT_DBG("ModPubVaSet"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -1404,15 +1495,17 @@ static void mod_pub_va_set(struct bt_mesh_model *model, retransmit = net_buf_simple_pull_u8(buf); mod_id = buf->data; - BT_DBG("elem_addr 0x%04x cred_flag %u", elem_addr, cred_flag); - BT_DBG("pub_app_idx 0x%03x, pub_ttl %u pub_period 0x%02x", + BT_DBG("ElemAddr 0x%04x CredFlag %u", elem_addr, cred_flag); + BT_DBG("PubAppIdx 0x%04x PubTTL %u PubPeriod 0x%02x", pub_app_idx, pub_ttl, pub_period); - BT_DBG("retransmit 0x%02x (count %u interval %ums)", retransmit, + BT_DBG("Retransmit 0x%02x Count %u Interval %u", + retransmit, BLE_MESH_PUB_TRANSMIT_COUNT(retransmit), BLE_MESH_PUB_TRANSMIT_INT(retransmit)); elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); mod = NULL; vnd = (buf->len == 4U); pub_addr = 0U; @@ -1422,6 +1515,7 @@ static void mod_pub_va_set(struct bt_mesh_model *model, mod = get_model(elem, buf, &vnd); if (!mod) { + BT_DBG("StatusInvalidModel"); pub_addr = 0U; status = STATUS_INVALID_MODEL; goto send_status; @@ -1434,15 +1528,16 @@ static void mod_pub_va_set(struct bt_mesh_model *model, } send_status: - send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, - status, mod_id); + send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, status, mod_id); } -#else +#else /* CONFIG_BLE_MESH_LABEL_COUNT > 0 */ static size_t mod_sub_list_clear(struct bt_mesh_model *mod) { size_t clear_count = 0U; int i; + BT_DBG("ModSubListClear"); + /* Unref stored labels related to this model */ for (i = 0, clear_count = 0; i < ARRAY_SIZE(mod->groups); i++) { if (mod->groups[i] != BLE_MESH_ADDR_UNASSIGNED) { @@ -1451,6 +1546,8 @@ static size_t mod_sub_list_clear(struct bt_mesh_model *mod) } } + BT_DBG("ClearCount %u", clear_count); + return clear_count; } @@ -1458,12 +1555,14 @@ static void mod_pub_va_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { + uint16_t elem_addr = 0U, pub_addr = 0U; uint8_t *mod_id = NULL, status = 0U; struct bt_mesh_model *mod = NULL; struct bt_mesh_elem *elem = NULL; - uint16_t elem_addr = 0U, pub_addr = 0U; bool vnd = false; + BT_DBG("ModPubVaSet"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -1473,10 +1572,11 @@ static void mod_pub_va_set(struct bt_mesh_model *model, net_buf_simple_pull(buf, 16); mod_id = net_buf_simple_pull(buf, 4); - BT_DBG("elem_addr 0x%04x", elem_addr); + BT_DBG("ElemAddr 0x%04x", elem_addr); elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); mod = NULL; vnd = (buf->len == 4U); status = STATUS_INVALID_ADDRESS; @@ -1485,33 +1585,37 @@ static void mod_pub_va_set(struct bt_mesh_model *model, mod = get_model(elem, buf, &vnd); if (!mod) { + BT_DBG("StatusInvalidModel"); status = STATUS_INVALID_MODEL; goto send_status; } if (!mod->pub) { + BT_DBG("StatusNvalPubParam"); status = STATUS_NVAL_PUB_PARAM; goto send_status; } pub_addr = mod->pub->addr; + + BT_DBG("StatusInsuffResources"); status = STATUS_INSUFF_RESOURCES; send_status: - send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, - status, mod_id); + send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, status, mod_id); } #endif /* CONFIG_BLE_MESH_LABEL_COUNT > 0 */ static void send_mod_sub_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, uint8_t status, - uint16_t elem_addr, uint16_t sub_addr, uint8_t *mod_id, - bool vnd) + uint16_t elem_addr, uint16_t sub_addr, + uint8_t *mod_id, bool vnd) { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_STATUS, 9); - BT_DBG("status 0x%02x elem_addr 0x%04x sub_addr 0x%04x", status, - elem_addr, sub_addr); + BT_DBG("SendModSubStatus"); + BT_DBG("Status 0x%02x ElemAddr 0x%04x SubAddr 0x%04x Vnd %u", + status, elem_addr, sub_addr, vnd); bt_mesh_model_msg_init(&msg, OP_MOD_SUB_STATUS); @@ -1542,6 +1646,8 @@ static void mod_sub_add(struct bt_mesh_model *model, bool vnd = false; int i; + BT_DBG("ModSubAdd"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -1550,12 +1656,13 @@ static void mod_sub_add(struct bt_mesh_model *model, sub_addr = net_buf_simple_pull_le16(buf); - BT_DBG("elem_addr 0x%04x, sub_addr 0x%04x", elem_addr, sub_addr); + BT_DBG("ElemAddr 0x%04x SubAddr 0x%04x", elem_addr, sub_addr); mod_id = buf->data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); mod = NULL; vnd = (buf->len == 4U); status = STATUS_INVALID_ADDRESS; @@ -1564,18 +1671,19 @@ static void mod_sub_add(struct bt_mesh_model *model, mod = get_model(elem, buf, &vnd); if (!mod) { + BT_DBG("StatusInvalidModel"); status = STATUS_INVALID_MODEL; goto send_status; } if (!BLE_MESH_ADDR_IS_GROUP(sub_addr)) { + BT_DBG("StatusInvalidAddress"); status = STATUS_INVALID_ADDRESS; goto send_status; } if (bt_mesh_model_find_group(mod, sub_addr)) { /* Tried to add existing subscription */ - BT_DBG("found existing subscription"); status = STATUS_SUCCESS; goto send_status; } @@ -1592,6 +1700,7 @@ static void mod_sub_add(struct bt_mesh_model *model, } if (i == ARRAY_SIZE(mod->groups)) { + BT_DBG("StatusInsuffResources"); status = STATUS_INSUFF_RESOURCES; } else { status = STATUS_SUCCESS; @@ -1606,12 +1715,11 @@ static void mod_sub_add(struct bt_mesh_model *model, } send_status: - send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, - mod_id, vnd); + send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, mod_id, vnd); #if CONFIG_BLE_MESH_DF_SRV bt_mesh_directed_forwarding_node_solicitation(mod, bt_mesh_subnet_get(ctx->net_idx)); -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ if (status == STATUS_SUCCESS) { bt_mesh_cfg_server_state_change_t change = {0}; @@ -1636,6 +1744,8 @@ static void mod_sub_del(struct bt_mesh_model *model, uint8_t status = 0U; bool vnd = false; + BT_DBG("ModSubDel"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -1644,12 +1754,13 @@ static void mod_sub_del(struct bt_mesh_model *model, sub_addr = net_buf_simple_pull_le16(buf); - BT_DBG("elem_addr 0x%04x sub_addr 0x%04x", elem_addr, sub_addr); + BT_DBG("ElemAddr 0x%04x SubAddr 0x%04x", elem_addr, sub_addr); mod_id = buf->data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); mod = NULL; vnd = (buf->len == 4U); status = STATUS_INVALID_ADDRESS; @@ -1658,11 +1769,13 @@ static void mod_sub_del(struct bt_mesh_model *model, mod = get_model(elem, buf, &vnd); if (!mod) { + BT_DBG("StatusInvalidModel"); status = STATUS_INVALID_MODEL; goto send_status; } if (!BLE_MESH_ADDR_IS_GROUP(sub_addr)) { + BT_DBG("StatusInvalidAddress"); status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -1686,8 +1799,7 @@ static void mod_sub_del(struct bt_mesh_model *model, } send_status: - send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, - mod_id, vnd); + send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, mod_id, vnd); if (status == STATUS_SUCCESS) { bt_mesh_cfg_server_state_change_t change = {0}; @@ -1711,6 +1823,8 @@ static void mod_sub_overwrite(struct bt_mesh_model *model, uint8_t status = 0U; bool vnd = false; + BT_DBG("ModSubOverwrite"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -1719,12 +1833,13 @@ static void mod_sub_overwrite(struct bt_mesh_model *model, sub_addr = net_buf_simple_pull_le16(buf); - BT_DBG("elem_addr 0x%04x sub_addr 0x%04x", elem_addr, sub_addr); + BT_DBG("ElemAddr 0x%04x SubAddr 0x%04x", elem_addr, sub_addr); mod_id = buf->data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); mod = NULL; vnd = (buf->len == 4U); status = STATUS_INVALID_ADDRESS; @@ -1733,11 +1848,13 @@ static void mod_sub_overwrite(struct bt_mesh_model *model, mod = get_model(elem, buf, &vnd); if (!mod) { + BT_DBG("StatusInvalidModel"); status = STATUS_INVALID_MODEL; goto send_status; } if (!BLE_MESH_ADDR_IS_GROUP(sub_addr)) { + BT_DBG("StatusInvalidAddress"); status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -1760,13 +1877,13 @@ static void mod_sub_overwrite(struct bt_mesh_model *model, bt_mesh_lpn_group_add(sub_addr); } } else { + BT_DBG("StatusInsuffResources"); status = STATUS_INSUFF_RESOURCES; } send_status: - send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, - mod_id, vnd); + send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, mod_id, vnd); } static void mod_sub_del_all(struct bt_mesh_model *model, @@ -1780,18 +1897,21 @@ static void mod_sub_del_all(struct bt_mesh_model *model, uint8_t status = 0U; bool vnd = false; + BT_DBG("ModSubDelAll"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); return; } - BT_DBG("elem_addr 0x%04x", elem_addr); + BT_DBG("ElemAddr 0x%04x", elem_addr); mod_id = buf->data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); mod = NULL; vnd = (buf->len == 4U); status = STATUS_INVALID_ADDRESS; @@ -1800,6 +1920,7 @@ static void mod_sub_del_all(struct bt_mesh_model *model, mod = get_model(elem, buf, &vnd); if (!mod) { + BT_DBG("StatusInvalidModel"); status = STATUS_INVALID_MODEL; goto send_status; } @@ -1832,6 +1953,8 @@ static void mod_sub_get(struct bt_mesh_model *model, uint16_t addr = 0U, id = 0U; int i; + BT_DBG("ModSubGet"); + addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(addr)) { BT_ERR("Prohibited element address 0x%04x", addr); @@ -1840,12 +1963,13 @@ static void mod_sub_get(struct bt_mesh_model *model, id = net_buf_simple_pull_le16(buf); - BT_DBG("addr 0x%04x id 0x%04x", addr, id); + BT_DBG("ElemAddr 0x%04x ID 0x%04x", addr, id); bt_mesh_model_msg_init(&msg, OP_MOD_SUB_LIST); elem = bt_mesh_elem_find(addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); net_buf_simple_add_u8(&msg, STATUS_INVALID_ADDRESS); net_buf_simple_add_le16(&msg, addr); net_buf_simple_add_le16(&msg, id); @@ -1854,6 +1978,7 @@ static void mod_sub_get(struct bt_mesh_model *model, mod = bt_mesh_model_find(elem, id); if (!mod) { + BT_DBG("StatusInvalidModel"); net_buf_simple_add_u8(&msg, STATUS_INVALID_MODEL); net_buf_simple_add_le16(&msg, addr); net_buf_simple_add_le16(&msg, id); @@ -1888,6 +2013,8 @@ static void mod_sub_get_vnd(struct bt_mesh_model *model, uint16_t company = 0U, addr = 0U, id = 0U; int i; + BT_DBG("ModSubGetVnd"); + addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(addr)) { BT_ERR("Prohibited element address 0x%04x", addr); @@ -1897,12 +2024,13 @@ static void mod_sub_get_vnd(struct bt_mesh_model *model, company = net_buf_simple_pull_le16(buf); id = net_buf_simple_pull_le16(buf); - BT_DBG("addr 0x%04x company 0x%04x id 0x%04x", addr, company, id); + BT_DBG("ElemAddr 0x%04x CID 0x%04x ID 0x%04x", addr, company, id); bt_mesh_model_msg_init(&msg, OP_MOD_SUB_LIST_VND); elem = bt_mesh_elem_find(addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); net_buf_simple_add_u8(&msg, STATUS_INVALID_ADDRESS); net_buf_simple_add_le16(&msg, addr); net_buf_simple_add_le16(&msg, company); @@ -1912,6 +2040,7 @@ static void mod_sub_get_vnd(struct bt_mesh_model *model, mod = bt_mesh_model_find_vnd(elem, company, id); if (!mod) { + BT_DBG("StatusInvalidModel"); net_buf_simple_add_u8(&msg, STATUS_INVALID_MODEL); net_buf_simple_add_le16(&msg, addr); net_buf_simple_add_le16(&msg, company); @@ -1951,6 +2080,8 @@ static void mod_sub_va_add(struct bt_mesh_model *model, bool vnd = false; int i; + BT_DBG("ModSubVaAdd"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -1959,11 +2090,12 @@ static void mod_sub_va_add(struct bt_mesh_model *model, label_uuid = net_buf_simple_pull_mem(buf, 16); - BT_DBG("elem_addr 0x%04x", elem_addr); + BT_DBG("ElemAddr 0x%04x", elem_addr); mod_id = buf->data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); mod = NULL; vnd = (buf->len == 4U); sub_addr = BLE_MESH_ADDR_UNASSIGNED; @@ -1973,6 +2105,7 @@ static void mod_sub_va_add(struct bt_mesh_model *model, mod = get_model(elem, buf, &vnd); if (!mod) { + BT_DBG("StatusInvalidModel"); sub_addr = BLE_MESH_ADDR_UNASSIGNED; status = STATUS_INVALID_MODEL; goto send_status; @@ -2001,6 +2134,7 @@ static void mod_sub_va_add(struct bt_mesh_model *model, } if (i == ARRAY_SIZE(mod->groups)) { + BT_DBG("StatusInsuffResources"); status = STATUS_INSUFF_RESOURCES; } else { if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) { @@ -2015,8 +2149,7 @@ static void mod_sub_va_add(struct bt_mesh_model *model, } send_status: - send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, - mod_id, vnd); + send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, mod_id, vnd); } static void mod_sub_va_del(struct bt_mesh_model *model, @@ -2032,6 +2165,8 @@ static void mod_sub_va_del(struct bt_mesh_model *model, uint8_t status = 0U; bool vnd = false; + BT_DBG("ModSubVaDel"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -2040,12 +2175,13 @@ static void mod_sub_va_del(struct bt_mesh_model *model, label_uuid = net_buf_simple_pull_mem(buf, 16); - BT_DBG("elem_addr 0x%04x", elem_addr); + BT_DBG("ElemAddr 0x%04x", elem_addr); mod_id = buf->data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); mod = NULL; vnd = (buf->len == 4U); sub_addr = BLE_MESH_ADDR_UNASSIGNED; @@ -2055,6 +2191,7 @@ static void mod_sub_va_del(struct bt_mesh_model *model, mod = get_model(elem, buf, &vnd); if (!mod) { + BT_DBG("StatusInvalidModel"); sub_addr = BLE_MESH_ADDR_UNASSIGNED; status = STATUS_INVALID_MODEL; goto send_status; @@ -2079,12 +2216,12 @@ static void mod_sub_va_del(struct bt_mesh_model *model, status = STATUS_SUCCESS; } else { + BT_DBG("StatusCannotRemove"); status = STATUS_CANNOT_REMOVE; } send_status: - send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, - mod_id, vnd); + send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, mod_id, vnd); } static void mod_sub_va_overwrite(struct bt_mesh_model *model, @@ -2099,6 +2236,8 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, uint8_t status = 0U; bool vnd = false; + BT_DBG("ModSubVaOverwrite"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -2107,12 +2246,13 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, label_uuid = net_buf_simple_pull_mem(buf, 16); - BT_DBG("elem_addr 0x%04x", elem_addr); + BT_DBG("ElemAddr 0x%04x", elem_addr); mod_id = buf->data; elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); mod = NULL; vnd = (buf->len == 4U); status = STATUS_INVALID_ADDRESS; @@ -2121,6 +2261,7 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, mod = get_model(elem, buf, &vnd); if (!mod) { + BT_DBG("StatusInvalidModel"); status = STATUS_INVALID_MODEL; goto send_status; } @@ -2145,14 +2286,14 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, } } } else { + BT_DBG("StatusInsuffResources"); status = STATUS_INSUFF_RESOURCES; } send_status: - send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, - mod_id, vnd); + send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, mod_id, vnd); } -#else +#else /* CONFIG_BLE_MESH_LABEL_COUNT > 0 */ static void mod_sub_va_add(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) @@ -2164,6 +2305,8 @@ static void mod_sub_va_add(struct bt_mesh_model *model, uint8_t status = 0U; bool vnd = false; + BT_DBG("ModSubVaAdd"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -2176,6 +2319,7 @@ static void mod_sub_va_add(struct bt_mesh_model *model, elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); mod = NULL; vnd = (buf->len == 4U); status = STATUS_INVALID_ADDRESS; @@ -2184,10 +2328,12 @@ static void mod_sub_va_add(struct bt_mesh_model *model, mod = get_model(elem, buf, &vnd); if (!mod) { + BT_DBG("StatusInvalidModel"); status = STATUS_INVALID_MODEL; goto send_status; } + BT_DBG("StatusInsuffResources"); status = STATUS_INSUFF_RESOURCES; send_status: @@ -2205,6 +2351,8 @@ static void mod_sub_va_del(struct bt_mesh_model *model, uint8_t status = 0U; bool vnd = false; + BT_DBG("ModSubVaDel"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -2217,16 +2365,19 @@ static void mod_sub_va_del(struct bt_mesh_model *model, elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); vnd = (buf->len == 4U); status = STATUS_INVALID_ADDRESS; goto send_status; } if (!get_model(elem, buf, &vnd)) { + BT_DBG("StatusInvalidModel"); status = STATUS_INVALID_MODEL; goto send_status; } + BT_DBG("StatusInsuffResources"); status = STATUS_INSUFF_RESOURCES; send_status: @@ -2244,6 +2395,8 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, uint8_t status = 0U; bool vnd = false; + BT_DBG("ModSubVaOverwrite"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -2256,16 +2409,19 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); vnd = (buf->len == 4U); status = STATUS_INVALID_ADDRESS; goto send_status; } if (!get_model(elem, buf, &vnd)) { + BT_DBG("StatusInvalidModel"); status = STATUS_INVALID_MODEL; goto send_status; } + BT_DBG("StatusInsuffResources"); status = STATUS_INSUFF_RESOURCES; send_status: @@ -2280,6 +2436,8 @@ static void send_net_key_status(struct bt_mesh_model *model, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_STATUS, 3); + BT_DBG("SendNetKeyStatus"); + bt_mesh_model_msg_init(&msg, OP_NET_KEY_STATUS); net_buf_simple_add_u8(&msg, status); @@ -2298,13 +2456,15 @@ static void net_key_add(struct bt_mesh_model *model, uint16_t idx = 0U; int err = 0; + BT_DBG("NetKeyAdd"); + idx = net_buf_simple_pull_le16(buf); if (idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", idx); return; } - BT_DBG("idx 0x%04x", idx); + BT_DBG("NetIdx 0x%04x", idx); sub = bt_mesh_subnet_get(idx); if (!sub) { @@ -2318,8 +2478,8 @@ static void net_key_add(struct bt_mesh_model *model, } if (!sub) { - send_net_key_status(model, ctx, idx, - STATUS_INSUFF_RESOURCES); + BT_DBG("StatusInsuffResources"); + send_net_key_status(model, ctx, idx, STATUS_INSUFF_RESOURCES); return; } } @@ -2329,6 +2489,7 @@ static void net_key_add(struct bt_mesh_model *model, uint8_t status = 0U; if (memcmp(buf->data, sub->keys[0].net, 16)) { + BT_DBG("StatusIdxAlreadyStored"); status = STATUS_IDX_ALREADY_STORED; } else { status = STATUS_SUCCESS; @@ -2340,6 +2501,7 @@ static void net_key_add(struct bt_mesh_model *model, err = bt_mesh_net_keys_create(&sub->keys[0], buf->data); if (err) { + BT_DBG("StatusUnspecified"); send_net_key_status(model, ctx, idx, STATUS_UNSPECIFIED); return; } @@ -2347,7 +2509,6 @@ static void net_key_add(struct bt_mesh_model *model, sub->net_idx = idx; if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - BT_DBG("Storing NetKey persistently"); bt_mesh_store_subnet(sub); } @@ -2368,7 +2529,7 @@ static void net_key_add(struct bt_mesh_model *model, if (sub->directed_proxy != BLE_MESH_DIRECTED_PROXY_NOT_SUPPORTED) { bt_mesh_directed_proxy_server_directed_proxy_caps_send(sub, false); } -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV && CONFIG_BLE_MESH_SUPPORT_DIRECTED_PROXY */ bt_mesh_adv_update(); } else { @@ -2381,7 +2542,7 @@ static void net_key_add(struct bt_mesh_model *model, if (bt_mesh_directed_forwarding_sub_init(sub)) { BT_ERR("Failed to init subnet for directed forward"); } -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ bt_mesh_cfg_server_state_change_t change = {0}; change.cfg_netkey_add.net_idx = sub->net_idx; @@ -2398,16 +2559,19 @@ static void net_key_update(struct bt_mesh_model *model, uint16_t idx = 0U; int err = 0; + BT_DBG("NetKeyUpdate"); + idx = net_buf_simple_pull_le16(buf); if (idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", idx); return; } - BT_DBG("idx 0x%04x", idx); + BT_DBG("NetIdx 0x%04x", idx); sub = bt_mesh_subnet_get(idx); if (!sub) { + BT_DBG("StatusInvalidNetKey"); send_net_key_status(model, ctx, idx, STATUS_INVALID_NETKEY); return; } @@ -2432,6 +2596,7 @@ static void net_key_update(struct bt_mesh_model *model, /* fall through */ case BLE_MESH_KR_PHASE_2: case BLE_MESH_KR_PHASE_3: + BT_DBG("StatusCannotUpdate"); send_net_key_status(model, ctx, idx, STATUS_CANNOT_UPDATE); return; } @@ -2443,6 +2608,7 @@ static void net_key_update(struct bt_mesh_model *model, } if (err) { + BT_DBG("StatusUnspecified"); send_net_key_status(model, ctx, idx, STATUS_UNSPECIFIED); return; } @@ -2450,7 +2616,6 @@ static void net_key_update(struct bt_mesh_model *model, sub->kr_phase = BLE_MESH_KR_PHASE_1; if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - BT_DBG("Storing NetKey persistently"); bt_mesh_store_subnet(sub); } @@ -2467,6 +2632,8 @@ static void net_key_update(struct bt_mesh_model *model, static void hb_pub_disable(struct bt_mesh_cfg_srv *cfg) { + BT_DBG("HbPubDisable"); + cfg->hb_pub.dst = BLE_MESH_ADDR_UNASSIGNED; cfg->hb_pub.count = 0U; cfg->hb_pub.ttl = 0U; @@ -2483,13 +2650,15 @@ static void net_key_del(struct bt_mesh_model *model, uint16_t del_idx = 0U; uint8_t status = 0U; + BT_DBG("NetKeyDel"); + del_idx = net_buf_simple_pull_le16(buf); if (del_idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", del_idx); return; } - BT_DBG("idx 0x%04x", del_idx); + BT_DBG("NetIdx 0x%04x", del_idx); sub = bt_mesh_subnet_get(del_idx); if (!sub) { @@ -2504,6 +2673,7 @@ static void net_key_del(struct bt_mesh_model *model, * The NetKey List must contain a minimum of one NetKey. */ if (ctx->net_idx == del_idx) { + BT_DBG("StatusCannotRemove"); status = STATUS_CANNOT_REMOVE; goto send_status; } @@ -2525,8 +2695,8 @@ static void net_key_del(struct bt_mesh_model *model, #if CONFIG_BLE_MESH_SETTINGS bt_mesh_clear_directed_forwarding_table_data(del_idx); -#endif -#endif +#endif /* CONFIG_BLE_MESH_SETTINGS */ +#endif /* CONFIG_BLE_MESH_DF_SRV && CONFIG_BLE_MESH_SUPPORT_DIRECTED_PROXY */ bt_mesh_subnet_del(sub, true); status = STATUS_SUCCESS; @@ -2540,11 +2710,11 @@ static void net_key_del(struct bt_mesh_model *model, * Index of the deleted NetKey are removed. */ bt_mesh_delete_netkey_in_bridge_table(del_idx); -#endif /* CONFIG_BLE_MESH_BRC_SRV */ +#endif /* CONFIG_BLE_MESH_BRC_SRV */ #if CONFIG_BLE_MESH_RPR_SRV bt_mesh_rpr_srv_netkey_del(del_idx); -#endif +#endif /* CONFIG_BLE_MESH_RPR_SRV */ send_status: send_net_key_status(model, ctx, del_idx, status); @@ -2565,6 +2735,8 @@ static void net_key_get(struct bt_mesh_model *model, IDX_LEN(CONFIG_BLE_MESH_SUBNET_COUNT)); uint16_t prev = 0U, i = 0U; + BT_DBG("NetKeyGet"); + bt_mesh_model_msg_init(&msg, OP_NET_KEY_LIST); prev = BLE_MESH_KEY_UNUSED; @@ -2602,9 +2774,10 @@ static void node_identity_get(struct bt_mesh_model *model, uint8_t node_id = 0U; uint16_t idx = 0U; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("NodeIdentityGet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); idx = net_buf_simple_pull_le16(buf); if (idx > 0xfff) { @@ -2616,6 +2789,7 @@ static void node_identity_get(struct bt_mesh_model *model, sub = bt_mesh_subnet_get(idx); if (!sub) { + BT_DBG("StatusInvalidNetKey"); net_buf_simple_add_u8(&msg, STATUS_INVALID_NETKEY); node_id = 0x00; } else { @@ -2640,9 +2814,10 @@ static void node_identity_set(struct bt_mesh_model *model, uint8_t node_id = 0U; uint16_t idx = 0U; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("NodeIdentitySet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); idx = net_buf_simple_pull_le16(buf); if (idx > 0xfff) { @@ -2660,6 +2835,7 @@ static void node_identity_set(struct bt_mesh_model *model, sub = bt_mesh_subnet_get(idx); if (!sub) { + BT_DBG("StatusInvalidNetKey"); net_buf_simple_add_u8(&msg, STATUS_INVALID_NETKEY); net_buf_simple_add_le16(&msg, idx); net_buf_simple_add_u8(&msg, node_id); @@ -2672,7 +2848,8 @@ static void node_identity_set(struct bt_mesh_model *model, * Identity state shall be Disable (0x00). */ bt_mesh_proxy_private_identity_disable(); -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ + bt_mesh_proxy_server_identity_start(sub); } else { bt_mesh_proxy_server_identity_stop(sub); @@ -2697,6 +2874,10 @@ static void create_mod_app_status(struct net_buf_simple *msg, { bt_mesh_model_msg_init(msg, OP_MOD_APP_STATUS); + BT_DBG("CreateModAppStatus"); + BT_DBG("ElemAddr 0x%04x AppIdx 0x%04x Status 0x%02x Vnd %u", + elem_addr, app_idx, status, vnd); + net_buf_simple_add_u8(msg, status); net_buf_simple_add_le16(msg, elem_addr); net_buf_simple_add_le16(msg, app_idx); @@ -2719,6 +2900,8 @@ static void mod_app_bind(struct bt_mesh_model *model, uint8_t *mod_id = NULL, status = 0U; bool vnd = false; + BT_DBG("ModAppBind"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -2730,6 +2913,7 @@ static void mod_app_bind(struct bt_mesh_model *model, elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); mod = NULL; vnd = (buf->len == 4U); status = STATUS_INVALID_ADDRESS; @@ -2738,24 +2922,24 @@ static void mod_app_bind(struct bt_mesh_model *model, mod = get_model(elem, buf, &vnd); if (!mod) { + BT_DBG("StatusInvalidModel"); status = STATUS_INVALID_MODEL; goto send_status; } /* Configuration Server only allows device key based access */ if (model == mod) { - BT_ERR("Client tried to bind AppKey to Configuration Model"); + BT_ERR("StatusCannotBind"); status = STATUS_CANNOT_BIND; goto send_status; } status = mod_bind(mod, key_app_idx); - BT_INFO("bind app key %#x on mode %#x", key_app_idx, mod->id); + BT_INFO("AppIdx 0x%04x ID 0x%04x", key_app_idx, mod->id); + send_status: - BT_DBG("status 0x%02x", status); - create_mod_app_status(&msg, mod, vnd, elem_addr, key_app_idx, status, - mod_id); + create_mod_app_status(&msg, mod, vnd, elem_addr, key_app_idx, status, mod_id); if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) { BT_ERR("Unable to send Config Model App Bind Status"); @@ -2783,6 +2967,8 @@ static void mod_app_unbind(struct bt_mesh_model *model, uint8_t *mod_id = NULL, status = 0U; bool vnd = false; + BT_DBG("ModAppUnbind"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -2794,6 +2980,7 @@ static void mod_app_unbind(struct bt_mesh_model *model, elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); mod = NULL; vnd = (buf->len == 4U); status = STATUS_INVALID_ADDRESS; @@ -2802,6 +2989,7 @@ static void mod_app_unbind(struct bt_mesh_model *model, mod = get_model(elem, buf, &vnd); if (!mod) { + BT_DBG("StatusInvalidModel"); status = STATUS_INVALID_MODEL; goto send_status; } @@ -2809,9 +2997,7 @@ static void mod_app_unbind(struct bt_mesh_model *model, status = mod_unbind(mod, key_app_idx, true); send_status: - BT_DBG("status 0x%02x", status); - create_mod_app_status(&msg, mod, vnd, elem_addr, key_app_idx, status, - mod_id); + create_mod_app_status(&msg, mod, vnd, elem_addr, key_app_idx, status, mod_id); if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) { BT_ERR("Unable to send Config Model App Unbind Status"); @@ -2828,23 +3014,22 @@ static void mod_app_unbind(struct bt_mesh_model *model, } } -#define KEY_LIST_LEN (CONFIG_BLE_MESH_MODEL_KEY_COUNT * 2) +#define KEY_LIST_LEN (CONFIG_BLE_MESH_MODEL_KEY_COUNT * 2) static void mod_app_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - NET_BUF_SIMPLE_DEFINE(msg, - MAX(BLE_MESH_MODEL_BUF_LEN(OP_VND_MOD_APP_LIST, - 9 + KEY_LIST_LEN), - BLE_MESH_MODEL_BUF_LEN(OP_SIG_MOD_APP_LIST, - 9 + KEY_LIST_LEN))); + NET_BUF_SIMPLE_DEFINE(msg, MAX(BLE_MESH_MODEL_BUF_LEN(OP_VND_MOD_APP_LIST, 9 + KEY_LIST_LEN), + BLE_MESH_MODEL_BUF_LEN(OP_SIG_MOD_APP_LIST, 9 + KEY_LIST_LEN))); struct bt_mesh_model *mod = NULL; struct bt_mesh_elem *elem = NULL; uint8_t *mod_id = NULL, status = 0U; uint16_t elem_addr = 0U; bool vnd = false; + BT_DBG("ModAppGet"); + elem_addr = net_buf_simple_pull_le16(buf); if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_ERR("Prohibited element address 0x%04x", elem_addr); @@ -2853,10 +3038,11 @@ static void mod_app_get(struct bt_mesh_model *model, mod_id = buf->data; - BT_DBG("elem_addr 0x%04x", elem_addr); + BT_DBG("ElemAddr 0x%04x", elem_addr); elem = bt_mesh_elem_find(elem_addr); if (!elem) { + BT_DBG("StatusInvalidAddress"); mod = NULL; vnd = (buf->len == 4U); status = STATUS_INVALID_ADDRESS; @@ -2865,6 +3051,7 @@ static void mod_app_get(struct bt_mesh_model *model, mod = get_model(elem, buf, &vnd); if (!mod) { + BT_DBG("StatusInvalidModel"); status = STATUS_INVALID_MODEL; goto send_list; } @@ -2908,15 +3095,15 @@ static void node_reset(struct bt_mesh_model *model, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_RESET_STATUS, 0); - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); - + BT_DBG("NodeReset"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); bt_mesh_model_msg_init(&msg, OP_NODE_RESET_STATUS); - /* Send the response first since we won't have any keys left to - * send it later. + /* Send the response first since we won't have any keys + * left to send it later. */ if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) { BT_ERR("Unable to send Config Node Reset Status"); @@ -2933,6 +3120,8 @@ static void send_friend_status(struct bt_mesh_model *model, BLE_MESH_MODEL_BUF_DEFINE(msg, OP_FRIEND_STATUS, 1); struct bt_mesh_cfg_srv *cfg = model->user_data; + BT_DBG("SendFrndStatus"); + bt_mesh_model_msg_init(&msg, OP_FRIEND_STATUS); net_buf_simple_add_u8(&msg, cfg->frnd); @@ -2945,9 +3134,10 @@ static void friend_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("FrndGet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); send_friend_status(model, ctx); } @@ -2958,9 +3148,10 @@ static void friend_set(struct bt_mesh_model *model, { struct bt_mesh_cfg_srv *cfg = model->user_data; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("FrndSet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); if (buf->data[0] != 0x00 && buf->data[0] != 0x01) { BT_WARN("Invalid Friend value 0x%02x", buf->data[0]); @@ -2972,7 +3163,7 @@ static void friend_set(struct bt_mesh_model *model, goto send_status; } - BT_DBG("Friend 0x%02x -> 0x%02x", cfg->frnd, buf->data[0]); + BT_DBG("Frnd 0x%02x -> 0x%02x", cfg->frnd, buf->data[0]); if (cfg->frnd == buf->data[0]) { goto send_status; @@ -2993,7 +3184,7 @@ static void friend_set(struct bt_mesh_model *model, * then the value of the directed friend state shall be 0x00. */ bt_mesh_disable_directed_friend_state(ctx->net_idx); -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV && CONFIG_BLE_MESH_FRIEND */ } } @@ -3016,7 +3207,8 @@ static void lpn_timeout_get(struct bt_mesh_model *model, lpn_addr = net_buf_simple_pull_le16(buf); - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x lpn_addr 0x%02x", + BT_DBG("LPNTimeoutGet"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x LPN 0x%04x", ctx->net_idx, ctx->app_idx, ctx->addr, lpn_addr); if (!BLE_MESH_ADDR_IS_UNICAST(lpn_addr)) { @@ -3054,6 +3246,8 @@ static void send_krp_status(struct bt_mesh_model *model, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_KRP_STATUS, 4); + BT_DBG("SendKrpStatus"); + bt_mesh_model_msg_init(&msg, OP_KRP_STATUS); net_buf_simple_add_u8(&msg, status); @@ -3071,20 +3265,22 @@ static void krp_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct bt_mesh_subnet *sub = NULL; uint16_t idx = 0U; + BT_DBG("KrpGet"); + idx = net_buf_simple_pull_le16(buf); if (idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", idx); return; } - BT_DBG("idx 0x%04x", idx); + BT_DBG("NetIdx 0x%04x", idx); sub = bt_mesh_subnet_get(idx); if (!sub) { + BT_DBG("StatusInvalidNetKey"); send_krp_status(model, ctx, idx, 0x00, STATUS_INVALID_NETKEY); } else { - send_krp_status(model, ctx, idx, sub->kr_phase, - STATUS_SUCCESS); + send_krp_status(model, ctx, idx, sub->kr_phase, STATUS_SUCCESS); } } @@ -3095,6 +3291,8 @@ static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, uint8_t phase = 0U; uint16_t idx = 0U; + BT_DBG("KrpSet"); + idx = net_buf_simple_pull_le16(buf); phase = net_buf_simple_pull_u8(buf); @@ -3103,15 +3301,16 @@ static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, return; } - BT_DBG("idx 0x%04x transition 0x%02x", idx, phase); + BT_DBG("NetIdx 0x%04x Phase 0x%02x", idx, phase); sub = bt_mesh_subnet_get(idx); if (!sub) { + BT_DBG("StatusInvalidNetKey"); send_krp_status(model, ctx, idx, 0x00, STATUS_INVALID_NETKEY); return; } - BT_DBG("%u -> %u", sub->kr_phase, phase); + BT_DBG("KrPhase %u -> %u", sub->kr_phase, phase); if (phase < BLE_MESH_KR_PHASE_2 || phase > BLE_MESH_KR_PHASE_3 || (sub->kr_phase == BLE_MESH_KR_NORMAL && @@ -3126,7 +3325,6 @@ static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, sub->kr_flag = 1; if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - BT_DBG("Storing kr phase persistently"); bt_mesh_store_subnet(sub); } @@ -3157,6 +3355,8 @@ static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, static uint8_t hb_log(uint16_t val) { + BT_DBG("HbLog, Val 0x%04x", val); + switch (val) { case 0x0000: return 0x00; @@ -3169,6 +3369,8 @@ static uint8_t hb_log(uint16_t val) static uint8_t hb_pub_count_log(uint16_t val) { + BT_DBG("HbPubCountLog, Val 0x%04x", val); + switch (val) { case 0x0000: return 0x00; @@ -3183,6 +3385,8 @@ static uint8_t hb_pub_count_log(uint16_t val) static uint16_t hb_pwr2(uint8_t val, uint8_t sub) { + BT_DBG("HbPwr2, Val 0x%02x Sub 0x%02x", val, sub); + switch (val) { case 0x00: return 0x0000; @@ -3210,7 +3414,7 @@ static void hb_pub_send_status(struct bt_mesh_model *model, BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_STATUS, 10); struct bt_mesh_cfg_srv *cfg = model->user_data; - BT_DBG("src 0x%04x status 0x%02x", ctx->addr, status); + BT_DBG("HbPubSendStatus, Src 0x%04x Status 0x%02x", ctx->addr, status); bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_PUB_STATUS); @@ -3239,7 +3443,7 @@ static void heartbeat_pub_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - BT_DBG("src 0x%04x", ctx->addr); + BT_DBG("HeartbeatPubGet, Src 0x%04x", ctx->addr); hb_pub_send_status(model, ctx, STATUS_SUCCESS, NULL); } @@ -3253,27 +3457,30 @@ static void heartbeat_pub_set(struct bt_mesh_model *model, uint16_t dst = 0U, feat = 0U, idx = 0U; uint8_t status = 0U; - BT_DBG("src 0x%04x", ctx->addr); + BT_DBG("HeartbeatPubSet, Src 0x%04x", ctx->addr); dst = sys_le16_to_cpu(param->dst); /* All other address types but virtual are valid */ if (BLE_MESH_ADDR_IS_VIRTUAL(dst)) { + BT_DBG("StatusInvalidAddress"); status = STATUS_INVALID_ADDRESS; goto failed; } if (param->count_log > 0x11 && param->count_log != 0xff) { + BT_DBG("StatusCannotSet"); status = STATUS_CANNOT_SET; goto failed; } if (param->period_log > 0x11) { + BT_DBG("StatusCannotSet"); status = STATUS_CANNOT_SET; goto failed; } if (param->ttl > BLE_MESH_TTL_MAX && param->ttl != BLE_MESH_TTL_DEFAULT) { - BT_ERR("Invalid TTL value 0x%02x", param->ttl); + BT_ERR("InvalidTTL %u", param->ttl); return; } @@ -3281,11 +3488,12 @@ static void heartbeat_pub_set(struct bt_mesh_model *model, idx = sys_le16_to_cpu(param->net_idx); if (idx > 0xfff) { - BT_ERR("Invalid NetKeyIndex 0x%04x", idx); + BT_ERR("InvalidNetIdx 0x%04x", idx); return; } if (!bt_mesh_subnet_get(idx)) { + BT_DBG("StatusInvalidNetKey"); status = STATUS_INVALID_NETKEY; goto failed; } @@ -3302,7 +3510,7 @@ static void heartbeat_pub_set(struct bt_mesh_model *model, cfg->hb_pub.count = hb_pwr2(param->count_log, 1); cfg->hb_pub.ttl = param->ttl; - BT_DBG("period %u ms", hb_pwr2(param->period_log, 1) * 1000U); + BT_DBG("Period %u", hb_pwr2(param->period_log, 1) * 1000U); /* Note: Send heartbeat message here will cause wrong heartbeat status message */ #if 0 @@ -3343,14 +3551,15 @@ static void heartbeat_pub_set(struct bt_mesh_model *model, } static void hb_sub_send_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, uint8_t status) + struct bt_mesh_msg_ctx *ctx, + uint8_t status) { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_STATUS, 9); struct bt_mesh_cfg_srv *cfg = model->user_data; uint16_t period = 0U; int64_t uptime = 0; - BT_DBG("src 0x%04x status 0x%02x", ctx->addr, status); + BT_DBG("HbSubSendStatus, Src 0x%04x Status 0x%02x", ctx->addr, status); uptime = k_uptime_get(); if (uptime > cfg->hb_sub.expiry) { @@ -3378,7 +3587,7 @@ static void heartbeat_sub_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - BT_DBG("src 0x%04x", ctx->addr); + BT_DBG("HeartbeatSubGet, Src 0x%04x", ctx->addr); hb_sub_send_status(model, ctx, STATUS_SUCCESS); } @@ -3392,13 +3601,13 @@ static void heartbeat_sub_set(struct bt_mesh_model *model, uint8_t sub_period = 0U; int32_t period_ms = 0; - BT_DBG("src 0x%04x", ctx->addr); + BT_DBG("HeartbeatSubSet, Src 0x%04x", ctx->addr); sub_src = net_buf_simple_pull_le16(buf); sub_dst = net_buf_simple_pull_le16(buf); sub_period = net_buf_simple_pull_u8(buf); - BT_DBG("sub_src 0x%04x sub_dst 0x%04x period 0x%02x", + BT_DBG("SubSrc 0x%04x SubDst 0x%04x SubPeriod 0x%02x", sub_src, sub_dst, sub_period); if (sub_src != BLE_MESH_ADDR_UNASSIGNED && @@ -3447,7 +3656,7 @@ static void heartbeat_sub_set(struct bt_mesh_model *model, /* Let the transport layer know it needs to handle this address */ bt_mesh_set_hb_sub_dst(cfg->hb_sub.dst); - BT_DBG("period_ms %u", period_ms); + BT_DBG("Period %ld", period_ms); if (period_ms) { cfg->hb_sub.expiry = k_uptime_get() + period_ms; @@ -3529,7 +3738,8 @@ static void hb_publish(struct k_work *work) struct bt_mesh_subnet *sub = NULL; uint16_t period_ms = 0U; - BT_DBG("hb_pub.count: %u", cfg->hb_pub.count); + BT_DBG("HbPublish, NetIdx 0x%04x Count %u", + cfg->hb_pub.net_idx, cfg->hb_pub.count); sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx); if (!sub) { @@ -3557,15 +3767,20 @@ static void hb_publish(struct k_work *work) static bool conf_is_valid(struct bt_mesh_cfg_srv *cfg) { + BT_DBG("ConfIsValid"); + if (cfg->relay > 0x02) { + BT_ERR("InvalidRelay 0x%02x", cfg->relay); return false; } if (cfg->beacon > 0x01) { + BT_ERR("InvalidBeacon 0x%02x", cfg->beacon); return false; } if (cfg->default_ttl > BLE_MESH_TTL_MAX) { + BT_ERR("InvalidDefaultTTL 0x%02x", cfg->default_ttl); return false; } @@ -3591,6 +3806,8 @@ static int cfg_srv_init(struct bt_mesh_model *model) { struct bt_mesh_cfg_srv *cfg = model->user_data; + BT_DBG("CfgSrvInit"); + if (!bt_mesh_model_in_primary(model)) { BT_ERR("Configuration Server only allowed in primary element"); return -EINVAL; @@ -3602,7 +3819,6 @@ static int cfg_srv_init(struct bt_mesh_model *model) } if (!conf_is_valid(cfg)) { - BT_ERR("Invalid values in configuration"); return -EINVAL; } @@ -3637,6 +3853,8 @@ static int cfg_srv_deinit(struct bt_mesh_model *model) { struct bt_mesh_cfg_srv *cfg = model->user_data; + BT_DBG("CfgSrvDeinit"); + if (!bt_mesh_model_in_primary(model)) { BT_ERR("Configuration Server only allowed in primary element"); return -EINVAL; @@ -3682,6 +3900,9 @@ static void mod_reset(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, clear_count = mod_sub_list_clear(mod); + BT_DBG("ModReset, ClearCount %lu Vnd %u Primary %u", + clear_count, vnd, primary); + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && clear_count && store) { bt_mesh_store_mod_sub(mod); } @@ -3689,6 +3910,8 @@ static void mod_reset(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, void bt_mesh_mod_sub_reset(bool store) { + BT_DBG("ModSubReset, Store %u", store); + bt_mesh_model_foreach(mod_reset, &store); } @@ -3697,6 +3920,8 @@ void bt_mesh_cfg_reset(bool store) struct bt_mesh_cfg_srv *cfg = conf; int i; + BT_DBG("CfgReset, Store %u", store); + if (!cfg) { return; } @@ -3725,7 +3950,11 @@ void bt_mesh_cfg_reset(bool store) uint8_t bt_mesh_net_transmit_get(void) { + BT_DBG("NetTransmitGet"); + if (conf) { + BT_DBG("Val 0x%02x", conf->net_transmit); + return conf->net_transmit; } @@ -3734,6 +3963,8 @@ uint8_t bt_mesh_net_transmit_get(void) void bt_mesh_relay_local_set(bool enable) { + BT_DBG("RelayLocalSet, Enable %u", enable); + if (conf && conf->relay != BLE_MESH_RELAY_NOT_SUPPORTED) { if (enable) { conf->relay = BLE_MESH_RELAY_ENABLED; @@ -3745,7 +3976,11 @@ void bt_mesh_relay_local_set(bool enable) uint8_t bt_mesh_relay_get(void) { + BT_DBG("RelayGet"); + if (conf) { + BT_DBG("Val 0x%02x", conf->relay); + return conf->relay; } @@ -3754,8 +3989,11 @@ uint8_t bt_mesh_relay_get(void) uint8_t bt_mesh_friend_get(void) { + BT_DBG("FrndGet"); + if (conf) { - BT_DBG("conf %p conf->frnd 0x%02x", conf, conf->frnd); + BT_DBG("Val 0x%02x", conf->frnd); + return conf->frnd; } @@ -3764,7 +4002,11 @@ uint8_t bt_mesh_friend_get(void) uint8_t bt_mesh_relay_retransmit_get(void) { + BT_DBG("RelayRetransmitGet"); + if (conf) { + BT_DBG("Val 0x%02x", conf->relay_retransmit); + return conf->relay_retransmit; } @@ -3773,7 +4015,11 @@ uint8_t bt_mesh_relay_retransmit_get(void) uint8_t bt_mesh_secure_beacon_get(void) { + BT_DBG("SecureBeaconGet"); + if (conf) { + BT_DBG("Val 0x%02x", conf->beacon); + return conf->beacon; } @@ -3782,7 +4028,11 @@ uint8_t bt_mesh_secure_beacon_get(void) uint8_t bt_mesh_gatt_proxy_get(void) { + BT_DBG("GattProxyGet"); + if (conf) { + BT_DBG("Val 0x%02x", conf->gatt_proxy); + return conf->gatt_proxy; } @@ -3791,7 +4041,11 @@ uint8_t bt_mesh_gatt_proxy_get(void) uint8_t bt_mesh_default_ttl_get(void) { + BT_DBG("DefaultTTLGet"); + if (conf) { + BT_DBG("Val 0x%02x", conf->default_ttl); + return conf->default_ttl; } @@ -3802,7 +4056,7 @@ uint8_t *bt_mesh_label_uuid_get(uint16_t addr) { int i; - BT_DBG("addr 0x%04x", addr); + BT_DBG("LabelUUIDGet, Addr 0x%04x", addr); for (i = 0; i < ARRAY_SIZE(labels); i++) { if (labels[i].addr == addr) { @@ -3819,6 +4073,8 @@ uint8_t *bt_mesh_label_uuid_get(uint16_t addr) struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void) { + BT_DBG("HbPubGet"); + if (!conf) { return NULL; } @@ -3828,6 +4084,8 @@ struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void) void bt_mesh_hb_pub_disable(void) { + BT_DBG("HbPubDisable"); + if (conf) { hb_pub_disable(conf); } @@ -3835,6 +4093,8 @@ void bt_mesh_hb_pub_disable(void) struct bt_mesh_cfg_srv *bt_mesh_cfg_get(void) { + BT_DBG("CfgGet, Conf %p", conf); + return conf; } @@ -3842,7 +4102,7 @@ void bt_mesh_subnet_del(struct bt_mesh_subnet *sub, bool store) { int i; - BT_DBG("NetIdx 0x%03x store %u", sub->net_idx, store); + BT_DBG("SubnetDel, NetIdx 0x%04x Store %u", sub->net_idx, store); if (conf && conf->hb_pub.net_idx == sub->net_idx) { hb_pub_disable(conf); diff --git a/components/bt/esp_ble_mesh/core/crypto.c b/components/bt/esp_ble_mesh/core/crypto.c index 2577c65efba2..a9991e324b36 100644 --- a/components/bt/esp_ble_mesh/core/crypto.c +++ b/components/bt/esp_ble_mesh/core/crypto.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,9 +24,9 @@ #if CONFIG_BLE_MESH_V11_SUPPORT #include "mesh_v1.1/utils.h" -#endif +#endif /* CONFIG_BLE_MESH_V11_SUPPORT */ -#define NET_MIC_LEN(pdu) (((pdu)[1] & 0x80) ? 8 : 4) +#define NET_MIC_LEN(pdu) (((pdu)[1] & 0x80) ? 8 : 4) #define APP_MIC_LEN(aszmic) ((aszmic) ? 8 : 4) int bt_mesh_aes_cmac(const uint8_t key[16], struct bt_mesh_sg *sg, @@ -369,10 +369,11 @@ static int bt_mesh_ccm_encrypt(const uint8_t key[16], uint8_t nonce[13], size_t i = 0U, j = 0U; int err = 0; - BT_DBG("key %s", bt_hex(key, 16)); - BT_DBG("nonce %s", bt_hex(nonce, 13)); - BT_DBG("msg (len %u) %s", msg_len, bt_hex(msg, msg_len)); - BT_DBG("aad_len %u mic_size %u", aad_len, mic_size); + BT_DBG("CCMEncrypt"); + BT_DBG("Key %s", bt_hex(key, 16)); + BT_DBG("Nonce %s", bt_hex(nonce, 13)); + BT_DBG("Len %u: %s", msg_len, bt_hex(msg, msg_len)); + BT_DBG("AADLen %u MicSize %u", aad_len, mic_size); /* Unsupported AAD size */ if (aad_len >= 0xff00) { @@ -580,7 +581,7 @@ int bt_mesh_net_obfuscate(uint8_t *pdu, uint32_t iv_index, uint8_t tmp[16] = {0}; int err = 0, i; - BT_DBG("IVIndex %u, PrivacyKey %s", iv_index, bt_hex(privacy_key, 16)); + BT_DBG("IVIndex %lu PrivacyKey %s", iv_index, bt_hex(privacy_key, 16)); sys_put_be32(iv_index, &priv_rand[5]); memcpy(&priv_rand[9], &pdu[7], 7); @@ -589,6 +590,7 @@ int bt_mesh_net_obfuscate(uint8_t *pdu, uint32_t iv_index, err = bt_mesh_encrypt_be(privacy_key, priv_rand, tmp); if (err) { + BT_ERR("NetObfuscateFailed (%d)", err); return err; } @@ -606,9 +608,9 @@ int bt_mesh_net_encrypt(const uint8_t key[16], struct net_buf_simple *buf, uint8_t nonce[13] = {0}; int err = 0; - BT_DBG("IVIndex %u EncKey %s mic_len %u", iv_index, bt_hex(key, 16), - mic_len); - BT_DBG("PDU (len %u) %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("IVIndex %u EncKey %s MicLen %u proxy %u/%u", + iv_index, bt_hex(key, 16), mic_len, proxy, proxy_solic); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); #if CONFIG_BLE_MESH_PROXY if (proxy) { @@ -633,6 +635,8 @@ int bt_mesh_net_encrypt(const uint8_t key[16], struct net_buf_simple *buf, NULL, 0, &buf->data[7], mic_len); if (!err) { net_buf_simple_add(buf, mic_len); + } else { + BT_ERR("NetEncryptFailed (%d)", err); } return err; @@ -643,10 +647,11 @@ int bt_mesh_net_decrypt(const uint8_t key[16], struct net_buf_simple *buf, { uint8_t mic_len = NET_MIC_LEN(buf->data); uint8_t nonce[13] = {0}; + int err; - BT_DBG("PDU (%u bytes) %s", buf->len, bt_hex(buf->data, buf->len)); - BT_DBG("iv_index %u, key %s mic_len %u", iv_index, bt_hex(key, 16), - mic_len); + BT_DBG("IVIndex %u EncKey %s MicLen %u proxy %u/%u", + iv_index, bt_hex(key, 16), mic_len, proxy, proxy_solic); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); #if CONFIG_BLE_MESH_PROXY if (proxy) { @@ -669,8 +674,13 @@ int bt_mesh_net_decrypt(const uint8_t key[16], struct net_buf_simple *buf, buf->len -= mic_len; - return bt_mesh_ccm_decrypt(key, nonce, &buf->data[7], buf->len - 7, - NULL, 0, &buf->data[7], mic_len); + err = bt_mesh_ccm_decrypt(key, nonce, &buf->data[7], buf->len - 7, + NULL, 0, &buf->data[7], mic_len); + if (err) { + BT_ERR("NetDecrypt failed (%d)", err); + } + + return err; } static void create_app_nonce(uint8_t nonce[13], bool dev_key, uint8_t aszmic, @@ -698,14 +708,15 @@ int bt_mesh_app_encrypt(const uint8_t key[16], bool dev_key, uint8_t aszmic, uint8_t nonce[13] = {0}; int err = 0; + BT_DBG("AppEncrypt"); BT_DBG("AppKey %s", bt_hex(key, 16)); - BT_DBG("dev_key %u src 0x%04x dst 0x%04x", dev_key, src, dst); - BT_DBG("seq_num 0x%08x iv_index 0x%08x", seq_num, iv_index); - BT_DBG("Clear: %s", bt_hex(buf->data, buf->len)); + BT_DBG("DevKey %u Src 0x%04x Dst 0x%04x", dev_key, src, dst); + BT_DBG("SeqNum 0x%08lx IVIndex 0x%08lx", seq_num, iv_index); + BT_DBG("Data %u %s", buf->len, bt_hex(buf->data, buf->len)); create_app_nonce(nonce, dev_key, aszmic, src, dst, seq_num, iv_index); - BT_DBG("Nonce %s", bt_hex(nonce, 13)); + BT_DBG("Nonce %s", bt_hex(nonce, 13)); err = bt_mesh_ccm_encrypt(key, nonce, buf->data, buf->len, ad, ad ? 16 : 0, buf->data, APP_MIC_LEN(aszmic)); @@ -725,12 +736,12 @@ int bt_mesh_app_decrypt(const uint8_t key[16], bool dev_key, uint8_t aszmic, uint8_t nonce[13] = {0}; int err = 0; - BT_DBG("EncData (len %u) %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("EncData %u %s", buf->len, bt_hex(buf->data, buf->len)); create_app_nonce(nonce, dev_key, aszmic, src, dst, seq_num, iv_index); BT_DBG("AppKey %s", bt_hex(key, 16)); - BT_DBG("Nonce %s", bt_hex(nonce, 13)); + BT_DBG("Nonce %s", bt_hex(nonce, 13)); err = bt_mesh_ccm_decrypt(key, nonce, buf->data, buf->len, ad, ad ? 16 : 0, out->data, APP_MIC_LEN(aszmic)); diff --git a/components/bt/esp_ble_mesh/core/ext_adv.c b/components/bt/esp_ble_mesh/core/ext_adv.c new file mode 100644 index 000000000000..8b85076aedbe --- /dev/null +++ b/components/bt/esp_ble_mesh/core/ext_adv.c @@ -0,0 +1,502 @@ +/* Bluetooth Mesh */ + +/* + * SPDX-FileCopyrightText: 2017 Intel Corporation + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include "mesh/kernel.h" +#include "mesh.h" +#include "mesh/hci.h" +#include "mesh/common.h" +#include "mesh/ffs.h" +#include "ext_adv.h" +#include "beacon.h" +#include "prov_common.h" +#include "foundation.h" +#include "proxy_server.h" +#include "proxy_client.h" +#include "prov_pvnr.h" +#include "mesh/adapter.h" + +#include "adv_common.h" +#include "ble_adv.h" + +static struct bt_mesh_adv_inst *adv_insts; + +static int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration) +{ + struct net_buf *buf = inst->sending_buf; + const struct bt_mesh_send_cb *cb = BLE_MESH_ADV(buf)->cb; + void *cb_data = BLE_MESH_ADV(buf)->cb_data; + struct bt_mesh_adv_param param = {0}; + uint16_t duration = 0U, adv_int = 0U; + uint8_t adv_cnt = 0; + struct bt_mesh_adv_data ad = {0}; + int err = 0; +#if CONFIG_BLE_MESH_EXT_ADV + uint8_t is_ext_adv = false; +#endif + + BT_DBG("ExtAdvSend, Type %u", BLE_MESH_ADV(buf)->type); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); + + switch (BLE_MESH_ADV(buf)->type) { +#if CONFIG_BLE_MESH_EXT_ADV + case BLE_MESH_ADV_EXT_PROV: + case BLE_MESH_ADV_EXT_DATA: + case BLE_MESH_ADV_EXT_RELAY_DATA: +#if CONFIG_BLE_MESH_LONG_PACKET + case BLE_MESH_ADV_EXT_LONG_PROV: + 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; + } +#endif /* CONFIG_BLE_MESH_EXT_ADV */ + case BLE_MESH_ADV_PROV: + case BLE_MESH_ADV_DATA: +#if CONFIG_BLE_MESH_FRIEND + case BLE_MESH_ADV_FRIEND: +#endif /* CONFIG_BLE_MESH_FRIEND */ +#if CONFIG_BLE_MESH_RELAY_ADV_BUF + case BLE_MESH_ADV_RELAY_DATA: +#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */ +#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX + case BLE_MESH_ADV_PROXY_SOLIC: +#endif /* CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX */ + case BLE_MESH_ADV_BEACON: + case BLE_MESH_ADV_URI: { +#if CONFIG_BLE_MESH_EXT_ADV + if (is_ext_adv) { + param.primary_phy = EXT_ADV(buf)->primary_phy; + param.secondary_phy = EXT_ADV(buf)->secondary_phy; + param.include_tx_power = EXT_ADV(buf)->include_tx_power; + param.tx_power = EXT_ADV(buf)->tx_power; + } else +#endif + { + param.primary_phy = BLE_MESH_ADV_PRI_PHY_DEFAULT; + param.secondary_phy = BLE_MESH_ADV_SEC_PHY_DEFAULT; + param.include_tx_power = BLE_MESH_TX_POWER_INCLUDE_DEFAULT; + param.tx_power = BLE_MESH_TX_POWER_DEFAULT; + } + + if (BLE_MESH_ADV(buf)->adv_itvl != BLE_MESH_ADV_ITVL_DEFAULT) { + adv_int = MAX(ADV_ITVL_MIN, BLE_MESH_ADV(buf)->adv_itvl); + } else { + adv_int = MAX(ADV_ITVL_MIN, + BLE_MESH_TRANSMIT_INT(BLE_MESH_ADV(buf)->xmit)); + } + + if (BLE_MESH_ADV(buf)->adv_cnt != BLE_MESH_ADV_CNT_DEFAULT) { + adv_cnt = BLE_MESH_ADV(buf)->adv_cnt; + } else { + adv_cnt = BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1; + } + + duration = adv_cnt * (adv_int + 10); + + BT_DBG("count %u interval %ums duration %ums", + adv_cnt, adv_int, duration); + + ad.type = adv_type[BLE_MESH_ADV(buf)->type]; + ad.data_len = buf->len; + ad.data = buf->data; + + param.options = 0U; + param.interval_min = ADV_SCAN_UNIT(adv_int); + param.interval_max = param.interval_min; + + param.adv_duration = duration; + param.adv_count = adv_cnt; + + if (BLE_MESH_ADV(buf)->channel_map) { + param.channel_map = BLE_MESH_ADV(buf)->channel_map; + } else { + param.channel_map = BLE_MESH_ADV_CHAN_DEFAULT; + } + +#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX + if (BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_PROXY_SOLIC) { + bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL); + + struct bt_mesh_adv_data solic_ad[2] = { + BLE_MESH_ADV_DATA_BYTES(BLE_MESH_DATA_UUID16_ALL, 0x59, 0x18), + BLE_MESH_ADV_DATA(BLE_MESH_DATA_SVC_DATA16, buf->data, buf->len), + }; + + err = bt_le_ext_adv_start(CONFIG_BLE_MESH_ADV_INST_ID, ¶m, + solic_ad, ARRAY_SIZE(solic_ad), NULL, 0); + } else +#endif /* CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX */ + { + bt_mesh_adv_buf_ref_debug(__func__, buf, 4U, BLE_MESH_BUF_REF_SMALL); + + err = bt_le_ext_adv_start(inst->id, ¶m, &ad, 1, NULL, 0); + } + } + break; + +#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV + case BLE_MESH_ADV_BLE: + struct bt_mesh_ble_adv_data data = {0}; + struct bt_mesh_ble_adv_tx *tx = cb_data; + + if (tx == NULL) { + BT_ERR("Invalid adv user data"); + net_buf_unref(buf); + return -EINVAL; + } + + BT_DBG("interval %dms, duration %dms, period %dms, count %d", + ADV_SCAN_INT(tx->param.interval), tx->param.duration, + tx->param.period, tx->param.count); + + data.adv_data_len = tx->buf->data[0]; + if (data.adv_data_len) { + memcpy(data.adv_data, tx->buf->data + 1, data.adv_data_len); + } + data.scan_rsp_data_len = tx->buf->data[data.adv_data_len + 1]; + if (data.scan_rsp_data_len) { + memcpy(data.scan_rsp_data, tx->buf->data + data.adv_data_len + 2, data.scan_rsp_data_len); + } + duration = tx->param.duration; + + bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL); + + err = bt_mesh_ble_ext_adv_start(inst->id, &tx->param, &data); + break; +#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */ + + default: + BT_ERR("InvalidAdvType %u", BLE_MESH_ADV(buf)->type); + break; + } + + adv_send_start(duration, err, cb, cb_data); + if (err) { + BT_ERR("Start advertising failed: err %d", err); + return err; + } + + *adv_duration = duration; + + BT_DBG("Advertising started. %u ms", duration); + return 0; +} + +static int find_valid_msg_from_queue(bt_mesh_queue_t *msg_queue, bt_mesh_msg_t *msg) +{ + BT_DBG("FindValidMsgFromQueue"); + + while(uxQueueMessagesWaiting(msg_queue->handle)) { + xQueueReceive(msg_queue->handle, msg, K_WAIT(K_FOREVER)); + + /* In the previous adv task design, only the *buf of messages pushed to the queue + * by adv_update would be empty, but in the new design, there is a new processing + * method for adv_update's messages, so *buf here cannot be empty. + */ + assert(msg->arg); + + BT_DBG("Buf %p Relay %u Busy %u", + BLE_MESH_MSG_NET_BUF(msg), msg->relay, + !!bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(BLE_MESH_MSG_NET_BUF(msg)))); + + /* If the message is cancelled for advertising, then continue to retrieve the next + * message from that queue. + */ + if (!bt_mesh_atomic_cas(&BLE_MESH_ADV_BUSY(BLE_MESH_MSG_NET_BUF(msg)), 1, 0)) { + bt_mesh_adv_buf_ref_debug(__func__, BLE_MESH_MSG_NET_BUF(msg), 1U, BLE_MESH_BUF_REF_EQUAL); + + /* Cancel the adv task's reference to this data packet. + * Tips: + * The reference of buffer by adv_task occurs when the buffer is pushed into + * the queue. + */ + net_buf_unref(BLE_MESH_MSG_NET_BUF(msg)); + + /* Avoid reading the last message in the queue, which could lead to pointing + * to an invalid buffer due to the absence of other messages in the queue. + */ + msg->arg = NULL; + continue; + } + +#if CONFIG_BLE_MESH_RELAY_ADV_BUF + /* If the relay message should be ignored, then continue to retrieve the next message + * from that queue. + */ + if (msg->relay && bt_mesh_ignore_relay_packet(msg->timestamp)) { + /* If the interval between "current time - msg.timestamp" is bigger than + * BLE_MESH_RELAY_TIME_INTERVAL, this relay packet will not be sent. + */ + BT_DBG("Ignore relay packet"); + + net_buf_unref(BLE_MESH_MSG_NET_BUF(msg)); + msg->arg = NULL; + continue; + } +#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */ + + break; + } + + if (msg->arg == NULL) { + return -EINVAL; + } + + return 0; +} + +static int activate_idle_adv_instance(uint32_t *update_evts, uint16_t *min_duration) +{ + uint16_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; + bt_mesh_msg_t msg = {0}; + uint32_t spt_mask = 0; + uint32_t evts = 0; + + BT_DBG("ActivateIdleAdvInst"); + +#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \ + CONFIG_BLE_MESH_GATT_PROXY_SERVER + if (!adv_insts[BLE_MESH_ADV_PROXY_INST].busy) { + BT_DBG("Mesh Proxy Advertising start"); + + duration = bt_mesh_proxy_server_adv_start(); + if (duration < cur_min_duration) { + cur_min_duration = duration; + } + + adv_insts[BLE_MESH_ADV_PROXY_INST].busy = true; + evts |= ADV_TASK_ADV_INST_EVT(adv_insts[BLE_MESH_ADV_PROXY_INST].id); + } +#endif + + for (int i = BLE_MESH_ADV_INST; i < BLE_MESH_ADV_INST_TYPES_NUM; i++) { + struct bt_mesh_adv_inst *instance = &adv_insts[i]; + + if (instance->busy +#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \ + CONFIG_BLE_MESH_GATT_PROXY_SERVER + || unlikely(instance->id == CONFIG_BLE_MESH_PROXY_ADV_INST_ID) +#endif + ) { + BT_DBG("AdvInstSkipped, InstID %u Busy %u", instance->id, instance->busy); + continue; + } + + spt_mask = instance->spt_mask; + adv_type = 0; + + while(spt_mask) { + adv_type = find_lsb_set(spt_mask) - 1; + spt_mask &= ~BIT(adv_type); + msg_queue = &(bt_mesh_adv_types_mgmt_get(adv_type)->adv_q->q); + + /* If no new message in the queue, the *buf (aka: msg.arg) will be empty */ + if (find_valid_msg_from_queue(msg_queue, &msg)) { + BT_DBG("NoMsgForAdvInst, InstID %u", instance->id); + continue; + } + + instance->sending_buf = (struct net_buf *)msg.arg; + + if (adv_send(instance, &duration)) { + /* When this adv instance fails to broadcast, it could be due to some + * persistent issues, such as incorrect adv parameter settings, or it + * could be due to some temporary issues, such as memory allocation + * failure. + * + * Therefore, it is advisable to skip subsequent queue reads for this + * instance and attempt to broadcast subsequent data again next time, + * rather than disabling the adv instance. + */ + BT_ERR("AdvSendFailed, InstID %u AdvType %u SptMask %08lx Buf %p", + instance->id, adv_type, instance->spt_mask, instance->sending_buf); + + net_buf_unref(instance->sending_buf); + instance->sending_buf = NULL; + break; + } + + BT_DBG("Activate, InstID %u AdvType %u SptMask %08lx Buf %p Duration %u/%u", + instance->id, adv_type, instance->spt_mask, + instance->sending_buf, duration, cur_min_duration); + + if (duration < cur_min_duration) { + cur_min_duration = duration; + } + + instance->busy = true; + evts |= ADV_TASK_ADV_INST_EVT(adv_insts[i].id); + + /* Must be nullified to avoid affecting the next adv instance's judgment + * on whether the message queue is empty. + */ + msg.arg = NULL; + break; + } + } + + BT_DBG("ActivateEnd, Duration %u UpdateEvts %08lx Evts%08lx", + cur_min_duration, *update_evts, evts); + + *min_duration = cur_min_duration; + *update_evts |= evts; + + return 0; +} + +static uint32_t received_adv_evts_handle(uint32_t recv_evts) +{ + BT_DBG("RecvAdvEvtsHandle, RecvEvts 0x%08lx", recv_evts); + + if (!recv_evts) { + return 0; + } + + for (int i = 0; recv_evts && i < BLE_MESH_ADV_INST_TYPES_NUM; i++) { + uint32_t evt = ADV_TASK_ADV_INST_EVT(adv_insts[i].id); + + if (recv_evts & evt) { + recv_evts &= ~evt; + +#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \ + CONFIG_BLE_MESH_GATT_PROXY_SERVER + if (unlikely(i == BLE_MESH_ADV_PROXY_INST)) { + BT_DBG("Mesh Proxy Advertising auto stop"); + + bt_mesh_proxy_server_adv_flag_set(false); + } else +#endif + { + adv_send_end(0, BLE_MESH_ADV(adv_insts[i].sending_buf)->cb, + BLE_MESH_ADV(adv_insts[i].sending_buf)->cb_data); + + 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; + } + + adv_insts[i].busy = false; + } + } + + return recv_evts; +} + +static void adv_thread(void *p) +{ + uint16_t adv_duration = K_FOREVER; + uint32_t recv_evts = 0; + uint32_t wait_evts = 0; + + BT_DBG("ExtAdvThread"); + + while (1) { + adv_duration = K_FOREVER; + wait_evts |= ADV_TASK_PKT_SEND_EVT; + + activate_idle_adv_instance(&wait_evts, &adv_duration); + + bt_mesh_adv_task_wait(wait_evts, adv_duration, &recv_evts); + + BT_DBG("WaitEvts %08lx RecvEvts %08lx", wait_evts, recv_evts); + + wait_evts &= ~recv_evts; + +#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \ + CONFIG_BLE_MESH_GATT_PROXY_SERVER + if (recv_evts & ADV_TASK_PROXY_ADV_UPD_EVT) { + adv_insts[BLE_MESH_ADV_PROXY_INST].busy = false; + recv_evts &= ~ADV_TASK_PROXY_ADV_UPD_EVT; + } +#endif + + /* The `recv_evts == ADV_TASK_PKT_SEND_EVT` indicates that new packets + * have been put into the queue, and the advertising instances started + * previously have not yet been stopped. + */ + if (recv_evts == ADV_TASK_PKT_SEND_EVT) { + continue; + } + + if (recv_evts & ADV_TASK_PKT_SEND_EVT) { + recv_evts &= ~ADV_TASK_PKT_SEND_EVT; + } + + recv_evts = received_adv_evts_handle(recv_evts); + + if (recv_evts) { + BT_ERR("RecvEvts %08lx", recv_evts); + } + } +} + +void bt_mesh_adv_update(void) +{ + BT_DBG("ExtAdvUpdate"); + +#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \ + CONFIG_BLE_MESH_GATT_PROXY_SERVER + BT_DBG("Mesh Proxy Advertising stopped manually"); + + bt_mesh_proxy_server_adv_stop(); + + if (adv_insts[BLE_MESH_ADV_PROXY_INST].busy) { + bt_mesh_adv_task_wakeup(ADV_TASK_PROXY_ADV_UPD_EVT); + } +#endif +} + +void bt_mesh_adv_init(void) +{ + BT_DBG("ExtAdvInit"); + + bt_mesh_adv_common_init(); + + adv_insts = bt_mesh_get_adv_insts_set(); + +#if CONFIG_BLE_MESH_RELAY_ADV_BUF + bt_mesh_relay_adv_init(); +#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */ + +#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV + bt_mesh_ble_adv_init(); +#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */ + + bt_mesh_adv_task_init(adv_thread); +} + +#if CONFIG_BLE_MESH_DEINIT +void bt_mesh_adv_deinit(void) +{ + BT_DBG("ExtAdvDeinit"); + + bt_mesh_adv_task_deinit(); + + bt_mesh_adv_common_deinit(); + + adv_insts = NULL; + +#if CONFIG_BLE_MESH_RELAY_ADV_BUF + bt_mesh_relay_adv_deinit(); +#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */ + +#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV + bt_mesh_ble_adv_deinit(); +#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */ +} +#endif /* CONFIG_BLE_MESH_DEINIT */ diff --git a/components/bt/esp_ble_mesh/core/ext_adv.h b/components/bt/esp_ble_mesh/core/ext_adv.h new file mode 100644 index 000000000000..eaa9c4f81973 --- /dev/null +++ b/components/bt/esp_ble_mesh/core/ext_adv.h @@ -0,0 +1,33 @@ +/* Bluetooth Mesh */ + +/* + * SPDX-FileCopyrightText: 2017 Intel Corporation + * SPDX-FileContributor: 2024-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _EXT_ADV_H_ +#define _EXT_ADV_H_ + +#include "mesh/atomic.h" +#include "mesh/access.h" +#include "mesh/adapter.h" +#include "mesh/queue.h" +#include "adv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void bt_mesh_adv_update(void); + +void bt_mesh_adv_init(void); + +void bt_mesh_adv_deinit(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _EXT_ADV_H_ */ diff --git a/components/bt/esp_ble_mesh/core/fast_prov.c b/components/bt/esp_ble_mesh/core/fast_prov.c index 049a12bb438c..3fe9b742483d 100644 --- a/components/bt/esp_ble_mesh/core/fast_prov.c +++ b/components/bt/esp_ble_mesh/core/fast_prov.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,12 +27,15 @@ const uint8_t *bt_mesh_fast_prov_dev_key_get(uint16_t dst) { const uint8_t *key = NULL; + BT_DBG("FastProvDevKeyGet, Dst 0x%04x", dst); + if (!BLE_MESH_ADDR_IS_UNICAST(dst)) { BT_ERR("Invalid unicast address 0x%04x", dst); return NULL; } if (bt_mesh_is_provisioner_en() == false) { + BT_DBG("NodeDevKey"); return bt_mesh.dev_key; } @@ -42,9 +45,11 @@ const uint8_t *bt_mesh_fast_prov_dev_key_get(uint16_t dst) */ key = bt_mesh_provisioner_dev_key_get(dst); if (key) { + BT_DBG("PvnrDevKey"); return key; } + BT_DBG("NodeDevKeyFinal"); return bt_mesh.dev_key; } @@ -53,9 +58,12 @@ struct bt_mesh_subnet *bt_mesh_fast_prov_subnet_get(uint16_t net_idx) struct bt_mesh_subnet *sub = NULL; int i; + BT_DBG("FastProvSubnetGet, NetIdx 0x%04x", net_idx); + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { sub = &bt_mesh.sub[i]; if (sub->net_idx == net_idx) { + BT_DBG("NodeSub"); return sub; } } @@ -63,10 +71,12 @@ struct bt_mesh_subnet *bt_mesh_fast_prov_subnet_get(uint16_t net_idx) for (i = 0; i < ARRAY_SIZE(bt_mesh.p_sub); i++) { sub = bt_mesh.p_sub[i]; if (sub && sub->net_idx == net_idx) { + BT_DBG("PvnrSub"); return sub; } } + BT_DBG("NoSub"); return NULL; } @@ -75,10 +85,13 @@ struct bt_mesh_app_key *bt_mesh_fast_prov_app_key_find(uint16_t app_idx) struct bt_mesh_app_key *key = NULL; int i; + BT_DBG("FastProvAppKeyFind, AppIdx 0x%04x", app_idx); + for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { key = &bt_mesh.app_keys[i]; if (key->net_idx != BLE_MESH_KEY_UNUSED && key->app_idx == app_idx) { + BT_DBG("NodeAppKey"); return key; } } @@ -87,15 +100,19 @@ struct bt_mesh_app_key *bt_mesh_fast_prov_app_key_find(uint16_t app_idx) key = bt_mesh.p_app_keys[i]; if (key && key->net_idx != BLE_MESH_KEY_UNUSED && key->app_idx == app_idx) { + BT_DBG("PvnrAppKey"); return key; } } + BT_DBG("NoAppKey"); return NULL; } uint8_t bt_mesh_set_fast_prov_net_idx(uint16_t net_idx) { + BT_DBG("SetFastProvNetIdx, NetIdx 0x%04x", net_idx); + /* Set net_idx for fast provisioning */ bt_mesh_provisioner_set_fast_prov_net_idx(net_idx); @@ -116,6 +133,8 @@ uint8_t bt_mesh_fast_prov_net_key_add(const uint8_t net_key[16]) net_idx = bt_mesh_provisioner_get_fast_prov_net_idx(); bt_mesh.p_net_idx_next = net_idx; + BT_DBG("FastProvNetKeyAdd, NetIdx 0x%04x", net_idx); + err = bt_mesh_provisioner_local_net_key_add(net_key, &net_idx); if (err) { BT_ERR("Invalid NetKeyIndex 0x%04x", net_idx); @@ -130,12 +149,16 @@ const uint8_t *bt_mesh_fast_prov_net_key_get(uint16_t net_idx) { struct bt_mesh_subnet *sub = NULL; + BT_DBG("FastProvNetKeyGet, NetIdx 0x%04x", net_idx); + sub = bt_mesh_fast_prov_subnet_get(net_idx); if (!sub) { BT_ERR("Invalid NetKeyIndex 0x%04x", net_idx); return NULL; } + BT_DBG("KrFlag %u", sub->kr_flag); + return (sub->kr_flag ? sub->keys[1].net : sub->keys[0].net); } @@ -143,17 +166,23 @@ const uint8_t *bt_mesh_get_fast_prov_app_key(uint16_t net_idx, uint16_t app_idx) { struct bt_mesh_app_key *key = NULL; + BT_DBG("GetFastProvAppKey, NetIdx 0x%04x AppIdx 0x%04x", net_idx, app_idx); + key = bt_mesh_fast_prov_app_key_find(app_idx); if (!key) { BT_ERR("Invalid AppKeyIndex 0x%04x", app_idx); return NULL; } + BT_DBG("KeyUpdated %u", key->updated); + return (key->updated ? key->keys[1].val : key->keys[0].val); } uint8_t bt_mesh_set_fast_prov_action(uint8_t action) { + BT_DBG("SetFastProvAction, Action %u", action); + if (!action || action > ACTION_EXIT) { return 0x01; } @@ -168,9 +197,11 @@ uint8_t bt_mesh_set_fast_prov_action(uint8_t action) if (bt_mesh_secure_beacon_get() == BLE_MESH_SECURE_BEACON_ENABLED) { bt_mesh_secure_beacon_disable(); } + if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) { bt_mesh_proxy_client_prov_enable(); } + bt_mesh_provisioner_set_primary_elem_addr(bt_mesh_primary_addr()); bt_mesh_provisioner_set_prov_bearer(BLE_MESH_PROV_ADV, false); bt_mesh_provisioner_fast_prov_enable(true); @@ -179,11 +210,15 @@ uint8_t bt_mesh_set_fast_prov_action(uint8_t action) if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) { bt_mesh_proxy_client_prov_disable(); } + if (bt_mesh_secure_beacon_get() == BLE_MESH_SECURE_BEACON_ENABLED) { bt_mesh_secure_beacon_enable(); } + bt_mesh_atomic_and(bt_mesh.flags, ~(BIT(BLE_MESH_PROVISIONER) | BIT(BLE_MESH_VALID_PROV))); + bt_mesh_provisioner_fast_prov_enable(false); + if (action == ACTION_EXIT) { bt_mesh_provisioner_remove_node(NULL); } @@ -191,4 +226,5 @@ uint8_t bt_mesh_set_fast_prov_action(uint8_t action) return 0x0; } + #endif /* CONFIG_BLE_MESH_FAST_PROV */ diff --git a/components/bt/esp_ble_mesh/core/foundation.h b/components/bt/esp_ble_mesh/core/foundation.h index 4f3aa79ad11a..66f8c5ea2b8c 100644 --- a/components/bt/esp_ble_mesh/core/foundation.h +++ b/components/bt/esp_ble_mesh/core/foundation.h @@ -287,6 +287,7 @@ uint8_t bt_mesh_default_ttl_get(void); void bt_mesh_subnet_del(struct bt_mesh_subnet *sub, bool store); struct bt_mesh_app_key *bt_mesh_app_key_alloc(uint16_t app_idx); + void bt_mesh_app_key_del(struct bt_mesh_app_key *key, bool store); static inline void key_idx_pack(struct net_buf_simple *buf, diff --git a/components/bt/esp_ble_mesh/core/friend.c b/components/bt/esp_ble_mesh/core/friend.c index aa9607492b22..e31810e26326 100644 --- a/components/bt/esp_ble_mesh/core/friend.c +++ b/components/bt/esp_ble_mesh/core/friend.c @@ -91,6 +91,9 @@ static struct bt_mesh_adv *adv_alloc(int id) static bool is_lpn_unicast(struct bt_mesh_friend *frnd, uint16_t addr) { + BT_INFO("IsLPNUnicast, LPN 0x%04x NumElem %u Addr 0x%04x", + frnd->lpn, frnd->num_elem, addr); + if (frnd->lpn == BLE_MESH_ADDR_UNASSIGNED) { return false; } @@ -103,11 +106,16 @@ struct bt_mesh_friend *bt_mesh_friend_find(uint16_t net_idx, uint16_t lpn_addr, { int i; - BT_DBG("net_idx 0x%04x lpn_addr 0x%04x", net_idx, lpn_addr); + BT_DBG("FrndFind"); + BT_DBG("NetIdx 0x%04x LPN 0x%04x Valid %u Established %u", + net_idx, lpn_addr, valid, established); for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; + BT_DBG("%u: LPN 0x%04x NetIdx 0x%04x Valid %u Established %u", + i, frnd->lpn, frnd->net_idx, frnd->valid, frnd->established); + if (valid && !frnd->valid) { continue; } @@ -130,11 +138,15 @@ struct bt_mesh_friend *bt_mesh_friend_find(uint16_t net_idx, uint16_t lpn_addr, static void purge_buffers(sys_slist_t *list) { + BT_DBG("PurgeBuffers"); + while (!sys_slist_is_empty(list)) { struct net_buf *buf = NULL; buf = (void *)sys_slist_get_not_empty(list); + BT_DBG("Buf %p Ref %u", buf, buf->ref); + buf->frags = NULL; buf->flags &= ~NET_BUF_FRAGS; @@ -149,18 +161,21 @@ static void purge_buffers(sys_slist_t *list) */ static int32_t recv_delay(struct bt_mesh_friend *frnd) { + BT_DBG("RecvDelay, LPN 0x%04x RecvWin %u RecvDelay %u", + frnd->lpn, CONFIG_BLE_MESH_FRIEND_RECV_WIN, frnd->recv_delay); + #if CONFIG_BLE_MESH_FRIEND_RECV_WIN > 50 return (int32_t)frnd->recv_delay + (CONFIG_BLE_MESH_FRIEND_RECV_WIN / 5); -#else +#else /* CONFIG_BLE_MESH_FRIEND_RECV_WIN > 50 */ return frnd->recv_delay; -#endif +#endif /* CONFIG_BLE_MESH_FRIEND_RECV_WIN > 50 */ } static void friend_clear(struct bt_mesh_friend *frnd, uint8_t reason) { int i; - BT_DBG("LPN 0x%04x", frnd->lpn); + BT_DBG("FrndClear, LPN 0x%04x Reason 0x%02x", frnd->lpn, reason); k_delayed_work_cancel(&frnd->timer); @@ -182,9 +197,13 @@ static void friend_clear(struct bt_mesh_friend *frnd, uint8_t reason) friend_cred_del(frnd->net_idx, frnd->lpn); if (frnd->last) { + BT_DBG("FrndLast, Buf %p Ref %u PendingBuf %u", + frnd->last, frnd->last->ref, frnd->pending_buf); + /* Cancel the sending if necessary */ if (frnd->pending_buf) { bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 2U, BLE_MESH_BUF_REF_EQUAL); + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(frnd->last), 0); } else { bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 1U, BLE_MESH_BUF_REF_EQUAL); @@ -199,6 +218,8 @@ static void friend_clear(struct bt_mesh_friend *frnd, uint8_t reason) for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) { struct bt_mesh_friend_seg *seg = &frnd->seg[i]; + BT_DBG("%u: SegCount %u", i, seg->seg_count); + purge_buffers(&seg->queue); seg->seg_count = 0U; } @@ -216,11 +237,13 @@ void bt_mesh_friend_clear_net_idx(uint16_t net_idx) { int i; - BT_DBG("net_idx 0x%04x", net_idx); + BT_DBG("FrndClearNetIdx, NetIdx 0x%04x", net_idx); for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; + BT_DBG("%u: LPN 0x%04x NetIdx 0x%04x", i, frnd->lpn, frnd->net_idx); + if (frnd->net_idx == BLE_MESH_KEY_UNUSED) { continue; } @@ -235,11 +258,13 @@ void bt_mesh_friend_sec_update(uint16_t net_idx) { int i; - BT_DBG("net_idx 0x%04x", net_idx); + BT_DBG("FrndSecUpdate, NetIdx 0x%04x", net_idx); for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; + BT_DBG("%u: NetIdx 0x%04x", i, frnd->net_idx); + if (frnd->net_idx == BLE_MESH_KEY_UNUSED) { continue; } @@ -279,19 +304,21 @@ int bt_mesh_friend_clear(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) }; struct bt_mesh_ctl_friend_clear_confirm cfm = {0}; + BT_DBG("FrndClear, NetIdx 0x%04x", rx->sub->net_idx); + if (buf->len < sizeof(*msg)) { - BT_WARN("Too short Friend Clear (len %d)", buf->len); + BT_WARN("Too short FriendClear (len %d)", buf->len); return -EINVAL; } lpn_addr = sys_be16_to_cpu(msg->lpn_addr); lpn_counter = sys_be16_to_cpu(msg->lpn_counter); - BT_DBG("LPN addr 0x%04x counter 0x%04x", lpn_addr, lpn_counter); + BT_DBG("LPN 0x%04x Counter %u", lpn_addr, lpn_counter); frnd = bt_mesh_friend_find(rx->sub->net_idx, lpn_addr, false, false); if (!frnd) { - BT_WARN("No matching LPN addr 0x%04x", lpn_addr); + BT_WARN("NoMatchLPN, Addr 0x%04x", lpn_addr); return 0; } @@ -327,6 +354,8 @@ static bool friend_sub_exist(struct bt_mesh_friend *frnd, uint16_t addr) { int i; + BT_DBG("IsFrndSubExist, Addr 0x%04x", addr); + for (i = 0; i < ARRAY_SIZE(frnd->sub_list); i++) { if (frnd->sub_list[i] == addr) { return true; @@ -340,6 +369,8 @@ static void friend_sub_add(struct bt_mesh_friend *frnd, uint16_t addr) { int i; + BT_DBG("FrndSubAdd, Addr 0x%04x", addr); + for (i = 0; i < ARRAY_SIZE(frnd->sub_list); i++) { if (frnd->sub_list[i] == BLE_MESH_ADDR_UNASSIGNED) { frnd->sub_list[i] = addr; @@ -354,6 +385,8 @@ static void friend_sub_rem(struct bt_mesh_friend *frnd, uint16_t addr) { int i; + BT_DBG("FrndSubRem, Addr 0x%04x", addr); + for (i = 0; i < ARRAY_SIZE(frnd->sub_list); i++) { if (frnd->sub_list[i] == addr) { frnd->sub_list[i] = BLE_MESH_ADDR_UNASSIGNED; @@ -408,6 +441,10 @@ static int unseg_app_sdu_unpack(struct bt_mesh_friend *frnd, uint16_t app_idx = FRIEND_ADV(buf)->app_idx; int err = 0; + BT_DBG("UnsegAppSduUnpack"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x RecvDst 0x%04x", + frnd->net_idx, app_idx, meta->net.ctx.recv_dst); + meta->subnet = friend_subnet_get(frnd->net_idx); if (!meta->subnet) { BT_ERR("Invalid subnet for unseg app sdu"); @@ -416,6 +453,7 @@ static int unseg_app_sdu_unpack(struct bt_mesh_friend *frnd, meta->is_dev_key = (app_idx == BLE_MESH_KEY_DEV); bt_mesh_net_header_parse(&buf->b, &meta->net); + err = bt_mesh_upper_key_get(meta->subnet, app_idx, &meta->key, &meta->aid, meta->net.ctx.addr); if (err) { @@ -446,6 +484,8 @@ static int unseg_app_sdu_decrypt(struct bt_mesh_friend *frnd, net_buf_simple_pull(&sdu, 10); sdu.len -= 4; + BT_DBG("UnsegAppSduDecrypt, SduLen %u", sdu.len); + return bt_mesh_app_decrypt(meta->key, meta->is_dev_key, 0, &sdu, &sdu, meta->ad, meta->net.ctx.addr, meta->net.ctx.recv_dst, meta->net.seq, @@ -462,6 +502,8 @@ static int unseg_app_sdu_encrypt(struct bt_mesh_friend *frnd, net_buf_simple_pull(&sdu, 10); sdu.len -= 4; + BT_DBG("UnsegAppSduEncrypt, SduLen %u", sdu.len); + return bt_mesh_app_encrypt(meta->key, meta->is_dev_key, 0, &sdu, meta->ad, meta->net.ctx.addr, meta->net.ctx.recv_dst, bt_mesh.seq, @@ -474,6 +516,10 @@ static int unseg_app_sdu_prepare(struct bt_mesh_friend *frnd, struct unseg_app_sdu_meta meta = {0}; int err = 0; + BT_DBG("UnsegAppSduPrepare"); + BT_DBG("LPN 0x%04x AppIdx 0x%04x Buf %p", + frnd->lpn, FRIEND_ADV(buf)->app_idx, buf); + if (FRIEND_ADV(buf)->app_idx == BLE_MESH_KEY_UNUSED) { return 0; } @@ -487,6 +533,7 @@ static int unseg_app_sdu_prepare(struct bt_mesh_friend *frnd, * unchanged. */ if (meta.net.seq == bt_mesh.seq) { + BT_DBG("Seq 0x%06x", bt_mesh.seq); return 0; } @@ -514,8 +561,11 @@ static int encrypt_friend_pdu(struct bt_mesh_friend *frnd, struct net_buf *buf, uint8_t nid = 0U; int err = 0; + BT_DBG("EncryptFrndPDU, LPN 0x%04x NetIdx 0x%04x Cred %u", + frnd->lpn, frnd->net_idx, master_cred); + if (!sub) { - BT_ERR("Invalid subnet to encrypt friend pdu"); + BT_ERR("NoSubToEncryptFrndPDU"); return -EINVAL; } @@ -525,7 +575,7 @@ static int encrypt_friend_pdu(struct bt_mesh_friend *frnd, struct net_buf *buf, nid = sub->keys[sub->kr_flag].nid; } else { if (friend_cred_get(sub, frnd->lpn, &nid, &enc, &priv)) { - BT_ERR("friend_cred_get failed"); + BT_ERR("FrndCredNotFound"); return -ENOENT; } } @@ -538,6 +588,7 @@ static int encrypt_friend_pdu(struct bt_mesh_friend *frnd, struct net_buf *buf, if (FRIEND_ADV(buf)->app_idx != BLE_MESH_KEY_UNUSED) { err = unseg_app_sdu_prepare(frnd, buf); if (err) { + BT_DBG("UnsegAppSduPrepareFailed, Err %d", err); return err; } } @@ -552,15 +603,15 @@ static int encrypt_friend_pdu(struct bt_mesh_friend *frnd, struct net_buf *buf, iv_index = (bt_mesh.iv_index - ((bt_mesh.iv_index & 1) != ivi)); } + BT_DBG("Src 0x%04x NID 0x%02x IVIndex 0x%08lx", src, nid, iv_index); + buf->data[0] = (nid | (iv_index & 1) << 7); if (bt_mesh_net_encrypt(enc, &buf->b, iv_index, false, false)) { - BT_ERR("Encrypting failed"); return -EINVAL; } if (bt_mesh_net_obfuscate(buf->data, iv_index, priv)) { - BT_ERR("Obfuscating failed"); return -EINVAL; } @@ -573,7 +624,7 @@ static struct net_buf *encode_friend_ctl(struct bt_mesh_friend *frnd, { struct friend_pdu_info info = {0}; - BT_DBG("LPN 0x%04x", frnd->lpn); + BT_DBG("EncodeFrndCTL"); net_buf_simple_push_u8(sdu, TRANS_CTL_HDR(ctl_op, 0)); @@ -587,21 +638,25 @@ static struct net_buf *encode_friend_ctl(struct bt_mesh_friend *frnd, info.iv_index = BLE_MESH_NET_IVI_TX; + BT_DBG("CTLOp 0x%02x IVIndex 0x%08lx", ctl_op, info.iv_index); + return create_friend_pdu(frnd, &info, sdu); } static struct net_buf *encode_update(struct bt_mesh_friend *frnd, uint8_t md) { + struct bt_mesh_subnet *sub = friend_subnet_get(frnd->net_idx); struct bt_mesh_ctl_friend_update *upd = NULL; NET_BUF_SIMPLE_DEFINE(sdu, 1 + sizeof(*upd)); - struct bt_mesh_subnet *sub = friend_subnet_get(frnd->net_idx); + + BT_DBG("EncodeUpdate, NetIdx 0x%04x", frnd->net_idx); if (!sub) { BT_ERR("Friend subnet 0x%04x not found", frnd->net_idx); return NULL; } - BT_DBG("lpn 0x%04x md 0x%02x", frnd->lpn, md); + BT_DBG("LPN 0x%04x MD %u", frnd->lpn, md); net_buf_simple_reserve(&sdu, 1); @@ -619,7 +674,7 @@ static void enqueue_sub_cfm(struct bt_mesh_friend *frnd, uint8_t xact) NET_BUF_SIMPLE_DEFINE(sdu, 1 + sizeof(*cfm)); struct net_buf *buf = NULL; - BT_DBG("lpn 0x%04x xact 0x%02x", frnd->lpn, xact); + BT_DBG("EnqueueSubCFM, LPN 0x%04x Xact 0x%02x", frnd->lpn, xact); net_buf_simple_reserve(&sdu, 1); @@ -637,7 +692,7 @@ static void enqueue_sub_cfm(struct bt_mesh_friend *frnd, uint8_t xact) } if (frnd->last) { - BT_DBG("Discarding last PDU"); + BT_DBG("DiscardFrndLast, Buf %p Ref %u", frnd->last, frnd->last->ref); net_buf_unref(frnd->last); } @@ -647,9 +702,12 @@ static void enqueue_sub_cfm(struct bt_mesh_friend *frnd, uint8_t xact) static void friend_recv_delay(struct bt_mesh_friend *frnd) { + int32_t delay = recv_delay(frnd); + + BT_INFO("FrndRecvDelay, Delay %ld", delay); + frnd->pending_req = 1U; - k_delayed_work_submit(&frnd->timer, recv_delay(frnd)); - BT_INFO("Waiting RecvDelay of %d ms", recv_delay(frnd)); + k_delayed_work_submit(&frnd->timer, delay); } int bt_mesh_friend_sub_add(struct bt_mesh_net_rx *rx, @@ -658,6 +716,8 @@ int bt_mesh_friend_sub_add(struct bt_mesh_net_rx *rx, struct bt_mesh_friend *frnd = NULL; uint8_t xact = 0U; + BT_DBG("FrndSubAdd"); + if (buf->len < BLE_MESH_FRIEND_SUB_MIN_LEN) { BT_WARN("Too short Friend Subscription Add (len %d)", buf->len); return -EINVAL; @@ -665,7 +725,7 @@ int bt_mesh_friend_sub_add(struct bt_mesh_net_rx *rx, frnd = bt_mesh_friend_find(rx->sub->net_idx, rx->ctx.addr, true, true); if (!frnd) { - BT_WARN("No matching LPN addr 0x%04x", rx->ctx.addr); + BT_WARN("NoMatchLPN, Addr 0x%04x", rx->ctx.addr); return 0; } @@ -689,6 +749,7 @@ int bt_mesh_friend_sub_add(struct bt_mesh_net_rx *rx, } if (friend_sub_exist(frnd, addr)) { + BT_DBG("FrndSubExist, Addr 0x%04x", addr); continue; } @@ -699,9 +760,9 @@ int bt_mesh_friend_sub_add(struct bt_mesh_net_rx *rx, #if CONFIG_BLE_MESH_DF_SRV return bt_mesh_directed_friend_solicitation(frnd, rx->sub); -#else +#else /* CONFIG_BLE_MESH_DF_SRV */ return 0; -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ } int bt_mesh_friend_sub_rem(struct bt_mesh_net_rx *rx, @@ -710,6 +771,8 @@ int bt_mesh_friend_sub_rem(struct bt_mesh_net_rx *rx, struct bt_mesh_friend *frnd = NULL; uint8_t xact = 0U; + BT_DBG("FrndSubRem"); + if (buf->len < BLE_MESH_FRIEND_SUB_MIN_LEN) { BT_WARN("Too short Friend Subscription Remove (len %d)", buf->len); return -EINVAL; @@ -717,7 +780,7 @@ int bt_mesh_friend_sub_rem(struct bt_mesh_net_rx *rx, frnd = bt_mesh_friend_find(rx->sub->net_idx, rx->ctx.addr, true, true); if (!frnd) { - BT_WARN("No matching LPN addr 0x%04x", rx->ctx.addr); + BT_WARN("NoMatchLPN, Addr 0x%04x", rx->ctx.addr); return 0; } @@ -736,7 +799,7 @@ int bt_mesh_friend_sub_rem(struct bt_mesh_net_rx *rx, if (!BLE_MESH_ADDR_IS_GROUP(addr) && !BLE_MESH_ADDR_IS_VIRTUAL(addr) && !BLE_MESH_ADDR_IS_FIXED_GROUP(addr)) { - BT_WARN("Invalid friend sub addr 0x%04x to remove", addr); + BT_WARN("InvalidFrndSub, Addr 0x%04x", addr); continue; } @@ -750,6 +813,8 @@ int bt_mesh_friend_sub_rem(struct bt_mesh_net_rx *rx, static void enqueue_buf(struct bt_mesh_friend *frnd, struct net_buf *buf) { + BT_DBG("EnqueueBuf, Buf %p QueueSize %u", buf, frnd->queue_size); + net_buf_slist_put(&frnd->queue, buf); frnd->queue_size++; } @@ -758,6 +823,8 @@ static void enqueue_update(struct bt_mesh_friend *frnd, uint8_t md) { struct net_buf *buf = NULL; + BT_DBG("EnqueueUpdate, LPN 0x%04x MD %u", frnd->lpn, md); + buf = encode_update(frnd, md); if (!buf) { BT_ERR("Unable to encode Friend Update"); @@ -772,6 +839,8 @@ int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) struct bt_mesh_ctl_friend_poll *msg = (void *)buf->data; struct bt_mesh_friend *frnd = NULL; + BT_DBG("FrndPoll"); + if (buf->len < sizeof(*msg)) { BT_WARN("Too short Friend Poll (len %d)", buf->len); return -EINVAL; @@ -779,7 +848,7 @@ int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) frnd = bt_mesh_friend_find(rx->sub->net_idx, rx->ctx.addr, true, false); if (!frnd) { - BT_WARN("No matching LPN addr 0x%04x", rx->ctx.addr); + BT_WARN("NoMatchLPN, Addr 0x%04x", rx->ctx.addr); return 0; } @@ -793,12 +862,13 @@ int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) return 0; } - BT_DBG("msg->fsn %u frnd->fsn %u", (msg->fsn & 1), frnd->fsn); + BT_DBG("MsgFSN %u FrndFSN %u", (msg->fsn & 1), frnd->fsn); friend_recv_delay(frnd); if (!frnd->established) { - BT_INFO("Friendship established with 0x%04x", frnd->lpn); + BT_INFO("Friendship established with LPN 0x%04x", frnd->lpn); + frnd->established = 1U; if (friend_cb) { friend_cb(true, frnd->lpn, 0); @@ -806,7 +876,8 @@ int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) } if (msg->fsn == frnd->fsn && frnd->last) { - BT_DBG("Re-sending last PDU"); + BT_DBG("ResendFrndLast"); + frnd->send_last = 1U; } else { if (frnd->last) { @@ -817,8 +888,8 @@ int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) frnd->fsn = msg->fsn; if (sys_slist_is_empty(&frnd->queue)) { + BT_DBG("EnqueueFrndUpdate"); enqueue_update(frnd, 0); - BT_DBG("Enqueued Friend Update to empty queue"); } } @@ -829,6 +900,8 @@ static struct bt_mesh_friend *find_clear(uint16_t prev_friend) { int i; + BT_DBG("FindClear, PrevFrnd 0x%04x", prev_friend); + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; @@ -844,6 +917,8 @@ static void friend_clear_sent(int err, void *user_data) { struct bt_mesh_friend *frnd = user_data; + BT_DBG("FrndClearSent, RepeatSec %u Err %d", frnd->clear.repeat_sec, err); + k_delayed_work_submit(&frnd->clear.timer, K_SECONDS(frnd->clear.repeat_sec)); frnd->clear.repeat_sec *= 2U; @@ -875,6 +950,8 @@ static void send_friend_clear(struct bt_mesh_friend *frnd) .lpn_counter = sys_cpu_to_be16(frnd->lpn_counter), }; + BT_DBG("SendFrndClear, Addr 0x%04x", frnd->clear.frnd); + if (!tx.sub) { BT_ERR("Invalid subnet for Friend Clear"); return; @@ -886,13 +963,15 @@ static void send_friend_clear(struct bt_mesh_friend *frnd) static void clear_timeout(struct k_work *work) { - struct bt_mesh_friend *frnd = CONTAINER_OF(work, struct bt_mesh_friend, - clear.timer.work); + struct bt_mesh_friend *frnd = CONTAINER_OF(work, struct bt_mesh_friend, clear.timer.work); uint32_t duration = 0U; - BT_DBG("LPN 0x%04x (old) Friend 0x%04x", frnd->lpn, frnd->clear.frnd); - duration = k_uptime_get_32() - frnd->clear.start; + + BT_DBG("ClearTimeout"); + BT_DBG("LPN 0x%04x Frnd 0x%04x Duration %lu PollTo %ld", + frnd->lpn, frnd->clear.frnd, duration, frnd->poll_to); + if (duration > 2 * frnd->poll_to) { BT_DBG("Clear Procedure timer expired"); frnd->clear.frnd = BLE_MESH_ADDR_UNASSIGNED; @@ -904,11 +983,13 @@ static void clear_timeout(struct k_work *work) static void clear_procedure_start(struct bt_mesh_friend *frnd) { - BT_DBG("LPN 0x%04x (old) Friend 0x%04x", frnd->lpn, frnd->clear.frnd); - frnd->clear.start = k_uptime_get_32(); frnd->clear.repeat_sec = 1U; + BT_DBG("ClearProcedureStart"); + BT_DBG("LPN 0x%04x Frnd 0x%04x ClearStart %lu", + frnd->lpn, frnd->clear.frnd, frnd->clear.start); + send_friend_clear(frnd); } @@ -919,6 +1000,8 @@ int bt_mesh_friend_clear_cfm(struct bt_mesh_net_rx *rx, struct bt_mesh_friend *frnd = NULL; uint16_t lpn_addr = 0U, lpn_counter = 0U; + BT_DBG("FrndClearCFM"); + if (buf->len < sizeof(*msg)) { BT_WARN("Too short Friend Clear Confirm (len %d)", buf->len); return -EINVAL; @@ -956,6 +1039,9 @@ static void enqueue_offer(struct bt_mesh_friend *frnd, int8_t rssi) NET_BUF_SIMPLE_DEFINE(sdu, 1 + sizeof(*off)); struct net_buf *buf = NULL; + BT_DBG("EnqueueOffset"); + BT_DBG("LPN 0x%04x Counter %u Rssi %d", frnd->lpn, frnd->counter, rssi); + net_buf_simple_reserve(&sdu, 1); off = net_buf_simple_add(&sdu, sizeof(*off)); @@ -1000,7 +1086,7 @@ static int32_t offer_delay(struct bt_mesh_friend *frnd, int8_t rssi, uint8_t cri static const uint8_t fact[] = { 10, 15, 20, 25 }; int32_t delay = 0; - BT_INFO("ReceiveWindowFactor %u ReceiveWindow %u RSSIFactor %u RSSI %d", + BT_INFO("RecvWinFactor %u RecvWin %u RssiFactor %u Rssi %d", fact[RECV_WIN_FACT(crit)], RECV_WIN, fact[RSSI_FACT(crit)], rssi); @@ -1009,7 +1095,7 @@ static int32_t offer_delay(struct bt_mesh_friend *frnd, int8_t rssi, uint8_t cri delay -= (int32_t)fact[RSSI_FACT(crit)] * rssi; delay /= 10; - BT_DBG("Local Delay calculated as %d ms", delay); + BT_DBG("OfferDelay %d", delay); if (delay < 100) { return K_MSEC(100); @@ -1025,13 +1111,15 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) uint32_t poll_to = 0U; int i; + BT_DBG("FrndReq"); + if (buf->len < sizeof(*msg)) { BT_WARN("Too short Friend Request (len %d)", buf->len); return -EINVAL; } if (msg->recv_delay <= 0x09) { - BT_WARN("Prohibited ReceiveDelay (0x%02x)", msg->recv_delay); + BT_WARN("Prohibited RecvDelay (0x%02x)", msg->recv_delay); return -EINVAL; } @@ -1058,7 +1146,7 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) } if (CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE < MIN_QUEUE_SIZE(msg->criteria)) { - BT_WARN("We have a too small Friend Queue size (%u < %u)", + BT_WARN("Too small Friend Queue size (%u < %u)", CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE, MIN_QUEUE_SIZE(msg->criteria)); return 0; @@ -1093,11 +1181,10 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) frnd->lpn_counter = sys_be16_to_cpu(msg->lpn_counter); frnd->clear.frnd = sys_be16_to_cpu(msg->prev_addr); - BT_INFO("LPN 0x%04x rssi %d recv_delay %u poll_to %ums", - frnd->lpn, rx->ctx.recv_rssi, frnd->recv_delay, frnd->poll_to); + BT_INFO("LPN 0x%04x Rssi %d RecvDelay %u PollTo %u", + frnd->lpn, rx->ctx.recv_rssi, frnd->recv_delay, frnd->poll_to); - /** - * Spec says: + /* Spec says: * After a friendship has been established, if the PreviousAddress field * of the Friend Request message contains a valid unicast address that is * not the Friend node’s own unicast address, then the Friend node shall @@ -1109,11 +1196,9 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) } k_delayed_work_submit(&frnd->timer, - offer_delay(frnd, rx->ctx.recv_rssi, - msg->criteria)); + offer_delay(frnd, rx->ctx.recv_rssi, msg->criteria)); - friend_cred_create(rx->sub, frnd->lpn, frnd->lpn_counter, - frnd->counter); + friend_cred_create(rx->sub, frnd->lpn, frnd->lpn_counter, frnd->counter); enqueue_offer(frnd, rx->ctx.recv_rssi); @@ -1127,6 +1212,8 @@ static bool is_seg(struct bt_mesh_friend_seg *seg, uint16_t src, uint16_t seq_ze uint16_t buf_seq_zero = 0U; uint16_t buf_src = 0U; + BT_DBG("IsSeg, Buf %p", buf); + if (!buf) { return false; } @@ -1148,6 +1235,9 @@ static struct bt_mesh_friend_seg *get_seg(struct bt_mesh_friend *frnd, struct bt_mesh_friend_seg *unassigned = NULL; int i; + BT_DBG("GetSeg, Src 0x%04x SeqZero 0x%04x SegCount %u", + src, seq_zero, seg_count); + for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) { struct bt_mesh_friend_seg *seg = &frnd->seg[i]; @@ -1173,15 +1263,18 @@ static void enqueue_friend_pdu(struct bt_mesh_friend *frnd, struct net_buf *buf) { struct bt_mesh_friend_seg *seg = NULL; + uint16_t seq_zero = 0; - BT_DBG("type %u", type); + BT_DBG("EnqueueFrndPDU, Type %u", type); if (type == BLE_MESH_FRIEND_PDU_SINGLE) { enqueue_buf(frnd, buf); return; } - uint16_t seq_zero = (((buf->data[10] << 8 | buf->data[11]) >> 2) & TRANS_SEQ_ZERO_MASK); + seq_zero = (((buf->data[10] << 8 | buf->data[11]) >> 2) & TRANS_SEQ_ZERO_MASK); + + BT_DBG("Src 0x%04x SegCount %u SegZero 0x%04x", src, seg_count, seq_zero); seg = get_seg(frnd, src, seq_zero, seg_count); if (!seg) { @@ -1207,7 +1300,7 @@ static void buf_send_start(uint16_t duration, int err, void *user_data) { struct bt_mesh_friend *frnd = user_data; - BT_DBG("err %d", err); + BT_DBG("BufSendStart, Err %d", err); frnd->pending_buf = 0U; @@ -1222,7 +1315,7 @@ static void buf_send_end(int err, void *user_data) { struct bt_mesh_friend *frnd = user_data; - BT_DBG("err %d", err); + BT_DBG("BufSendEnd, Err %d", err); if (frnd->pending_req) { BT_WARN("Another request before previous completed sending"); @@ -1230,47 +1323,48 @@ static void buf_send_end(int err, void *user_data) } if (frnd->established) { + BT_DBG("WaitForNextPoll %u", frnd->poll_to); + k_delayed_work_submit(&frnd->timer, frnd->poll_to); - BT_DBG("Waiting %u ms for next poll", frnd->poll_to); } else { /* Friend offer timeout is 1 second */ + BT_DBG("WaitForFirstPoll"); + k_delayed_work_submit(&frnd->timer, K_SECONDS(1)); - BT_DBG("Waiting for first poll"); } } static void friend_timeout(struct k_work *work) { - struct bt_mesh_friend *frnd = CONTAINER_OF(work, struct bt_mesh_friend, - timer.work); + struct bt_mesh_friend *frnd = CONTAINER_OF(work, struct bt_mesh_friend, timer.work); static const struct bt_mesh_send_cb buf_sent_cb = { .start = buf_send_start, .end = buf_send_end, }; + BT_DBG("FrndTimeout"); + if (frnd->pending_buf != 0U) { BT_ERR("Previous buffer not yet sent!"); return; } - BT_DBG("lpn 0x%04x send_last %u last %p", frnd->lpn, - frnd->send_last, frnd->last); + BT_DBG("LPN 0x%04x SendLast %u FrndLast %p", frnd->lpn, frnd->send_last, frnd->last); if (frnd->send_last && frnd->last) { - BT_DBG("Sending frnd->last %p", frnd->last); frnd->send_last = 0U; goto send_last; } if (frnd->established && !frnd->pending_req) { - BT_WARN("Friendship lost with 0x%04x", frnd->lpn); + BT_WARN("FriendshipLost, LPN 0x%04x", frnd->lpn); friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_POLL_TIMEOUT); return; } frnd->last = (void *)sys_slist_get(&frnd->queue); if (!frnd->last) { - BT_WARN("Friendship not established with 0x%04x", frnd->lpn); + BT_WARN("FriendshipNotEstablished, LPN 0x%04x", frnd->lpn); friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_ESTABLISH_FAIL); return; } @@ -1283,8 +1377,9 @@ static void friend_timeout(struct k_work *work) frnd->last->flags &= ~NET_BUF_FRAGS; frnd->last->frags = NULL; - BT_DBG("Sending buf %p from Friend Queue of LPN 0x%04x", - frnd->last, frnd->lpn); + BT_DBG("SendBufFromFrndQueue, Last %p QueueSize %u LPN 0x%04x", + frnd->last, frnd->queue_size, frnd->lpn); + frnd->queue_size--; send_last: @@ -1302,6 +1397,8 @@ int bt_mesh_friend_init(void) { int i; + BT_DBG("FrndInit"); + if (friend_init == true) { BT_WARN("%s, Already", __func__); return -EALREADY; @@ -1333,6 +1430,8 @@ int bt_mesh_friend_deinit(void) { int i; + BT_DBG("FrndDeinit"); + if (friend_init == false) { BT_WARN("%s, Already", __func__); return -EALREADY; @@ -1363,6 +1462,8 @@ static bool is_segack(struct net_buf *buf, const uint64_t *seqauth, uint16_t src struct net_buf_simple_state state = {0}; bool found = false; + BT_DBG("IsSegAck, Len %u", buf->len); + if (buf->len != 16) { return false; } @@ -1372,23 +1473,27 @@ static bool is_segack(struct net_buf *buf, const uint64_t *seqauth, uint16_t src net_buf_skip(buf, 1); /* skip IVI, NID */ if (!(net_buf_pull_u8(buf) >> 7)) { + BT_DBG("Not SegAck"); goto end; } net_buf_pull(buf, 3); /* skip SEQNUM */ if (src != net_buf_pull_be16(buf)) { + BT_DBG("SrcNotSegAck"); goto end; } net_buf_skip(buf, 2); /* skip dst */ - if (TRANS_CTL_OP((uint8_t *) net_buf_pull_mem(buf, 1)) != TRANS_CTL_OP_ACK) { + if (TRANS_CTL_OP((uint8_t *)net_buf_pull_mem(buf, 1)) != TRANS_CTL_OP_ACK) { + BT_DBG("OpNotSegAck"); goto end; } - found = ((net_buf_pull_be16(buf) >> 2) & TRANS_SEQ_ZERO_MASK) == - (*seqauth & TRANS_SEQ_ZERO_MASK); + found = (((net_buf_pull_be16(buf) >> 2) & TRANS_SEQ_ZERO_MASK) == + (*seqauth & TRANS_SEQ_ZERO_MASK)); + end: net_buf_simple_restore(&buf->b, &state); return found; @@ -1399,17 +1504,18 @@ static void friend_purge_old_ack(struct bt_mesh_friend *frnd, { sys_snode_t *cur = NULL, *prev = NULL; - BT_DBG("SeqAuth %llx src 0x%04x", *seq_auth, src); + BT_DBG("FrndPurgeOldAck, SeqAuth %llx Src 0x%04x", *seq_auth, src); for (cur = sys_slist_peek_head(&frnd->queue); - cur != NULL; prev = cur, cur = sys_slist_peek_next(cur)) { + cur != NULL; prev = cur, cur = sys_slist_peek_next(cur)) { struct net_buf *buf = (void *)cur; if (is_segack(buf, seq_auth, src)) { - BT_DBG("Removing old ack from Friend Queue"); + BT_DBG("RemoveOldAckFromFrndQueue, QueueSize %u", frnd->queue_size); sys_slist_remove(&frnd->queue, prev, cur); frnd->queue_size--; + /* Make sure old slist entry state doesn't remain */ buf->frags = NULL; @@ -1428,6 +1534,9 @@ static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd, struct friend_pdu_info info = {0}; struct net_buf *buf = NULL; + BT_DBG("FrndLPNEnqueueRx, LPN 0x%04x QueueSize %u Type 0x%02x", + frnd->lpn, frnd->queue_size, type); + /* Because of network loopback, tx packets will also be passed into * this rx function. These packets have already been added to the * queue, and should be ignored. @@ -1436,8 +1545,6 @@ static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd, return; } - BT_DBG("LPN 0x%04x queue_size %u", frnd->lpn, frnd->queue_size); - if (type == BLE_MESH_FRIEND_PDU_SINGLE && seq_auth) { friend_purge_old_ack(frnd, seq_auth, rx->ctx.addr); } @@ -1465,7 +1572,7 @@ static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd, enqueue_friend_pdu(frnd, type, info.src, seg_count, buf); - BT_DBG("Queued message for LPN 0x%04x, queue_size %u", + BT_DBG("QueuedMsg, LPN 0x%04x QueueSize %u", frnd->lpn, frnd->queue_size); } @@ -1478,7 +1585,7 @@ static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd, struct friend_pdu_info info = {0}; struct net_buf *buf = NULL; - BT_DBG("LPN 0x%04x", frnd->lpn); + BT_DBG("FrndLPNEnqueueTx, LPN 0x%04x Type 0x%02x", frnd->lpn, type); if (type == BLE_MESH_FRIEND_PDU_SINGLE && seq_auth) { friend_purge_old_ack(frnd, seq_auth, tx->src); @@ -1510,7 +1617,7 @@ static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd, enqueue_friend_pdu(frnd, type, info.src, seg_count, buf); - BT_DBG("Queued message for LPN 0x%04x", frnd->lpn); + BT_DBG("QueuedMsg, LPN 0x%04x", frnd->lpn); } static bool friend_lpn_matches(struct bt_mesh_friend *frnd, uint16_t net_idx, @@ -1518,6 +1625,10 @@ static bool friend_lpn_matches(struct bt_mesh_friend *frnd, uint16_t net_idx, { int i; + BT_DBG("IsFrndLPNMatch"); + BT_DBG("LPN 0x%04x NetIdx 0x%04x/0x%04x Addr 0x%04x Established %u", + frnd->lpn, net_idx, frnd->net_idx, addr, frnd->established); + if (!frnd->established) { return false; } @@ -1543,12 +1654,13 @@ bool bt_mesh_friend_match(uint16_t net_idx, uint16_t addr) { int i; + BT_DBG("FrndMatch, NetIdx 0x%04x Addr 0x%04x", net_idx, addr); + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; if (friend_lpn_matches(frnd, net_idx, addr)) { - BT_DBG("LPN 0x%04x matched address 0x%04x", - frnd->lpn, addr); + BT_DBG("LPNMatch, LPN 0x%04x Addr 0x%04x", frnd->lpn, addr); return true; } } @@ -1562,6 +1674,8 @@ bool bt_mesh_friend_unicast_match(uint16_t net_idx, uint16_t addr, uint8_t *sele { int i; + BT_DBG("FrndUnicastMatch, NetIdx 0x%04x addr 0x%04x", net_idx, addr); + if (!BLE_MESH_ADDR_IS_UNICAST(addr) || selem == NULL) { BT_ERR("%s, Invalid parameter", __func__); return false; @@ -1587,6 +1701,10 @@ static bool friend_queue_has_space(struct bt_mesh_friend *frnd, uint16_t addr, uint32_t total = 0U; int i; + BT_DBG("IsFrndQueueHasSpace"); + BT_DBG("LPN 0x%04x SegCount %u QueueSize %u Addr 0x%04x", + frnd->lpn, seg_count, CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE, addr); + if (seg_count > CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE) { return false; } @@ -1595,8 +1713,8 @@ static bool friend_queue_has_space(struct bt_mesh_friend *frnd, uint16_t addr, struct bt_mesh_friend_seg *seg = &frnd->seg[i]; if (seq_auth && is_seg(seg, addr, *seq_auth & TRANS_SEQ_ZERO_MASK)) { - /* If there's a segment queue for this message then the - * space verification has already happened. + /* If there's a segment queue for this message then the space + * verification has already happened. */ return true; } @@ -1604,6 +1722,8 @@ static bool friend_queue_has_space(struct bt_mesh_friend *frnd, uint16_t addr, total += seg->seg_count; } + BT_DBG("TotalCount %u", total); + /* If currently pending segments combined with this segmented message * are more than the Friend Queue Size, then there's no space. This * is because we don't have a mechanism of aborting already pending @@ -1618,6 +1738,10 @@ bool bt_mesh_friend_queue_has_space(uint16_t net_idx, uint16_t src, uint16_t dst bool someone_has_space = false, friend_match = false; int i; + BT_DBG("FrndQueueHasSpace"); + BT_DBG("NetIdx 0x%04x Src 0x%04x Dst 0x%04x SegCount %u", + net_idx, src, dst, seg_count); + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; @@ -1636,6 +1760,7 @@ bool bt_mesh_friend_queue_has_space(uint16_t net_idx, uint16_t src, uint16_t dst * transport layer can continue its work. */ if (!friend_match) { + BT_DBG("NoMatchLPN"); return true; } @@ -1653,6 +1778,9 @@ static bool friend_queue_prepare_space(struct bt_mesh_friend *frnd, uint16_t add bool pending_segments = false; uint8_t avail_space = 0U; + BT_DBG("FrndQueuePrepareSpace"); + BT_DBG("LPN 0x%04x Addr 0x%04x SegCount %u", frnd->lpn, addr, seg_count); + if (!friend_queue_has_space(frnd, addr, seq_auth, seg_count)) { return false; } @@ -1668,6 +1796,9 @@ static bool friend_queue_prepare_space(struct bt_mesh_friend *frnd, uint16_t add return false; } + BT_DBG("PendingSeg %u AvailSpace %u QueueSize %u", + pending_segments, avail_space, frnd->queue_size); + frnd->queue_size--; avail_space++; @@ -1690,15 +1821,19 @@ void bt_mesh_friend_enqueue_rx(struct bt_mesh_net_rx *rx, { int i; + BT_DBG("FrndEnqueueRx"); + BT_DBG("FrndMatch %u RecvTTL %u NetIf %u FrndGet %u", + rx->friend_match, rx->ctx.recv_ttl, rx->net_if, + bt_mesh_friend_get()); + if (!rx->friend_match || (rx->ctx.recv_ttl <= 1U && rx->net_if != BLE_MESH_NET_IF_LOCAL) || bt_mesh_friend_get() != BLE_MESH_FRIEND_ENABLED) { return; } - BT_DBG("recv_ttl %u net_idx 0x%04x src 0x%04x dst 0x%04x", - rx->ctx.recv_ttl, rx->sub->net_idx, rx->ctx.addr, - rx->ctx.recv_dst); + BT_DBG("NetIdx 0x%04x Src 0x%04x Dst 0x%04x", + rx->sub->net_idx, rx->ctx.addr, rx->ctx.recv_dst); for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; @@ -1713,8 +1848,7 @@ void bt_mesh_friend_enqueue_rx(struct bt_mesh_net_rx *rx, continue; } - friend_lpn_enqueue_rx(frnd, rx, type, seq_auth, seg_count, - sbuf); + friend_lpn_enqueue_rx(frnd, rx, type, seq_auth, seg_count, sbuf); } } @@ -1726,14 +1860,15 @@ bool bt_mesh_friend_enqueue_tx(struct bt_mesh_net_tx *tx, bool matched = false; int i; + BT_DBG("FrndEnqueueTx"); + BT_DBG("NetIdx 0x%04x Dst 0x%04x Src 0x%04x FrndState %u", + tx->sub->net_idx, tx->ctx->addr, tx->src, bt_mesh_friend_get()); + if (!bt_mesh_friend_match(tx->sub->net_idx, tx->ctx->addr) || bt_mesh_friend_get() != BLE_MESH_FRIEND_ENABLED) { return matched; } - BT_DBG("net_idx 0x%04x dst 0x%04x src 0x%04x", tx->sub->net_idx, - tx->ctx->addr, tx->src); - for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; @@ -1760,6 +1895,9 @@ void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, uint16_t src, { int i; + BT_DBG("FrndClearComplete"); + BT_DBG("NetIdx 0x%04x Src 0x%04x Dst 0x%04x", sub->net_idx, src, dst); + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; int j; @@ -1788,6 +1926,8 @@ void bt_mesh_friend_remove_lpn(uint16_t lpn_addr) { struct bt_mesh_friend *frnd = NULL; + BT_DBG("FrndRemoveLPN, Addr 0x%04x", lpn_addr); + frnd = bt_mesh_friend_find(BLE_MESH_KEY_ANY, lpn_addr, false, false); if (frnd) { friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_DISABLE); diff --git a/components/bt/esp_ble_mesh/core/health_cli.c b/components/bt/esp_ble_mesh/core/health_cli.c index 1e03d93513c4..df9685e45fe3 100644 --- a/components/bt/esp_ble_mesh/core/health_cli.c +++ b/components/bt/esp_ble_mesh/core/health_cli.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -68,6 +68,8 @@ static void health_client_recv_status(struct bt_mesh_model *model, struct net_buf_simple buf = {0}; uint8_t evt_type = 0xFF; + BT_DBG("HealthClientRecvStatus"); + if (!model || !ctx || !status || !len) { BT_ERR("%s, Invalid parameter", __func__); return; @@ -83,6 +85,8 @@ static void health_client_recv_status(struct bt_mesh_model *model, if (!node) { BT_DBG("Unexpected Health Status 0x%04x", ctx->recv_op); } else { + BT_DBG("OpCode 0x%08lx RecvOp 0x%08lx", node->opcode, ctx->recv_op); + switch (node->opcode) { case OP_HEALTH_FAULT_GET: case OP_HEALTH_PERIOD_GET: @@ -131,9 +135,10 @@ static void health_fault_status(struct bt_mesh_model *model, { struct bt_mesh_health_fault_status status = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("HealthFaultStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status.test_id = net_buf_simple_pull_u8(buf); status.cid = net_buf_simple_pull_le16(buf); @@ -154,9 +159,10 @@ static void health_current_status(struct bt_mesh_model *model, { struct bt_mesh_health_current_status status = {0}; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("HealthCurrentStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status.test_id = net_buf_simple_pull_u8(buf); status.cid = net_buf_simple_pull_le16(buf); @@ -177,9 +183,10 @@ static void health_period_status(struct bt_mesh_model *model, { uint8_t status = 0U; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("HealthPeriodStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status = net_buf_simple_pull_u8(buf); @@ -192,9 +199,10 @@ static void health_attention_status(struct bt_mesh_model *model, { uint8_t status = 0U; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); + BT_DBG("HealthAttentionStatus"); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); status = net_buf_simple_pull_u8(buf); @@ -213,6 +221,8 @@ int bt_mesh_health_attention_get(bt_mesh_client_common_param_t *param) { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_GET, 0); + BT_DBG("HealthAttentionGet"); + bt_mesh_model_msg_init(&msg, OP_ATTENTION_GET); return bt_mesh_client_send_msg(param, &msg, true, timeout_handler); @@ -223,6 +233,8 @@ int bt_mesh_health_attention_set(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_SET, 1); + BT_DBG("HealthAttentionSet, Attention 0x%02x NeedAck %u", attention, need_ack); + bt_mesh_model_msg_init(&msg, need_ack ? OP_ATTENTION_SET : OP_ATTENTION_SET_UNREL); net_buf_simple_add_u8(&msg, attention); @@ -233,6 +245,8 @@ int bt_mesh_health_period_get(bt_mesh_client_common_param_t *param) { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_GET, 0); + BT_DBG("HealthPeriodGet"); + bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_GET); return bt_mesh_client_send_msg(param, &msg, true, timeout_handler); @@ -243,6 +257,8 @@ int bt_mesh_health_period_set(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_SET, 1); + BT_DBG("HealthPeriodSet, Divisor 0x%02x NeedAck %u", divisor, need_ack); + bt_mesh_model_msg_init(&msg, need_ack ? OP_HEALTH_PERIOD_SET : OP_HEALTH_PERIOD_SET_UNREL); net_buf_simple_add_u8(&msg, divisor); @@ -254,6 +270,8 @@ 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_mesh_model_msg_init(&msg, need_ack ? OP_HEALTH_FAULT_TEST : OP_HEALTH_FAULT_TEST_UNREL); net_buf_simple_add_u8(&msg, test_id); net_buf_simple_add_le16(&msg, cid); @@ -266,6 +284,8 @@ int bt_mesh_health_fault_clear(bt_mesh_client_common_param_t *param, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_CLEAR, 2); + BT_DBG("HealthFaultClear, CID 0x%04x NeedAck %u", cid, need_ack); + bt_mesh_model_msg_init(&msg, need_ack ? OP_HEALTH_FAULT_CLEAR : OP_HEALTH_FAULT_CLEAR_UNREL); net_buf_simple_add_le16(&msg, cid); @@ -276,6 +296,8 @@ int bt_mesh_health_fault_get(bt_mesh_client_common_param_t *param, uint16_t cid) { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_GET, 2); + BT_DBG("HealthFaultGet, CID 0x%04x", cid); + bt_mesh_model_msg_init(&msg, OP_HEALTH_FAULT_GET); net_buf_simple_add_le16(&msg, cid); @@ -287,6 +309,8 @@ static int health_cli_init(struct bt_mesh_model *model) health_internal_data_t *internal = NULL; bt_mesh_health_client_t *client = NULL; + BT_DBG("HealthCliInit"); + if (!model) { BT_ERR("Invalid Health Client model"); return -EINVAL; @@ -328,6 +352,8 @@ static int health_cli_deinit(struct bt_mesh_model *model) { bt_mesh_health_client_t *client = NULL; + BT_DBG("HealthCliDeinit"); + if (!model) { BT_ERR("Invalid Health Client model"); return -EINVAL; diff --git a/components/bt/esp_ble_mesh/core/health_srv.c b/components/bt/esp_ble_mesh/core/health_srv.c index a27e4547b211..98656586e7b9 100644 --- a/components/bt/esp_ble_mesh/core/health_srv.c +++ b/components/bt/esp_ble_mesh/core/health_srv.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,8 +26,7 @@ /* Health Server context of the primary element */ struct bt_mesh_health_srv *health_srv; -/** - * When an Element receives a Health Fault Get, or a Health Fault Test, or +/* When an Element receives a Health Fault Get, or a Health Fault Test, or * a Health Fault Test Unacknowledged, or a Health Fault Clear, or a Health * Fault Clear Unacknowledged message that is not successfully processed * (i.e. the Company ID field that does not identify any Health Fault state @@ -48,6 +47,8 @@ static uint8_t health_get_curr_fault_count(struct bt_mesh_model *model) } } + BT_DBG("HealthGetCurrFaultCount, Count %u", count); + return count; } @@ -61,6 +62,8 @@ static void health_get_fault_value(struct bt_mesh_model *model, array_size = current ? ARRAY_SIZE(srv->test.curr_faults) : ARRAY_SIZE(srv->test.reg_faults); + BT_DBG("HealthGetFaultValue, Current %u Size %lu", current, array_size); + for (i = 0U; i < array_size; i++) { if (net_buf_simple_tailroom(msg) == 0) { return; @@ -70,6 +73,8 @@ static void health_get_fault_value(struct bt_mesh_model *model, if (fault != HEALTH_NO_FAULT) { net_buf_simple_add_u8(msg, fault); } + + BT_DBG("%u: Fault 0x%02x", i, fault); } } @@ -78,12 +83,16 @@ static bool health_is_test_id_exist(struct bt_mesh_model *model, uint8_t test_id struct bt_mesh_health_srv *srv = model->user_data; int i; + BT_DBG("HealthIsTestIDExist, TestID 0x%02x", test_id); + for (i = 0; i < srv->test.id_count; i++) { if (srv->test.test_ids[i] == test_id) { + BT_DBG("TestIDExist"); return true; } } + BT_DBG("TestIDNotExist"); return false; } @@ -94,19 +103,23 @@ static int health_send_fault_status(struct bt_mesh_model *model, struct net_buf_simple *msg = NULL; int err = 0; + BT_DBG("HealthSendFaultStatus"); + msg = bt_mesh_alloc_buf(4 + ARRAY_SIZE(srv->test.reg_faults) + 4); if (!msg) { BT_ERR("%s, Out of memory", __func__); return -ENOMEM; } + BT_DBG("TestID 0x%02x CID 0x%04x", + srv->test.prev_test_id, srv->test.company_id); + bt_mesh_model_msg_init(msg, OP_HEALTH_FAULT_STATUS); net_buf_simple_add_u8(msg, srv->test.prev_test_id); net_buf_simple_add_le16(msg, srv->test.company_id); if (ctx->recv_op != OP_HEALTH_FAULT_CLEAR) { - /** - * For Health Fault Clear, the FaultArray field in Health Fault Status - * shall be empty. + /* For Health Fault Clear, the FaultArray field + * in Health Fault Status shall be empty. */ health_get_fault_value(model, msg, false); } @@ -127,6 +140,8 @@ static void health_fault_get(struct bt_mesh_model *model, struct bt_mesh_health_srv *srv = model->user_data; uint16_t company_id = 0U; + BT_DBG("HealthFaultGet"); + if (!srv) { BT_ERR("No Health Server context provided"); return; @@ -138,7 +153,7 @@ static void health_fault_get(struct bt_mesh_model *model, return; } - BT_DBG("company_id 0x%04x", company_id); + BT_DBG("CID 0x%04x", company_id); health_send_fault_status(model, ctx); } @@ -150,6 +165,8 @@ static void health_fault_clear(struct bt_mesh_model *model, struct bt_mesh_health_srv *srv = model->user_data; uint16_t company_id = 0U; + BT_DBG("HealthFaultClear"); + if (!srv) { BT_ERR("No Health Server context provided"); return; @@ -161,7 +178,7 @@ static void health_fault_clear(struct bt_mesh_model *model, return; } - BT_DBG("company_id 0x%04x", company_id); + BT_DBG("CID 0x%04x", company_id); memset(srv->test.reg_faults, HEALTH_NO_FAULT, ARRAY_SIZE(srv->test.reg_faults)); @@ -182,6 +199,8 @@ static void health_fault_test(struct bt_mesh_model *model, uint16_t company_id = 0U; uint8_t test_id = 0U; + BT_DBG("HealthFaultTest"); + if (!srv) { BT_ERR("No Health Server context provided"); return; @@ -199,7 +218,7 @@ static void health_fault_test(struct bt_mesh_model *model, return; } - BT_DBG("test 0x%02x company 0x%04x", test_id, company_id); + BT_DBG("TestID 0x%02x CID 0x%04x", test_id, company_id); srv->test.prev_test_id = test_id; @@ -219,13 +238,16 @@ static void send_attention_status(struct bt_mesh_model *model, struct bt_mesh_health_srv *srv = model->user_data; uint8_t time = 0U; + BT_DBG("SendAttentionStatus"); + if (!srv) { BT_ERR("No Health Server context provided"); return; } time = k_delayed_work_remaining_get(&srv->attn_timer) / 1000; - BT_DBG("%u second%s", time, (time == 1U) ? "" : "s"); + + BT_DBG("Time %u", time); bt_mesh_model_msg_init(&msg, OP_ATTENTION_STATUS); net_buf_simple_add_u8(&msg, time); @@ -239,6 +261,8 @@ static void attention_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { + BT_DBG("AttentionGet"); + send_attention_status(model, ctx); } @@ -250,7 +274,7 @@ static void health_set_attention(struct bt_mesh_model *model, time = net_buf_simple_pull_u8(buf); - BT_DBG("%u second%s", time, (time == 1U) ? "" : "s"); + BT_DBG("HealthSetAttention, Time %u", time); bt_mesh_attention(model, time); } @@ -259,6 +283,8 @@ static void attention_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { + BT_DBG("AttentionSet"); + health_set_attention(model, ctx, buf); if (ctx->recv_op == OP_ATTENTION_SET) { @@ -271,6 +297,8 @@ static void send_health_period_status(struct bt_mesh_model *model, { BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_STATUS, 1); + BT_DBG("SendHealthPeriodStatus"); + bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_STATUS); net_buf_simple_add_u8(&msg, model->pub->period_div); @@ -283,6 +311,8 @@ static void health_period_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { + BT_DBG("HealthPeriodGet"); + send_health_period_status(model, ctx); } @@ -292,13 +322,15 @@ static void health_set_period(struct bt_mesh_model *model, { uint8_t period = 0U; + BT_DBG("HealthSetPeriod"); + period = net_buf_simple_pull_u8(buf); if (period > 15) { BT_WARN("Prohibited period value %u", period); return; } - BT_DBG("period %u", period); + BT_DBG("Period %u", period); model->pub->period_div = period; } @@ -307,6 +339,8 @@ static void health_period_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { + BT_DBG("HealthPeriodSet"); + health_set_period(model, ctx, buf); if (ctx->recv_op == OP_HEALTH_PERIOD_SET) { @@ -334,6 +368,8 @@ static size_t health_get_current(struct bt_mesh_model *model, { struct bt_mesh_health_srv *srv = model->user_data; + BT_DBG("HealthGetCurrent"); + if (!srv) { BT_ERR("No Health Server context provided"); return 0; @@ -344,6 +380,9 @@ static size_t health_get_current(struct bt_mesh_model *model, return 0; } + BT_DBG("TestID 0x%02x CID 0x%04x", + srv->test.prev_test_id, srv->test.company_id); + bt_mesh_model_msg_init(msg, OP_HEALTH_CURRENT_STATUS); net_buf_simple_add_u8(msg, srv->test.prev_test_id); net_buf_simple_add_le16(msg, srv->test.company_id); @@ -357,6 +396,8 @@ static int health_pub_update(struct bt_mesh_model *model) struct bt_mesh_model_pub *pub = model->pub; size_t count = 0U; + BT_DBG("HealthPubUpdate"); + if (!pub || !pub->msg) { BT_ERR("Invalid health publication context"); return -EINVAL; @@ -369,6 +410,8 @@ static int health_pub_update(struct bt_mesh_model *model) pub->fast_period = 0U; } + BT_DBG("Count %lu", count); + return 0; } @@ -376,6 +419,8 @@ int bt_mesh_fault_update(struct bt_mesh_elem *elem) { struct bt_mesh_model *model = NULL; + BT_DBG("FaultUpdate"); + model = bt_mesh_model_find(elem, BLE_MESH_MODEL_ID_HEALTH_SRV); if (!model) { BT_ERR("Health Server not exists"); @@ -409,6 +454,8 @@ static void attention_off(struct k_work *work) return; } + BT_DBG("AttentionOff"); + if (srv->cb.attn_off) { srv->cb.attn_off(srv->model); } @@ -423,6 +470,8 @@ static int health_srv_init(struct bt_mesh_model *model) * supported by any secondary elements. */ + BT_DBG("HealthSrvInit"); + if (!srv) { BT_ERR("No Health Server context provided"); return -EINVAL; @@ -433,6 +482,8 @@ static int health_srv_init(struct bt_mesh_model *model) return -EINVAL; } + BT_DBG("TestIDCount %u", srv->test.id_count); + if (!model->pub) { BT_ERR("Health Server has no publication support"); return -EINVAL; @@ -460,6 +511,8 @@ static int health_srv_deinit(struct bt_mesh_model *model) { struct bt_mesh_health_srv *srv = model->user_data; + BT_DBG("HealthSrvDeinit"); + if (!srv) { BT_ERR("No Health Server context provided"); return -EINVAL; @@ -499,6 +552,8 @@ void bt_mesh_attention(struct bt_mesh_model *model, uint8_t time) { struct bt_mesh_health_srv *srv = NULL; + BT_DBG("Attention, Time %u", time); + if (!model) { srv = health_srv; if (!srv) { diff --git a/components/bt/esp_ble_mesh/core/heartbeat.c b/components/bt/esp_ble_mesh/core/heartbeat.c index 4ff63a13abe0..444ea285decc 100644 --- a/components/bt/esp_ble_mesh/core/heartbeat.c +++ b/components/bt/esp_ble_mesh/core/heartbeat.c @@ -1,6 +1,6 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -21,11 +21,15 @@ static uint16_t hb_sub_dst = BLE_MESH_ADDR_UNASSIGNED; void bt_mesh_set_hb_sub_dst(uint16_t addr) { + BT_DBG("SetHbSubDst 0x%04x", addr); + hb_sub_dst = addr; } uint16_t bt_mesh_get_hb_sub_dst(void) { + BT_DBG("GetHbSubDst 0x%04x", hb_sub_dst); + return hb_sub_dst; } @@ -33,6 +37,9 @@ void bt_mesh_heartbeat_recv(uint16_t src, uint16_t dst, uint8_t hops, uint16_t f { struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get(); + BT_DBG("HeartbeatRecv"); + BT_DBG("Src 0x%04x Dst 0x%04x Hops %u Feat 0x%04x", src, dst, hops, feat); + if (cfg == NULL) { BT_WARN("No configuration server context available"); return; @@ -55,9 +62,8 @@ void bt_mesh_heartbeat_recv(uint16_t src, uint16_t dst, uint8_t hops, uint16_t f cfg->hb_sub.count++; } - BT_DBG("src 0x%04x dst 0x%04x hops %u min %u max %u count %u", src, - dst, hops, cfg->hb_sub.min_hops, cfg->hb_sub.max_hops, - cfg->hb_sub.count); + BT_DBG("MinHops %u MaxHops %u Count %u", + cfg->hb_sub.min_hops, cfg->hb_sub.max_hops, cfg->hb_sub.count); if (cfg->hb_sub.func) { cfg->hb_sub.func(hops, feat); @@ -67,7 +73,6 @@ void bt_mesh_heartbeat_recv(uint16_t src, uint16_t dst, uint8_t hops, uint16_t f void bt_mesh_heartbeat_send(void) { struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get(); - uint16_t feat = 0U; struct __attribute__((packed)) { uint8_t init_ttl; uint16_t feat; @@ -85,6 +90,9 @@ void bt_mesh_heartbeat_send(void) .src = bt_mesh_model_elem(cfg->model)->addr, .xmit = bt_mesh_net_transmit_get(), }; + uint16_t feat = 0U; + + BT_DBG("HeartbeatSend, Dst 0x%04x", cfg->hb_pub.dst); /* Do nothing if heartbeat publication is not enabled */ if (cfg->hb_pub.dst == BLE_MESH_ADDR_UNASSIGNED) { @@ -111,7 +119,7 @@ void bt_mesh_heartbeat_send(void) hb.feat = sys_cpu_to_be16(feat); - BT_INFO("InitTTL %u feat 0x%04x", cfg->hb_pub.ttl, feat); + BT_INFO("InitTTL %u Feat 0x%04x", cfg->hb_pub.ttl, feat); bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb), NULL, NULL); @@ -149,6 +157,8 @@ int bt_mesh_pvnr_register_hb_recv_cb(bt_mesh_pvnr_hb_recv_cb_t cb) int bt_mesh_pvnr_set_hb_recv_filter_type(uint8_t type) { + BT_DBG("PvnrSetHbRecvFilterType"); + if (type > HEARTBEAT_FILTER_REJECTLIST) { BT_ERR("Invalid heartbeat filter type 0x%02x", type); return -EINVAL; @@ -158,6 +168,8 @@ int bt_mesh_pvnr_set_hb_recv_filter_type(uint8_t type) * clear the existing filter entries. */ if (hb_rx.type != type) { + BT_DBG("OldType %u NewType %u", hb_rx.type, type); + memset(&hb_rx, 0, offsetof(struct heartbeat_recv, cb)); hb_rx.type = type; } @@ -169,6 +181,8 @@ static int hb_filter_alloc(uint16_t src, uint16_t dst) { int i; + BT_DBG("HbFilterAlloc, Src 0x%04x Dst 0x%04x", src, dst); + for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) { struct heartbeat_filter *filter = &hb_rx.filter[i]; @@ -180,7 +194,7 @@ static int hb_filter_alloc(uint16_t src, uint16_t dst) } } - BT_ERR("Heartbeat filter is full!"); + BT_ERR("HbFilterFull"); return -ENOMEM; } @@ -188,6 +202,8 @@ static int hb_filter_add(uint16_t src, uint16_t dst) { int i; + BT_DBG("HbFilterAdd, Src 0x%04x Dst 0x%04x", src, dst); + if (!(BLE_MESH_ADDR_IS_UNICAST(src) && (BLE_MESH_ADDR_IS_UNICAST(dst) || BLE_MESH_ADDR_IS_GROUP(dst)))) { BT_ERR("Invalid filter address, src 0x%04x, dst 0x%04x", src, dst); @@ -199,7 +215,7 @@ static int hb_filter_add(uint16_t src, uint16_t dst) struct heartbeat_filter *filter = &hb_rx.filter[i]; if (filter->src == src && filter->dst == dst) { - BT_WARN("Filter already exists, src 0x%04x dst 0x%04x", filter->src, filter->dst); + BT_DBG("FilterIndex %u", i); return 0; } } @@ -211,6 +227,8 @@ static int hb_filter_remove(uint16_t src, uint16_t dst) { int i; + BT_DBG("HbFilterRemove, Src 0x%04x Dst 0x%04x", src, dst); + if (!(BLE_MESH_ADDR_IS_UNICAST(src) && (BLE_MESH_ADDR_IS_UNICAST(dst) || BLE_MESH_ADDR_IS_GROUP(dst)))) { BT_ERR("Invalid filter address, src 0x%04x, dst 0x%04x", src, dst); @@ -221,6 +239,7 @@ static int hb_filter_remove(uint16_t src, uint16_t dst) struct heartbeat_filter *filter = &hb_rx.filter[i]; if (filter->src == src && filter->dst == dst) { + BT_DBG("FilterIndex %u", i); memset(filter, 0, sizeof(struct heartbeat_filter)); } } @@ -236,7 +255,7 @@ int bt_mesh_pvnr_set_hb_recv_filter_info(uint8_t op, uint16_t src, uint16_t dst) case HEARTBEAT_FILTER_REMOVE: return hb_filter_remove(src, dst); default: - BT_ERR("Invalid heartbeat filter opcode 0x%02x", op); + BT_ERR("Invalid HbFilterOpCode 0x%02x", op); return -EINVAL; } } @@ -248,6 +267,7 @@ static bool filter_with_rejectlist(uint16_t hb_src, uint16_t hb_dst) for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) { struct heartbeat_filter *filter = &hb_rx.filter[i]; if (hb_src == filter->src && hb_dst == filter->dst) { + BT_DBG("InRejectList, Src 0x%04x Dst 0x%04x", hb_src, hb_dst); return true; } } @@ -262,6 +282,7 @@ static bool filter_with_acceptlist(uint16_t hb_src, uint16_t hb_dst) for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) { struct heartbeat_filter *filter = &hb_rx.filter[i]; if (hb_src == filter->src && hb_dst == filter->dst) { + BT_DBG("InAcceptList, Src 0x%04x Dst 0x%04x", hb_src, hb_dst); return false; } } @@ -273,6 +294,8 @@ void bt_mesh_pvnr_heartbeat_recv(uint16_t hb_src, uint16_t hb_dst, uint8_t init_ttl, uint8_t rx_ttl, uint8_t hops, uint16_t feat, int8_t rssi) { + BT_DBG("PvnrHeartbeatRecv"); + if (hb_rx.cb == NULL) { BT_DBG("Receiving heartbeat is not enabled"); return; @@ -280,16 +303,17 @@ void bt_mesh_pvnr_heartbeat_recv(uint16_t hb_src, uint16_t hb_dst, if (hb_rx.type == HEARTBEAT_FILTER_REJECTLIST) { if (filter_with_rejectlist(hb_src, hb_dst)) { - BT_INFO("Filtered by rejectlist, src 0x%04x, dst 0x%04x", hb_src, hb_dst); return; } } else { if (filter_with_acceptlist(hb_src, hb_dst)) { - BT_INFO("Filtered by acceptlist, src 0x%04x, dst 0x%04x", hb_src, hb_dst); return; } } + BT_DBG("Src 0x%04x Dst 0x%04x InitTTL %u RxTTL %u Hops %u Feat 0x%04x Rssi %d", + hb_src, hb_dst, init_ttl, rx_ttl, hops, feat, rssi); + if (hb_rx.cb) { hb_rx.cb(hb_src, hb_dst, init_ttl, rx_ttl, hops, feat, rssi); } diff --git a/components/bt/esp_ble_mesh/core/include/mesh/adapter.h b/components/bt/esp_ble_mesh/core/include/mesh/adapter.h index 1cb239a3caca..5a1e4326a926 100644 --- a/components/bt/esp_ble_mesh/core/include/mesh/adapter.h +++ b/components/bt/esp_ble_mesh/core/include/mesh/adapter.h @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2017 Nordic Semiconductor ASA * SPDX-FileCopyrightText: 2015-2017 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -553,7 +553,7 @@ struct bt_mesh_gatt_attr { * @param len Length of data to read * @param offset Offset to start reading from * - * @return Number fo bytes read, or in case of an error + * @return Number of bytes read, or in case of an error * BLE_MESH_GATT_ERR() with a specific ATT error code. */ ssize_t (*read)(struct bt_mesh_conn *conn, diff --git a/components/bt/esp_ble_mesh/core/local.c b/components/bt/esp_ble_mesh/core/local.c index 4451e0d7b263..c0fc5b3f453e 100644 --- a/components/bt/esp_ble_mesh/core/local.c +++ b/components/bt/esp_ble_mesh/core/local.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,14 +22,17 @@ static struct bt_mesh_model *find_model(uint16_t elem_addr, uint16_t cid, uint16 { struct bt_mesh_elem *elem = NULL; + BT_DBG("FindModelLocal"); + BT_DBG("ElemAddr 0x%04x CID 0x%04x ID 0x%04x", elem_addr, cid, mod_id); + if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { - BT_ERR("Invalid unicast address 0x%04x", elem_addr); + BT_ERR("InvalidUnicastAddr 0x%04x", elem_addr); return NULL; } elem = bt_mesh_elem_find(elem_addr); if (elem == NULL) { - BT_ERR("No element found, addr 0x%04x", elem_addr); + BT_ERR("NoElemFound 0x%04x", elem_addr); return NULL; } @@ -46,19 +49,23 @@ int bt_mesh_model_subscribe_group_addr(uint16_t elem_addr, uint16_t cid, struct bt_mesh_model *model = NULL; int i; + BT_DBG("ModelSubGroupAddrLocal"); + BT_DBG("ElemAddr 0x%04x CID 0x%04x ID 0x%04x GroupAddr 0x%04x", + elem_addr, cid, mod_id, group_addr); + model = find_model(elem_addr, cid, mod_id); if (model == NULL) { - BT_ERR("Subscribe, model not found, cid 0x%04x, mod_id 0x%04x", cid, mod_id); + BT_ERR("ModelNotFound, CID 0x%04x ID 0x%04x", cid, mod_id); return -ENODEV; } if (!BLE_MESH_ADDR_IS_GROUP(group_addr)) { - BT_ERR("Subscribe, not a group address 0x%04x", group_addr); + BT_ERR("NotGroupAddr 0x%04x", group_addr); return -EINVAL; } if (bt_mesh_model_find_group(model, group_addr)) { - BT_INFO("Group address 0x%04x already exists", group_addr); + BT_INFO("GroupAddrExist 0x%04x", group_addr); return 0; } @@ -74,12 +81,11 @@ int bt_mesh_model_subscribe_group_addr(uint16_t elem_addr, uint16_t cid, bt_mesh_lpn_group_add(group_addr); } - BT_INFO("Subscribe group address 0x%04x", group_addr); return 0; } } - BT_ERR("Subscribe, model sub is full!"); + BT_ERR("ModelSubFull"); return -ENOMEM; } @@ -89,20 +95,24 @@ int bt_mesh_model_unsubscribe_group_addr(uint16_t elem_addr, uint16_t cid, struct bt_mesh_model *model = NULL; uint16_t *match = NULL; + BT_DBG("ModelUnsubGroupAddrLocal"); + BT_DBG("ElemAddr 0x%04x CID 0x%04x ID 0x%04x GroupAddr 0x%04x", + elem_addr, cid, mod_id, group_addr); + model = find_model(elem_addr, cid, mod_id); if (model == NULL) { - BT_ERR("Unsubscribe, model not found, cid 0x%04x, mod_id 0x%04x", cid, mod_id); + BT_ERR("ModelNotFound, CID 0x%04x ID 0x%04x", cid, mod_id); return -ENODEV; } if (!BLE_MESH_ADDR_IS_GROUP(group_addr)) { - BT_ERR("Unsubscribe, not a group address 0x%04x", group_addr); + BT_ERR("NotGroupAddr 0x%04x", group_addr); return -EINVAL; } match = bt_mesh_model_find_group(model, group_addr); if (match == NULL) { - BT_WARN("Group address 0x%04x not exists", group_addr); + BT_WARN("GroupAddrExist 0x%04x", group_addr); return -EEXIST; } @@ -116,7 +126,6 @@ int bt_mesh_model_unsubscribe_group_addr(uint16_t elem_addr, uint16_t cid, bt_mesh_lpn_group_del(&group_addr, 1); } - BT_INFO("Unsubscribe group address 0x%04x", group_addr); return 0; } @@ -126,20 +135,24 @@ int bt_mesh_enable_directed_forwarding(uint16_t net_idx, bool directed_forwardin { struct bt_mesh_subnet *sub = NULL; + BT_DBG("EnableDFLocal, NetIdx 0x%04x DF %u DFRelay %u", + net_idx, directed_forwarding, directed_forwarding_relay); + if (net_idx > 0xFFF) { - BT_ERR("Invalid NetKeyIndex 0x%04x", net_idx); + BT_ERR("InvalidNetIdx 0x%04x", net_idx); return -EINVAL; } sub = bt_mesh_subnet_get(net_idx); if (!sub) { - BT_ERR("NetKey 0x%04x not exists", net_idx); + BT_ERR("NetIdxNotExist 0x%04x", net_idx); return -EINVAL; } if (directed_forwarding == BLE_MESH_DIRECTED_FORWARDING_DISABLED && directed_forwarding_relay == BLE_MESH_DIRECTED_RELAY_ENABLED) { - BT_ERR("Invalid Config directed forwarding: %d, directed forwarding relay: %d", directed_forwarding, directed_forwarding_relay); + BT_ERR("InvalidDFConfig %u/%u", + directed_forwarding, directed_forwarding_relay); return -EINVAL; } @@ -155,14 +168,16 @@ const uint8_t *bt_mesh_node_get_local_net_key(uint16_t net_idx) { struct bt_mesh_subnet *sub = NULL; + BT_DBG("NodeGetNetKeyLocal, NetIdx 0x%04x", net_idx); + if (net_idx > 0xFFF) { - BT_ERR("Invalid NetKeyIndex 0x%04x", net_idx); + BT_ERR("InvalidNetIdx 0x%04x", net_idx); return NULL; } sub = bt_mesh_subnet_get(net_idx); if (!sub) { - BT_ERR("NetKey 0x%04x not exists", net_idx); + BT_ERR("NetIdxNotExist 0x%04x", net_idx); return NULL; } @@ -173,14 +188,16 @@ const uint8_t *bt_mesh_node_get_local_app_key(uint16_t app_idx) { struct bt_mesh_app_key *key = NULL; + BT_DBG("NodeGetAppKeyLocal, AppIdx 0x%04x", app_idx); + if (app_idx > 0xFFF) { - BT_ERR("Invalid AppKeyIndex 0x%04x", app_idx); + BT_ERR("InvalidAppIdx 0x%04x", app_idx); return NULL; } key = bt_mesh_app_key_get(app_idx); if (!key) { - BT_ERR("AppKey 0x%04x not exists", app_idx); + BT_ERR("AppIdxNotExist 0x%04x", app_idx); return NULL; } @@ -193,19 +210,21 @@ int bt_mesh_node_local_net_key_add(uint16_t net_idx, const uint8_t net_key[16]) int err = 0; int i; + BT_DBG("NodeAddNetKeyLocal, NetIdx 0x%04x", net_idx); + if (net_idx > 0xFFF || net_key == NULL) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; } if (!bt_mesh_is_provisioned()) { - BT_ERR("Not provisioned, failed to add NetKey"); + BT_ERR("NotProvisioned"); return -EIO; } sub = bt_mesh_subnet_get(net_idx); if (sub) { - BT_WARN("NetKey 0x%04x already exists", net_idx); + BT_WARN("NetIdxExist 0x%04x", net_idx); return -EEXIST; } @@ -215,7 +234,7 @@ int bt_mesh_node_local_net_key_add(uint16_t net_idx, const uint8_t net_key[16]) memcmp(bt_mesh.sub[i].keys[0].net, net_key, 16) == 0) || (bt_mesh.sub[i].kr_flag == true && memcmp(bt_mesh.sub[i].keys[1].net, net_key, 16) == 0)) { - BT_WARN("Key value %s already exists", bt_hex(net_key, 16)); + BT_WARN("NetKeyValExist %s", bt_hex(net_key, 16)); return -EEXIST; } } @@ -229,13 +248,13 @@ int bt_mesh_node_local_net_key_add(uint16_t net_idx, const uint8_t net_key[16]) } if (sub == NULL) { - BT_ERR("NetKey is full!"); + BT_ERR("NetKeyFull"); return -ENOMEM; } err = bt_mesh_net_keys_create(&sub->keys[0], net_key); if (err) { - BT_ERR("Failed to create keys for NetKey 0x%04x", net_idx); + BT_ERR("NetKeyCreateFail 0x%04x", net_idx); return -EIO; } @@ -249,7 +268,6 @@ int bt_mesh_node_local_net_key_add(uint16_t net_idx, const uint8_t net_key[16]) } if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - BT_DBG("Storing NetKey persistently"); bt_mesh_store_subnet(sub); } @@ -264,24 +282,26 @@ int bt_mesh_node_local_app_key_add(uint16_t net_idx, uint16_t app_idx, { struct bt_mesh_app_key *key = NULL; + BT_DBG("NodeAddAppKeyLocal, NetIdx 0x%04x AppIdx 0x%04x", net_idx, app_idx); + if (net_idx > 0xFFF || app_idx > 0xFFF || app_key == NULL) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; } if (!bt_mesh_is_provisioned()) { - BT_ERR("Not provisioned, failed to add AppKey"); + BT_ERR("NotProvisioned"); return -EIO; } if (bt_mesh_subnet_get(net_idx) == NULL) { - BT_ERR("Subnet 0x%04x not exists", net_idx); + BT_ERR("NetIdxNotExist 0x%04x", net_idx); return -EIO; } key = bt_mesh_app_key_get(app_idx); if (key) { - BT_WARN("AppKey 0x%04x already exists", app_idx); + BT_WARN("AppIdxExist 0x%04x", app_idx); return -EEXIST; } @@ -291,7 +311,7 @@ int bt_mesh_node_local_app_key_add(uint16_t net_idx, uint16_t app_idx, memcmp(bt_mesh.app_keys[i].keys[0].val, app_key, 16) == 0) || (bt_mesh.app_keys[i].updated == true && memcmp(bt_mesh.app_keys[i].keys[1].val, app_key, 16) == 0)) { - BT_WARN("Key value %s already exists", bt_hex(app_key, 16)); + BT_WARN("AppKeyValExist %s", bt_hex(app_key, 16)); return -EEXIST; } } @@ -302,7 +322,7 @@ int bt_mesh_node_local_app_key_add(uint16_t net_idx, uint16_t app_idx, struct bt_mesh_app_keys *keys = &key->keys[0]; if (bt_mesh_app_id(app_key, &keys->id)) { - BT_ERR("Failed to generate AID"); + BT_ERR("GenAIDFail"); return -EIO; } @@ -312,15 +332,12 @@ int bt_mesh_node_local_app_key_add(uint16_t net_idx, uint16_t app_idx, memcpy(keys->val, app_key, 16); if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - BT_DBG("Storing AppKey persistently"); bt_mesh_store_app_key(key); } - BT_INFO("Add AppKey 0x%04x, NetKeyIndex 0x%04x", app_idx, net_idx); return 0; } - BT_ERR("AppKey is full!"); return -ENOMEM; } @@ -330,25 +347,29 @@ int bt_mesh_node_bind_app_key_to_model(uint16_t elem_addr, uint16_t mod_id, struct bt_mesh_model *model = NULL; int i; + BT_DBG("NodeBindAppKeyLocal"); + BT_DBG("ElemAddr 0x%04x CID 0x%04x ID 0x%04x AppIdx 0x%04x", + elem_addr, cid, mod_id, app_idx); + if (!bt_mesh_is_provisioned()) { - BT_ERR("Not provisioned, failed to bind AppKey"); + BT_ERR("NotProvisioned"); return -EIO; } model = find_model(elem_addr, cid, mod_id); if (model == NULL) { - BT_ERR("Bind, model(id 0x%04x, cid 0x%04x) not found", mod_id, cid); + BT_ERR("ModelNotFound, ID 0x%04x CID 0x%04x", mod_id, cid); return -ENODEV; } if (bt_mesh_app_key_get(app_idx) == NULL) { - BT_ERR("Bind, AppKey 0x%03x not exists", app_idx); + BT_ERR("AppIdxNotExist 0x%04x", app_idx); return -ENODEV; } for (i = 0; i < ARRAY_SIZE(model->keys); i++) { if (model->keys[i] == app_idx) { - BT_WARN("Already bound to AppKey 0x%04x", app_idx); + BT_WARN("AppIdxBound 0x%04x", app_idx); return -EALREADY; } } @@ -356,16 +377,16 @@ int bt_mesh_node_bind_app_key_to_model(uint16_t elem_addr, uint16_t mod_id, for (i = 0; i < ARRAY_SIZE(model->keys); i++) { if (model->keys[i] == BLE_MESH_KEY_UNUSED) { model->keys[i] = app_idx; + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { bt_mesh_store_mod_bind(model); } - BT_INFO("Model(id 0x%04x, cid 0x%04x) bound to AppKey 0x%04x", mod_id, cid, app_idx); return 0; } } - BT_ERR("Model bound is full!"); + BT_ERR("ModelBindFull"); return -ENOMEM; } #endif /* CONFIG_BLE_MESH_NODE */ diff --git a/components/bt/esp_ble_mesh/core/lpn.c b/components/bt/esp_ble_mesh/core/lpn.c index 80f5b4321afc..a38b0944e4de 100644 --- a/components/bt/esp_ble_mesh/core/lpn.c +++ b/components/bt/esp_ble_mesh/core/lpn.c @@ -81,30 +81,30 @@ static const char *state2str(int state) { switch (state) { case BLE_MESH_LPN_DISABLED: - return "disabled"; + return "Disabled"; case BLE_MESH_LPN_CLEAR: - return "clear"; + return "Clear"; case BLE_MESH_LPN_TIMER: - return "timer"; + return "Timer"; case BLE_MESH_LPN_ENABLED: - return "enabled"; + return "Enabled"; case BLE_MESH_LPN_REQ_WAIT: - return "req wait"; + return "ReqWait"; case BLE_MESH_LPN_WAIT_OFFER: - return "wait offer"; + return "WaitOffer"; case BLE_MESH_LPN_ESTABLISHED: - return "established"; + return "Established"; case BLE_MESH_LPN_RECV_DELAY: - return "recv delay"; + return "RecvDelay"; case BLE_MESH_LPN_WAIT_UPDATE: - return "wait update"; + return "WaitUpdate"; case BLE_MESH_LPN_OFFER_RECV: - return "offer recv"; + return "OfferRecv"; default: - return "(unknown)"; + return "(Unknown)"; } } -#endif +#endif /* !CONFIG_BLE_MESH_NO_LOG */ static inline void lpn_set_state(int state) { @@ -120,9 +120,9 @@ static inline void group_zero(bt_mesh_atomic_t *target) for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) { bt_mesh_atomic_set(&target[i], 0); } -#else +#else /* CONFIG_BLE_MESH_LPN_GROUPS > 32 */ bt_mesh_atomic_set(target, 0); -#endif +#endif /* CONFIG_BLE_MESH_LPN_GROUPS > 32 */ } static inline void group_set(bt_mesh_atomic_t *target, bt_mesh_atomic_t *source) @@ -133,9 +133,9 @@ static inline void group_set(bt_mesh_atomic_t *target, bt_mesh_atomic_t *source) for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) { (void)bt_mesh_atomic_or(&target[i], bt_mesh_atomic_get(&source[i])); } -#else +#else /* CONFIG_BLE_MESH_LPN_GROUPS > 32 */ (void)bt_mesh_atomic_or(target, bt_mesh_atomic_get(source)); -#endif +#endif /* CONFIG_BLE_MESH_LPN_GROUPS > 32 */ } static inline void group_clear(bt_mesh_atomic_t *target, bt_mesh_atomic_t *source) @@ -146,9 +146,9 @@ static inline void group_clear(bt_mesh_atomic_t *target, bt_mesh_atomic_t *sourc for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) { (void)bt_mesh_atomic_and(&target[i], ~bt_mesh_atomic_get(&source[i])); } -#else +#else /* CONFIG_BLE_MESH_LPN_GROUPS > 32 */ (void)bt_mesh_atomic_and(target, ~bt_mesh_atomic_get(source)); -#endif +#endif /* CONFIG_BLE_MESH_LPN_GROUPS > 32 */ } static void clear_friendship(bool force, bool disable); @@ -159,6 +159,8 @@ static void friend_clear_sent(int err, void *user_data) { struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + BT_DBG("FrndClearSent, Err %d", err); + /* We're switching away from Low Power behavior, so permanently * enable scanning. */ @@ -169,6 +171,8 @@ static void friend_clear_sent(int err, void *user_data) lpn->req_attempts++; + BT_DBG("ReqAttempts %u", lpn->req_attempts); + if (err) { BT_ERR("Sending Friend Clear failed (err %d)", err); lpn_set_state(BLE_MESH_LPN_ENABLED); @@ -206,6 +210,8 @@ static int send_friend_clear(void) .lpn_counter = sys_cpu_to_be16(bt_mesh.lpn.counter), }; + BT_DBG("SendFrndClear"); + return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR, &req, sizeof(req), &clear_sent_cb, NULL); } @@ -215,10 +221,12 @@ static void clear_friendship(bool force, bool disable) struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get(); struct bt_mesh_lpn *lpn = &bt_mesh.lpn; - BT_DBG("force %u disable %u", force, disable); + BT_DBG("ClearFriendship, Force %u Disable %u", force, disable); if (!force && lpn->established && !lpn->clear_success && lpn->req_attempts < CLEAR_ATTEMPTS) { + BT_DBG("SendFrndClear, ReqAttempts %u", lpn->req_attempts); + send_friend_clear(); lpn->disable = disable; return; @@ -253,7 +261,7 @@ static void clear_friendship(bool force, bool disable) bt_mesh_restore_directed_forwarding_state(bt_mesh.sub[0].net_idx, lpn->old_directed_forwarding); } -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ lpn->frnd = BLE_MESH_ADDR_UNASSIGNED; lpn->fsn = 0U; @@ -306,6 +314,8 @@ static void friend_req_sent(uint16_t duration, int err, void *user_data) return; } + BT_DBG("FrndReqSent, duration %u", duration); + lpn->adv_duration = duration; if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) { @@ -349,6 +359,8 @@ static int send_friend_req(struct bt_mesh_lpn *lpn) .lpn_counter = sys_cpu_to_be16(lpn->counter), }; + BT_DBG("SendFrndReq, NetIdx 0x%04x", ctx.net_idx); + return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_REQ, &req, sizeof(req), &friend_req_sent_cb, NULL); } @@ -357,7 +369,7 @@ static void req_sent(uint16_t duration, int err, void *user_data) { struct bt_mesh_lpn *lpn = &bt_mesh.lpn; - BT_DBG("req 0x%02x duration %u err %d state %s", + BT_DBG("ReqSent, Req 0x%02x Duration %u Err %d State %s", lpn->sent_req, duration, err, state2str(lpn->state)); if (err) { @@ -372,6 +384,9 @@ static void req_sent(uint16_t duration, int err, void *user_data) if (lpn->established || IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) { lpn_set_state(BLE_MESH_LPN_RECV_DELAY); + + BT_DBG("RecvDelay %u ScanLatency %u", LPN_RECV_DELAY, SCAN_LATENCY); + /* We start scanning a bit early to eliminate risk of missing * response data due to HCI and other latencies. */ @@ -379,6 +394,9 @@ static void req_sent(uint16_t duration, int err, void *user_data) LPN_RECV_DELAY - SCAN_LATENCY); } else { lpn_set_state(BLE_MESH_LPN_OFFER_RECV); + + BT_DBG("RecvDelay %u RecvWin %u", LPN_RECV_DELAY, lpn->recv_win); + /** * Friend Update is replied by Friend Node with TTL set to 0 and Network * Transmit set to 30ms which will cause the packet easy to be missed. @@ -416,7 +434,7 @@ static int send_friend_poll(void) uint8_t fsn = lpn->fsn; int err = 0; - BT_DBG("lpn->sent_req 0x%02x", lpn->sent_req); + BT_DBG("SendFrndPoll, Req 0x%02x ", lpn->sent_req); if (lpn->sent_req) { if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) { @@ -438,6 +456,8 @@ static int send_friend_poll(void) void bt_mesh_lpn_disable(bool force) { + BT_DBG("LPNDisable, Force %u State 0x%02x", force, bt_mesh.lpn.state); + if (bt_mesh.lpn.state == BLE_MESH_LPN_DISABLED) { return; } @@ -449,6 +469,8 @@ int bt_mesh_lpn_set(bool enable, bool force) { struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + BT_DBG("LPNSet, Enable %u Force %u State 0x%02x", enable, force, lpn->state); + if (enable) { if (lpn->state != BLE_MESH_LPN_DISABLED) { return 0; @@ -479,7 +501,7 @@ int bt_mesh_lpn_set(bool enable, bool force) send_friend_req(lpn); } else { if (IS_ENABLED(CONFIG_BLE_MESH_LPN_AUTO) && - lpn->state == BLE_MESH_LPN_TIMER) { + lpn->state == BLE_MESH_LPN_TIMER) { k_delayed_work_cancel(&lpn->timer); lpn_set_state(BLE_MESH_LPN_DISABLED); } else { @@ -492,7 +514,7 @@ int bt_mesh_lpn_set(bool enable, bool force) static void friend_response_received(struct bt_mesh_lpn *lpn) { - BT_DBG("lpn->sent_req 0x%02x", lpn->sent_req); + BT_DBG("FrndRspRecv, Req 0x%02x Fsn %u", lpn->sent_req, lpn->fsn); if (lpn->sent_req == TRANS_CTL_OP_FRIEND_POLL) { lpn->fsn++; @@ -509,6 +531,8 @@ void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx) { struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + BT_DBG("LPNMsgRecv, Req 0x%02x State 0x%02x", lpn->sent_req, lpn->state); + if (lpn->state == BLE_MESH_LPN_TIMER) { BT_DBG("Restarting establishment timer"); k_delayed_work_submit(&lpn->timer, LPN_AUTO_TIMEOUT); @@ -522,8 +546,6 @@ void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx) friend_response_received(lpn); - BT_DBG("Requesting more messages from Friend"); - send_friend_poll(); } @@ -537,6 +559,8 @@ int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx, uint16_t frnd_counter = 0U; int err = 0; + BT_DBG("LPNFrndOffer"); + if (buf->len < sizeof(*msg)) { BT_WARN("Too short Friend Offer"); return -EINVAL; @@ -554,9 +578,9 @@ int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx, frnd_counter = sys_be16_to_cpu(msg->frnd_counter); - BT_INFO("recv_win %u queue_size %u sub_list_size %u rssi %d counter %u", - msg->recv_win, msg->queue_size, msg->sub_list_size, msg->rssi, - frnd_counter); + BT_INFO("Frnd 0x%04x RecvWin %u QueueSize %u SubListSize %u FrndCounter %u Rssi %d", + rx->ctx.addr, msg->recv_win, msg->queue_size, + msg->sub_list_size, frnd_counter, msg->rssi); lpn->frnd = rx->ctx.addr; @@ -575,6 +599,8 @@ int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx, err = send_friend_poll(); if (err) { + BT_ERR("SendFrndPollFailed, Err %d", err); + friend_cred_clear(cred); lpn->frnd = BLE_MESH_ADDR_UNASSIGNED; lpn->recv_win = 0U; @@ -598,6 +624,8 @@ int bt_mesh_lpn_friend_clear_cfm(struct bt_mesh_net_rx *rx, struct bt_mesh_lpn *lpn = &bt_mesh.lpn; uint16_t addr = 0U, counter = 0U; + BT_DBG("LPNFrndClearCFM"); + if (buf->len < sizeof(*msg)) { BT_WARN("Too short Friend Clear Confirm"); return -EINVAL; @@ -611,7 +639,7 @@ int bt_mesh_lpn_friend_clear_cfm(struct bt_mesh_net_rx *rx, addr = sys_be16_to_cpu(msg->lpn_addr); counter = sys_be16_to_cpu(msg->lpn_counter); - BT_DBG("LPNAddress 0x%04x LPNCounter 0x%04x", addr, counter); + BT_DBG("LPN 0x%04x Counter 0x%04x", addr, counter); if (addr != bt_mesh_primary_addr() || counter != lpn->counter) { BT_WARN("Invalid parameters in Friend Clear Confirm"); @@ -630,8 +658,11 @@ static void lpn_group_add(uint16_t group) uint16_t *free_slot = NULL; int i; + BT_DBG("LPNGroupAdd, Addr 0x%04x", group); + for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) { if (lpn->groups[i] == group) { + BT_DBG("ClearLPNToRemove"); bt_mesh_atomic_clear_bit(lpn->to_remove, i); return; } @@ -655,10 +686,13 @@ static void lpn_group_del(uint16_t group) struct bt_mesh_lpn *lpn = &bt_mesh.lpn; int i; + BT_DBG("LPNGroupDel, Addr 0x%04x", group); + for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) { if (lpn->groups[i] == group) { if (bt_mesh_atomic_test_bit(lpn->added, i) || bt_mesh_atomic_test_bit(lpn->pending, i)) { + BT_DBG("Set LPNToRemove"); bt_mesh_atomic_set_bit(lpn->to_remove, i); lpn->groups_changed = 1U; } else { @@ -676,9 +710,9 @@ 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])); } -#else +#else /* CONFIG_BLE_MESH_LPN_GROUPS > 32 */ return popcount(bt_mesh_atomic_get(target)); -#endif +#endif /* CONFIG_BLE_MESH_LPN_GROUPS > 32 */ } static bool sub_update(uint8_t op) @@ -703,7 +737,7 @@ static bool sub_update(uint8_t op) struct bt_mesh_ctl_friend_sub req = {0}; size_t i = 0U, g = 0U; - BT_DBG("op 0x%02x sent_req 0x%02x", op, lpn->sent_req); + BT_DBG("SubUpdate, OP 0x%02x Req 0x%02x ", op, lpn->sent_req); if (lpn->sent_req) { return false; @@ -725,7 +759,8 @@ static bool sub_update(uint8_t op) } if (added_count + g >= lpn->queue_size) { - BT_WARN("Friend Queue Size exceeded"); + BT_WARN("FrndQueueExceeded, Added %u G %u Size %u", + added_count, g, lpn->queue_size); break; } @@ -744,6 +779,8 @@ static bool sub_update(uint8_t op) req.xact = lpn->xact_next++; + BT_DBG("Xact %u G %u", req.xact, g); + if (bt_mesh_ctl_send(&tx, op, &req, 1 + g * 2, &req_sent_cb, NULL) < 0) { group_zero(lpn->pending); @@ -752,14 +789,19 @@ static bool sub_update(uint8_t op) lpn->xact_pending = req.xact; lpn->sent_req = op; + return true; } static void update_timeout(struct bt_mesh_lpn *lpn) { + BT_DBG("UpdateTimeout"); + if (lpn->established) { BT_WARN("No response from Friend during ReceiveWindow"); + bt_mesh_scan_disable(); + lpn_set_state(BLE_MESH_LPN_ESTABLISHED); k_delayed_work_submit(&lpn->timer, POLL_RETRY_TIMEOUT); } else { @@ -767,6 +809,8 @@ static void update_timeout(struct bt_mesh_lpn *lpn) bt_mesh_scan_disable(); } + BT_DBG("ReqAttempts %u", lpn->req_attempts); + if (lpn->req_attempts < FIRST_POLL_ATTEMPTS) { BT_WARN("Retrying first Friend Poll"); lpn->sent_req = 0U; @@ -784,7 +828,7 @@ static void lpn_timeout(struct k_work *work) { struct bt_mesh_lpn *lpn = &bt_mesh.lpn; - BT_DBG("state: %s", state2str(lpn->state)); + BT_DBG("LPNTimeout, State: %s", state2str(lpn->state)); switch (lpn->state) { case BLE_MESH_LPN_DISABLED: @@ -830,6 +874,8 @@ static void lpn_timeout(struct k_work *work) clear_friendship(true, false); break; case BLE_MESH_LPN_ESTABLISHED: + BT_DBG("ReqAttempts %u vs. %u", lpn->req_attempts, REQ_ATTEMPTS(lpn)); + if (lpn->req_attempts < REQ_ATTEMPTS(lpn)) { uint8_t req = lpn->sent_req; @@ -867,11 +913,13 @@ static void lpn_timeout(struct k_work *work) void bt_mesh_lpn_group_add(uint16_t group) { - BT_DBG("group 0x%04x", group); + BT_DBG("LPNGroupAdd, Addr 0x%04x", group); lpn_group_add(group); if (!bt_mesh_lpn_established() || bt_mesh.lpn.sent_req) { + BT_INFO("Established %u Req 0x%02x", + bt_mesh_lpn_established(), bt_mesh.lpn.sent_req); return; } @@ -882,6 +930,8 @@ void bt_mesh_lpn_group_del(uint16_t *groups, size_t group_count) { int i; + BT_DBG("LPNGroupDel, GroupCount %u", group_count); + for (i = 0; i < group_count; i++) { if (groups[i] != BLE_MESH_ADDR_UNASSIGNED) { BT_DBG("group 0x%04x", groups[i]); @@ -890,6 +940,8 @@ void bt_mesh_lpn_group_del(uint16_t *groups, size_t group_count) } if (!bt_mesh_lpn_established() || bt_mesh.lpn.sent_req) { + BT_INFO("Established %u Req 0x%02x", + bt_mesh_lpn_established(), bt_mesh.lpn.sent_req); return; } @@ -900,6 +952,7 @@ static int32_t poll_timeout(struct bt_mesh_lpn *lpn) { /* If we're waiting for segment acks keep polling at high freq */ if (bt_mesh_tx_in_progress()) { + BT_DBG("PollTimeout, Max %u", POLL_TIMEOUT_MAX(lpn)); return MIN(POLL_TIMEOUT_MAX(lpn), K_SECONDS(1)); } @@ -909,7 +962,7 @@ static int32_t poll_timeout(struct bt_mesh_lpn *lpn) POLL_TIMEOUT_MAX(lpn)); } - BT_DBG("Poll Timeout is %ums", lpn->poll_timeout); + BT_DBG("PollTimeout %u", lpn->poll_timeout); return lpn->poll_timeout; } @@ -920,12 +973,15 @@ int bt_mesh_lpn_friend_sub_cfm(struct bt_mesh_net_rx *rx, struct bt_mesh_ctl_friend_sub_confirm *msg = (void *)buf->data; struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + BT_DBG("LPNFrndSubCFM"); + if (buf->len < sizeof(*msg)) { BT_WARN("Too short Friend Subscription Confirm"); return -EINVAL; } - BT_DBG("xact 0x%02x", msg->xact); + BT_DBG("Xact %u Req 0x%02x GroupsChanged %u PendingPoll %u", + msg->xact, lpn->sent_req, lpn->groups_changed, lpn->pending_poll); if (!lpn->sent_req) { BT_WARN("No pending subscription list message"); @@ -987,11 +1043,16 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx, struct bt_mesh_subnet *sub = rx->sub; uint32_t iv_index = 0U; + BT_DBG("LPNFrndUpdate"); + if (buf->len < sizeof(*msg)) { BT_WARN("Too short Friend Update"); return -EINVAL; } + BT_DBG("Req 0x%02x KrPhase %u Established %u", + lpn->sent_req, sub->kr_phase, lpn->established); + if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) { BT_WARN("Unexpected friend update"); return 0; @@ -1034,8 +1095,7 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx, } /* Set initial poll timeout */ - lpn->poll_timeout = MIN(POLL_TIMEOUT_MAX(lpn), - POLL_TIMEOUT_INIT); + lpn->poll_timeout = MIN(POLL_TIMEOUT_MAX(lpn), POLL_TIMEOUT_INIT); /* If the Low Power node supports directed forwarding functionality when * the friendship is established in a subnet, the Low Power node shall @@ -1046,18 +1106,16 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx, */ #if CONFIG_BLE_MESH_DF_SRV lpn->old_directed_forwarding = bt_mesh_get_and_disable_directed_forwarding_state(sub); -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ } friend_response_received(lpn); iv_index = sys_be32_to_cpu(msg->iv_index); - BT_INFO("flags 0x%02x iv_index 0x%08x md %u", msg->flags, iv_index, - msg->md); + BT_INFO("Flags 0x%02x IVIndex 0x%08lx MD %u", msg->flags, iv_index, msg->md); - if (bt_mesh_kr_update(sub, BLE_MESH_KEY_REFRESH(msg->flags), - rx->new_key)) { + if (bt_mesh_kr_update(sub, BLE_MESH_KEY_REFRESH(msg->flags), rx->new_key)) { bt_mesh_net_secure_beacon_update(sub); } @@ -1086,12 +1144,12 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx, int bt_mesh_lpn_poll(void) { + BT_DBG("LPNPoll, Established %u", bt_mesh.lpn.established); + if (!bt_mesh.lpn.established) { return -EAGAIN; } - BT_DBG("Requesting more messages"); - return send_friend_poll(); } @@ -1104,6 +1162,8 @@ int bt_mesh_lpn_init(void) { struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + BT_DBG("LPNInit"); + k_delayed_work_init(&lpn->timer, lpn_timeout); if (lpn->state == BLE_MESH_LPN_ENABLED) { @@ -1130,6 +1190,8 @@ int bt_mesh_lpn_deinit(void) { struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + BT_DBG("LPNDeinit"); + bt_mesh_lpn_disable(true); k_delayed_work_free(&lpn->timer); diff --git a/components/bt/esp_ble_mesh/core/main.c b/components/bt/esp_ble_mesh/core/main.c index 957234e312e3..cc5543697e9a 100644 --- a/components/bt/esp_ble_mesh/core/main.c +++ b/components/bt/esp_ble_mesh/core/main.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -32,12 +32,14 @@ #if CONFIG_BLE_MESH_V11_SUPPORT #include "mesh_v1.1/utils.h" -#endif +#endif /* CONFIG_BLE_MESH_V11_SUPPORT */ static bool mesh_init = false; bool bt_mesh_is_initialized(void) { + BT_DBG("IsInitialized %u", mesh_init); + return mesh_init; } @@ -48,9 +50,10 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, bool pb_gatt_enabled = false; int err = 0; - BT_INFO("Primary Element: 0x%04x", addr); - BT_INFO("net_idx 0x%04x flags 0x%02x iv_index 0x%04x", - net_idx, flags, iv_index); + BT_INFO("NodeProvisioned"); + BT_INFO("PrimaryAddr 0x%04x", addr); + BT_INFO("NetIdx 0x%04x Flags 0x%02x IVIndex 0x%08lx", + net_idx, flags, iv_index); BT_INFO("DevKey %s", bt_hex(dev_key, 16)); BT_INFO("NetKey %s", bt_hex(net_key, 16)); @@ -69,9 +72,12 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, pb_gatt_enabled = false; } + BT_DBG("PbGattEnabled %u", pb_gatt_enabled); + err = bt_mesh_net_create(net_idx, flags, net_key, iv_index); if (err) { BT_ERR("Create network for node failed"); + bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_VALID); if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) && pb_gatt_enabled) { @@ -89,11 +95,11 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) && IS_ENABLED(CONFIG_BLE_MESH_LPN_SUB_ALL_NODES_ADDR)) { + BT_DBG("LPNAllNodesAdded"); bt_mesh_lpn_group_add(BLE_MESH_ADDR_ALL_NODES); } if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - BT_DBG("Storing network information persistently"); bt_mesh_store_net(); bt_mesh_store_subnet(&bt_mesh.sub[0]); bt_mesh_store_iv(false); @@ -106,6 +112,8 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, void bt_mesh_node_reset(void) { + BT_DBG("NodeLocalReset"); + if (!bt_mesh_is_provisioned()) { BT_WARN("%s, Not provisioned", __func__); return; @@ -154,7 +162,7 @@ void bt_mesh_node_reset(void) #if CONFIG_BLE_MESH_PRB_SRV bt_mesh_private_beacon_disable(); -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ bt_mesh_comp_unprovision(); @@ -165,7 +173,7 @@ void bt_mesh_node_reset(void) bt_mesh_clear_role(); #if CONFIG_BLE_MESH_DF_SRV bt_mesh_clear_all_directed_forwarding_table_data(); -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ } memset(bt_mesh.flags, 0, sizeof(bt_mesh.flags)); @@ -177,34 +185,52 @@ void bt_mesh_node_reset(void) bool bt_mesh_is_node(void) { - return bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_NODE); + bool is_node = bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_NODE); + + BT_DBG("IsNode %u", is_node); + + return is_node; } bool bt_mesh_is_provisioned(void) { + bool is_provisioned = false; + if (bt_mesh_is_node()) { - return bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID); - } else { - return false; + is_provisioned = bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID); } + + BT_DBG("IsProvisioned %u", is_provisioned); + + return is_provisioned; } bool bt_mesh_is_provisioner(void) { - return bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_PROVISIONER); + bool is_pvnr = bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_PROVISIONER); + + BT_DBG("IsPvnr %u", is_pvnr); + + return is_pvnr; } bool bt_mesh_is_provisioner_en(void) { + bool is_pvnr_en = false; + if (bt_mesh_is_provisioner()) { - return bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID_PROV); + is_pvnr_en = bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID_PROV); } - return false; + BT_DBG("IsPvnrEn %u", is_pvnr_en); + + return is_pvnr_en; } static bool prov_bearers_valid(bt_mesh_prov_bearer_t bearers) { + BT_DBG("ProvBearersValid, Bearers 0x%02x", bearers); + if ((!(bearers & (BLE_MESH_PROV_ADV | BLE_MESH_PROV_GATT))) || (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) && !IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) && @@ -215,6 +241,7 @@ static bool prov_bearers_valid(bt_mesh_prov_bearer_t bearers) BT_ERR("Invalid bearers 0x%02x", bearers); return false; } + return true; } @@ -222,6 +249,8 @@ int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) { int err = 0; + BT_DBG("ProvEnable, Bearers 0x%02x", bearers); + if (bt_mesh_is_provisioned()) { BT_WARN("%s, Already", __func__); return -EALREADY; @@ -247,6 +276,7 @@ int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) if (role == BLE_MESH_SETTINGS_ROLE_NONE) { bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_NODE); } + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS_BACKWARD_COMPATIBILITY) || role == BLE_MESH_SETTINGS_ROLE_NONE) { if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { @@ -277,6 +307,8 @@ int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers) { + BT_DBG("ProvDisable, Bearers 0x%02x", bearers); + if (bt_mesh_is_provisioned()) { BT_WARN("%s, Already provisioned", __func__); return -EALREADY; @@ -309,6 +341,8 @@ int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers) static void model_suspend(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { + BT_DBG("ModelSuspend, Vnd %u Primary %u", vnd, primary); + if (mod->pub && mod->pub->update) { mod->pub->count = 0U; k_delayed_work_cancel(&mod->pub->timer); @@ -319,6 +353,8 @@ int bt_mesh_suspend(void) { int err = 0; + BT_DBG("Suspend"); + if (!bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID)) { return -EINVAL; } @@ -344,7 +380,7 @@ int bt_mesh_suspend(void) if (bt_mesh_private_beacon_state_get() == BLE_MESH_PRIVATE_BEACON_ENABLED) { bt_mesh_private_beacon_disable(); } -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ bt_mesh_model_foreach(model_suspend, NULL); @@ -354,6 +390,8 @@ int bt_mesh_suspend(void) static void model_resume(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { + BT_DBG("ModelResume, Vnd %u Primary %u", vnd, primary); + if (mod->pub && mod->pub->update) { int32_t period_ms = bt_mesh_model_pub_period_get(mod); @@ -367,6 +405,8 @@ int bt_mesh_resume(void) { int err = 0; + BT_DBG("Resume"); + if (!bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID)) { return -EINVAL; } @@ -390,7 +430,7 @@ int bt_mesh_resume(void) if (bt_mesh_private_beacon_state_get() == BLE_MESH_PRIVATE_BEACON_ENABLED) { bt_mesh_private_beacon_enable(); } -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ bt_mesh_model_foreach(model_resume, NULL); @@ -402,6 +442,8 @@ int bt_mesh_init(const struct bt_mesh_prov *prov, { int err = 0; + BT_DBG("Init"); + if (mesh_init == true) { BT_WARN("%s, Already", __func__); return -EALREADY; @@ -414,7 +456,7 @@ int bt_mesh_init(const struct bt_mesh_prov *prov, BT_ERR("Bluetooth Mesh v1.1 init failed"); return err; } -#endif +#endif /* CONFIG_BLE_MESH_V11_SUPPORT */ bt_mesh_mutex_init(); @@ -452,7 +494,7 @@ int bt_mesh_init(const struct bt_mesh_prov *prov, if (err) { return err; } -#endif +#endif /* CONFIG_BLE_MESH_PROXY_SOLIC */ if (IS_ENABLED(CONFIG_BLE_MESH_PROV)) { err = bt_mesh_prov_set(prov); @@ -507,6 +549,8 @@ int bt_mesh_deinit(struct bt_mesh_deinit_param *param) { int err = 0; + BT_DBG("Deinit"); + if (param == NULL) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; @@ -522,7 +566,7 @@ int bt_mesh_deinit(struct bt_mesh_deinit_param *param) #if CONFIG_BLE_MESH_PRB_SRV bt_mesh_private_beacon_disable(); -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node()) { if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) && @@ -583,7 +627,7 @@ int bt_mesh_deinit(struct bt_mesh_deinit_param *param) #if CONFIG_BLE_MESH_PROXY_SOLIC bt_mesh_proxy_solic_deinit(); -#endif +#endif /* CONFIG_BLE_MESH_PROXY_SOLIC */ if ((IS_ENABLED(CONFIG_BLE_MESH_NODE) && IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) || @@ -638,6 +682,8 @@ int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers) { int err = 0; + BT_DBG("PvnrEnable, Bearers 0x%02x", bearers); + if (bt_mesh_is_provisioner_en()) { BT_WARN("%s, Already", __func__); return -EALREADY; @@ -703,7 +749,7 @@ int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers) BLE_MESH_EXCEP_LIST_TYPE_MESH_PROV_ADV, NULL); } -#endif +#endif /* CONFIG_BLE_MESH_USE_DUPLICATE_SCAN */ if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) && (bearers & BLE_MESH_PROV_GATT)) { @@ -722,7 +768,7 @@ int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers) if (bt_mesh_private_beacon_state_get() == BLE_MESH_PRIVATE_BEACON_ENABLED) { bt_mesh_private_beacon_enable(); } -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ err = bt_mesh_scan_enable(); if (err) { @@ -736,6 +782,8 @@ int bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers) { bt_mesh_prov_bearer_t enable = 0U; + BT_DBG("PvnrDisable, Bearers 0x%02x", bearers); + if (!bt_mesh_is_provisioner_en()) { BT_WARN("%s, Already", __func__); return -EALREADY; @@ -762,7 +810,7 @@ int bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers) bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_SUB_CODE_REMOVE, BLE_MESH_EXCEP_LIST_TYPE_MESH_PROV_ADV, NULL); -#endif +#endif /* CONFIG_BLE_MESH_USE_DUPLICATE_SCAN */ } if (!(enable & (~bearers))) { @@ -776,7 +824,7 @@ int bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers) BLE_MESH_EXCEP_LIST_TYPE_MESH_BEACON, NULL); } -#endif +#endif /* CONFIG_BLE_MESH_USE_DUPLICATE_SCAN */ /* Clear corresponding flags */ bt_mesh_atomic_and(bt_mesh.flags, ~(BIT(BLE_MESH_PROVISIONER) | BIT(BLE_MESH_VALID_PROV))); @@ -794,7 +842,7 @@ int bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers) if (bt_mesh_private_beacon_state_get() == BLE_MESH_PRIVATE_BEACON_ENABLED) { bt_mesh_private_beacon_disable(); } -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) { bt_mesh_friend_clear_net_idx(BLE_MESH_KEY_ANY); diff --git a/components/bt/esp_ble_mesh/core/net.c b/components/bt/esp_ble_mesh/core/net.c index 15d099cc5cd3..209b0fdabd50 100644 --- a/components/bt/esp_ble_mesh/core/net.c +++ b/components/bt/esp_ble_mesh/core/net.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,7 +33,7 @@ #if CONFIG_BLE_MESH_V11_SUPPORT #include "mesh_v1.1/utils.h" -#endif +#endif /* CONFIG_BLE_MESH_V11_SUPPORT */ /* Minimum valid Mesh Network PDU length. The Network headers * themselves take up 9 bytes. After that there is a minimum of 1 byte @@ -41,23 +41,27 @@ * PDUs must use a 64-bit (8 byte) NetMIC, whereas CTL=0 PDUs have at least * a 32-bit (4 byte) NetMIC and AppMIC giving again a total of 8 bytes. */ -#define BLE_MESH_NET_MIN_PDU_LEN (BLE_MESH_NET_HDR_LEN + 1 + 8) +#define BLE_MESH_NET_MIN_PDU_LEN (BLE_MESH_NET_HDR_LEN + 1 + 8) /* Seq limit after IV Update is triggered */ -#define IV_UPDATE_SEQ_LIMIT 8000000 +#define IV_UPDATE_SEQ_LIMIT 8000000 /* Determine how many friendship credentials we need */ #if CONFIG_BLE_MESH_FRIEND -#define FRIEND_CRED_COUNT CONFIG_BLE_MESH_FRIEND_LPN_COUNT +#define FRIEND_CRED_COUNT CONFIG_BLE_MESH_FRIEND_LPN_COUNT #elif CONFIG_BLE_MESH_LOW_POWER -#define FRIEND_CRED_COUNT CONFIG_BLE_MESH_SUBNET_COUNT +#define FRIEND_CRED_COUNT CONFIG_BLE_MESH_SUBNET_COUNT #else -#define FRIEND_CRED_COUNT 0 +#define FRIEND_CRED_COUNT 0 #endif +#if CONFIG_BLE_MESH_RELAY_ADV_BUF +#define MAX_STORED_RELAY_COUNT (CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT / 2) +#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */ + #if FRIEND_CRED_COUNT > 0 static struct friend_cred friend_cred[FRIEND_CRED_COUNT]; -#endif +#endif /* FRIEND_CRED_COUNT > 0 */ static struct { uint32_t src:15, /* MSB of source address is always 0 */ @@ -83,10 +87,6 @@ struct bt_mesh_net bt_mesh = { static uint32_t dup_cache[4]; static int dup_cache_next; -#if CONFIG_BLE_MESH_RELAY_ADV_BUF -#define BLE_MESH_MAX_STORED_RELAY_COUNT (CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT / 2) -#endif - static bool check_dup(struct net_buf_simple *data) { const uint8_t *tail = net_buf_simple_tail(data); @@ -95,12 +95,17 @@ static bool check_dup(struct net_buf_simple *data) val = sys_get_be32(tail - 4) ^ sys_get_be32(tail - 8); + BT_DBG("CheckDup, Val 0x%08lx", val); + for (i = 0; i < ARRAY_SIZE(dup_cache); i++) { if (dup_cache[i] == val) { + BT_DBG("DupCacheFound"); return true; } } + BT_DBG("DupCacheAdd, CacheNext %ld %d", val, dup_cache_next); + dup_cache[dup_cache_next++] = val; dup_cache_next %= ARRAY_SIZE(dup_cache); @@ -112,9 +117,13 @@ static bool msg_cache_match(struct bt_mesh_net_rx *rx, { int i; + BT_DBG("MsgCacheMatch"); + for (i = 0; i < ARRAY_SIZE(msg_cache); i++) { if (msg_cache[i].src == BLE_MESH_NET_HDR_SRC(pdu->data) && msg_cache[i].seq == (BLE_MESH_NET_HDR_SEQ(pdu->data) & BIT_MASK(17))) { + BT_DBG("CacheFound, Src 0x%04x Seq 0x%06x", + msg_cache[i].src, msg_cache[i].seq); return true; } } @@ -124,6 +133,9 @@ static bool msg_cache_match(struct bt_mesh_net_rx *rx, static void msg_cache_add(struct bt_mesh_net_rx *rx) { + BT_DBG("MsgCacheAdd, Src 0x%04x Seq 0x%06x CacheNext %u", + rx->ctx.addr, rx->seq, msg_cache_next); + rx->msg_cache_idx = msg_cache_next++; msg_cache[rx->msg_cache_idx].src = rx->ctx.addr; msg_cache[rx->msg_cache_idx].seq = rx->seq; @@ -135,6 +147,8 @@ void bt_mesh_msg_cache_clear(uint16_t unicast_addr, uint8_t elem_num) { int i; + BT_DBG("MsgCacheClear, Addr 0x%04x ElemNum %u", unicast_addr, elem_num); + for (i = 0; i < ARRAY_SIZE(msg_cache); i++) { if (msg_cache[i].src >= unicast_addr && msg_cache[i].src < unicast_addr + elem_num) { @@ -146,6 +160,8 @@ void bt_mesh_msg_cache_clear(uint16_t unicast_addr, uint8_t elem_num) struct bt_mesh_subnet *bt_mesh_subnet_get(uint16_t net_idx) { + BT_DBG("SubnetGet, NetIdx 0x%04x", net_idx); + if (bt_mesh_is_provisioned()) { #if CONFIG_BLE_MESH_NODE if (!IS_ENABLED(CONFIG_BLE_MESH_FAST_PROV)) { @@ -161,7 +177,7 @@ struct bt_mesh_subnet *bt_mesh_subnet_get(uint16_t net_idx) } else { return bt_mesh_fast_prov_subnet_get(net_idx); } -#endif +#endif /* CONFIG_BLE_MESH_NODE */ } else if (bt_mesh_is_provisioner_en()) { #if CONFIG_BLE_MESH_PROVISIONER if (net_idx == BLE_MESH_KEY_ANY) { @@ -174,7 +190,7 @@ struct bt_mesh_subnet *bt_mesh_subnet_get(uint16_t net_idx) return bt_mesh.p_sub[i]; } } -#endif +#endif /* CONFIG_BLE_MESH_PROVISIONER */ } return NULL; @@ -187,6 +203,8 @@ int bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys, uint8_t nid = 0U; int err = 0; + BT_DBG("NetKeysCreate"); + err = bt_mesh_k2(key, p, sizeof(p), &nid, keys->enc, keys->privacy); if (err) { BT_ERR("Unable to generate NID, EncKey & PrivacyKey"); @@ -258,6 +276,9 @@ int friend_cred_set(struct friend_cred *cred, uint8_t idx, const uint8_t net_key uint8_t p[9] = {0}; int err = 0; + BT_DBG("FrndCredSet, NetIdx 0x%04x Addr 0x%04x Idx %u", + cred->net_idx, cred->addr, idx); + #if CONFIG_BLE_MESH_LOW_POWER if (cred->addr == bt_mesh.lpn.frnd) { lpn_addr = bt_mesh_primary_addr(); @@ -266,14 +287,13 @@ int friend_cred_set(struct friend_cred *cred, uint8_t idx, const uint8_t net_key lpn_addr = cred->addr; frnd_addr = bt_mesh_primary_addr(); } -#else +#else /* CONFIG_BLE_MESH_LOW_POWER */ lpn_addr = cred->addr; frnd_addr = bt_mesh_primary_addr(); -#endif +#endif /* CONFIG_BLE_MESH_LOW_POWER */ - BT_DBG("LPNAddress 0x%04x FriendAddress 0x%04x", lpn_addr, frnd_addr); - BT_DBG("LPNCounter 0x%04x FriendCounter 0x%04x", cred->lpn_counter, - cred->frnd_counter); + BT_DBG("LPN 0x%04x Frnd 0x%04x LPNCounter %u FrndCounter %u", + lpn_addr, frnd_addr, cred->lpn_counter, cred->frnd_counter); p[0] = 0x01; sys_put_be16(lpn_addr, p + 1); @@ -288,9 +308,9 @@ int friend_cred_set(struct friend_cred *cred, uint8_t idx, const uint8_t net_key return err; } - BT_DBG("Friend NID 0x%02x EncKey %s", cred->cred[idx].nid, - bt_hex(cred->cred[idx].enc, 16)); - BT_DBG("Friend PrivacyKey %s", bt_hex(cred->cred[idx].privacy, 16)); + BT_DBG("FrndNID 0x%02x EncKey %s", + cred->cred[idx].nid, bt_hex(cred->cred[idx].enc, 16)); + BT_DBG("FrndPrivacyKey %s", bt_hex(cred->cred[idx].privacy, 16)); return 0; } @@ -299,11 +319,14 @@ void friend_cred_refresh(uint16_t net_idx) { int i; + BT_DBG("FrndCredRefresh, NetIdx 0x%04x", net_idx); + for (i = 0; i < ARRAY_SIZE(friend_cred); i++) { struct friend_cred *cred = &friend_cred[i]; if (cred->addr != BLE_MESH_ADDR_UNASSIGNED && cred->net_idx == net_idx) { + BT_DBG("Refreshed, Addr 0x%04x", cred->addr); memcpy(&cred->cred[0], &cred->cred[1], sizeof(cred->cred[0])); } @@ -314,7 +337,7 @@ int friend_cred_update(struct bt_mesh_subnet *sub) { int err = 0, i; - BT_DBG("net_idx 0x%04x", sub->net_idx); + BT_DBG("FrndCredUpdate, NetIdx 0x%04x", sub->net_idx); for (i = 0; i < ARRAY_SIZE(friend_cred); i++) { struct friend_cred *cred = &friend_cred[i]; @@ -324,6 +347,8 @@ int friend_cred_update(struct bt_mesh_subnet *sub) continue; } + BT_DBG("UpdateFound, Addr 0x%04x", cred->addr); + err = friend_cred_set(cred, 1, sub->keys[1].net); if (err) { return err; @@ -339,7 +364,8 @@ struct friend_cred *friend_cred_create(struct bt_mesh_subnet *sub, uint16_t addr struct friend_cred *cred = NULL; int i, err = 0; - BT_DBG("net_idx 0x%04x addr 0x%04x", sub->net_idx, addr); + BT_DBG("FrndCredCreate, NetIdx 0x%04x KrFlag %u Addr 0x%04x", + sub->net_idx, sub->kr_flag, addr); for (cred = NULL, i = 0; i < ARRAY_SIZE(friend_cred); i++) { if ((friend_cred[i].addr == BLE_MESH_ADDR_UNASSIGNED) || @@ -379,6 +405,8 @@ struct friend_cred *friend_cred_create(struct bt_mesh_subnet *sub, uint16_t addr void friend_cred_clear(struct friend_cred *cred) { + BT_DBG("FrndCredClear, NetIdx 0x%04x Addr 0x%04x", cred->net_idx, cred->addr); + cred->net_idx = BLE_MESH_KEY_UNUSED; cred->addr = BLE_MESH_ADDR_UNASSIGNED; cred->lpn_counter = 0U; @@ -390,9 +418,13 @@ int friend_cred_del(uint16_t net_idx, uint16_t addr) { int i; + BT_DBG("FrndCredDel, NetIdx 0x%04x Addr 0x%04x", net_idx, addr); + for (i = 0; i < ARRAY_SIZE(friend_cred); i++) { struct friend_cred *cred = &friend_cred[i]; + BT_DBG("%u: NetIdx 0x%04x Addr 0x%04x", i, cred->net_idx, cred->addr); + if (cred->addr == addr && cred->net_idx == net_idx) { friend_cred_clear(cred); return 0; @@ -407,7 +439,8 @@ int friend_cred_get(struct bt_mesh_subnet *sub, uint16_t addr, uint8_t *nid, { int i; - BT_DBG("net_idx 0x%04x addr 0x%04x", sub->net_idx, addr); + BT_DBG("FrndCredGet, NetIdx 0x%04x KrFlag %u Addr 0x%04x", + sub->net_idx, sub->kr_flag, addr); for (i = 0; i < ARRAY_SIZE(friend_cred); i++) { struct friend_cred *cred = &friend_cred[i]; @@ -437,13 +470,15 @@ int friend_cred_get(struct bt_mesh_subnet *sub, uint16_t addr, uint8_t *nid, return -ENOENT; } -#else +#else /* (CONFIG_BLE_MESH_LOW_POWER || CONFIG_BLE_MESH_FRIEND) */ int friend_cred_get(struct bt_mesh_subnet *sub, uint16_t addr, uint8_t *nid, const uint8_t **enc, const uint8_t **priv) { + BT_DBG("FrndCredGetNoEnt"); + return -ENOENT; } -#endif /* FRIEND || LOW_POWER */ +#endif /* (CONFIG_BLE_MESH_LOW_POWER || CONFIG_BLE_MESH_FRIEND) */ uint8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub) { @@ -457,36 +492,40 @@ uint8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub) flags |= BLE_MESH_NET_FLAG_IVU; } + BT_DBG("NetFlags 0x%02x", flags); + return flags; } int bt_mesh_net_secure_beacon_update(struct bt_mesh_subnet *sub) { - uint8_t flags = bt_mesh_net_flags(sub); struct bt_mesh_subnet_keys *keys = NULL; + uint8_t flags = 0; + + BT_DBG("SecureBeaconUpdate, NetIdx 0x%04x KrFlag %u IVIndex %lu", + sub->net_idx, sub->kr_flag, bt_mesh.iv_index); if (sub->kr_flag) { - BT_DBG("NetIndex %u Using new key", sub->net_idx); keys = &sub->keys[1]; } else { - BT_DBG("NetIndex %u Using current key", sub->net_idx); keys = &sub->keys[0]; } - BT_DBG("flags 0x%02x, IVI 0x%08x", flags, bt_mesh.iv_index); + flags = bt_mesh_net_flags(sub); return bt_mesh_secure_beacon_auth(keys->beacon, flags, keys->net_id, bt_mesh.iv_index, sub->auth); } -int bt_mesh_net_create(uint16_t idx, uint8_t flags, const uint8_t key[16], +int bt_mesh_net_create(uint16_t net_idx, uint8_t flags, const uint8_t key[16], uint32_t iv_index) { struct bt_mesh_subnet *sub = NULL; int err = 0; - BT_DBG("idx %u flags 0x%02x iv_index %u", idx, flags, iv_index); - + BT_DBG("NetCreate"); + BT_DBG("NetIdx 0x%04x Flags 0x%02x IVIndex %lu Hours %u", + net_idx, flags, iv_index, BLE_MESH_IVU_HOURS); BT_DBG("NetKey %s", bt_hex(key, 16)); (void)memset(msg_cache, 0, sizeof(msg_cache)); @@ -509,7 +548,7 @@ int bt_mesh_net_create(uint16_t idx, uint8_t flags, const uint8_t key[16], } } - sub->net_idx = idx; + sub->net_idx = net_idx; if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) { sub->node_id = BLE_MESH_NODE_IDENTITY_STOPPED; @@ -517,7 +556,7 @@ int bt_mesh_net_create(uint16_t idx, uint8_t flags, const uint8_t key[16], sub->node_id = BLE_MESH_NODE_IDENTITY_NOT_SUPPORTED; #if CONFIG_BLE_MESH_PRB_SRV sub->private_node_id = BLE_MESH_PRIVATE_NODE_IDENTITY_NOT_SUPPORTED; -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ } bt_mesh.iv_index = iv_index; @@ -535,27 +574,29 @@ int bt_mesh_net_create(uint16_t idx, uint8_t flags, const uint8_t key[16], #if CONFIG_BLE_MESH_DF_SRV return bt_mesh_directed_forwarding_sub_init(sub); -#endif - +#else /* CONFIG_BLE_MESH_DF_SRV */ return 0; +#endif /* CONFIG_BLE_MESH_DF_SRV */ } void bt_mesh_net_revoke_keys(struct bt_mesh_subnet *sub) { int i; - BT_DBG("idx 0x%04x", sub->net_idx); + BT_DBG("RevokeKeys, NetIdx 0x%04x", sub->net_idx); memcpy(&sub->keys[0], &sub->keys[1], sizeof(sub->keys[0])); if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - BT_DBG("Store updated NetKey persistently"); bt_mesh_store_subnet(sub); } for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { struct bt_mesh_app_key *key = &bt_mesh.app_keys[i]; + BT_DBG("Revoke, NetIdx 0x%04x AppIdx 0x%04x KeyUpdated %u", + key->net_idx, key->app_idx, key->updated); + if (key->net_idx != sub->net_idx || !key->updated) { continue; } @@ -564,7 +605,6 @@ void bt_mesh_net_revoke_keys(struct bt_mesh_subnet *sub) key->updated = false; if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - BT_DBG("Store updated AppKey persistently"); bt_mesh_store_app_key(key); } } @@ -572,6 +612,9 @@ void bt_mesh_net_revoke_keys(struct bt_mesh_subnet *sub) bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, uint8_t new_kr, bool new_key) { + BT_DBG("KrUpdate, NewKr %u NewKey %u KrFlag %u KrPhase %u", + new_kr, new_key, sub->kr_flag, sub->kr_phase); + if (new_kr != sub->kr_flag && sub->kr_phase == BLE_MESH_KR_NORMAL) { BT_WARN("KR change in normal operation. Are we blacklisted?"); return false; @@ -582,10 +625,10 @@ bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, uint8_t new_kr, bool new_key) if (sub->kr_flag) { if (sub->kr_phase == BLE_MESH_KR_PHASE_1) { BT_INFO("Phase 1 -> Phase 2"); + sub->kr_phase = BLE_MESH_KR_PHASE_2; if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - BT_DBG("Storing kr phase persistently"); bt_mesh_store_subnet(sub); } @@ -606,14 +649,14 @@ bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, uint8_t new_kr, bool new_key) * Intentional fall-through. */ case BLE_MESH_KR_PHASE_2: - BT_INFO("KR Phase 0x%02x -> Normal", sub->kr_phase); + BT_INFO("KrPhase 0x%02x -> Normal", sub->kr_phase); #if CONFIG_BLE_MESH_PRB_SRV /* In this case, consider that kr_flag has changed, so * need to modify the content of the random field. */ bt_mesh_private_beacon_update_random(sub); -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ sub->kr_phase = BLE_MESH_KR_NORMAL; bt_mesh_net_revoke_keys(sub); @@ -633,15 +676,21 @@ bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, uint8_t new_kr, bool new_key) #if CONFIG_BLE_MESH_IV_UPDATE_TEST void bt_mesh_iv_update_test(bool enable) { + BT_DBG("IVUpdateTest, Enable %u", enable); + bt_mesh_atomic_set_bit_to(bt_mesh.flags, BLE_MESH_IVU_TEST, enable); + /* Reset the duration variable - needed for some PTS tests */ bt_mesh.ivu_duration = 0U; } bool bt_mesh_iv_update(void) { + BT_DBG("IVUpdate, IVIndex %lu InProgress %u", bt_mesh.iv_index, + bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS)); + if (!bt_mesh_is_provisioned()) { - BT_ERR("Not yet provisioned"); + BT_ERR("NotProvisioned"); return false; } @@ -660,6 +709,8 @@ bool bt_mesh_iv_update(void) /* Used for sending immediate beacons to Friend queues and GATT clients */ void bt_mesh_net_sec_update(struct bt_mesh_subnet *sub) { + BT_DBG("NetSecUpdate, NetIdx 0x%04x", sub ? sub->net_idx : BLE_MESH_KEY_ANY); + if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) { bt_mesh_friend_sec_update(sub ? sub->net_idx : BLE_MESH_KEY_ANY); } @@ -667,8 +718,8 @@ void bt_mesh_net_sec_update(struct bt_mesh_subnet *sub) if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) && (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED #if CONFIG_BLE_MESH_PRB_SRV - || bt_mesh_private_gatt_proxy_state_get() == BLE_MESH_PRIVATE_GATT_PROXY_ENABLED -#endif + || bt_mesh_private_gatt_proxy_state_get() == BLE_MESH_PRIVATE_GATT_PROXY_ENABLED +#endif /* CONFIG_BLE_MESH_PRB_SRV */ )) { bt_mesh_proxy_server_beacon_send(sub); } @@ -678,6 +729,11 @@ bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update) { int i; + BT_DBG("NetIVUpdate"); + BT_DBG("IVIndex %lu/%lu IVU %u InProgress %u", + iv_index, bt_mesh.iv_index, iv_update, + bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS)); + /* If a node in Normal Operation receives a Secure Network beacon or * a Mesh Private beacon with an IV index less than the last known * IV Index or greater than the last known IV Index + 42, the Secure @@ -685,7 +741,7 @@ bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update) */ if (iv_index < bt_mesh.iv_index || iv_index > bt_mesh.iv_index + 42) { - BT_ERR("IV Index out of sync: 0x%08x != 0x%08x", + BT_ERR("IVIndex out of sync: 0x%08x != 0x%08x", iv_index, bt_mesh.iv_index); return false; } @@ -721,7 +777,7 @@ bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update) if ((iv_index > bt_mesh.iv_index + 1) #if CONFIG_BLE_MESH_IVU_RECOVERY_IVI || (iv_index == bt_mesh.iv_index + 1 && !iv_update) -#endif +#endif /* CONFIG_BLE_MESH_IVU_RECOVERY_IVI */ ) { BT_WARN("Performing IV Index Recovery"); (void)memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl)); @@ -742,7 +798,7 @@ bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update) BT_WARN("Ignoring new index in normal mode"); return false; } -#endif +#endif /* !CONFIG_BLE_MESH_IVU_RECOVERY_IVI */ if (!iv_update) { /* Nothing to do */ @@ -802,9 +858,11 @@ bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update) bool bt_mesh_primary_subnet_exist(void) { if (bt_mesh_subnet_get(BLE_MESH_KEY_PRIMARY)) { + BT_DBG("PrimarySubnetExist"); return true; } + BT_DBG("PrimarySubnetNotExist"); return false; } @@ -812,6 +870,8 @@ uint32_t bt_mesh_next_seq(void) { uint32_t seq = bt_mesh.seq++; + BT_DBG("NextSeq %lu", seq); + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { bt_mesh_store_seq(); } @@ -836,8 +896,9 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf, uint16_t dst = 0U; int err = 0; - BT_DBG("net_idx 0x%04x new_key %u len %u", sub->net_idx, new_key, - buf->len); + BT_DBG("NetResend"); + BT_DBG("NetIdx 0x%04x NewKey %u Len %u Tag 0x%02x", + sub->net_idx, new_key, buf->len, tx_tag); /* Previously when resending the segments, only managed flooding * security credentials will be used. @@ -884,13 +945,11 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf, err = bt_mesh_net_obfuscate(buf->data, BLE_MESH_NET_IVI_TX, priv); if (err) { - BT_ERR("De-obfuscate failed (err %d)", err); return err; } err = bt_mesh_net_decrypt(enc, &buf->b, BLE_MESH_NET_IVI_TX, false, false); if (err) { - BT_ERR("Decrypt failed (err %d)", err); return err; } @@ -903,13 +962,11 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf, err = bt_mesh_net_encrypt(enc, &buf->b, BLE_MESH_NET_IVI_TX, false, false); if (err) { - BT_ERR("Encrypt failed (err %d)", err); return err; } err = bt_mesh_net_obfuscate(buf->data, BLE_MESH_NET_IVI_TX, priv); if (err) { - BT_ERR("Obfuscate failed (err %d)", err); return err; } @@ -927,6 +984,7 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf, } bt_mesh_adv_send(buf, BLE_MESH_ADV(buf)->xmit, cb, cb_data); + return 0; } @@ -934,8 +992,10 @@ static void bt_mesh_net_local(void) { struct net_buf *buf = NULL; + BT_DBG("NetLocal"); + while ((buf = net_buf_slist_get(&bt_mesh.local_queue))) { - BT_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); bt_mesh_net_recv(&buf->b, 0, BLE_MESH_NET_IF_LOCAL); net_buf_unref(buf); } @@ -949,6 +1009,10 @@ int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf, uint8_t nid = 0U; int err = 0; + BT_DBG("NetEncode"); + BT_DBG("Src 0x%04x Dst 0x%04x Cred 0x%02x CTL %u Proxy %u", + tx->src, tx->ctx->addr, tx->ctx->send_cred, ctl, proxy); + if (ctl && net_buf_simple_tailroom(buf) < BLE_MESH_MIC_LONG) { BT_ERR("Insufficient MIC space for CTL PDU"); return -EINVAL; @@ -959,9 +1023,6 @@ int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf, return -EINVAL; } - BT_DBG("src 0x%04x dst 0x%04x ctl %u seq 0x%06x", - tx->src, tx->ctx->addr, ctl, bt_mesh.seq); - net_buf_simple_push_be16(buf, tx->ctx->addr); net_buf_simple_push_be16(buf, tx->src); @@ -973,8 +1034,6 @@ int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf, net_buf_simple_push_u8(buf, tx->ctx->send_ttl); } - BT_INFO("Use security credentials 0x%02x, proxy %d", tx->ctx->send_cred, proxy); - if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) && tx->ctx->send_cred == BLE_MESH_FRIENDSHIP_CRED) { err = friend_cred_get(tx->sub, BLE_MESH_ADDR_UNASSIGNED, @@ -1035,16 +1094,13 @@ static void bt_mesh_net_adv_xmit_update(struct bt_mesh_net_tx *tx) */ if (bt_mesh_tag_friendship(tx->ctx->send_tag)) { tx->xmit = BLE_MESH_TRANSMIT(0, BLE_MESH_TRANSMIT_INT(bt_mesh_net_transmit_get())); - return; - } - - if (bt_mesh_tag_relay(tx->ctx->send_tag)) { + } else if (bt_mesh_tag_relay(tx->ctx->send_tag)) { tx->xmit = bt_mesh_relay_retransmit_get(); } else { tx->xmit = bt_mesh_net_transmit_get(); } - return; + BT_INFO("NetAdvXmitUpdate, Tag 0x%02x Xmit 0x%02x", tx->ctx->send_tag, tx->xmit); } #endif /* !CONFIG_BLE_MESH_V11_SUPPORT */ @@ -1054,11 +1110,11 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, uint8_t bearer = BLE_MESH_ALL_BEARERS; int err = 0; - BT_DBG("src 0x%04x dst 0x%04x len %u headroom %u tailroom %u", - tx->src, tx->ctx->addr, buf->len, net_buf_headroom(buf), - net_buf_tailroom(buf)); - BT_DBG("Payload len %u: %s", buf->len, bt_hex(buf->data, buf->len)); - BT_DBG("Seq 0x%06x", bt_mesh.seq); + BT_DBG("NetSend"); + BT_DBG("Src 0x%04x Dst 0x%04x TTL %u Cred %u Tag 0x%02x Seq 0x%06x Room %u/%u", + tx->src, tx->ctx->addr, tx->ctx->send_ttl, tx->ctx->send_cred, + tx->ctx->send_tag, bt_mesh.seq, net_buf_headroom(buf), net_buf_tailroom(buf)); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); if (tx->ctx->send_ttl == BLE_MESH_TTL_DEFAULT) { tx->ctx->send_ttl = bt_mesh_default_ttl_get(); @@ -1092,6 +1148,8 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, #if CONFIG_BLE_MESH_DF_SRV bt_mesh_update_net_send_cred(tx, &bearer); + + BT_DBG("TxBearer 0x%02x", bearer); #endif /* CONFIG_BLE_MESH_DF_SRV */ err = bt_mesh_net_encode(tx, &buf->b, false); @@ -1142,6 +1200,8 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, bt_mesh_tag_relay(tx->ctx->send_tag)) && tx->ctx->send_cred != BLE_MESH_FRIENDSHIP_CRED) { if (bt_mesh_proxy_client_relay(&buf->b, tx->ctx->addr)) { + BT_DBG("ProxyClientRelay"); + /* If Proxy Client succeeds to send messages with GATT bearer, * we can directly finish here. And if not, which means no * connection has been created with Proxy Client, here we will @@ -1203,17 +1263,14 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, */ bt_mesh_net_adv_xmit_update(tx); - BT_INFO("Network PDU, count %d, interval %d", - BLE_MESH_TRANSMIT_COUNT(tx->xmit), BLE_MESH_TRANSMIT_INT(tx->xmit)); bt_mesh_adv_send(buf, tx->xmit, cb, cb_data); err = 0; goto done; } - BT_WARN("Not sent, src 0x%04x, dst 0x%04x, ttl %d, cred 0x%02x, tag 0x%02x", - tx->src, tx->ctx->addr, tx->ctx->send_ttl, tx->ctx->send_cred, - tx->ctx->send_tag); + BT_WARN("NetNotSend"); + err = -EIO; done: @@ -1227,7 +1284,10 @@ static bool auth_match(struct bt_mesh_subnet_keys *keys, { uint8_t net_auth[8] = {0}; + BT_DBG("AuthMatch"); + if (memcmp(net_id, keys->net_id, 8)) { + BT_DBG("NetID %s != %s", bt_hex(net_id, 8), bt_hex(keys->net_id, 8)); return false; } @@ -1235,8 +1295,7 @@ static bool auth_match(struct bt_mesh_subnet_keys *keys, net_auth); if (memcmp(auth, net_auth, 8)) { - BT_WARN("Authentication Value %s != %s", - bt_hex(auth, 8), bt_hex(net_auth, 8)); + BT_WARN("NetAuth %s != %s", bt_hex(auth, 8), bt_hex(net_auth, 8)); return false; } @@ -1252,6 +1311,8 @@ struct bt_mesh_subnet *bt_mesh_subnet_find_with_snb(const uint8_t net_id[8], uin subnet_size = bt_mesh_rx_netkey_size(); + BT_DBG("SubnetFindWithSnb, Size %lu", subnet_size); + for (i = 0; i < subnet_size; i++) { struct bt_mesh_subnet *sub = bt_mesh_rx_netkey_get(i); @@ -1282,8 +1343,10 @@ int net_decrypt(struct bt_mesh_subnet *sub, const uint8_t *enc, size_t data_len, struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) { - BT_DBG("NID 0x%02x net_idx 0x%04x", BLE_MESH_NET_HDR_NID(data), sub->net_idx); - BT_DBG("IVI %u net->iv_index 0x%08x", BLE_MESH_NET_HDR_IVI(data), bt_mesh.iv_index); + BT_DBG("NetDecrypt"); + BT_DBG("IVI %u NID 0x%02x NetIdx 0x%04x IVIndex %lu NetIf %u", + BLE_MESH_NET_HDR_IVI(data), BLE_MESH_NET_HDR_NID(data), + sub->net_idx, bt_mesh.iv_index, rx->net_if); rx->old_iv = (BLE_MESH_NET_HDR_IVI(data) != (bt_mesh.iv_index & 0x01)); @@ -1305,12 +1368,11 @@ int net_decrypt(struct bt_mesh_subnet *sub, const uint8_t *enc, return -EALREADY; } - BT_DBG("src 0x%04x", rx->ctx.addr); + BT_DBG("Src 0x%04x", rx->ctx.addr); if (IS_ENABLED(CONFIG_BLE_MESH_PROXY) && rx->net_if == BLE_MESH_NET_IF_PROXY_CFG) { - return bt_mesh_net_decrypt(enc, buf, BLE_MESH_NET_IVI_RX(rx), - true, false); + return bt_mesh_net_decrypt(enc, buf, BLE_MESH_NET_IVI_RX(rx), true, false); } return bt_mesh_net_decrypt(enc, buf, BLE_MESH_NET_IVI_RX(rx), false, false); @@ -1323,7 +1385,9 @@ static int friend_decrypt(struct bt_mesh_subnet *sub, const uint8_t *data, { int i; - BT_DBG("NID 0x%02x net_idx 0x%04x", BLE_MESH_NET_HDR_NID(data), sub->net_idx); + BT_DBG("FrndDecrypt"); + BT_DBG("NID 0x%02x NetIdx 0x%04x KrPhase %u", + BLE_MESH_NET_HDR_NID(data), sub->net_idx, sub->kr_phase); for (i = 0; i < ARRAY_SIZE(friend_cred); i++) { struct friend_cred *cred = &friend_cred[i]; @@ -1335,6 +1399,7 @@ static int friend_decrypt(struct bt_mesh_subnet *sub, const uint8_t *data, if (BLE_MESH_NET_HDR_NID(data) == cred->cred[0].nid && !net_decrypt(sub, cred->cred[0].enc, cred->cred[0].privacy, data, data_len, rx, buf)) { + BT_DBG("UseOldKey"); return 0; } @@ -1345,6 +1410,7 @@ static int friend_decrypt(struct bt_mesh_subnet *sub, const uint8_t *data, if (BLE_MESH_NET_HDR_NID(data) == cred->cred[1].nid && !net_decrypt(sub, cred->cred[1].enc, cred->cred[1].privacy, data, data_len, rx, buf)) { + BT_DBG("UseNewKey"); rx->new_key = 1U; return 0; } @@ -1358,11 +1424,14 @@ static int flooding_decrypt(struct bt_mesh_subnet *sub, const uint8_t *data, size_t data_len, struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) { - BT_DBG("NID 0x%02x net_idx 0x%04x", BLE_MESH_NET_HDR_NID(data), sub->net_idx); + BT_DBG("FloodingDecrypt"); + BT_DBG("NID 0x%02x NetIdx 0x%04x KrPhase %u", + BLE_MESH_NET_HDR_NID(data), sub->net_idx, sub->kr_phase); if (BLE_MESH_NET_HDR_NID(data) == sub->keys[0].nid && !net_decrypt(sub, sub->keys[0].enc, sub->keys[0].privacy, data, data_len, rx, buf)) { + BT_DBG("UseOldKey"); return 0; } @@ -1373,6 +1442,7 @@ static int flooding_decrypt(struct bt_mesh_subnet *sub, const uint8_t *data, if (BLE_MESH_NET_HDR_NID(data) == sub->keys[1].nid && !net_decrypt(sub, sub->keys[1].enc, sub->keys[1].privacy, data, data_len, rx, buf)) { + BT_DBG("UseNewKey"); rx->new_key = 1U; return 0; } @@ -1390,10 +1460,12 @@ static bool net_find_and_decrypt(const uint8_t *data, size_t data_len, array_size = bt_mesh_rx_netkey_size(); + BT_DBG("NetFindAndDecrypt, Size %u", array_size); + for (i = 0; i < array_size; i++) { sub = bt_mesh_rx_netkey_get(i); if (!sub) { - BT_DBG("Subnet not found"); + BT_DBG("SubNotFound"); continue; } @@ -1403,7 +1475,7 @@ static bool net_find_and_decrypt(const uint8_t *data, size_t data_len, #if CONFIG_BLE_MESH_BRC_SRV sub->sbr_net_idx = BLE_MESH_KEY_UNUSED; -#endif +#endif /* CONFIG_BLE_MESH_BRC_SRV */ #if (CONFIG_BLE_MESH_LOW_POWER || CONFIG_BLE_MESH_FRIEND) if (!friend_decrypt(sub, data, data_len, rx, buf)) { @@ -1412,7 +1484,7 @@ static bool net_find_and_decrypt(const uint8_t *data, size_t data_len, rx->sub = sub; return true; } -#endif +#endif /* (CONFIG_BLE_MESH_LOW_POWER || CONFIG_BLE_MESH_FRIEND) */ #if CONFIG_BLE_MESH_DF_SRV if (!bt_mesh_directed_decrypt(sub, data, data_len, rx, buf)) { @@ -1441,6 +1513,8 @@ static bool net_find_and_decrypt(const uint8_t *data, size_t data_len, */ static bool relay_to_adv(enum bt_mesh_net_if net_if) { + BT_DBG("RelayToAdv, NetIf %u", net_if); + switch (net_if) { case BLE_MESH_NET_IF_LOCAL: return true; @@ -1450,7 +1524,7 @@ static bool relay_to_adv(enum bt_mesh_net_if net_if) return (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED #if CONFIG_BLE_MESH_PRB_SRV || bt_mesh_private_gatt_proxy_state_get() == BLE_MESH_PRIVATE_GATT_PROXY_ENABLED -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ ); default: return false; @@ -1461,6 +1535,8 @@ static bool relay_to_adv(enum bt_mesh_net_if net_if) static uint8_t net_retransmission_adv(struct bt_mesh_net_rx *rx, uint8_t *cred, uint8_t *tag) { + BT_DBG("NetRetransmissionAdv"); + if (rx->ctx.recv_cred == BLE_MESH_FLOODING_CRED) { uint8_t bearer = BLE_MESH_NONE_BEARER; @@ -1484,6 +1560,8 @@ static uint8_t net_retransmission_adv(struct bt_mesh_net_rx *rx, *cred = BLE_MESH_FLOODING_CRED; } + BT_DBG("FloodingBearer 0x%02x", bearer); + return bearer; } @@ -1493,6 +1571,9 @@ static uint8_t net_retransmission_adv(struct bt_mesh_net_rx *rx, /* Condition: Directed friend is disabled. */ *cred = BLE_MESH_FLOODING_CRED; + + BT_DBG("FrndBearerAll"); + return BLE_MESH_ALL_BEARERS; } @@ -1502,6 +1583,8 @@ static uint8_t net_retransmission_adv(struct bt_mesh_net_rx *rx, static uint8_t net_retransmission_gatt(struct bt_mesh_net_rx *rx, uint8_t *cred, uint8_t *tag) { + BT_DBG("NetRetransmissionGatt"); + if (rx->ctx.recv_cred == BLE_MESH_FLOODING_CRED) { /* Inbound bearer: GATT; * Inbound Security Material: managed flooding; @@ -1511,6 +1594,9 @@ static uint8_t net_retransmission_gatt(struct bt_mesh_net_rx *rx, bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED) { /* Condition: Directed proxy is disabled. */ *cred = BLE_MESH_FLOODING_CRED; + + BT_DBG("FloodingBearerAll"); + return BLE_MESH_ALL_BEARERS; } @@ -1539,14 +1625,19 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, struct bt_mesh_net_rx *rx) { const uint8_t *enc = NULL, *priv = NULL; + bool netkey_changed = false; struct net_buf *buf = NULL; uint8_t bearer = 0; uint8_t xmit = 0U; uint8_t cred = 0; uint8_t nid = 0U; - bool netkey_changed = false; uint8_t tag = 0; + BT_DBG("NetRelay"); + BT_DBG("TTL %u CTL %u Dst 0x%04x RecvCred %u NetIf %u", + rx->ctx.recv_ttl, rx->ctl, rx->ctx.recv_dst, + rx->ctx.recv_cred, rx->net_if); + if (rx->net_if == BLE_MESH_NET_IF_LOCAL) { /* Locally originated PDUs with TTL=1 will only be delivered * to local elements as per Mesh Profile 1.0 section 3.4.5.2: @@ -1602,12 +1693,12 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, BT_ERR("Bridge RPL attack"); goto done; } -#endif +#endif /* CONFIG_BLE_MESH_BRC_SRV */ if (cred != BLE_MESH_FLOODING_CRED #if CONFIG_BLE_MESH_DF_SRV - && cred != BLE_MESH_DIRECTED_CRED -#endif + && cred != BLE_MESH_DIRECTED_CRED +#endif /* CONFIG_BLE_MESH_DF_SRV */ ) { BT_WARN("No outbound security cred found, inbound cred %d", rx->ctx.recv_cred); return; @@ -1623,8 +1714,6 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, return; } - BT_DBG("TTL %u CTL %u dst 0x%04x", rx->ctx.recv_ttl, rx->ctl, rx->ctx.recv_dst); - /* The Relay Retransmit state is only applied to adv-adv relaying. * Anything else (like GATT to adv, or locally originated packets) * use the Network Transmit state. @@ -1656,7 +1745,7 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, /* Check if the number of relay packets in queue is too large, if so * use minimum relay retransmit value for later relay packets. */ - if (bt_mesh_get_stored_relay_count() >= BLE_MESH_MAX_STORED_RELAY_COUNT) { + if (bt_mesh_get_stored_relay_count() >= MAX_STORED_RELAY_COUNT) { xmit = BLE_MESH_TRANSMIT(0, 20); } buf = bt_mesh_relay_adv_create(BLE_MESH_ADV_DATA, K_NO_WAIT); @@ -1692,10 +1781,12 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, /* Check if subnet bridge is supported & decide which NetKey is used */ if (bt_mesh_subnet_bridge_state_get() == BLE_MESH_SUBNET_BRIDGE_ENABLED) { netkey_changed = bt_mesh_bridge_change_net_key(rx, &enc, &priv, &nid, cred); + + BT_DBG("NetKeyChanged %u", netkey_changed); } -#endif +#endif /* CONFIG_BLE_MESH_BRC_SRV */ - BT_DBG("Relaying packet. TTL is now %u", BLE_MESH_NET_HDR_TTL(buf->data)); + BT_DBG("Relaying, NewTTL %u", BLE_MESH_NET_HDR_TTL(buf->data)); /* 1. Update NID if RX or RX was with friend credentials(included by case 3). * 2. Update NID if the net_key has changed. @@ -1711,12 +1802,10 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, * layer nonce includes the IVI. */ if (bt_mesh_net_encrypt(enc, &buf->b, BLE_MESH_NET_IVI_RX(rx), false, false)) { - BT_ERR("Re-encrypting failed"); goto done; } if (bt_mesh_net_obfuscate(buf->data, BLE_MESH_NET_IVI_RX(rx), priv)) { - BT_ERR("Re-obfuscating failed"); goto done; } @@ -1733,7 +1822,7 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, cred != BLE_MESH_FRIENDSHIP_CRED) || #if CONFIG_BLE_MESH_PRB_SRV bt_mesh_private_gatt_proxy_state_get() == BLE_MESH_PRIVATE_GATT_PROXY_ENABLED || -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ rx->net_if == BLE_MESH_NET_IF_LOCAL || rx->ctx.recv_cred == BLE_MESH_FRIENDSHIP_CRED)) { if (bt_mesh_proxy_server_relay(&buf->b, rx->ctx.recv_dst) && @@ -1749,9 +1838,9 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, rx->ctx.recv_cred == BLE_MESH_FRIENDSHIP_CRED) { #if !CONFIG_BLE_MESH_RELAY_ADV_BUF bt_mesh_adv_send(buf, xmit, NULL, NULL); -#else +#else /* !CONFIG_BLE_MESH_RELAY_ADV_BUF */ bt_mesh_relay_adv_send(buf, xmit, rx->ctx.addr, rx->ctx.recv_dst, NULL, NULL); -#endif +#endif /* !CONFIG_BLE_MESH_RELAY_ADV_BUF */ } done: @@ -1761,6 +1850,8 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, void bt_mesh_net_header_parse(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) { + BT_DBG("NetHeaderParse"); + rx->old_iv = (BLE_MESH_NET_HDR_IVI(buf->data) != (bt_mesh.iv_index & 0x01)); rx->ctl = BLE_MESH_NET_HDR_CTL(buf->data); rx->ctx.recv_ttl = BLE_MESH_NET_HDR_TTL(buf->data); @@ -1772,9 +1863,10 @@ void bt_mesh_net_header_parse(struct net_buf_simple *buf, int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) { + BT_DBG("NetDecode, NetIf %u", net_if); + if (data->len < BLE_MESH_NET_MIN_PDU_LEN) { BT_WARN("Dropping too short mesh packet (len %u)", data->len); - BT_WARN("%s", bt_hex(data->data, data->len)); return -EINVAL; } @@ -1782,7 +1874,7 @@ int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, return -EINVAL; } - BT_DBG("%u bytes: %s", data->len, bt_hex(data->data, data->len)); + BT_DBG("Len %u: %s", data->len, bt_hex(data->data, data->len)); rx->net_if = net_if; @@ -1818,8 +1910,6 @@ int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, rx->seq = BLE_MESH_NET_HDR_SEQ(buf->data); rx->ctx.recv_dst = BLE_MESH_NET_HDR_DST(buf->data); - BT_DBG("Decryption successful. Payload len %u", buf->len); - if (net_if != BLE_MESH_NET_IF_PROXY_CFG && rx->ctx.recv_dst == BLE_MESH_ADDR_UNASSIGNED) { BT_ERR("Destination address is unassigned; dropping packet"); @@ -1832,16 +1922,15 @@ int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, BT_ERR("Destination address is RFU; dropping packet 0x%02x", rx->ctx.recv_dst); return -EBADMSG; } -#endif +#endif /* !CONFIG_BLE_MESH_BQB_TEST */ if (net_if != BLE_MESH_NET_IF_LOCAL && bt_mesh_elem_find(rx->ctx.addr)) { BT_DBG("Dropping locally originated packet"); return -EBADMSG; } - BT_DBG("src 0x%04x dst 0x%04x ttl %u", rx->ctx.addr, rx->ctx.recv_dst, - rx->ctx.recv_ttl); - BT_DBG("PDU: %s", bt_hex(buf->data, buf->len)); + BT_DBG("Src 0x%04x Dst 0x%04x TTL %u", rx->ctx.addr, rx->ctx.recv_dst, rx->ctx.recv_ttl); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); msg_cache_add(rx); @@ -1851,25 +1940,31 @@ int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, static bool ready_to_recv(void) { if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { + BT_DBG("NodeReadyToRecv"); return true; } if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en()) { if (bt_mesh_provisioner_get_node_count()) { + BT_DBG("PvnrReadyToRecv"); return true; } } + BT_DBG("NotReadyToRecv"); return false; } static bool ignore_net_msg(uint16_t src, uint16_t dst) { + BT_DBG("IgnoreNetMsg, Src 0x%04x Dst 0x%04x", src, dst); + if (IS_ENABLED(CONFIG_BLE_MESH_FAST_PROV)) { /* When fast provisioning is enabled, the node addr * message will be sent to the Primary Provisioner, * which shall not be ignored here. */ + BT_DBG("FastProvNotIgnoreNetMsg"); return false; } @@ -1884,11 +1979,12 @@ static bool ignore_net_msg(uint16_t src, uint16_t dst) */ if (!bt_mesh_provisioner_get_node_with_addr(src) && !bt_mesh_elem_find(src)) { - BT_INFO("Not found node address 0x%04x", src); + BT_INFO("PvnrIgnoreNetMsg"); return true; } } + BT_DBG("NotIgnoreNetMsg"); return false; } @@ -1916,6 +2012,9 @@ void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi, /* Save the state so the buffer can later be relayed */ net_buf_simple_save(&buf, &state); + BT_DBG("NetRecv, Src 0x%04x Dst 0x%04x Rssi %d NetIf %u", + rx.ctx.addr, rx.ctx.recv_dst, rx.ctx.recv_rssi, net_if); + BT_BQB(BLE_MESH_BQB_TEST_LOG_LEVEL_PRIMARY_ID_NODE | \ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_NET, "\nNetRecv: ctl: %d, src: %d, dst: %d, ttl: %d, data: 0x%s", @@ -1933,10 +2032,12 @@ void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi, if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) && #if CONFIG_BLE_MESH_PRB_SRV bt_mesh_private_gatt_proxy_state_get() != BLE_MESH_PRIVATE_GATT_PROXY_ENABLED && -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ net_if == BLE_MESH_NET_IF_PROXY) { bt_mesh_proxy_server_addr_add(data, rx.ctx.addr); + BT_DBG("ProxyServerAddrAdd"); + if (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_DISABLED && !rx.local_match) { BT_INFO("Proxy is disabled; ignoring message"); @@ -1956,6 +2057,7 @@ void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi, !bt_mesh_addr_in_uar(&rx.sub->proxy_client_uar, rx.ctx.addr) && !bt_mesh_proxy_server_find_client_by_addr(rx.ctx.addr)) { rx.ctx.recv_tag |= BLE_MESH_TAG_IMMUTABLE_CRED; + BT_DBG("ImmutableCredTag"); } #endif /* CONFIG_BLE_MESH_DF_SRV */ } @@ -1992,7 +2094,7 @@ static void ivu_refresh(struct k_work *work) { bt_mesh.ivu_duration += BLE_MESH_IVU_HOURS; - BT_INFO("%s for %u hour%s", + BT_INFO("IVURefresh, %s for %u hour%s", bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS) ? "IVU in Progress" : "IVU Normal mode", bt_mesh.ivu_duration, bt_mesh.ivu_duration == 1U ? "" : "s"); @@ -2016,6 +2118,8 @@ static void ivu_refresh(struct k_work *work) void bt_mesh_net_start(void) { + BT_DBG("NetStart"); + if (bt_mesh_secure_beacon_get() == BLE_MESH_SECURE_BEACON_ENABLED) { bt_mesh_secure_beacon_enable(); } else { @@ -2028,7 +2132,7 @@ void bt_mesh_net_start(void) } else { bt_mesh_private_beacon_disable(); } -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) && bt_mesh_gatt_proxy_get() != BLE_MESH_GATT_PROXY_NOT_SUPPORTED) { @@ -2041,7 +2145,7 @@ void bt_mesh_net_start(void) bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_SUB_CODE_ADD, BLE_MESH_EXCEP_LIST_TYPE_MESH_BEACON, NULL); -#endif +#endif /* CONFIG_BLE_MESH_USE_DUPLICATE_SCAN */ if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) { /* TODO: Enable duplicate scan in Low Power Mode */ @@ -2060,6 +2164,7 @@ void bt_mesh_net_start(void) uint32_t iv_index = bt_mesh.iv_index; uint8_t flags = (uint8_t)bt_mesh.sub[0].kr_flag; const uint8_t *net_key = bt_mesh.sub[0].keys[flags].net; + if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS)) { flags |= BLE_MESH_NET_FLAG_IVU; } @@ -2070,16 +2175,20 @@ void bt_mesh_net_start(void) void bt_mesh_net_init(void) { + BT_DBG("NetInit"); + k_delayed_work_init(&bt_mesh.ivu_timer, ivu_refresh); } void bt_mesh_net_reset(void) { + BT_DBG("NetReset"); + k_delayed_work_cancel(&bt_mesh.ivu_timer); #if FRIEND_CRED_COUNT > 0 memset(friend_cred, 0, sizeof(friend_cred)); -#endif +#endif /* FRIEND_CRED_COUNT > 0 */ memset(msg_cache, 0, sizeof(msg_cache)); msg_cache_next = 0U; @@ -2094,6 +2203,8 @@ void bt_mesh_net_reset(void) #if CONFIG_BLE_MESH_DEINIT void bt_mesh_net_deinit(void) { + BT_DBG("NetDeinit"); + bt_mesh_net_reset(); k_delayed_work_free(&bt_mesh.ivu_timer); diff --git a/components/bt/esp_ble_mesh/core/net.h b/components/bt/esp_ble_mesh/core/net.h index 7da8c4a07824..493954178fdd 100644 --- a/components/bt/esp_ble_mesh/core/net.h +++ b/components/bt/esp_ble_mesh/core/net.h @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -66,7 +66,7 @@ struct bt_mesh_subnet { #if CONFIG_BLE_MESH_BRC_SRV uint16_t sbr_net_idx; /* NetKeyIndex of bridged subnet */ -#endif +#endif /* CONFIG_BLE_MESH_BRC_SRV */ bool kr_flag; /* Key Refresh Flag */ uint8_t kr_phase; /* Key Refresh Phase */ @@ -163,17 +163,17 @@ struct bt_mesh_rpl { bool old_iv; #if CONFIG_BLE_MESH_SETTINGS bool store; -#endif +#endif /* CONFIG_BLE_MESH_SETTINGS */ uint32_t seq; }; #if CONFIG_BLE_MESH_FRIEND #define FRIEND_SEG_RX CONFIG_BLE_MESH_FRIEND_SEG_RX #define FRIEND_SUB_LIST_SIZE CONFIG_BLE_MESH_FRIEND_SUB_LIST_SIZE -#else +#else /* CONFIG_BLE_MESH_FRIEND */ #define FRIEND_SEG_RX 0 #define FRIEND_SUB_LIST_SIZE 0 -#endif +#endif /* CONFIG_BLE_MESH_FRIEND */ struct bt_mesh_friend { uint16_t lpn; @@ -220,10 +220,10 @@ struct bt_mesh_friend { }; #if CONFIG_BLE_MESH_LOW_POWER -#define LPN_GROUPS CONFIG_BLE_MESH_LPN_GROUPS -#else -#define LPN_GROUPS 0 -#endif +#define LPN_GROUPS CONFIG_BLE_MESH_LPN_GROUPS +#else /* CONFIG_BLE_MESH_LOW_POWER */ +#define LPN_GROUPS 0 +#endif /* CONFIG_BLE_MESH_LOW_POWER */ /* Low Power Node state */ struct bt_mesh_lpn { @@ -275,7 +275,7 @@ struct bt_mesh_lpn { #if CONFIG_BLE_MESH_DF_SRV uint8_t old_directed_forwarding; -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ /* Duration reported for last advertising packet */ uint16_t adv_duration; @@ -331,11 +331,11 @@ struct bt_mesh_net { #if CONFIG_BLE_MESH_FRIEND /* Friend state, unique for each LPN that we're Friends for */ struct bt_mesh_friend frnd[CONFIG_BLE_MESH_FRIEND_LPN_COUNT]; -#endif +#endif /* CONFIG_BLE_MESH_FRIEND */ #if CONFIG_BLE_MESH_LOW_POWER struct bt_mesh_lpn lpn; /* Low Power Node state */ -#endif +#endif /* CONFIG_BLE_MESH_LOW_POWER */ /* Number of hours in current IV Update state */ uint8_t ivu_duration; @@ -362,7 +362,7 @@ struct bt_mesh_net { struct bt_mesh_subnet *p_sub[CONFIG_BLE_MESH_PROVISIONER_SUBNET_COUNT]; /* Next net_idx can be assigned */ uint16_t p_net_idx_next; -#endif +#endif /* CONFIG_BLE_MESH_PROVISIONER */ }; /* Network interface */ @@ -393,7 +393,7 @@ struct bt_mesh_net_rx { friend_match:1, /* Matched an LPN we're friends for */ #if CONFIG_BLE_MESH_NOT_RELAY_REPLAY_MSG replay_msg:1, /* Replayed messages */ -#endif +#endif /* CONFIG_BLE_MESH_NOT_RELAY_REPLAY_MSG */ sbr_rpl:1; /* Bridge RPL attacker */ uint16_t msg_cache_idx; /* Index of entry in message cache */ }; @@ -431,7 +431,7 @@ void bt_mesh_msg_cache_clear(uint16_t unicast_addr, uint8_t elem_num); int bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys, const uint8_t key[16]); -int bt_mesh_net_create(uint16_t idx, uint8_t flags, const uint8_t key[16], +int bt_mesh_net_create(uint16_t net_idx, uint8_t flags, const uint8_t key[16], uint32_t iv_index); uint8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub); diff --git a/components/bt/esp_ble_mesh/core/nimble_host/adapter.c b/components/bt/esp_ble_mesh/core/nimble_host/adapter.c index 1a1632117189..42cbec6a5495 100644 --- a/components/bt/esp_ble_mesh/core/nimble_host/adapter.c +++ b/components/bt/esp_ble_mesh/core/nimble_host/adapter.c @@ -698,8 +698,7 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg) return 0; case BLE_GAP_EVENT_ADV_COMPLETE: - MODLOG_DFLT(INFO, "advertise complete; reason=%d", - event->adv_complete.reason); + BT_DBG("advertise complete; reason=%d", event->adv_complete.reason); return 0; case BLE_GAP_EVENT_ENC_CHANGE: diff --git a/components/bt/esp_ble_mesh/core/prov_common.c b/components/bt/esp_ble_mesh/core/prov_common.c index 6f9e1dfa417c..bf5657852b87 100644 --- a/components/bt/esp_ble_mesh/core/prov_common.c +++ b/components/bt/esp_ble_mesh/core/prov_common.c @@ -48,6 +48,7 @@ void bt_mesh_prov_buf_init(struct net_buf_simple *buf, uint8_t type) bt_mesh_output_action_t bt_mesh_prov_output_action(uint8_t action) { + BT_DBG("ProvOutputAction:%d", action); switch (action) { case OUTPUT_OOB_BLINK: return BLE_MESH_BLINK; @@ -66,6 +67,7 @@ bt_mesh_output_action_t bt_mesh_prov_output_action(uint8_t action) bt_mesh_input_action_t bt_mesh_prov_input_action(uint8_t action) { + BT_DBG("ProvInputAction:%d", action); switch (action) { case INPUT_OOB_PUSH: return BLE_MESH_PUSH; @@ -151,20 +153,27 @@ static uint8_t bt_mesh_prov_buf_type_get(struct net_buf_simple *buf) uint8_t node_next_xact_id(struct bt_mesh_prov_link *link) { + uint8_t nxt_xact_id = 0; if (link->tx.id != 0 && link->tx.id != 0xFF) { - return ++link->tx.id; + nxt_xact_id = ++link->tx.id; + } else { + link->tx.id = 0x80; + nxt_xact_id = 0x80; } - link->tx.id = 0x80; - return link->tx.id; + BT_DBG("NodeNextXActId:%d", nxt_xact_id); + return nxt_xact_id; } uint8_t pvnr_next_xact_id(struct bt_mesh_prov_link *link) { + uint8_t nxt_xact_id = 0; if (link->tx.id > 0x7F) { link->tx.id = 0; } - return link->tx.id++; + nxt_xact_id = link->tx.id++; + BT_DBG("PvnrNextXActId:%d", nxt_xact_id); + return nxt_xact_id; } bool bt_mesh_gen_prov_start(struct bt_mesh_prov_link *link, @@ -186,7 +195,7 @@ bool bt_mesh_gen_prov_start(struct bt_mesh_prov_link *link, link->rx.id = rx->xact_id; link->rx.fcs = net_buf_simple_pull_u8(buf); - BT_DBG("len %u last_seg %u total_len %u fcs 0x%02x", buf->len, + BT_DBG("LinkId:%08x,len %u last_seg %u total_len %u fcs 0x%02x", link->link_id, buf->len, START_LAST_SEG(rx->gpc), link->rx.buf->len, link->rx.fcs); /* At least one-octet pdu type is needed */ @@ -227,9 +236,10 @@ bool bt_mesh_gen_prov_start(struct bt_mesh_prov_link *link, link->rx.last_seg = START_LAST_SEG(rx->gpc); memcpy(link->rx.buf->data, buf->data, buf->len); XACT_SEG_RECV(link, 0); - + BT_DBG("Seg: %04x, lastSeg: %04x, Data: %s", link->rx.seg, link->rx.last_seg, bt_hex(buf->data, buf->len)); /* Still have some segments to receive */ if (link->rx.seg) { + BT_DBG("Still have some segments to receive: %02x", link->rx.seg); return false; } @@ -242,7 +252,7 @@ bool bt_mesh_gen_prov_cont(struct bt_mesh_prov_link *link, { uint8_t seg = CONT_SEG_INDEX(rx->gpc); - BT_DBG("len %u, seg_index %u", buf->len, seg); + BT_DBG("LinkId:%08x,len %u,seg_index %u", link->link_id, buf->len, seg); if (link->rx.seg == 0 && link->rx.prev_id == rx->xact_id) { BT_INFO("Resending ack"); @@ -287,6 +297,7 @@ bool bt_mesh_gen_prov_cont(struct bt_mesh_prov_link *link, /* Still have some segments to receive */ if (link->rx.seg) { + BT_DBG("Still have some segments to receive: %02x", link->rx.seg); return false; } @@ -346,12 +357,14 @@ void bt_mesh_gen_prov_ack_send(struct bt_mesh_prov_link *link, uint8_t xact_id) net_buf_add_u8(buf, xact_id); net_buf_add_u8(buf, GPC_ACK); + BT_DBG("GenericProvAckSend,LinkId:%08x,XActId:%02x", link->link_id, xact_id); bt_mesh_adv_send(buf, PROV_XMIT, complete, link); net_buf_unref(buf); } static void free_segments(struct bt_mesh_prov_link *link) { + BT_DBG("FreeSegments:%08x", link->link_id); for (size_t i = 0; i < ARRAY_SIZE(link->tx.buf); i++) { struct net_buf *buf = link->tx.buf[i]; @@ -386,6 +399,7 @@ static void buf_sent(int err, void *user_data) int32_t timeout = RETRANSMIT_TIMEOUT; if (!link->tx.buf[0]) { + BT_DBG("LinkId:%08x,NoTxBuf", link->link_id); return; } @@ -412,6 +426,8 @@ static void prov_retransmit(struct k_work *work) struct bt_mesh_prov_link *link = work->user_data; int64_t timeout = TRANSACTION_TIMEOUT; + BT_DBG("LinkRetransmit:%08x,flag:%s", link->link_id, bt_hex(link->flags, sizeof(link->flags))); + if (!bt_mesh_atomic_test_bit(link->flags, LINK_ACTIVE) && !bt_mesh_atomic_test_bit(link->flags, LINK_CLOSING)) { BT_WARN("Link not active"); @@ -419,6 +435,9 @@ static void prov_retransmit(struct k_work *work) } #if CONFIG_BLE_MESH_FAST_PROV + BT_DBG("FastProv, TxPDUType %u LastTxPDU %u", + link->tx_pdu_type, link->last_tx_pdu); + if (link->tx_pdu_type >= link->last_tx_pdu) { timeout = K_SECONDS(30); } @@ -490,7 +509,7 @@ static void prov_retransmit(struct k_work *work) BT_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len)); - if (i + 1 < ARRAY_SIZE(link->tx.buf) && link->tx.buf[i + 1]) { + if (likely(i + 1 < ARRAY_SIZE(link->tx.buf) && link->tx.buf[i + 1])) { bt_mesh_adv_send(buf, PROV_XMIT, NULL, NULL); } else { bt_mesh_adv_send(buf, PROV_XMIT, &buf_sent_cb, link); @@ -518,7 +537,7 @@ static void send_reliable(struct bt_mesh_prov_link *link, uint8_t xmit) break; } - if (i + 1 < ARRAY_SIZE(link->tx.buf) && link->tx.buf[i + 1]) { + if (likely(i + 1 < ARRAY_SIZE(link->tx.buf) && link->tx.buf[i + 1])) { bt_mesh_adv_send(buf, xmit, NULL, NULL); } else { bt_mesh_adv_send(buf, xmit, &buf_sent_cb, link); @@ -651,6 +670,9 @@ int bt_mesh_prov_send_adv(struct bt_mesh_prov_link *link, struct net_buf_simple send_reliable(link, PROV_XMIT); #if CONFIG_BLE_MESH_FAST_PROV + BT_DBG("FastProv, TxPDUType %u LastTxPDU %u", + link->tx_pdu_type, link->last_tx_pdu); + if (link->tx_pdu_type >= link->last_tx_pdu) { timeout = K_SECONDS(60); } diff --git a/components/bt/esp_ble_mesh/core/prov_node.c b/components/bt/esp_ble_mesh/core/prov_node.c index 77f015d9897a..0805c1ddb962 100644 --- a/components/bt/esp_ble_mesh/core/prov_node.c +++ b/components/bt/esp_ble_mesh/core/prov_node.c @@ -52,6 +52,7 @@ struct bt_mesh_prov_link *bt_mesh_prov_node_get_link(void) static void close_link(uint8_t reason) { + BT_DBG("LinkClose(Rpr:%d),Reason:%d", bt_mesh_atomic_test_bit(prov_link.flags, PB_REMOTE), reason); if (bt_mesh_atomic_test_bit(prov_link.flags, PB_REMOTE)) { if (prov_link.pb_remote_close) { prov_link.pb_remote_close(&prov_link, reason); @@ -69,6 +70,7 @@ void bt_mesh_prov_node_close_link(uint8_t reason) static void reset_state(void) { + BT_INFO("ProvLinkStateReset"); k_delayed_work_cancel(&prov_link.prot_timer); /* Disable Attention Timer if it was set */ @@ -122,6 +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_mesh_prov_clear_tx(&prov_link, true); if (bt_mesh_prov_get()->link_close) { @@ -267,6 +270,7 @@ static int prov_auth(uint8_t method, uint8_t action, uint8_t size) auth_size = PROV_AUTH_SIZE(&prov_link); + BT_INFO("ProvAuth:method:%d,action:%d,size:%d", method, action, size); switch (method) { case AUTH_METHOD_NO_OOB: if (action || size) { @@ -411,6 +415,7 @@ static void prov_start(const uint8_t *data) if ((bt_mesh_prov_get()->oob_type & BIT(PROV_ONLY_OOB_AUTH_SUPPORT)) && ((data[0] == PROV_ALG_P256_HMAC_SHA256 && data[2] == AUTH_METHOD_NO_OOB) || data[0] == PROV_ALG_P256_CMAC_AES128)) { + BT_WARN("InvalidCapabilities,Alg:%d,Method:%d", data[0], data[2]); close_link(PROV_ERR_NVAL_FMT); return; } @@ -561,9 +566,10 @@ int bt_mesh_input_number(uint32_t num) auth_size = PROV_AUTH_SIZE(&prov_link); - BT_INFO("%u", num); + BT_INFO("ProvInputNumber:%u", num); if (!bt_mesh_atomic_test_and_clear_bit(prov_link.flags, WAIT_NUMBER)) { + BT_WARN("InvalidFlag:WAIT_NUMBER"); return -EINVAL; } @@ -572,6 +578,7 @@ int bt_mesh_input_number(uint32_t num) send_input_complete(); if (!bt_mesh_atomic_test_bit(prov_link.flags, HAVE_DHKEY)) { + BT_INFO("DHKeyExists"); return 0; } @@ -587,6 +594,7 @@ int bt_mesh_input_string(const char *str) BT_INFO("%s", str); if (!bt_mesh_atomic_test_and_clear_bit(prov_link.flags, WAIT_STRING)) { + BT_WARN("InvalidFlag:WAIT_STRING"); return -EINVAL; } @@ -595,6 +603,7 @@ int bt_mesh_input_string(const char *str) send_input_complete(); if (!bt_mesh_atomic_test_bit(prov_link.flags, HAVE_DHKEY)) { + BT_INFO("DHKeyExists"); return 0; } @@ -712,6 +721,7 @@ int bt_mesh_set_oob_pub_key(const uint8_t pub_key_x[32], /* If remote public key is not got, just return */ if (!bt_mesh_atomic_test_bit(prov_link.flags, REMOTE_PUB_KEY)) { + BT_WARN("RemotePubKeyNotSet"); return 0; } @@ -902,6 +912,7 @@ static void prov_data(const uint8_t *data) uint8_t reason = 0; if (bt_mesh_rpr_srv_nppi_check(prov_link.pb_remote_nppi, pdu, net_idx, iv_index, addr, &reason) == false) { + BT_WARN("RprNppiCheckFail:%d", reason); close_link(reason); return; } @@ -924,6 +935,7 @@ static void prov_data(const uint8_t *data) pdu, net_idx, flags, iv_index, addr, dev_key); if (err) { + BT_WARN("RprNppiStoreFail:%d", err); close_link(PROV_ERR_UNEXP_ERR); return; } @@ -964,6 +976,7 @@ static void prov_data(const uint8_t *data) * using Node Identity. */ if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) && identity_enable) { + BT_DBG("EnableProxyIdentity"); bt_mesh_proxy_identity_enable(); } } @@ -973,7 +986,7 @@ static void prov_complete(const uint8_t *data) static void prov_failed(const uint8_t *data) { - BT_WARN("Error: 0x%02x", data[0]); + BT_WARN("ProvError: 0x%02x", data[0]); #if CONFIG_BLE_MESH_RPR_SRV if (bt_mesh_atomic_test_bit(prov_link.flags, PB_REMOTE)) { @@ -1011,7 +1024,7 @@ static const struct { #if CONFIG_BLE_MESH_PB_ADV static void link_open(struct prov_rx *rx, struct net_buf_simple *buf) { - BT_DBG("len %u", buf->len); + BT_DBG("LinkOpenLen:%u", buf->len); if (buf->len < 16) { BT_ERR("Too short bearer open message (len %u)", buf->len); @@ -1065,7 +1078,7 @@ static void link_open(struct prov_rx *rx, struct net_buf_simple *buf) static void link_ack(struct prov_rx *rx, struct net_buf_simple *buf) { - BT_DBG("len %u", buf->len); + BT_DBG("LinkAckLen:%u",buf->len); #if CONFIG_BLE_MESH_RPR_SRV if (bt_mesh_atomic_test_bit(prov_link.flags, PB_REMOTE)) { @@ -1094,7 +1107,7 @@ static void link_close(struct prov_rx *rx, struct net_buf_simple *buf) { uint8_t reason = 0; - BT_DBG("len %u", buf->len); + BT_DBG("LinkCloseLen %u", buf->len); if (buf->len != 1) { BT_ERR("Invalid Link Close length %d", buf->len); @@ -1258,12 +1271,14 @@ static void gen_prov_ack(struct prov_rx *rx, struct net_buf_simple *buf) BT_DBG("len %u", buf->len); if (!prov_link.tx.buf[0]) { + BT_DBG("AlreadyReceived"); return; } #if CONFIG_BLE_MESH_RPR_SRV if (bt_mesh_atomic_test_bit(prov_link.flags, PB_REMOTE)) { if (prov_link.tx.id == 0) { + BT_DBG("ZeroTxId"); return; } @@ -1278,6 +1293,7 @@ static void gen_prov_ack(struct prov_rx *rx, struct net_buf_simple *buf) #endif /* CONFIG_BLE_MESH_RPR_SRV */ if (rx->xact_id == prov_link.tx.id) { + BT_DBG("XActId:%04x,ReceivedAck", rx->xact_id); bt_mesh_prov_clear_tx(&prov_link, true); } } @@ -1342,7 +1358,7 @@ void bt_mesh_pb_adv_recv(struct net_buf_simple *buf) rx.xact_id = net_buf_simple_pull_u8(buf); rx.gpc = net_buf_simple_pull_u8(buf); - BT_DBG("link_id 0x%08x xact_id %u", rx.link_id, rx.xact_id); + BT_DBG("link_id 0x%08x xact_id %u gpc %u", rx.link_id, rx.xact_id, rx.gpc); if (bt_mesh_atomic_test_bit(prov_link.flags, LINK_ACTIVE) && prov_link.link_id != rx.link_id) { @@ -1441,7 +1457,7 @@ int bt_mesh_pb_gatt_recv(struct bt_mesh_conn *conn, struct net_buf_simple *buf) int bt_mesh_pb_gatt_open(struct bt_mesh_conn *conn) { - BT_DBG("conn %p", conn); + BT_DBG("ProvConnOpen %p", conn); /** * It's necessary to determine if it is PB_REMOTE because when the @@ -1482,7 +1498,7 @@ int bt_mesh_pb_gatt_open(struct bt_mesh_conn *conn) int bt_mesh_pb_gatt_close(struct bt_mesh_conn *conn, uint8_t reason) { - BT_DBG("conn %p", conn); + BT_DBG("ProvConnClose %p", conn); if (prov_link.conn != conn) { BT_ERR("Not connected"); diff --git a/components/bt/esp_ble_mesh/core/prov_pvnr.c b/components/bt/esp_ble_mesh/core/prov_pvnr.c index a0435587a98d..d1df4a69e11b 100644 --- a/components/bt/esp_ble_mesh/core/prov_pvnr.c +++ b/components/bt/esp_ble_mesh/core/prov_pvnr.c @@ -202,6 +202,7 @@ static inline void bt_mesh_pb_gatt_unlock(void) void bt_mesh_provisioner_pbg_count_dec(void) { + BT_DBG("PbgCntDec:%d", prov_ctx.pbg_count); if (prov_ctx.pbg_count) { prov_ctx.pbg_count--; } @@ -210,6 +211,7 @@ void bt_mesh_provisioner_pbg_count_dec(void) static inline void provisioner_pbg_count_inc(void) { prov_ctx.pbg_count++; + BT_DBG("PbgCntInc:%d", prov_ctx.pbg_count); } void bt_mesh_provisioner_clear_link_info(const uint8_t addr[6]) @@ -436,8 +438,8 @@ static int provisioner_start_prov_pb_gatt(const uint8_t uuid[16], const bt_mesh_ */ if (assign_addr == BLE_MESH_ADDR_UNASSIGNED && prov_ctx.alloc_addr == BLE_MESH_ADDR_UNASSIGNED) { - BT_ERR("No available unicast address to assign"); bt_mesh_pb_gatt_unlock(); + BT_ERR("No available unicast address to assign"); return -EIO; } @@ -451,6 +453,7 @@ static int provisioner_start_prov_pb_gatt(const uint8_t uuid[16], const bt_mesh_ !bt_mesh_atomic_test_bit(prov_links[i].flags, LINK_ACTIVE)) { if (bt_mesh_gattc_conn_create(addr, BLE_MESH_UUID_MESH_PROV_VAL)) { bt_mesh_pb_gatt_unlock(); + BT_ERR("ProvGattCreateFailed:%s", bt_hex(addr->val, 6)); return -EIO; } @@ -598,6 +601,7 @@ int bt_mesh_provisioner_add_unprov_dev(struct bt_mesh_unprov_dev_add *add_dev, u start: /* If not provisioning immediately, directly return here */ if (!(flags & START_PROV_NOW)) { + BT_DBG("StartProvNotSet"); return 0; } @@ -617,6 +621,9 @@ int bt_mesh_provisioner_add_unprov_dev(struct bt_mesh_unprov_dev_add *add_dev, u } if ((err = provisioner_check_unprov_dev_info(add_dev->uuid, add_dev->bearer))) { + if (err == -EALREADY) { + BT_INFO("The device is being provisioning"); + } return err; } @@ -710,6 +717,9 @@ int bt_mesh_provisioner_prov_device_with_addr(const uint8_t uuid[16], const uint } if ((err = provisioner_check_unprov_dev_info(uuid, bearer))) { + if (err == -EALREADY) { + BT_INFO("The device is being provisioning"); + } return err; } @@ -749,10 +759,12 @@ int bt_mesh_provisioner_delete_device(struct bt_mesh_device_delete *del_dev) return -EINVAL; } + BT_INFO("ProvisionerDeleteDevice:%s", bt_hex(del_dev->uuid, 16)); /* Find if the device is in the device queue */ for (i = 0; i < ARRAY_SIZE(unprov_dev); i++) { if (!memcmp(unprov_dev[i].uuid, del_dev->uuid, 16)) { memset(&unprov_dev[i], 0, sizeof(struct unprov_dev_queue)); + BT_INFO("Device is in the queue"); break; } } @@ -761,6 +773,7 @@ int bt_mesh_provisioner_delete_device(struct bt_mesh_device_delete *del_dev) for (i = 0; i < ARRAY_SIZE(prov_links); i++) { if (!memcmp(prov_links[i].uuid, del_dev->uuid, 16)) { close_link(&prov_links[i], CLOSE_REASON_FAILED); + BT_INFO("Device is being provisioned"); break; } } @@ -776,6 +789,7 @@ int bt_mesh_provisioner_set_dev_uuid_match(uint8_t offset, uint8_t length, return -EINVAL; } + BT_INFO("SetUUIDMatch,offset:%d,value:%s,flag:%d", offset, bt_hex(match, length), prov_flag); (void)memset(prov_ctx.match_value, 0, 16); prov_ctx.match_offset = offset; @@ -795,6 +809,7 @@ int bt_mesh_provisioner_adv_pkt_cb_register(unprov_adv_pkt_cb_t cb) return -EINVAL; } + BT_INFO("RegisterAdvCB:%p", notify_unprov_adv_pkt_cb); notify_unprov_adv_pkt_cb = cb; return 0; } @@ -815,6 +830,7 @@ int bt_mesh_provisioner_set_prov_data_info(struct bt_mesh_prov_data_info *info) } prov_ctx.net_idx = info->net_idx; + BT_INFO("SetProvCtx,NetIndex:%d", info->net_idx); } return 0; @@ -881,6 +897,7 @@ void bt_mesh_provisioner_set_prov_bearer(bt_mesh_prov_bearer_t bearers, bool cle } else { prov_ctx.bearers &= ~bearers; } + BT_INFO("ProvCtxBearer:%04x,clear:%d", prov_ctx.bearers, clear); } bt_mesh_prov_bearer_t bt_mesh_provisioner_get_prov_bearer(void) @@ -909,7 +926,7 @@ int bt_mesh_provisioner_set_static_oob_value(const uint8_t *value, uint8_t lengt prov_ctx.static_oob_len = MIN(BLE_MESH_PROV_STATIC_OOB_MAX_LEN, length); memcpy(prov_ctx.static_oob_val, value, prov_ctx.static_oob_len); - + BT_INFO("SetStaticOob:%s", bt_hex(value, prov_ctx.static_oob_len)); return 0; } @@ -984,11 +1001,13 @@ int bt_mesh_test_provisioner_update_alloc_addr(uint16_t unicast_addr, uint16_t e void bt_mesh_provisioner_fast_prov_enable(bool enable) { prov_ctx.fast_prov.enable = enable; + BT_INFO("FastProvEnable:%d", enable); } void bt_mesh_provisioner_set_fast_prov_net_idx(uint16_t net_idx) { prov_ctx.fast_prov.net_idx = net_idx; + BT_INFO("FastProvNetIdx:%d", net_idx); } uint16_t bt_mesh_provisioner_get_fast_prov_net_idx(void) @@ -1017,7 +1036,7 @@ uint8_t bt_mesh_set_fast_prov_unicast_addr_range(uint16_t min, uint16_t max) prov_ctx.fast_prov.unicast_addr_max = max; prov_ctx.alloc_addr = prov_ctx.fast_prov.unicast_addr_min; - + BT_INFO("FastProv,AddrMin:%04x,Max:%04x,allocAddr:%04x", min, max, prov_ctx.alloc_addr); return 0x0; /* status: success */ } @@ -1038,6 +1057,7 @@ static struct net_buf_simple *get_rx_buf(const uint8_t idx) static void reset_adv_link(struct bt_mesh_prov_link *link, uint8_t reason) { + BT_INFO("ResetAdvLink:%08x", link->link_id); bt_mesh_prov_clear_tx(link, true); if (bt_mesh_prov_get()->prov_link_close) { @@ -1106,6 +1126,7 @@ static void send_link_open(struct bt_mesh_prov_link *link) if (bt_mesh_atomic_test_bit(prov_links[i].flags, LINK_ACTIVE) && prov_links[i].link_id == link->link_id) { bt_mesh_rand(&link->link_id, sizeof(link->link_id)); + BT_DBG("ProvLinkIdx:%d,LinkId:%08x", i, link->link_id); break; } } @@ -1280,6 +1301,7 @@ static void prov_capabilities(struct bt_mesh_prov_link *link, if ((algorithms & BIT(PROV_ALG_P256_CMAC_AES128)) || (!((oob_type & BIT(PROV_STATIC_OOB_AVAILABLE)) == 0x00 || output_size == 0x00 || input_size == 0x00))) { + BT_INFO("InvalidOobTypeSet:%02x,Alg:%02x", oob_type, algorithms); goto fail; } } @@ -1358,6 +1380,7 @@ static void prov_capabilities(struct bt_mesh_prov_link *link, * send Remote Provisioning PDU Send with Public Key. */ if (bt_mesh_atomic_test_bit(link->flags, PB_REMOTE)) { + BT_DBG("WaitForRprClientCmd"); return; } @@ -1387,6 +1410,7 @@ static int prov_auth(struct bt_mesh_prov_link *link, bt_mesh_input_action_t input = 0U; uint8_t auth_size = PROV_AUTH_SIZE(link); + BT_INFO("ProvAuth:method:%d,action:%d,size:%d", method, action, size); switch (method) { case AUTH_METHOD_NO_OOB: if (action || size) { @@ -1778,6 +1802,7 @@ static void prov_gen_dh_key(struct bt_mesh_prov_link *link) */ if (link->auth_method == AUTH_METHOD_OUTPUT || link->auth_method == AUTH_METHOD_INPUT) { + BT_INFO("WaitForNextAction:%d", link->auth_method); return; } @@ -1814,6 +1839,7 @@ static void prov_gen_dh_key(struct bt_mesh_prov_link *link) * Input Complete, because if the authentication method is * Output OOB or Input OOB, it will directly return above. */ + BT_DBG("LinkExpect:%d", link->expect); if (link->expect != PROV_INPUT_COMPLETE) { send_confirm(link); } @@ -2094,6 +2120,7 @@ static void send_prov_data(struct bt_mesh_prov_link *link) link->unicast_addr = alloc_addr; } + BT_DBG("ProvAllocAddr:%04x", link->unicast_addr); bt_mesh_prov_buf_init(&buf, PROV_DATA); err = bt_mesh_prov_encrypt(session_key, nonce, pdu, net_buf_simple_add(&buf, 33)); @@ -2310,7 +2337,7 @@ static void prov_complete(struct bt_mesh_prov_link *link, static void prov_failed(struct bt_mesh_prov_link *link, struct net_buf_simple *buf) { - BT_WARN("Error 0x%02x", buf->data[0]); + BT_WARN("ProvError 0x%02x", buf->data[0]); close_link(link, CLOSE_REASON_FAILED); } @@ -2360,7 +2387,7 @@ static void close_link(struct bt_mesh_prov_link *link, uint8_t reason) #if CONFIG_BLE_MESH_PB_ADV static void link_ack(struct bt_mesh_prov_link *link, struct prov_rx *rx, struct net_buf_simple *buf) { - BT_DBG("len %u", buf->len); + BT_DBG("LinkAckLen %u", buf->len); if (buf->len) { BT_ERR("Invalid Link ACK length %d", buf->len); @@ -2388,7 +2415,7 @@ static void link_ack(struct bt_mesh_prov_link *link, struct prov_rx *rx, struct static void link_close(struct bt_mesh_prov_link *link, struct prov_rx *rx, struct net_buf_simple *buf) { - BT_DBG("len %u", buf->len); + BT_DBG("LinkCloseLen %u", buf->len); if (buf->len != 1) { BT_ERR("Invalid Link Close length %d", buf->len); @@ -2511,10 +2538,12 @@ static void gen_prov_ack(struct bt_mesh_prov_link *link, BT_DBG("len %u", buf->len); if (!link->tx.buf[0]) { + BT_DBG("NullTxbuf"); return; } if (!link->tx.id) { + BT_DBG("ZeroTxId"); return; } @@ -2620,7 +2649,7 @@ void bt_mesh_provisioner_pb_adv_recv(struct net_buf_simple *buf) rx.xact_id = net_buf_simple_pull_u8(buf); rx.gpc = net_buf_simple_pull_u8(buf); - BT_DBG("link_id 0x%08x xact_id %u", rx.link_id, rx.xact_id); + BT_DBG("link_id 0x%08x xact_id %u gpc %u", rx.link_id, rx.xact_id, rx.gpc); link = find_pba_link(rx.link_id); if (link == NULL) { @@ -2783,7 +2812,7 @@ static void protocol_timeout(struct k_work *work) { struct bt_mesh_prov_link *link = work->user_data; - BT_WARN("Protocol timeout"); + BT_WARN("Protocol timeout,RmtAddr:%s", bt_hex(link->addr.val, 6)); close_link(link, CLOSE_REASON_TIMEOUT); } @@ -3112,6 +3141,7 @@ int bt_mesh_rpr_cli_pdu_recv(struct bt_mesh_prov_link *link, uint8_t type, return -EINVAL; } + BT_INFO("RprCliProvType:%d", type); prov_handlers[type].func(link, buf); return 0; } diff --git a/components/bt/esp_ble_mesh/core/proxy_client.c b/components/bt/esp_ble_mesh/core/proxy_client.c index d89c5ff1fdfe..d8d68c934701 100644 --- a/components/bt/esp_ble_mesh/core/proxy_client.c +++ b/components/bt/esp_ble_mesh/core/proxy_client.c @@ -23,11 +23,11 @@ #if CONFIG_BLE_MESH_V11_SUPPORT #include "mesh_v1.1/utils.h" -#endif +#endif /* CONFIG_BLE_MESH_V11_SUPPORT */ #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \ CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \ - (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT) + (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT) static struct bt_mesh_proxy_server { struct bt_mesh_conn *conn; @@ -40,7 +40,8 @@ static struct bt_mesh_proxy_server { #if CONFIG_BLE_MESH_GATT_PROXY_CLIENT uint16_t net_idx; -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */ + uint8_t msg_type; struct k_delayed_work sar_timer; @@ -53,7 +54,7 @@ static struct { struct bt_mesh_prov_link *link; bt_mesh_addr_t addr; } waiting_conn_link[BLE_MESH_MAX_CONN]; -#endif +#endif /* CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT */ static uint8_t server_buf_data[BLE_MESH_PROXY_BUF_SIZE * BLE_MESH_MAX_CONN]; @@ -61,6 +62,8 @@ static struct bt_mesh_proxy_server *find_server(struct bt_mesh_conn *conn) { int i; + BT_DBG("FindServer, ConnHandle 0x%04x", conn->handle); + for (i = 0; i < ARRAY_SIZE(servers); i++) { if (servers[i].conn == conn) { return &servers[i]; @@ -74,15 +77,16 @@ static void proxy_sar_timeout(struct k_work *work) { struct bt_mesh_proxy_server *server = NULL; - BT_WARN("%s", __func__); + BT_WARN("ProxySARTimeout"); server = CONTAINER_OF(work, struct bt_mesh_proxy_server, sar_timer.work); if (!server || !server->conn) { - BT_ERR("Invalid proxy server parameter"); + BT_ERR("InvalidProxyServerParam"); return; } net_buf_simple_reset(&server->buf); + bt_mesh_gattc_disconnect(server->conn); } @@ -90,6 +94,8 @@ static void proxy_sar_timeout(struct k_work *work) int bt_mesh_rpr_srv_set_waiting_prov_link(struct bt_mesh_prov_link *link, bt_mesh_addr_t *addr) { + BT_DBG("RPRSrvSetWaitingProvLink"); + for (size_t i = 0; i < ARRAY_SIZE(waiting_conn_link);i++) { if (waiting_conn_link[i].link == NULL) { waiting_conn_link[i].link = link; @@ -103,8 +109,7 @@ int bt_mesh_rpr_srv_set_waiting_prov_link(struct bt_mesh_prov_link *link, #endif /* CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT */ #if CONFIG_BLE_MESH_GATT_PROXY_CLIENT -/** - * The following callbacks are used to notify proper information +/* The following callbacks are used to notify proper information * to the application layer. */ static proxy_client_recv_adv_cb_t proxy_client_adv_recv_cb; @@ -139,6 +144,8 @@ static void filter_status(struct bt_mesh_proxy_server *server, uint8_t filter_type = 0U; uint16_t list_size = 0U; + BT_DBG("FilterStatus"); + if (buf->len != 3) { BT_ERR("Invalid Proxy Filter Status length %d", buf->len); return; @@ -152,10 +159,11 @@ static void filter_status(struct bt_mesh_proxy_server *server, list_size = net_buf_simple_pull_be16(buf); - BT_INFO("filter_type 0x%02x, list_size %d", filter_type, list_size); + BT_INFO("FilterType %u ListSize %u", filter_type, list_size); if (proxy_client_filter_status_recv_cb) { - proxy_client_filter_status_recv_cb(server - servers, rx->ctx.addr, server->net_idx, filter_type, list_size); + proxy_client_filter_status_recv_cb(server - servers, rx->ctx.addr, + server->net_idx, filter_type, list_size); } } @@ -167,7 +175,7 @@ static void recv_directed_proxy_caps_status(struct bt_mesh_proxy_server *server, uint8_t directed_proxy = net_buf_simple_pull_u8(buf); uint8_t use_directed = net_buf_simple_pull_u8(buf); - BT_INFO("Directed Proxy 0x%02x, Use Directed 0x%02x", directed_proxy, use_directed); + BT_INFO("DirectedProxy %u UseDirected %u", directed_proxy, use_directed); ARG_UNUSED(directed_proxy); ARG_UNUSED(use_directed); @@ -181,13 +189,14 @@ static void proxy_cfg(struct bt_mesh_proxy_server *server) uint8_t opcode = 0U; int err = 0; + BT_DBG("ProxyCfg"); + if (server->buf.len > 29) { BT_ERR("Too large proxy cfg pdu (len %d)", server->buf.len); return; } - err = bt_mesh_net_decode(&server->buf, BLE_MESH_NET_IF_PROXY_CFG, - &rx, &buf); + err = bt_mesh_net_decode(&server->buf, BLE_MESH_NET_IF_PROXY_CFG, &rx, &buf); if (err) { BT_ERR("Failed to decode Proxy Configuration (err %d)", err); return; @@ -201,7 +210,7 @@ static void proxy_cfg(struct bt_mesh_proxy_server *server) rx.local_match = 1U; if (bt_mesh_rpl_check(&rx, NULL)) { - BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", + BT_WARN("Replay, Src 0x%04x Dst 0x%04x Seq 0x%06x", rx.ctx.addr, rx.ctx.recv_dst, rx.seq); return; } @@ -209,7 +218,7 @@ static void proxy_cfg(struct bt_mesh_proxy_server *server) /* Remove network headers */ net_buf_simple_pull(&buf, BLE_MESH_NET_HDR_LEN); - BT_DBG("%u bytes: %s", buf.len, bt_hex(buf.data, buf.len)); + BT_DBG("Len %u: %s", buf.len, bt_hex(buf.data, buf.len)); if (buf.len < 3) { BT_WARN("Too short proxy configuration PDU"); @@ -243,6 +252,8 @@ static void proxy_cfg(struct bt_mesh_proxy_server *server) static void proxy_complete_pdu(struct bt_mesh_proxy_server *server) { + BT_DBG("ProxyCompletePDU"); + switch (server->msg_type) { #if CONFIG_BLE_MESH_GATT_PROXY_CLIENT case BLE_MESH_PROXY_NET_PDU: @@ -265,14 +276,14 @@ static void proxy_complete_pdu(struct bt_mesh_proxy_server *server) if (server->conn == bt_mesh_prov_node_get_link()->conn) { bt_mesh_pb_gatt_recv(server->conn, &server->buf); } else -#endif +#endif /* CONFIG_BLE_MESH_RPR_SRV */ { #if CONFIG_BLE_MESH_PROVISIONER bt_mesh_provisioner_pb_gatt_recv(server->conn, &server->buf); -#endif +#endif /* CONFIG_BLE_MESH_PROVISIONER */ } break; -#endif +#endif /* CONFIG_BLE_MESH_PB_GATT && (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV) */ default: BT_WARN("Unhandled Message Type 0x%02x", server->msg_type); break; @@ -291,6 +302,8 @@ static ssize_t proxy_recv(struct bt_mesh_conn *conn, const uint8_t *data = buf; uint16_t srvc_uuid = 0U; + BT_DBG("ProxyRecv, ConnHandle 0x%04x", conn->handle); + if (!server) { BT_ERR("No Proxy Server object found"); return -ENOTCONN; @@ -377,7 +390,8 @@ static ssize_t proxy_recv(struct bt_mesh_conn *conn, static int proxy_send(struct bt_mesh_conn *conn, const void *data, uint16_t len) { - BT_DBG("%u bytes: %s", len, bt_hex(data, len)); + BT_DBG("ProxySend"); + BT_DBG("Len %u: %s", len, bt_hex(data, len)); return bt_mesh_gattc_write_no_rsp(conn, NULL, data, len); } @@ -388,13 +402,15 @@ int bt_mesh_proxy_client_segment_send(struct bt_mesh_conn *conn, uint8_t type, uint16_t mtu = 0U; int err = 0; + BT_DBG("ProxyClientSegSend"); + if (conn == NULL) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; } - BT_DBG("conn %p type 0x%02x len %u: %s", conn, type, msg->len, - bt_hex(msg->data, msg->len)); + BT_DBG("ConnHandle 0x%04x Type %u", conn->handle, type); + BT_DBG("Len %u: %s", msg->len, bt_hex(msg->data, msg->len)); mtu = bt_mesh_gattc_get_mtu_info(conn); if (!mtu) { @@ -402,6 +418,8 @@ int bt_mesh_proxy_client_segment_send(struct bt_mesh_conn *conn, uint8_t type, return -ENOTCONN; } + BT_DBG("MTU %u", mtu); + /* ATT_MTU - OpCode (1 byte) - Handle (2 bytes) */ mtu -= 3; if (mtu > msg->len) { @@ -433,6 +451,8 @@ int bt_mesh_proxy_client_send(struct bt_mesh_conn *conn, uint8_t type, { struct bt_mesh_proxy_server *server = find_server(conn); + BT_DBG("ProxyClientSend, ConnHandle 0x%04x Type %u", conn->handle, type); + if (!server) { BT_ERR("No Proxy Server object found"); return -ENOTCONN; @@ -450,6 +470,8 @@ static void proxy_connected(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn, int { struct bt_mesh_proxy_server *server = NULL; + BT_DBG("ProxyConnected, ConnHandle 0x%04x ID %d", conn->handle, id); + if (!servers[id].conn) { server = &servers[id]; } @@ -475,7 +497,7 @@ static void proxy_connected(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn, int break; } } -#endif +#endif /* CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT */ bt_mesh_gattc_exchange_mtu(id); } @@ -484,7 +506,7 @@ static void proxy_disconnected(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn, { struct bt_mesh_proxy_server *server = find_server(conn); - BT_DBG("conn %p, handle is %d, reason 0x%02x", conn, conn->handle, reason); + BT_DBG("ProxyDisconnected, ConnHandle 0x%04x Reason 0x%02x", conn->handle, reason); if (!server) { BT_ERR("No Proxy Server object found"); @@ -521,14 +543,15 @@ static void proxy_disconnected(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn, proxy_client_disconnect_cb(addr, server - servers, server->net_idx, reason); } } -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */ k_delayed_work_cancel(&server->sar_timer); + server->conn = NULL; server->conn_type = CLI_NONE; #if CONFIG_BLE_MESH_GATT_PROXY_CLIENT server->net_idx = BLE_MESH_KEY_UNUSED; -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */ } #if CONFIG_BLE_MESH_PB_GATT && \ @@ -537,6 +560,8 @@ static ssize_t prov_write_ccc(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn) { struct bt_mesh_proxy_server *server = find_server(conn); + BT_DBG("ProvWriteCCC, ConnHandle 0x%04x", conn->handle); + if (!server) { BT_ERR("No Proxy Server object found"); return -ENOTCONN; @@ -555,11 +580,11 @@ static ssize_t prov_write_ccc(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn) return bt_mesh_rpr_srv_recv_link_ack(addr->val, false); } -#endif +#endif /* CONFIG_BLE_MESH_RPR_SRV */ #if CONFIG_BLE_MESH_PROVISIONER return bt_mesh_provisioner_pb_gatt_open(conn, addr->val); -#endif +#endif /* CONFIG_BLE_MESH_PROVISIONER */ } return -ENOMEM; @@ -569,6 +594,8 @@ static ssize_t prov_recv_ntf(struct bt_mesh_conn *conn, uint8_t *data, uint16_t { struct bt_mesh_proxy_server *server = find_server(conn); + BT_DBG("ProvRecvNtf, ConnHandle 0x%04x", conn->handle); + if (!server) { BT_ERR("No Proxy Server object found"); return -ENOTCONN; @@ -585,6 +612,8 @@ int bt_mesh_proxy_client_prov_enable(void) { int i; + BT_DBG("ProxyClientProvEnable"); + for (i = 0; i < ARRAY_SIZE(servers); i++) { if (servers[i].conn) { servers[i].conn_type = CLI_PROV; @@ -598,6 +627,8 @@ int bt_mesh_proxy_client_prov_disable(void) { int i; + BT_DBG("ProxyClientProvDisable"); + for (i = 0; i < ARRAY_SIZE(servers); i++) { struct bt_mesh_proxy_server *server = &servers[i]; @@ -616,6 +647,8 @@ static ssize_t proxy_write_ccc(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn) { struct bt_mesh_proxy_server *server = find_server(conn); + BT_DBG("ProxyWriteCCC, ConnHandle 0x%04x", conn->handle); + if (!server) { BT_ERR("No Proxy Server object found"); return -ENOTCONN; @@ -631,11 +664,12 @@ static ssize_t proxy_write_ccc(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn) } #if CONFIG_BLE_MESH_BQB_TEST - /* notify maybe received first */ + /* Notification maybe received firstly */ if (server->conn_type == CLI_PROXY) { return 0; } -#endif +#endif /* CONFIG_BLE_MESH_BQB_TEST */ + return -EINVAL; } @@ -643,20 +677,23 @@ static ssize_t proxy_recv_ntf(struct bt_mesh_conn *conn, uint8_t *data, uint16_t { struct bt_mesh_proxy_server *server = find_server(conn); + BT_DBG("ProxyRecvNtf, ConnHandle 0x%04x", conn->handle); + if (!server) { BT_ERR("No Proxy Server object found"); return -ENOTCONN; } #if CONFIG_BLE_MESH_BQB_TEST - /* update conn type if notify received before write ccc */ + /* Update conn type if notification received before writing ccc */ if (server->conn_type == CLI_NONE) { server->conn_type = CLI_PROXY; + if (proxy_client_connect_cb) { proxy_client_connect_cb(&server->addr, server - servers, server->net_idx); } } -#endif +#endif /* CONFIG_BLE_MESH_BQB_TEST */ if (server->conn_type == CLI_PROXY) { return proxy_recv(conn, NULL, data, len, 0, 0); @@ -665,8 +702,7 @@ static ssize_t proxy_recv_ntf(struct bt_mesh_conn *conn, uint8_t *data, uint16_t return -EINVAL; } -/** - * Currently proxy client doesn't need bt_mesh_proxy_client_gatt_enable() +/* Currently proxy client doesn't need bt_mesh_proxy_client_gatt_enable() * and bt_mesh_proxy_client_gatt_disable() functions, and once they are * used, proxy client can be enabled to parse node_id_adv and net_id_adv * in order to support proxy client role. @@ -677,6 +713,8 @@ int bt_mesh_proxy_client_gatt_enable(void) { int i; + BT_DBG("ProxyClientGattEnable"); + for (i = 0; i < ARRAY_SIZE(servers); i++) { if (servers[i].conn) { servers[i].conn_type = CLI_PROXY; @@ -696,8 +734,9 @@ int bt_mesh_proxy_client_gatt_disable(void) { int i; - /** - * TODO: + BT_DBG("ProxyClientGattDisable"); + + /* TODO: * Once this function is invoked, proxy client shall stop handling * node_id & net_id adv packets, and if proxy connection exists, * it should be disconnected. @@ -739,6 +778,8 @@ static struct bt_mesh_subnet *bt_mesh_is_net_id_exist(const uint8_t net_id[8]) size = bt_mesh_rx_netkey_size(); + BT_DBG("IsNetIDExist, Size %u", size); + for (i = 0U; i < size; i++) { sub = bt_mesh_rx_netkey_get(i); if (sub && !memcmp(sub->keys[sub->kr_flag].net_id, net_id, 8)) { @@ -753,8 +794,11 @@ void bt_mesh_proxy_client_gatt_adv_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr, int8_t rssi) { bt_mesh_proxy_adv_ctx_t ctx = {0}; + struct bt_mesh_subnet *sub = NULL; uint8_t type = 0U; + BT_DBG("ProxyClientGattAdvRecv, Rssi %d", rssi); + /* Check if connection reaches the maximum limitation */ if (bt_mesh_gattc_get_free_conn_count() == 0) { BT_INFO("BLE connections for mesh reach max limit"); @@ -763,14 +807,15 @@ void bt_mesh_proxy_client_gatt_adv_recv(struct net_buf_simple *buf, type = net_buf_simple_pull_u8(buf); + BT_DBG("Type %u", type); + switch (type) { - case BLE_MESH_PROXY_ADV_NET_ID: { + case BLE_MESH_PROXY_ADV_NET_ID: if (buf->len != sizeof(ctx.net_id.net_id)) { BT_WARN("Malformed Network ID"); return; } - struct bt_mesh_subnet *sub = NULL; sub = bt_mesh_is_net_id_exist(buf->data); if (!sub) { return; @@ -779,7 +824,6 @@ void bt_mesh_proxy_client_gatt_adv_recv(struct net_buf_simple *buf, memcpy(ctx.net_id.net_id, buf->data, buf->len); ctx.net_id.net_idx = sub->net_idx; break; - } case BLE_MESH_PROXY_ADV_NODE_ID: /* Gets node identity information. * hash = aes-ecb(identity key, 16 octets(padding + random + src)) mod 2^64, @@ -808,6 +852,8 @@ int bt_mesh_proxy_client_connect(const uint8_t addr[6], uint8_t addr_type, uint1 bt_mesh_addr_t remote_addr = {0}; int result = 0; + BT_DBG("ProxyClientConnect, NetIdx 0x%04x", net_idx); + if (!addr || addr_type > BLE_MESH_ADDR_RANDOM) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; @@ -830,13 +876,13 @@ int bt_mesh_proxy_client_disconnect(uint8_t conn_handle) { struct bt_mesh_conn *conn = NULL; + BT_DBG("ProxyClientDisconnect, ConnHandle 0x%04x", conn_handle); + if (conn_handle >= BLE_MESH_MAX_CONN) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; } - BT_DBG("conn_handle %d", conn_handle); - conn = servers[conn_handle].conn; if (!conn) { BT_ERR("Not connected, conn handle %d", conn_handle); @@ -853,6 +899,8 @@ bool bt_mesh_proxy_client_relay(struct net_buf_simple *buf, uint16_t dst) int err = 0; int i; + BT_DBG("ProxyClientRelay, Dst 0x%04x", dst); + for (i = 0; i < ARRAY_SIZE(servers); i++) { struct bt_mesh_proxy_server *server = &servers[i]; NET_BUF_SIMPLE_DEFINE(msg, 32); @@ -883,12 +931,15 @@ static int beacon_send(struct bt_mesh_conn *conn, struct bt_mesh_subnet *sub, bo { NET_BUF_SIMPLE_DEFINE(buf, 28); + BT_DBG("BeaconSend, ConnHandle 0x%04x Private %u", conn->handle, private); + net_buf_simple_reserve(&buf, 1); + #if CONFIG_BLE_MESH_PRB_SRV if (private) { bt_mesh_private_beacon_create(sub, &buf); } else -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ { bt_mesh_secure_beacon_create(sub, &buf); } @@ -902,6 +953,8 @@ bool bt_mesh_proxy_client_beacon_send(struct bt_mesh_subnet *sub, bool private) int err = 0; int i; + BT_DBG("ProxyClientBeaconSend, Private %u", private); + /* NULL means we send Secure Network Beacon or Mesh Private Beacon on all subnets */ if (!sub) { #if CONFIG_BLE_MESH_NODE @@ -958,6 +1011,8 @@ static int send_proxy_cfg(struct bt_mesh_conn *conn, uint16_t net_idx, struct bt uint16_t alloc_len = 0U; int err = 0; + BT_DBG("SendProxyCfg, ConnHandle 0x%04x NetIdx 0x%04x", conn->handle, net_idx); + tx.sub = bt_mesh_subnet_get(net_idx); if (!tx.sub) { BT_ERR("NetKey 0x%04x not found", net_idx); @@ -1021,6 +1076,7 @@ static int send_proxy_cfg(struct bt_mesh_conn *conn, uint16_t net_idx, struct bt */ buf = bt_mesh_alloc_buf(1 + BLE_MESH_NET_HDR_LEN + alloc_len + 8); if (!buf) { + BT_ERR("Out of memory"); return -ENOMEM; } @@ -1055,11 +1111,10 @@ static int send_proxy_cfg(struct bt_mesh_conn *conn, uint16_t net_idx, struct bt #endif /* CONFIG_BLE_MESH_DF_SRV */ } - BT_DBG("len %u bytes: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); err = bt_mesh_net_encode(&tx, buf, true); if (err) { - BT_ERR("Encoding proxy cfg message failed (err %d)", err); goto end; } @@ -1078,13 +1133,14 @@ int bt_mesh_proxy_client_cfg_send(uint8_t conn_handle, uint16_t net_idx, { struct bt_mesh_conn *conn = NULL; - if (conn_handle >= BLE_MESH_MAX_CONN || !pdu || pdu->opcode > BLE_MESH_PROXY_CFG_DIRECTED_PROXY_CONTROL) { + BT_DBG("ProxyClientCfgSend, ConnHandle 0x%04x NetIdx 0x%04x", conn_handle, net_idx); + + if (conn_handle >= BLE_MESH_MAX_CONN || !pdu || + pdu->opcode > BLE_MESH_PROXY_CFG_DIRECTED_PROXY_CONTROL) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; } - BT_DBG("conn_handle %d, net_idx 0x%04x", conn_handle, net_idx); - conn = servers[conn_handle].conn; if (!conn) { BT_ERR("Not connected, conn handle %d", conn_handle); @@ -1096,7 +1152,7 @@ int bt_mesh_proxy_client_cfg_send(uint8_t conn_handle, uint16_t net_idx, */ if (servers[conn_handle].net_idx != net_idx) { BT_ERR("NetKeyIndex 0x%04x mismatch, expect 0x%04x", - net_idx, servers[conn_handle].net_idx); + net_idx, servers[conn_handle].net_idx); return -EIO; } @@ -1108,16 +1164,19 @@ int bt_mesh_proxy_client_init(void) { int i; + BT_DBG("ProxyClientInit"); + /* Initialize the server receive buffers */ for (i = 0; i < ARRAY_SIZE(servers); i++) { struct bt_mesh_proxy_server *server = &servers[i]; k_delayed_work_init(&server->sar_timer, proxy_sar_timeout); + server->buf.size = BLE_MESH_PROXY_BUF_SIZE; server->buf.__buf = server_buf_data + (i * BLE_MESH_PROXY_BUF_SIZE); #if CONFIG_BLE_MESH_GATT_PROXY_CLIENT server->net_idx = BLE_MESH_KEY_UNUSED; -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */ } bt_mesh_gattc_conn_cb_register(&conn_callbacks); @@ -1126,7 +1185,7 @@ int bt_mesh_proxy_client_init(void) bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_SUB_CODE_ADD, BLE_MESH_EXCEP_LIST_TYPE_MESH_PROXY_ADV, NULL); -#endif +#endif /* CONFIG_BLE_MESH_USE_DUPLICATE_SCAN && CONFIG_BLE_MESH_GATT_PROXY_CLIENT */ return 0; } @@ -1136,6 +1195,8 @@ int bt_mesh_proxy_client_deinit(void) { int i; + BT_DBG("ProxyClientDeinit"); + /* Initialize the server receive buffers */ for (i = 0; i < ARRAY_SIZE(servers); i++) { struct bt_mesh_proxy_server *server = &servers[i]; diff --git a/components/bt/esp_ble_mesh/core/proxy_server.c b/components/bt/esp_ble_mesh/core/proxy_server.c index cc98e03cdc4e..ed73f1144ac4 100644 --- a/components/bt/esp_ble_mesh/core/proxy_server.c +++ b/components/bt/esp_ble_mesh/core/proxy_server.c @@ -24,7 +24,7 @@ #if CONFIG_BLE_MESH_V11_SUPPORT #include "mesh_v1.1/utils.h" -#endif +#endif /* CONFIG_BLE_MESH_V11_SUPPORT */ #if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \ CONFIG_BLE_MESH_GATT_PROXY_SERVER @@ -65,19 +65,19 @@ static bool proxy_adv_enabled; #if CONFIG_BLE_MESH_GATT_PROXY_SERVER static void proxy_send_beacons(struct k_work *work); static uint16_t proxy_ccc_val; -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ #if CONFIG_BLE_MESH_PB_GATT static uint16_t prov_ccc_val; static bool prov_fast_adv; static uint32_t prov_start_time; -#endif +#endif /* CONFIG_BLE_MESH_PB_GATT */ static struct bt_mesh_proxy_client clients[BLE_MESH_MAX_CONN] = { [0 ... (BLE_MESH_MAX_CONN - 1)] = { #if CONFIG_BLE_MESH_PROXY_PRIVACY .proxy_privacy = BLE_MESH_PROXY_PRIVACY_DISABLED, -#endif +#endif /* CONFIG_BLE_MESH_PROXY_PRIVACY */ }, }; @@ -94,6 +94,8 @@ static char device_name[DEVICE_NAME_SIZE + 1]; struct bt_mesh_proxy_client *bt_mesh_proxy_server_get_client(uint8_t index) { + BT_DBG("ProxyServerGetClient, Index %u", index); + return &clients[0]; } @@ -104,11 +106,15 @@ uint8_t bt_mesh_proxy_server_get_client_count(void) int bt_mesh_set_device_name(const char *name) { + BT_DBG("SetDeviceName"); + if (!name) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; } + BT_DBG("Name %s", name); + if (strlen(name) > DEVICE_NAME_SIZE) { BT_ERR("Too long device name (len %d)", strlen(name)); return -EINVAL; @@ -122,6 +128,8 @@ int bt_mesh_set_device_name(const char *name) const char *bt_mesh_get_device_name(void) { + BT_DBG("GetDeviceName %s", device_name); + return device_name; } @@ -129,6 +137,8 @@ static struct bt_mesh_proxy_client *find_client(struct bt_mesh_conn *conn) { int i; + BT_DBG("FindClient, ConnHandle 0x%04x", conn->handle); + for (i = 0; i < ARRAY_SIZE(clients); i++) { if (clients[i].conn == conn) { return &clients[i]; @@ -142,7 +152,7 @@ static void proxy_sar_timeout(struct k_work *work) { struct bt_mesh_proxy_client *client = NULL; - BT_WARN("Proxy SAR timeout"); + BT_WARN("ProxySARTimeout"); client = CONTAINER_OF(work, struct bt_mesh_proxy_client, sar_timer.work); if (!client || !client->conn) { @@ -155,8 +165,7 @@ static void proxy_sar_timeout(struct k_work *work) } #if CONFIG_BLE_MESH_GATT_PROXY_SERVER -/** - * The following callbacks are used to notify proper information +/* The following callbacks are used to notify proper information * to the application layer. */ static proxy_server_connect_cb_t proxy_server_connect_cb; @@ -177,6 +186,8 @@ static int next_idx; bool bt_mesh_proxy_server_find_client_by_addr(uint16_t addr) { + BT_DBG("ProxyServerFindClient, Addr 0x%04x", addr); + for (size_t i = 0; i < ARRAY_SIZE(clients); i++) { if (clients[i].conn) { for (size_t j = 0; j < ARRAY_SIZE(clients[i].filter); j++) { @@ -204,6 +215,8 @@ uint8_t bt_mesh_proxy_server_get_all_client_type(void) } } + BT_DBG("ProxyServerGetAllClientType, type 0x%02x", client_type); + return client_type; } @@ -212,13 +225,16 @@ static int filter_set(struct bt_mesh_proxy_client *client, { uint8_t type = 0U; + BT_INFO("FilterSet"); + if (buf->len < 1) { BT_WARN("Too short Filter Set message"); return -EINVAL; } type = net_buf_simple_pull_u8(buf); - BT_INFO("Set filter type 0x%02x", type); + + BT_INFO("Type 0x%02x", type); switch (type) { case 0x00: @@ -249,7 +265,7 @@ static void filter_add(struct bt_mesh_proxy_client *client, * is the element address of Proxy Client. */ - BT_DBG("addr 0x%04x", addr); + BT_DBG("FilterAdd, Addr 0x%04x ProxyClient %u", addr, proxy_client); if (addr == BLE_MESH_ADDR_UNASSIGNED) { return; @@ -279,14 +295,14 @@ static void filter_add(struct bt_mesh_proxy_client *client, } } - BT_WARN("Proxy filter is full!"); + BT_WARN("ProxyFilterFull"); } static void filter_remove(struct bt_mesh_proxy_client *client, uint16_t addr) { int i; - BT_DBG("addr 0x%04x", addr); + BT_DBG("FilterRemove, Addr 0x%04x", addr); if (addr == BLE_MESH_ADDR_UNASSIGNED) { return; @@ -314,6 +330,8 @@ static void send_filter_status(struct bt_mesh_proxy_client *client, uint16_t filter_size = 0U; int i, err = 0; + BT_DBG("SetFilterStatus"); + /* Configuration messages always have dst unassigned */ tx.ctx->addr = BLE_MESH_ADDR_UNASSIGNED; tx.ctx->send_cred = BLE_MESH_FLOODING_CRED, @@ -337,11 +355,10 @@ static void send_filter_status(struct bt_mesh_proxy_client *client, net_buf_simple_add_be16(buf, filter_size); - BT_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); err = bt_mesh_net_encode(&tx, buf, true); if (err) { - BT_ERR("Encoding proxy filter status failed (err %d)", err); return; } @@ -358,13 +375,14 @@ static void proxy_cfg(struct bt_mesh_proxy_client *client) uint8_t opcode = 0U; int err = 0; + BT_DBG("ProxyCfg"); + if (client->buf.len > 29) { BT_ERR("Too large proxy cfg pdu (len %d)", client->buf.len); return; } - err = bt_mesh_net_decode(&client->buf, BLE_MESH_NET_IF_PROXY_CFG, - &rx, &buf); + err = bt_mesh_net_decode(&client->buf, BLE_MESH_NET_IF_PROXY_CFG, &rx, &buf); if (err) { BT_ERR("Failed to decode Proxy Configuration (err %d)", err); return; @@ -373,7 +391,7 @@ static void proxy_cfg(struct bt_mesh_proxy_client *client) rx.local_match = 1U; if (bt_mesh_rpl_check(&rx, NULL)) { - BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", + BT_WARN("Replay, Src 0x%04x Dst 0x%04x Seq 0x%06x", rx.ctx.addr, rx.ctx.recv_dst, rx.seq); return; } @@ -381,7 +399,7 @@ static void proxy_cfg(struct bt_mesh_proxy_client *client) /* Remove network headers */ net_buf_simple_pull(&buf, BLE_MESH_NET_HDR_LEN); - BT_DBG("%u bytes: %s", buf.len, bt_hex(buf.data, buf.len)); + BT_DBG("Len %u: %s", buf.len, bt_hex(buf.data, buf.len)); if (buf.len < 1) { BT_WARN("Too short proxy configuration PDU"); @@ -437,6 +455,8 @@ static int beacon_send(struct bt_mesh_proxy_client *client, struct bt_mesh_subne { NET_BUF_SIMPLE_DEFINE(buf, 28); + BT_DBG("BeaconSend"); + net_buf_simple_reserve(&buf, 1); #if CONFIG_BLE_MESH_PROXY_PRIVACY @@ -448,7 +468,7 @@ static int beacon_send(struct bt_mesh_proxy_client *client, struct bt_mesh_subne bt_mesh_private_beacon_create(sub, &buf); } else -#endif +#endif /* CONFIG_BLE_MESH_PROXY_PRIVACY */ { bt_mesh_secure_beacon_create(sub, &buf); } @@ -458,10 +478,12 @@ static int beacon_send(struct bt_mesh_proxy_client *client, struct bt_mesh_subne static void proxy_send_beacons(struct k_work *work) { - struct bt_mesh_proxy_client *client = NULL; + struct bt_mesh_proxy_client *client = CONTAINER_OF(work, + struct bt_mesh_proxy_client, + send_beacons);; int i; - client = CONTAINER_OF(work, struct bt_mesh_proxy_client, send_beacons); + BT_DBG("ProxySendBeacons"); /* Upon connection, the Proxy Server shall evaluate Proxy Privacy parameter * for the connection and the Proxy Server shall retain the value of the @@ -496,7 +518,7 @@ static void proxy_send_beacons(struct k_work *work) } else if (sub->proxy_privacy == BLE_MESH_PROXY_PRIVACY_ENABLED) { #if CONFIG_BLE_MESH_PRB_SRV /* TODO: Send Mesh Private Beacon */ -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ } } #endif @@ -507,6 +529,8 @@ void bt_mesh_proxy_server_beacon_send(struct bt_mesh_subnet *sub) { int i; + BT_DBG("ProxyServerBeaconSend, Sub %p", sub); + if (!sub) { /* NULL means we send on all subnets */ for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { @@ -532,10 +556,14 @@ void bt_mesh_proxy_server_identity_start(struct bt_mesh_subnet *sub) /* Prioritize the recently enabled subnet */ next_idx = sub - bt_mesh.sub; + + BT_DBG("ProxyServerIdentityStart, NextIdx %d", next_idx); } void bt_mesh_proxy_server_identity_stop(struct bt_mesh_subnet *sub) { + BT_DBG("ProxyServerIdentityStop"); + sub->node_id = BLE_MESH_NODE_IDENTITY_STOPPED; sub->node_id_start = 0U; } @@ -544,7 +572,10 @@ int bt_mesh_proxy_identity_enable(void) { int i, count = 0; + BT_DBG("ProxyIdentityEnable"); + if (!bt_mesh_is_provisioned()) { + BT_DBG("NotProvisioned"); return -EAGAIN; } @@ -560,9 +591,12 @@ int bt_mesh_proxy_identity_enable(void) } bt_mesh_proxy_server_identity_start(sub); + count++; } + BT_DBG("SubCount %u", count); + if (count) { bt_mesh_adv_update(); } @@ -578,16 +612,22 @@ void bt_mesh_proxy_server_private_identity_start(struct bt_mesh_subnet *sub) /* Prioritize the recently enabled subnet */ next_idx = sub - bt_mesh.sub; + + BT_DBG("ProxyServerPrivateIdentityStart, NextIdx %d", next_idx); } void bt_mesh_proxy_server_private_identity_stop(struct bt_mesh_subnet *sub) { + BT_DBG("ProxyServerPrivateIdentityStop"); + sub->private_node_id = BLE_MESH_PRIVATE_NODE_IDENTITY_STOPPED; sub->node_id_start = 0U; } bool bt_mesh_proxy_server_is_node_id_enable(void) { + BT_DBG("ProxyServerIsNodeIDEnable"); + for (size_t i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { /* If the Node Identity state of the node for any subnet * is 0x01 (i.e. running), return true. @@ -607,22 +647,27 @@ static bool is_exist_private_node_id_enable(void) { for (size_t i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { /* If the value of the Node Identity state of the node - * for any subnet is 0x01,If exist return true. + * for any subnet is 0x01, if exist return true. */ struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; if (sub->net_idx != BLE_MESH_KEY_UNUSED && sub->private_node_id == BLE_MESH_PRIVATE_NODE_IDENTITY_RUNNING) { + BT_DBG("PrivateNodeIDExist, NetIdx 0x%04x", sub->net_idx); return true; } } + BT_DBG("PrivateNodeIDNotExist"); return false; } int bt_mesh_proxy_private_identity_disable(void) { + BT_DBG("ProxyPrivateIdentityDisable"); + if (!bt_mesh_is_provisioned()) { + BT_DBG("NotProvisioned"); return -EAGAIN; } @@ -648,7 +693,10 @@ int bt_mesh_proxy_private_identity_enable(void) { int count = 0; + BT_DBG("ProxyPrivateIdentityEnable"); + if (!bt_mesh_is_provisioned()) { + BT_DBG("NotProvisioned"); return -EAGAIN; } @@ -664,9 +712,12 @@ int bt_mesh_proxy_private_identity_enable(void) } bt_mesh_proxy_server_private_identity_start(sub); + count++; } + BT_DBG("SubCount %u", count); + if (count) { bt_mesh_adv_update(); } @@ -674,10 +725,12 @@ int bt_mesh_proxy_private_identity_enable(void) return 0; } #endif /* CONFIG_BLE_MESH_PRB_SRV */ -#endif /* GATT_PROXY */ +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ static void proxy_complete_pdu(struct bt_mesh_proxy_client *client) { + BT_DBG("ProxyCompletePDU"); + switch (client->msg_type) { #if CONFIG_BLE_MESH_GATT_PROXY_SERVER case BLE_MESH_PROXY_NET_PDU: @@ -692,13 +745,13 @@ static void proxy_complete_pdu(struct bt_mesh_proxy_client *client) BT_DBG("Mesh Configuration PDU"); proxy_cfg(client); break; -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ #if CONFIG_BLE_MESH_PB_GATT case BLE_MESH_PROXY_PROV: BT_DBG("Mesh Provisioning PDU"); bt_mesh_pb_gatt_recv(client->conn, &client->buf); break; -#endif +#endif /* CONFIG_BLE_MESH_PB_GATT */ default: BT_WARN("Unhandled Message Type 0x%02x", client->msg_type); break; @@ -709,27 +762,35 @@ static void proxy_complete_pdu(struct bt_mesh_proxy_client *client) #if CONFIG_BLE_MESH_GATT_PROXY_SERVER if (client->msg_type < BLE_MESH_PROXY_PROV && client->proxy_msg_recv == false) { - client->proxy_msg_recv = true; - /** - * @Spec: P626 - * When a new connection is established between a Proxy Client and the Directed Proxy Server, and the - * first message received from the Proxy Client is a successfully processed DIRECTED_PROXY_CONTROL - * message, then the Directed Proxy Server shall set the Proxy_Client_Type parameter to Directed Proxy Client, - * shall set the Use_Directed parameter to Disable for all subnets known to the Directed Proxy Server - * except the subnet identified by the received message; - * otherwise, the Directed Proxy Server shall set the Proxy_Client_Type parameter to Proxy Client. + /* @Spec: P626 + * When a new connection is established between a Proxy Client and + * the Directed Proxy Server, and the first message received from + * the Proxy Client is a successfully processed DIRECTED_PROXY_CONTROL + * message, then the Directed Proxy Server shall set the Proxy_Client_Type + * parameter to Directed Proxy Client, shall set the Use_Directed + * parameter to Disable for all subnets known to the Directed Proxy + * Server except the subnet identified by the received message; + * otherwise, the Directed Proxy Server shall set the Proxy_Client_Type + * parameter to Proxy Client. * - * If the first message received is DIRECTED_PROXY_CONTROL, proxy_client_type will be set to Directed Proxy Client, - * But if device didn't receive DIRECTED_PROXY_CONTROL message and all received is normal proxy message, That - * client type will be always in UNSET state, because we set client type in handle function of DIRECTED_PROXY_CONTROL. + * If the first message received is DIRECTED_PROXY_CONTROL, proxy_client_type + * will be set to Directed Proxy Client. + * But if device didn't receive DIRECTED_PROXY_CONTROL message and all + * received is normal proxy message, That client type will be always in + * UNSET state, because we set client type in handle function of + * DIRECTED_PROXY_CONTROL. * * So the flowing code was used to avoid that situation. - */ + */ + client->proxy_msg_recv = true; + + BT_DBG("ProxyClientTypeUpdate"); + if (client->proxy_client_type == BLE_MESH_PROXY_CLI_TYPE_UNSET) { client->proxy_client_type = BLE_MESH_PROXY_CLI_TYPE_PROXY_CLIENT; } } -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ } #define ATTR_IS_PROV(attr) (attr->user_data != NULL) @@ -741,6 +802,8 @@ static ssize_t proxy_recv(struct bt_mesh_conn *conn, struct bt_mesh_proxy_client *client = find_client(conn); const uint8_t *data = buf; + BT_DBG("ProxyRecv"); + if (!client) { BT_ERR("No Proxy Client found"); return -ENOTCONN; @@ -826,7 +889,7 @@ static void proxy_connected(struct bt_mesh_conn *conn, uint8_t err) struct bt_mesh_proxy_client *client = NULL; int i; - BT_DBG("conn %p err 0x%02x", conn, err); + BT_DBG("ProxyConnected, ConnHandle 0x%04x Err 0x%02x", conn->handle, err); if (gatt_svc == MESH_GATT_PROV && conn_count == 1) { BT_WARN("Only one prov connection could exists"); @@ -845,7 +908,9 @@ static void proxy_connected(struct bt_mesh_conn *conn, uint8_t err) * Network Identity type. */ bt_mesh_proxy_server_stop_solic_adv_priv_net_id(); -#endif +#endif /* CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX */ + + BT_DBG("ConnCount %u vs. %u", conn_count, BLE_MESH_MAX_CONN); /* Try to re-enable advertising in case it's possible */ if (conn_count < BLE_MESH_MAX_CONN) { @@ -866,13 +931,15 @@ static void proxy_connected(struct bt_mesh_conn *conn, uint8_t err) client->conn = bt_mesh_conn_ref(conn); client->filter_type = SRV_NONE; + #if CONFIG_BLE_MESH_GATT_PROXY_SERVER (void)memset(client->filter, 0, sizeof(client->filter)); if (proxy_server_connect_cb) { proxy_server_connect_cb(conn->handle); } -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ + net_buf_simple_reset(&client->buf); } @@ -880,7 +947,8 @@ static void proxy_disconnected(struct bt_mesh_conn *conn, uint8_t reason) { int i; - BT_DBG("conn %p reason 0x%02x", conn, reason); + BT_DBG("ProxyDisconnected, ConnHandle 0x%04x Count %u Reason 0x%02x", + conn->handle, conn_count, reason); conn_count--; @@ -892,7 +960,8 @@ static void proxy_disconnected(struct bt_mesh_conn *conn, uint8_t reason) if (proxy_server_disconnect_cb) { proxy_server_disconnect_cb(conn->handle, reason); } -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ + if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) && client->filter_type == SRV_PROV) { bt_mesh_pb_gatt_close(conn, reason); @@ -900,11 +969,11 @@ static void proxy_disconnected(struct bt_mesh_conn *conn, uint8_t reason) #if CONFIG_BLE_MESH_PROXY_PRIVACY client->proxy_privacy = BLE_MESH_PROXY_PRIVACY_DISABLED; -#endif +#endif /* CONFIG_BLE_MESH_PROXY_PRIVACY */ #if CONFIG_BLE_MESH_GATT_PROXY_SERVER && CONFIG_BLE_MESH_PRB_SRV k_delayed_work_cancel(&rand_upd_timer); -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER && CONFIG_BLE_MESH_PRB_SRV */ k_delayed_work_cancel(&client->sar_timer); bt_mesh_conn_unref(client->conn); @@ -924,13 +993,15 @@ static void proxy_disconnected(struct bt_mesh_conn *conn, uint8_t reason) if (bt_mesh_directed_proxy_server_update_dep_node(NULL, &clients[i], 0)) { BT_ERR("Proxy disconnected, failed to update dependent node"); } -#endif /* CONFIG_BLE_MESH_DF_SRV */ +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER && CONFIG_BLE_MESH_DF_SRV */ } struct net_buf_simple *bt_mesh_proxy_server_get_buf(void) { struct net_buf_simple *buf = &clients[0].buf; + BT_DBG("ProxyServerGetBuf"); + net_buf_simple_reset(buf); return buf; @@ -945,9 +1016,11 @@ static ssize_t prov_ccc_write(struct bt_mesh_conn *conn, struct bt_mesh_proxy_client *client = NULL; uint16_t *value = attr->user_data; - BT_DBG("len %u: %s", len, bt_hex(buf, len)); + BT_DBG("ProvCCCWrite"); + BT_DBG("Len %u: %s", len, bt_hex(buf, len)); if (len != sizeof(*value)) { + BT_WARN("MismatchLen %u != %u", len, sizeof(*value)); return BLE_MESH_GATT_ERR(BLE_MESH_ATT_ERR_INVALID_ATTRIBUTE_LEN); } @@ -978,6 +1051,8 @@ static ssize_t prov_ccc_read(struct bt_mesh_conn *conn, { uint16_t *value = attr->user_data; + BT_DBG("ProvCCCRead, Len %u", len); + return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset, value, sizeof(*value)); } @@ -1007,6 +1082,8 @@ int bt_mesh_proxy_server_prov_enable(void) { int i; + BT_DBG("ProxyServerProvEnable"); + if (gatt_svc == MESH_GATT_PROV) { BT_WARN("%s, Already", __func__); return -EALREADY; @@ -1035,6 +1112,8 @@ int bt_mesh_proxy_server_prov_disable(bool disconnect) { int i; + BT_DBG("ProxyServerProvDisable, Disconnect %u", disconnect); + if (gatt_svc == MESH_GATT_NONE) { BT_WARN("%s, Already", __func__); return -EALREADY; @@ -1078,9 +1157,11 @@ static ssize_t proxy_ccc_write(struct bt_mesh_conn *conn, struct bt_mesh_proxy_client *client = NULL; uint16_t value = 0U; - BT_DBG("len %u: %s", len, bt_hex(buf, len)); + BT_DBG("ProxyCCCWrite"); + BT_DBG("Len %u: %s", len, bt_hex(buf, len)); if (len != sizeof(value)) { + BT_WARN("MismatchLen %u != %u", len, sizeof(value)); return BLE_MESH_GATT_ERR(BLE_MESH_ATT_ERR_INVALID_ATTRIBUTE_LEN); } @@ -1135,6 +1216,8 @@ static ssize_t proxy_ccc_read(struct bt_mesh_conn *conn, { uint16_t *value = attr->user_data; + BT_DBG("ProxyCCCRead, Len %u", len); + return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset, value, sizeof(*value)); } @@ -1164,6 +1247,8 @@ int bt_mesh_proxy_server_gatt_enable(void) { int i; + BT_DBG("ProxyServerGattEnable"); + if (gatt_svc == MESH_GATT_PROXY) { BT_WARN("%s, Already", __func__); return -EALREADY; @@ -1190,6 +1275,8 @@ void bt_mesh_proxy_server_gatt_disconnect(void) { int i; + BT_DBG("ProxyServerGattDisconnect"); + for (i = 0; i < ARRAY_SIZE(clients); i++) { struct bt_mesh_proxy_client *client = &clients[i]; @@ -1203,6 +1290,8 @@ void bt_mesh_proxy_server_gatt_disconnect(void) int bt_mesh_proxy_server_gatt_disable(void) { + BT_DBG("ProxyServerGattDisable"); + if (gatt_svc == MESH_GATT_NONE) { BT_WARN("%s, Already", __func__); return -EALREADY; @@ -1227,7 +1316,7 @@ void bt_mesh_proxy_server_addr_add(struct net_buf_simple *buf, uint16_t addr) struct bt_mesh_proxy_client, buf); - BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr); + BT_DBG("ProxyServerAddrAdd, Type %u Addr 0x%04x", client->filter_type, addr); if (client->filter_type == SRV_WHITELIST) { filter_add(client, addr, true); @@ -1236,16 +1325,16 @@ void bt_mesh_proxy_server_addr_add(struct net_buf_simple *buf, uint16_t addr) } } -static bool client_filter_match(struct bt_mesh_proxy_client *client, - uint16_t addr) +static bool client_filter_match(struct bt_mesh_proxy_client *client, uint16_t addr) { int i; - BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr); + BT_DBG("ClientFilterMatch, Type %u Addr 0x%04x", client->filter_type, addr); if (client->filter_type == SRV_BLACKLIST) { for (i = 0; i < ARRAY_SIZE(client->filter); i++) { if (client->filter[i].addr == addr) { + BT_DBG("InBlackList"); return false; } } @@ -1254,12 +1343,14 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client, } if (addr == BLE_MESH_ADDR_ALL_NODES) { + BT_DBG("AllNodes"); return true; } if (client->filter_type == SRV_WHITELIST) { for (i = 0; i < ARRAY_SIZE(client->filter); i++) { if (client->filter[i].addr == addr) { + BT_DBG("InWhiteList"); return true; } } @@ -1273,7 +1364,7 @@ bool bt_mesh_proxy_server_relay(struct net_buf_simple *buf, uint16_t dst) bool relayed = false; int i; - BT_DBG("%u bytes to dst 0x%04x", buf->len, dst); + BT_DBG("ProxyServerRelay, Len %u Dst 0x%04x", buf->len, dst); for (i = 0; i < ARRAY_SIZE(clients); i++) { struct bt_mesh_proxy_client *client = &clients[i]; @@ -1299,24 +1390,24 @@ bool bt_mesh_proxy_server_relay(struct net_buf_simple *buf, uint16_t dst) return relayed; } - #endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ static int proxy_send(struct bt_mesh_conn *conn, const void *data, uint16_t len) { - BT_DBG("%u bytes: %s", len, bt_hex(data, len)); + BT_DBG("ProxySend"); + BT_DBG("Len %u: %s", len, bt_hex(data, len)); #if CONFIG_BLE_MESH_GATT_PROXY_SERVER if (gatt_svc == MESH_GATT_PROXY) { return bt_mesh_gatts_notify(conn, &proxy_attrs[4], data, len); } -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ #if CONFIG_BLE_MESH_PB_GATT if (gatt_svc == MESH_GATT_PROV) { return bt_mesh_gatts_notify(conn, &prov_attrs[4], data, len); } -#endif +#endif /* CONFIG_BLE_MESH_PB_GATT */ return 0; } @@ -1326,11 +1417,15 @@ int bt_mesh_proxy_server_segment_send(struct bt_mesh_conn *conn, uint8_t type, { uint16_t mtu = 0U; - BT_DBG("conn %p type 0x%02x len %u: %s", conn, type, msg->len, - bt_hex(msg->data, msg->len)); + BT_DBG("ProxyServerSegSend"); + BT_DBG("ConnHandle 0x%04x Type %u", conn->handle, type); + BT_DBG("Len %u: %s", msg->len, bt_hex(msg->data, msg->len)); /* ATT_MTU - OpCode (1 byte) - Handle (2 bytes) */ mtu = bt_mesh_gatt_get_mtu(conn) - 3; + + BT_DBG("MTU %u", mtu); + if (mtu > msg->len) { net_buf_simple_push_u8(msg, BLE_MESH_PROXY_PDU_HDR(BLE_MESH_PROXY_SAR_COMP, type)); return proxy_send(conn, msg->data, msg->len); @@ -1360,6 +1455,8 @@ int bt_mesh_proxy_server_send(struct bt_mesh_conn *conn, uint8_t type, { struct bt_mesh_proxy_client *client = find_client(conn); + BT_DBG("ProxyServerSend, Type 0x%02x", type); + if (!client) { BT_ERR("No Proxy Client found"); return -ENOTCONN; @@ -1381,10 +1478,9 @@ static const struct bt_mesh_adv_data prov_ad[] = { BLE_MESH_ADV_DATA_BYTES(BLE_MESH_DATA_UUID16_ALL, 0x27, 0x18), BLE_MESH_ADV_DATA(BLE_MESH_DATA_SVC_DATA16, prov_svc_data, sizeof(prov_svc_data)), }; -#endif /* PB_GATT */ +#endif /* CONFIG_BLE_MESH_PB_GATT */ #if CONFIG_BLE_MESH_GATT_PROXY_SERVER - #define NET_ID_LEN 11 #define NODE_ID_LEN 19 #define PRIVATE_NET_ID_LEN 19 @@ -1432,6 +1528,9 @@ static size_t gatt_proxy_adv_create(struct bt_mesh_adv_data *proxy_sd) /* One octet for Length, and another octet for AD type */ size_t sd_space = 29; + BT_DBG("GattProxyAdvCreate"); + BT_DBG("Name %u: %s", name_len, name); + if (name_len > sd_space) { proxy_sd->type = BLE_MESH_DATA_NAME_SHORTENED; proxy_sd->data_len = sd_space; @@ -1452,6 +1551,8 @@ static int node_id_adv(struct bt_mesh_subnet *sub) uint8_t tmp[16] = {0}; int err = 0; + BT_DBG("NodeIDAdv, NetIdx 0x%04x", sub->net_idx); + proxy_svc_data[2] = BLE_MESH_PROXY_ADV_NODE_ID; err = bt_mesh_rand(proxy_svc_data + 11, 8); @@ -1489,10 +1590,10 @@ static int net_id_adv(struct bt_mesh_subnet *sub) size_t proxy_sd_len = 0U; int err = 0; - proxy_svc_data[2] = BLE_MESH_PROXY_ADV_NET_ID; + BT_DBG("NetIDAdv, NetIdx 0x%04x", sub->net_idx); + BT_DBG("NetId %s", bt_hex(sub->keys[sub->kr_flag].net_id, 8)); - BT_DBG("Advertising with NetId %s", - bt_hex(sub->keys[sub->kr_flag].net_id, 8)); + proxy_svc_data[2] = BLE_MESH_PROXY_ADV_NET_ID; memcpy(proxy_svc_data + 3, sub->keys[sub->kr_flag].net_id, 8); proxy_sd_len = gatt_proxy_adv_create(&proxy_sd); @@ -1512,11 +1613,15 @@ static int net_id_adv(struct bt_mesh_subnet *sub) #if CONFIG_BLE_MESH_PRB_SRV void bt_mesh_proxy_server_update_net_id_rand(void) { + BT_DBG("ProxyServerUpdateNetIDRand"); + k_delayed_work_submit(&rand_upd_timer, RAND_UPDATE_INTERVAL); } void bt_mesh_proxy_server_update_net_id_rand_stop(void) { + BT_DBG("ProxyServerUpdateNetIDRandStop"); + k_delayed_work_cancel(&rand_upd_timer); } @@ -1524,6 +1629,8 @@ static void random_update_timeout(struct k_work *work) { int err = 0; + BT_DBG("RandomUpdateTimeout"); + err = bt_mesh_rand(net_id_random, 8); if (err) { BT_ERR("Generate random value failed"); @@ -1540,6 +1647,8 @@ static int private_node_id_adv(struct bt_mesh_subnet *sub) uint8_t tmp[16] = {0}; int err = 0; + BT_DBG("PrivateNodeIDAdv, NetIdx 0x%04x", sub->net_idx); + proxy_svc_data[2] = BLE_MESH_PROXY_ADV_PRIVATE_NODE_ID; err = bt_mesh_rand(proxy_svc_data + 11, 8); @@ -1560,8 +1669,13 @@ static int private_node_id_adv(struct bt_mesh_subnet *sub) memcpy(proxy_svc_data + 3, tmp + 8, 8); proxy_sd_len = gatt_proxy_adv_create(&proxy_sd); +#if CONFIG_BLE_MESH_USE_BLE_50 + err = bt_le_ext_adv_start(proxy_adv_inst, &fast_adv_param, private_node_id_ad, + ARRAY_SIZE(private_node_id_ad), &proxy_sd, proxy_sd_len); +#else /* CONFIG_BLE_MESH_USE_BLE_50 */ err = bt_le_adv_start(&fast_adv_param, private_node_id_ad, ARRAY_SIZE(private_node_id_ad), &proxy_sd, proxy_sd_len); +#endif /* CONFIG_BLE_MESH_USE_BLE_50 */ if (err) { BT_WARN("Failed to advertise with Private Node ID (err %d)", err); return err; @@ -1573,8 +1687,7 @@ static int private_node_id_adv(struct bt_mesh_subnet *sub) } #endif /* CONFIG_BLE_MESH_PRB_SRV */ -#if (CONFIG_BLE_MESH_PRB_SRV || \ - CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX) +#if (CONFIG_BLE_MESH_PRB_SRV || CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX) static int private_net_id_adv(struct bt_mesh_subnet *sub) { struct bt_mesh_adv_data proxy_sd = {0}; @@ -1582,6 +1695,8 @@ static int private_net_id_adv(struct bt_mesh_subnet *sub) uint8_t tmp[16] = {0}; int err = 0; + BT_DBG("PrivateNetIDAdv, NetIdx 0x%04x", sub->net_idx); + proxy_svc_data[2] = BLE_MESH_PROXY_ADV_PRIVATE_NET_ID; /* TODO: @@ -1604,8 +1719,13 @@ static int private_net_id_adv(struct bt_mesh_subnet *sub) proxy_sd_len = gatt_proxy_adv_create(&proxy_sd); +#if CONFIG_BLE_MESH_USE_BLE_50 + err = bt_le_ext_adv_start(proxy_adv_inst, &fast_adv_param, private_net_id_ad, + ARRAY_SIZE(private_net_id_ad), &proxy_sd, proxy_sd_len); +#else /* CONFIG_BLE_MESH_USE_BLE_50 */ err = bt_le_adv_start(&fast_adv_param, private_net_id_ad, ARRAY_SIZE(private_net_id_ad), &proxy_sd, proxy_sd_len); +#endif /* CONFIG_BLE_MESH_USE_BLE_50 */ if (err) { BT_WARN("Failed to advertise with Private Net ID (err %d)", err); return err; @@ -1615,11 +1735,12 @@ static int private_net_id_adv(struct bt_mesh_subnet *sub) return 0; } -#endif /* (CONFIG_BLE_MESH_PRB_SRV || \ - CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX) */ +#endif /* (CONFIG_BLE_MESH_PRB_SRV || CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX) */ static bool advertise_subnet(struct bt_mesh_subnet *sub) { + BT_DBG("AdvSubnet, NetIdx 0x%04x", sub->net_idx); + if (sub->net_idx == BLE_MESH_KEY_UNUSED) { return false; } @@ -1629,7 +1750,7 @@ static bool advertise_subnet(struct bt_mesh_subnet *sub) #if CONFIG_BLE_MESH_PRB_SRV || sub->private_node_id == BLE_MESH_PRIVATE_NODE_IDENTITY_RUNNING || bt_mesh_private_gatt_proxy_state_get() == BLE_MESH_PRIVATE_GATT_PROXY_ENABLED -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ ); } @@ -1638,10 +1759,13 @@ static struct bt_mesh_subnet *next_sub(void) struct bt_mesh_subnet *sub = NULL; int i; + BT_DBG("NextSub"); + for (i = next_idx; i < ARRAY_SIZE(bt_mesh.sub); i++) { sub = &bt_mesh.sub[i]; if (advertise_subnet(sub)) { next_idx = (i + 1) % ARRAY_SIZE(bt_mesh.sub); + BT_DBG("NextIdx %d", next_idx); return sub; } } @@ -1653,6 +1777,7 @@ static struct bt_mesh_subnet *next_sub(void) sub = &bt_mesh.sub[i]; if (advertise_subnet(sub)) { next_idx = (i + 1) % ARRAY_SIZE(bt_mesh.sub); + BT_DBG("NextIdx %d", next_idx); return sub; } } @@ -1672,6 +1797,8 @@ static int sub_count(void) } } + BT_DBG("SubCount %ld", count); + return count; } @@ -1681,6 +1808,8 @@ static int32_t gatt_proxy_advertise(struct bt_mesh_subnet *sub) int subnet_count = 0; uint32_t active = 0U; + BT_DBG("GattProxyAdvertise"); + if (conn_count == BLE_MESH_MAX_CONN) { BT_WARN("Connectable advertising deferred (max connections %d)", conn_count); return remaining; @@ -1691,6 +1820,8 @@ static int32_t gatt_proxy_advertise(struct bt_mesh_subnet *sub) return remaining; } + BT_DBG("NetIdx 0x%04x NodeID %u", sub->net_idx, sub->node_id); + if (sub->node_id == BLE_MESH_NODE_IDENTITY_RUNNING) { active = k_uptime_get_32() - sub->node_id_start; @@ -1703,6 +1834,7 @@ static int32_t gatt_proxy_advertise(struct bt_mesh_subnet *sub) BT_DBG("Node ID stopped"); } } + #if CONFIG_BLE_MESH_PRB_SRV else if (sub->private_node_id == BLE_MESH_PRIVATE_NODE_IDENTITY_RUNNING) { active = k_uptime_get_32() - sub->node_id_start; @@ -1721,7 +1853,7 @@ static int32_t gatt_proxy_advertise(struct bt_mesh_subnet *sub) if (sub->node_id == BLE_MESH_NODE_IDENTITY_STOPPED #if CONFIG_BLE_MESH_PRB_SRV && sub->private_node_id == BLE_MESH_PRIVATE_NODE_IDENTITY_STOPPED -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ ) { if (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED) { net_id_adv(sub); @@ -1730,11 +1862,10 @@ static int32_t gatt_proxy_advertise(struct bt_mesh_subnet *sub) else if (bt_mesh_private_gatt_proxy_state_get() == BLE_MESH_PRIVATE_GATT_PROXY_ENABLED) { private_net_id_adv(sub); } -#endif +#endif /* CONFIG_BLE_MESH_PRB_SRV */ } subnet_count = sub_count(); - BT_DBG("sub_count %u", subnet_count); if (subnet_count > 1) { int32_t max_timeout = 0; @@ -1747,16 +1878,18 @@ static int32_t gatt_proxy_advertise(struct bt_mesh_subnet *sub) max_timeout = NODE_ID_TIMEOUT / MAX(subnet_count, 6); max_timeout = MAX(max_timeout, K_SECONDS(1)); + BT_DBG("Remaining %d MaxTimeout %d", remaining, max_timeout); + if (remaining > max_timeout || remaining < 0) { remaining = max_timeout; } } - BT_DBG("Advertising %d ms for net_idx 0x%04x", remaining, sub->net_idx); + BT_DBG("Remaining %d NetIdx 0x%04x", remaining, sub->net_idx); return remaining; } -#endif /* GATT_PROXY */ +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ #if CONFIG_BLE_MESH_PB_GATT static size_t gatt_prov_adv_create(struct bt_mesh_adv_data prov_sd[2]) @@ -1766,6 +1899,8 @@ static size_t gatt_prov_adv_create(struct bt_mesh_adv_data prov_sd[2]) size_t prov_sd_len = 0U; size_t sd_space = 31U; + BT_DBG("GattProvAdvCreate"); + if (bt_mesh_prov_get() == NULL) { BT_ERR("No provisioning context provided"); return 0; @@ -1816,33 +1951,43 @@ static int32_t solic_adv_private_net_id(void) struct bt_mesh_subnet *sub = NULL; int32_t remaining = 0; + BT_DBG("SolicAdvPrivateNetID"); + remaining = bt_mesh_proxy_server_get_solic_adv_remaining(); if (remaining == 0) { + BT_DBG("RemainingZero"); return 0; } net_idx = bt_mesh_proxy_server_get_solic_adv_net_idx(); if (net_idx == BLE_MESH_KEY_UNUSED) { + BT_DBG("UnusedNetIdx"); return 0; } sub = bt_mesh_subnet_get(net_idx); if (sub == NULL) { + BT_DBG("NoSub"); return 0; } private_net_id_adv(sub); + return remaining; } #endif /* CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX */ int32_t bt_mesh_proxy_server_adv_start(void) { + BT_DBG("ProxyServerAdvStart"); if (gatt_svc == MESH_GATT_NONE) { + BT_DBG("GattSvcNone"); return K_FOREVER; } #if CONFIG_BLE_MESH_PB_GATT + BT_DBG("ProvFastAdv %u", prov_fast_adv); + if (prov_fast_adv) { prov_start_time = k_uptime_get_32(); } @@ -1852,6 +1997,8 @@ int32_t bt_mesh_proxy_server_adv_start(void) struct bt_mesh_adv_data prov_sd[2]; size_t prov_sd_len; + BT_DBG("NotProvisioned"); + if (k_uptime_get_32() - prov_start_time < K_SECONDS(60)) { param = &fast_adv_param; } else { @@ -1871,7 +2018,7 @@ int32_t bt_mesh_proxy_server_adv_start(void) } } } -#endif /* PB_GATT */ +#endif /* CONFIG_BLE_MESH_PB_GATT */ #if CONFIG_BLE_MESH_GATT_PROXY_SERVER if (bt_mesh_is_provisioned()) { @@ -1899,7 +2046,7 @@ void bt_mesh_proxy_server_adv_stop(void) { int err = 0; - BT_DBG("adv_enabled %u", proxy_adv_enabled); + BT_DBG("ProxyServerAdvStop, Enabled %u", proxy_adv_enabled); if (!proxy_adv_enabled) { return; @@ -1922,13 +2069,15 @@ int bt_mesh_proxy_server_init(void) { int i; + BT_DBG("ProxyServerInit"); + #if CONFIG_BLE_MESH_GATT_PROXY_SERVER bt_mesh_gatts_service_register(&proxy_svc); -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ #if CONFIG_BLE_MESH_PB_GATT bt_mesh_gatts_service_register(&prov_svc); -#endif +#endif /* CONFIG_BLE_MESH_PB_GATT */ /* Initialize the client receive buffers */ for (i = 0; i < ARRAY_SIZE(clients); i++) { @@ -1936,9 +2085,10 @@ int bt_mesh_proxy_server_init(void) client->buf.size = BLE_MESH_PROXY_BUF_SIZE; client->buf.__buf = client_buf_data + (i * BLE_MESH_PROXY_BUF_SIZE); -#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER) + +#if CONFIG_BLE_MESH_GATT_PROXY_SERVER k_delayed_work_init(&client->send_beacons, proxy_send_beacons); -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ k_delayed_work_init(&client->sar_timer, proxy_sar_timeout); } @@ -1947,11 +2097,12 @@ int bt_mesh_proxy_server_init(void) BT_ERR("Failed to create a random update timer"); return -EIO; } -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER && CONFIG_BLE_MESH_PRB_SRV */ bt_mesh_gatts_conn_cb_register(&conn_callbacks); strncpy(device_name, "ESP-BLE-MESH", DEVICE_NAME_SIZE); + return bt_mesh_gatts_set_local_device_name(device_name); } @@ -1960,30 +2111,34 @@ int bt_mesh_proxy_server_deinit(void) { int i; + BT_DBG("ProxyServerDeinit"); + proxy_adv_enabled = false; gatt_svc = MESH_GATT_NONE; #if CONFIG_BLE_MESH_GATT_PROXY_SERVER bt_mesh_gatts_service_deregister(&proxy_svc); next_idx = 0; -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ #if CONFIG_BLE_MESH_PB_GATT bt_mesh_gatts_service_deregister(&prov_svc); -#endif +#endif /* CONFIG_BLE_MESH_PB_GATT */ for (i = 0; i < ARRAY_SIZE(clients); i++) { struct bt_mesh_proxy_client *client = &clients[i]; -#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER) + +#if CONFIG_BLE_MESH_GATT_PROXY_SERVER k_delayed_work_free(&client->send_beacons); -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ k_delayed_work_free(&client->sar_timer); + memset(client, 0, sizeof(struct bt_mesh_proxy_client)); } #if CONFIG_BLE_MESH_GATT_PROXY_SERVER && CONFIG_BLE_MESH_PRB_SRV k_delayed_work_free(&rand_upd_timer); -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER && CONFIG_BLE_MESH_PRB_SRV */ memset(client_buf_data, 0, sizeof(client_buf_data)); memset(device_name, 0, sizeof(device_name)); diff --git a/components/bt/esp_ble_mesh/core/proxy_server.h b/components/bt/esp_ble_mesh/core/proxy_server.h index b98728910de1..c1994a56d420 100644 --- a/components/bt/esp_ble_mesh/core/proxy_server.h +++ b/components/bt/esp_ble_mesh/core/proxy_server.h @@ -57,7 +57,7 @@ struct bt_mesh_proxy_client { #if CONFIG_BLE_MESH_PROXY_PRIVACY uint8_t proxy_privacy; -#endif +#endif /* CONFIG_BLE_MESH_PROXY_PRIVACY */ #endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */ struct k_delayed_work sar_timer; diff --git a/components/bt/esp_ble_mesh/core/rpl.c b/components/bt/esp_ble_mesh/core/rpl.c index 4e3e4c91cbce..c6ab282472d8 100644 --- a/components/bt/esp_ble_mesh/core/rpl.c +++ b/components/bt/esp_ble_mesh/core/rpl.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +17,9 @@ void bt_mesh_update_rpl(struct bt_mesh_rpl *rpl, struct bt_mesh_net_rx *rx) { + BT_DBG("UpdateRPL, Src 0x%04x Seq 0x%06x OldIV %u", + rx->ctx.addr, rx->seq, rx->old_iv); + rpl->src = rx->ctx.addr; rpl->seq = rx->seq; rpl->old_iv = rx->old_iv; @@ -33,9 +36,16 @@ void bt_mesh_update_rpl(struct bt_mesh_rpl *rpl, struct bt_mesh_net_rx *rx) */ static bool rpl_check_and_store(struct bt_mesh_net_rx *rx, struct bt_mesh_rpl **match) { + BT_DBG("%s, Src 0x%04x Seq %lu OldIV %u", + match ? "RPLOnlyCheck" : "RPLCheckAndStore", + rx->ctx.addr, rx->seq, rx->old_iv); + for (size_t i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) { struct bt_mesh_rpl *rpl = &bt_mesh.rpl[i]; + BT_DBG("RPL%u, Src 0x%04x Seq %lu OldIV %u", + i, rpl->src, rpl->seq, rpl->old_iv); + /* Empty slot */ if (rpl->src == BLE_MESH_ADDR_UNASSIGNED) { if (match) { @@ -50,6 +60,7 @@ static bool rpl_check_and_store(struct bt_mesh_net_rx *rx, struct bt_mesh_rpl ** /* Existing slot for given address */ if (rpl->src == rx->ctx.addr) { if (rx->old_iv && !rpl->old_iv) { + BT_DBG("DueToOldIV"); return true; } @@ -66,25 +77,30 @@ static bool rpl_check_and_store(struct bt_mesh_net_rx *rx, struct bt_mesh_rpl ** #if CONFIG_BLE_MESH_NOT_RELAY_REPLAY_MSG rx->replay_msg = 1; -#endif +#endif /* CONFIG_BLE_MESH_NOT_RELAY_REPLAY_MSG */ + BT_DBG("DueToSeq"); return true; } } - BT_ERR("RPL is full!"); + BT_ERR("RPLFull"); return true; } bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx, struct bt_mesh_rpl **match) { + BT_DBG("RPLCheck"); + /* Don't bother checking messages from ourselves */ if (rx->net_if == BLE_MESH_NET_IF_LOCAL) { + BT_DBG("LocalNetIf"); return false; } /* The RPL is used only for the local node */ if (!rx->local_match) { + BT_DBG("LocalNotMatch"); return false; } @@ -96,9 +112,14 @@ void bt_mesh_rpl_update(void) /* Discard "old old" IV Index entries from RPL and flag * any other ones (which are valid) as old. */ + BT_DBG("RPLUpdate"); + for (size_t i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) { struct bt_mesh_rpl *rpl = &bt_mesh.rpl[i]; + BT_DBG("RPL%u, Src 0x%04x Seq %lu OldIV %u", + i, rpl->src, rpl->seq, rpl->old_iv); + if (rpl->src) { if (rpl->old_iv) { (void)memset(rpl, 0, sizeof(*rpl)); @@ -115,6 +136,8 @@ void bt_mesh_rpl_update(void) void bt_mesh_rpl_reset_single(uint16_t src, bool erase) { + BT_DBG("RPLResetSingle, Src 0x%04x Erase %u", src, erase); + if (!BLE_MESH_ADDR_IS_UNICAST(src)) { return; } @@ -132,6 +155,8 @@ void bt_mesh_rpl_reset_single(uint16_t src, bool erase) void bt_mesh_rpl_reset(bool erase) { + BT_DBG("RPLReset, Erase %u", erase); + (void)memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl)); if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && erase) { diff --git a/components/bt/esp_ble_mesh/core/scan.c b/components/bt/esp_ble_mesh/core/scan.c index 4ddd2418d3cb..c709d9eaecd4 100644 --- a/components/bt/esp_ble_mesh/core/scan.c +++ b/components/bt/esp_ble_mesh/core/scan.c @@ -29,7 +29,7 @@ #if CONFIG_BLE_MESH_V11_SUPPORT #include "mesh_v1.1/utils.h" -#endif +#endif /* CONFIG_BLE_MESH_V11_SUPPORT */ /* Scan Window and Interval are equal for continuous scanning */ #define SCAN_INTERVAL 0x20 @@ -60,6 +60,11 @@ int bt_mesh_unprov_dev_fifo_dequeue(uint8_t *uuid, uint8_t *addr) { uint8_t idx = 0; + BT_DBG("UnprovDevFifoDequeue, PairNum %u StartIdx %u EndIdx %u", + unprov_dev_info_fifo.pair_num, + unprov_dev_info_fifo.start_idx, + unprov_dev_info_fifo.end_idx); + if (unprov_dev_info_fifo.pair_num == 0) { return 0; } @@ -84,9 +89,11 @@ int bt_mesh_unprov_dev_fifo_dequeue(uint8_t *uuid, uint8_t *addr) int bt_mesh_unprov_dev_info_query(uint8_t uuid[16], uint8_t addr[6], uint8_t *adv_type, uint8_t query_type) { + uint8_t pair_num = unprov_dev_info_fifo.pair_num; uint8_t idx = 0; uint8_t cnt = 0; - uint8_t pair_num = unprov_dev_info_fifo.pair_num; + + BT_DBG("UnprovDevInfoQuery, QueryType 0x%02x PairNum %u", query_type, pair_num); if (uuid == NULL && addr == NULL) { BT_WARN("No available information to query"); @@ -95,42 +102,49 @@ int bt_mesh_unprov_dev_info_query(uint8_t uuid[16], uint8_t addr[6], while (cnt < pair_num) { idx = (cnt + unprov_dev_info_fifo.start_idx) % BLE_MESH_STORE_UNPROV_INFO_MAX_NUM; + + BT_DBG("Count %u StartIdx %u Idx %u", cnt, unprov_dev_info_fifo.start_idx, idx); + if (query_type & BLE_MESH_STORE_UNPROV_INFO_QUERY_TYPE_UUID) { if (!memcmp(unprov_dev_info_fifo.info[idx].addr, addr, 6)) { if (query_type & BLE_MESH_STORE_UNPROV_INFO_QUERY_TYPE_EXISTS) { return 0; - } else { - memcpy(uuid, unprov_dev_info_fifo.info[idx].uuid, 16); - *adv_type = unprov_dev_info_fifo.info[idx].adv_type; - break; } + + memcpy(uuid, unprov_dev_info_fifo.info[idx].uuid, 16); + *adv_type = unprov_dev_info_fifo.info[idx].adv_type; + break; } } else { if (!memcmp(unprov_dev_info_fifo.info[idx].uuid, uuid, 16)) { if (query_type & BLE_MESH_STORE_UNPROV_INFO_QUERY_TYPE_EXISTS) { return 0; - } else { - memcpy(addr, unprov_dev_info_fifo.info[idx].addr, 6); - *adv_type = unprov_dev_info_fifo.info[idx].adv_type; - break; } + + memcpy(addr, unprov_dev_info_fifo.info[idx].addr, 6); + *adv_type = unprov_dev_info_fifo.info[idx].adv_type; + break; } } + cnt++; } if (cnt == pair_num) { + BT_DBG("Count == PairNum"); return -1; } return 0; - } int bt_mesh_unprov_dev_fifo_enqueue(uint8_t uuid[16], const uint8_t addr[6], uint8_t adv_type) { uint8_t idx = 0; + BT_DBG("UnprovDevFifoEnqueue, EndIdx %u PairNum %u", + unprov_dev_info_fifo.end_idx, unprov_dev_info_fifo.pair_num); + if (uuid == NULL || addr == NULL) { BT_ERR("Invalid argument %s", __func__); return -EINVAL; @@ -154,6 +168,9 @@ int bt_mesh_unprov_dev_fifo_enqueue(uint8_t uuid[16], const uint8_t addr[6], uin idx = (idx + 1) % BLE_MESH_STORE_UNPROV_INFO_MAX_NUM; unprov_dev_info_fifo.end_idx = idx; unprov_dev_info_fifo.pair_num++; + + BT_DBG("EndIdx %u PairNum %u", unprov_dev_info_fifo.end_idx, unprov_dev_info_fifo.pair_num); + return 0; } @@ -164,19 +181,22 @@ const bt_mesh_addr_t *bt_mesh_get_unprov_dev_addr(void) uint8_t bt_mesh_get_adv_type(void) { + BT_DBG("CurrentAdvType %u", current_adv_type); + return current_adv_type; } - #endif /* (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV) */ #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \ CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \ CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX || \ - (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT) + (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT) static bool adv_flags_valid(struct net_buf_simple *buf) { uint8_t flags = 0U; + BT_DBG("IsAdvFlagsValid"); + if (buf->len != 1U) { BT_DBG("Unexpected adv flags length %d", buf->len); return false; @@ -184,7 +204,7 @@ static bool adv_flags_valid(struct net_buf_simple *buf) flags = net_buf_simple_pull_u8(buf); - BT_DBG("Received adv pkt with flags: 0x%02x", flags); + BT_DBG("Flags 0x%02x", flags); /* Flags context will not be checked currently */ ARG_UNUSED(flags); @@ -194,6 +214,8 @@ static bool adv_flags_valid(struct net_buf_simple *buf) static bool adv_service_uuid_valid(struct net_buf_simple *buf, uint16_t *uuid) { + BT_DBG("IsAdvServiceUUIDValid"); + if (buf->len != 2U) { BT_DBG("Length not match mesh service uuid"); return false; @@ -201,40 +223,42 @@ static bool adv_service_uuid_valid(struct net_buf_simple *buf, uint16_t *uuid) *uuid = net_buf_simple_pull_le16(buf); - BT_DBG("Received adv pkt with service UUID: %d", *uuid); + BT_DBG("UUID 0x%04x", *uuid); if (*uuid != BLE_MESH_UUID_MESH_PROV_VAL && *uuid != BLE_MESH_UUID_MESH_PROXY_VAL && *uuid != BLE_MESH_UUID_MESH_PROXY_SOLIC_VAL) { + BT_DBG("UnexpectMeshUUID"); return false; } - /** - * @brief In remote provisioning. - * A Node could handle the unprovisioned beacon. + /* In remote provisioning, Node could handle unprovisioned device beacon. * CASE: MESH/SR/RPR/SCN/BV-01-C - */ + */ #if CONFIG_BLE_MESH_RPR_SRV if (*uuid == BLE_MESH_UUID_MESH_PROV_VAL && !IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) { + BT_DBG("IgnorePBGattUUID"); return false; } -#else +#else /* CONFIG_BLE_MESH_RPR_SRV */ if (*uuid == BLE_MESH_UUID_MESH_PROV_VAL && (bt_mesh_is_provisioner_en() == false || !IS_ENABLED(CONFIG_BLE_MESH_PB_GATT))) { + BT_DBG("IgnorePBGattUUID"); return false; } -#endif - +#endif /* CONFIG_BLE_MESH_RPR_SRV */ if (*uuid == BLE_MESH_UUID_MESH_PROXY_VAL && !IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)) { + BT_DBG("IgnoreProxyUUID"); return false; } if (*uuid == BLE_MESH_UUID_MESH_PROXY_SOLIC_VAL && !IS_ENABLED(CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX)) { + BT_DBG("IgnoreProxySolicUUID"); return false; } @@ -247,6 +271,8 @@ static void handle_adv_service_data(struct net_buf_simple *buf, { uint16_t type = 0U; + BT_DBG("HandleAdvServiceData, UUID 0x%04x", uuid); + if (!buf || !addr) { BT_ERR("%s, Invalid parameter", __func__); return; @@ -254,7 +280,7 @@ static void handle_adv_service_data(struct net_buf_simple *buf, type = net_buf_simple_pull_le16(buf); if (type != uuid) { - BT_DBG("Invalid Mesh Service Data UUID 0x%04x", type); + BT_DBG("UnexpectMeshUUID 0x%04x", type); return; } @@ -276,8 +302,13 @@ static void handle_adv_service_data(struct net_buf_simple *buf, #if CONFIG_BLE_MESH_RPR_SRV if (bt_mesh_is_provisioned()) { - const bt_mesh_addr_t *addr = bt_mesh_get_unprov_dev_addr(); + const bt_mesh_addr_t *addr = NULL; + + addr = bt_mesh_get_unprov_dev_addr(); + assert(addr); + bt_mesh_unprov_dev_fifo_enqueue(buf->data, addr->val, bt_mesh_get_adv_type()); + bt_mesh_rpr_srv_unprov_beacon_recv(buf, bt_mesh_get_adv_type(), addr, rssi); } #endif /* CONFIG_BLE_MESH_RPR_SRV */ @@ -300,7 +331,8 @@ static void handle_adv_service_data(struct net_buf_simple *buf, BT_DBG("Start to handle Mesh Proxy Service Data"); bt_mesh_proxy_client_gatt_adv_recv(buf, addr, rssi); break; -#endif +#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */ + #if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX case BLE_MESH_UUID_MESH_PROXY_SOLIC_VAL: if (buf->len != (1 + BLE_MESH_NET_HDR_LEN + 8)) { @@ -311,7 +343,8 @@ static void handle_adv_service_data(struct net_buf_simple *buf, BT_DBG("Start to handle Mesh Proxy Solic Service Data"); bt_mesh_proxy_server_solic_recv(buf, addr, rssi); break; -#endif +#endif /* CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX */ + default: break; } @@ -326,6 +359,8 @@ static bool ble_scan_en; int bt_mesh_start_ble_scan(struct bt_mesh_ble_scan_param *param) { + BT_DBG("StartBLEScan"); + if (ble_scan_en == true) { BT_WARN("%s, Already", __func__); return -EALREADY; @@ -338,6 +373,8 @@ int bt_mesh_start_ble_scan(struct bt_mesh_ble_scan_param *param) int bt_mesh_stop_ble_scan(void) { + BT_DBG("StopBLEScan"); + if (ble_scan_en == false) { BT_WARN("%s, Already", __func__); return -EALREADY; @@ -353,6 +390,7 @@ static void inline callback_ble_adv_pkt(const bt_mesh_addr_t *addr, uint16_t length, int8_t rssi) { if (ble_scan_en) { + BT_DBG("CallbackBLEAdvPkt, AdvType 0x%02x Len %u", adv_type, length); bt_mesh_ble_scan_cb_evt_to_btc(addr, adv_type, data, length, rssi); } } @@ -365,6 +403,8 @@ static bool rpr_ext_scan_handle_adv_pkt(const bt_mesh_addr_t *addr, struct net_buf_simple buf = {0}; bool rpr_adv = false; + BT_DBG("RPRExtScanHandleAdvPkt, Provisioned %u", bt_mesh_is_provisioned()); + if (bt_mesh_is_provisioned() == false) { return false; } @@ -382,15 +422,15 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, uint8_t scan_rsp_len) { #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \ - CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \ + CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \ CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX || \ - (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT) + (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT) uint16_t uuid = 0U; #endif #if (CONFIG_BLE_MESH_RPR_SRV || CONFIG_BLE_MESH_SUPPORT_BLE_SCAN) uint8_t *adv_data = buf->data; uint16_t adv_len = buf->len; -#endif +#endif /* (CONFIG_BLE_MESH_RPR_SRV || CONFIG_BLE_MESH_SUPPORT_BLE_SCAN) */ if (adv_type != BLE_MESH_ADV_NONCONN_IND && adv_type != BLE_MESH_ADV_IND) { #if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN @@ -399,7 +439,8 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, return; } - BT_DBG("scan, len %u: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("MeshScan"); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); #if (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV) unprov_dev_addr = addr; @@ -411,6 +452,7 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, uint8_t len, type; len = net_buf_simple_pull_u8(buf); + /* Check for early termination */ if (len == 0U) { #if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN @@ -420,7 +462,8 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, } if (len > buf->len) { - BT_DBG("AD malformed"); + BT_DBG("MalformedAD"); + #if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi); #endif @@ -443,35 +486,42 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, case BLE_MESH_DATA_MESH_MESSAGE: bt_mesh_net_recv(buf, rssi, BLE_MESH_NET_IF_ADV); break; + #if CONFIG_BLE_MESH_PB_ADV case BLE_MESH_DATA_MESH_PROV: if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node()) { bt_mesh_pb_adv_recv(buf); } + if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en()) { bt_mesh_provisioner_pb_adv_recv(buf); } break; #endif /* CONFIG_BLE_MESH_PB_ADV */ + case BLE_MESH_DATA_MESH_BEACON: bt_mesh_beacon_recv(buf, rssi); break; + #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \ CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \ CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX || \ - (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT) + (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT) case BLE_MESH_DATA_FLAGS: if (!adv_flags_valid(buf)) { BT_DBG("Adv Flags mismatch, ignore this adv pkt"); + #if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi); #endif return; } break; + case BLE_MESH_DATA_UUID16_ALL: if (!adv_service_uuid_valid(buf, &uuid)) { BT_DBG("Adv Service UUID mismatch, ignore this adv pkt"); + #if CONFIG_BLE_MESH_RPR_SRV if (rpr_ext_scan_handle_adv_pkt(addr, adv_data, adv_len)) { /* If handled as extended scan report successfully, then not @@ -479,17 +529,23 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, */ return; } -#endif +#endif /* CONFIG_BLE_MESH_RPR_SRV */ + #if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi); #endif return; } break; + case BLE_MESH_DATA_SVC_DATA16: handle_adv_service_data(buf, addr, uuid, rssi); break; -#endif +#endif /* (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \ + CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \ + CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX || \ + (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT) */ + default: #if CONFIG_BLE_MESH_RPR_SRV if (rpr_ext_scan_handle_adv_pkt(addr, adv_data, adv_len)) { @@ -498,7 +554,8 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, */ return; } -#endif +#endif /* CONFIG_BLE_MESH_RPR_SRV */ + #if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi); #endif @@ -538,9 +595,11 @@ int bt_mesh_scan_enable(void) .scan_fil_policy = BLE_MESH_SP_ADV_ALL, }; + BT_DBG("ScanEnable"); + err = bt_le_scan_start(&scan_param, bt_mesh_scan_cb); if (err && err != -EALREADY) { - BT_ERR("starting scan failed (err %d)", err); + BT_ERR("StartScanFailed, Err %d", err); return err; } @@ -551,9 +610,11 @@ int bt_mesh_scan_disable(void) { int err = 0; + BT_DBG("ScanDisable"); + err = bt_le_scan_stop(); if (err && err != -EALREADY) { - BT_ERR("stopping scan failed (err %d)", err); + BT_ERR("StopScanFailed, Err %d", err); return err; } @@ -563,23 +624,24 @@ int bt_mesh_scan_disable(void) #if CONFIG_BLE_MESH_TEST_USE_WHITE_LIST int bt_mesh_scan_with_wl_enable(void) { - int err = 0; - struct bt_mesh_scan_param scan_param = { .type = BLE_MESH_SCAN_PASSIVE, #if CONFIG_BLE_MESH_USE_DUPLICATE_SCAN .filter_dup = BLE_MESH_SCAN_FILTER_DUP_ENABLE, -#else +#else /* CONFIG_BLE_MESH_USE_DUPLICATE_SCAN */ .filter_dup = BLE_MESH_SCAN_FILTER_DUP_DISABLE, -#endif +#endif /* CONFIG_BLE_MESH_USE_DUPLICATE_SCAN */ .interval = SCAN_INTERVAL, .window = SCAN_WINDOW, .scan_fil_policy = BLE_MESH_SP_ADV_WL, }; + int err = 0; + + BT_DBG("ScanWithWLEnable"); err = bt_le_scan_start(&scan_param, bt_mesh_scan_cb); if (err && err != -EALREADY) { - BT_ERR("starting scan failed (err %d)", err); + BT_ERR("StartScanFailed, Err %d", err); return err; } diff --git a/components/bt/esp_ble_mesh/core/storage/settings.c b/components/bt/esp_ble_mesh/core/storage/settings.c index 40cf117f2e06..5aa4c3fee5c9 100644 --- a/components/bt/esp_ble_mesh/core/storage/settings.c +++ b/components/bt/esp_ble_mesh/core/storage/settings.c @@ -1,6 +1,6 @@ /* * SPDX-FileCopyrightText: 2018 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,7 +24,7 @@ #if CONFIG_BLE_MESH_V11_SUPPORT #include "mesh_v1.1/utils.h" -#endif +#endif /* CONFIG_BLE_MESH_V11_SUPPORT */ /* BLE Mesh NVS Key and corresponding data struct. * Note: The length of nvs key must be <= 15. @@ -207,6 +207,8 @@ static int role_set(const char *name) bool exist = false; int err = 0; + BT_DBG("RoleSet, Name %s", name); + err = bt_mesh_load_core_settings(name, (uint8_t *)bt_mesh.flags, sizeof(bt_mesh.flags), &exist); if (err) { BT_ERR("Failed to load mesh device role"); @@ -219,9 +221,9 @@ static int role_set(const char *name) !IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER)) { bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_NODE); } -#else +#else /* CONFIG_BLE_MESH_SETTINGS_BACKWARD_COMPATIBILITY */ return 0; -#endif +#endif /* CONFIG_BLE_MESH_SETTINGS_BACKWARD_COMPATIBILITY */ } return 0; @@ -233,6 +235,8 @@ static int net_set(const char *name) bool exist = false; int err = 0; + BT_DBG("NetSet, Name %s", name); + err = bt_mesh_load_core_settings(name, (uint8_t *)&net, sizeof(net), &exist); if (err) { BT_ERR("Failed to load node net info"); @@ -259,6 +263,8 @@ static int dkca_set(const char *name) bool exist = false; int err = 0; + BT_DBG("DkcaSet, Name %s", name); + err = bt_mesh_load_core_settings(name, bt_mesh.dev_key_ca, sizeof(bt_mesh.dev_key_ca), &exist); if (err) { BT_ERR("Failed to load DevKey Candidate"); @@ -280,6 +286,8 @@ static int iv_set(const char *name) bool exist = false; int err = 0; + BT_DBG("IVSet, Name %s", name); + err = bt_mesh_load_core_settings(name, (uint8_t *)&iv, sizeof(iv), &exist); if (err) { BT_ERR("Failed to load iv_index"); @@ -297,7 +305,7 @@ static int iv_set(const char *name) bt_mesh.ivu_duration = iv.iv_duration; BT_INFO("Restored IV Index 0x%08x (IV Update Flag %u) duration %u hours", - iv.iv_index, iv.iv_update, iv.iv_duration); + iv.iv_index, iv.iv_update, iv.iv_duration); return 0; } @@ -308,6 +316,8 @@ static int seq_set(const char *name) bool exist = false; int err = 0; + BT_DBG("SeqSet, Name %s", name); + err = bt_mesh_load_core_settings(name, (uint8_t *)&seq, sizeof(seq), &exist); if (err) { BT_ERR("Failed to load sequence number"); @@ -329,7 +339,7 @@ static int seq_set(const char *name) bt_mesh.seq += (CONFIG_BLE_MESH_SEQ_STORE_RATE - (bt_mesh.seq % CONFIG_BLE_MESH_SEQ_STORE_RATE)); bt_mesh.seq--; -#endif +#endif /* CONFIG_BLE_MESH_SEQ_STORE_RATE > 0 */ BT_INFO("Restored Sequence Number 0x%06x", bt_mesh.seq); @@ -340,6 +350,8 @@ static struct bt_mesh_rpl *rpl_find(uint16_t src) { int i; + BT_DBG("RPLFind, Src 0x%04x", src); + for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) { if (bt_mesh.rpl[i].src == src) { return &bt_mesh.rpl[i]; @@ -353,6 +365,8 @@ static struct bt_mesh_rpl *rpl_alloc(uint16_t src) { int i; + BT_DBG("RPLAlloc, Src 0x%04x", src); + for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) { if (bt_mesh.rpl[i].src == BLE_MESH_ADDR_UNASSIGNED) { bt_mesh.rpl[i].src = src; @@ -374,6 +388,8 @@ static int rpl_set(const char *name) int err = 0; int i; + BT_DBG("RPLSet, Name %s", name); + buf = bt_mesh_get_core_settings_item(name); if (!buf) { return 0; @@ -427,6 +443,8 @@ static struct bt_mesh_subnet *subnet_exist(uint16_t net_idx) { int i; + BT_DBG("SubnetExist, NetIdx 0x%04x", net_idx); + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { if (bt_mesh.sub[i].net_idx == net_idx) { return &bt_mesh.sub[i]; @@ -440,6 +458,8 @@ static struct bt_mesh_subnet *subnet_alloc(uint16_t net_idx) { int i; + BT_DBG("SubnetAlloc, NetIdx 0x%04x", net_idx); + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { if (bt_mesh.sub[i].net_idx == BLE_MESH_KEY_UNUSED) { bt_mesh.sub[i].net_idx = net_idx; @@ -454,6 +474,8 @@ static struct bt_mesh_app_key *appkey_exist(uint16_t app_idx) { int i; + BT_DBG("AppKeyExist, AppIdx 0x%04x", app_idx); + for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { if (bt_mesh.app_keys[i].net_idx != BLE_MESH_KEY_UNUSED && bt_mesh.app_keys[i].app_idx == app_idx) { @@ -475,6 +497,8 @@ static int net_key_set(const char *name) int err = 0; int i; + BT_DBG("NetKeySet, Name %s", name); + buf = bt_mesh_get_core_settings_item(name); if (!buf) { return 0; @@ -533,6 +557,8 @@ static int app_key_set(const char *name) int err = 0; int i; + BT_DBG("AppKeySet, Name %s", name); + buf = bt_mesh_get_core_settings_item(name); if (!buf) { return 0; @@ -564,7 +590,6 @@ static int app_key_set(const char *name) if (!app) { app = bt_mesh_app_key_alloc(app_idx); if (!app) { - BT_ERR("No space for a new appkey 0x%03x", app_idx); err = -ENOMEM; goto free; } @@ -579,7 +604,7 @@ static int app_key_set(const char *name) bt_mesh_app_id(app->keys[1].val, &app->keys[1].id); BT_INFO("Restored AppKeyIndex 0x%03x, NetKeyIndex 0x%03x", - app->app_idx, app->net_idx); + app->app_idx, app->net_idx); BT_INFO("Restored AppKey %s", bt_hex(app->keys[0].val, 16)); } @@ -595,6 +620,8 @@ static int hb_pub_set(const char *name) bool exist = false; int err = 0; + BT_DBG("HbPubSet, Name %s", name); + if (!hb_pub) { BT_ERR("Invalid heartbeat publication"); return -EINVAL; @@ -639,6 +666,8 @@ static int cfg_set(const char *name) bool exist = false; int err = 0; + BT_DBG("CfgSet, Name %s", name); + if (!cfg) { BT_ERR("Invalid configuration"); stored_cfg.valid = false; @@ -672,6 +701,8 @@ static int model_set_bind(bool vnd, struct bt_mesh_model *model, uint16_t model_ int err = 0; int i; + BT_DBG("ModelSetBind, Key 0x%04x Vnd %u", model_key, vnd); + /* Start with empty array regardless of cleared or set value */ for (i = 0; i < ARRAY_SIZE(model->keys); i++) { model->keys[i] = BLE_MESH_KEY_UNUSED; @@ -698,6 +729,8 @@ static int model_set_sub(bool vnd, struct bt_mesh_model *model, uint16_t model_k int err = 0; int i; + BT_DBG("ModelSetSub, Key 0x%04x Vnd %u", model_key, vnd); + /* Start with empty array regardless of cleared or set value */ for (i = 0; i < ARRAY_SIZE(model->groups); i++) { model->groups[i] = BLE_MESH_ADDR_UNASSIGNED; @@ -724,6 +757,8 @@ static int model_set_pub(bool vnd, struct bt_mesh_model *model, uint16_t model_k bool exist = false; int err = 0; + BT_DBG("ModelSetPub, Key 0x%04x Vnd %u", model_key, vnd); + if (!model->pub) { BT_INFO("Not support publication, model_id 0x%04x, cid 0x%04x", vnd ? model->vnd.id : model->id, vnd ? model->vnd.company : 0xFFFF); @@ -774,6 +809,8 @@ static int model_set(bool vnd, const char *name) size_t length = 0U; int i; + BT_DBG("ModelSet, Name %s Vnd %u", name, vnd); + buf = bt_mesh_get_core_settings_item(name); if (!buf) { return 0; @@ -790,7 +827,7 @@ static int model_set(bool vnd, const char *name) model = bt_mesh_model_get(vnd, elem_idx, model_idx); if (!model) { BT_ERR("%s model not found, elem_idx %u, model_idx %u", - vnd ? "vnd" : "sig", elem_idx, model_idx); + vnd ? "vnd" : "sig", elem_idx, model_idx); continue; } @@ -825,6 +862,8 @@ static int va_set(const char *name) int err = 0; int i; + BT_DBG("VaSet, Name %s", name); + buf = bt_mesh_get_core_settings_item(name); if (!buf) { return 0; @@ -869,7 +908,7 @@ static int va_set(const char *name) bt_mesh_free_buf(buf); return err; } -#endif +#endif /* CONFIG_BLE_MESH_LABEL_COUNT > 0 */ #if CONFIG_BLE_MESH_PROVISIONER static int p_prov_set(const char *name) @@ -878,6 +917,8 @@ static int p_prov_set(const char *name) bool exist = false; int err = 0; + BT_DBG("PvnrProvSet, Name %s", name); + err = bt_mesh_load_core_settings(name, (uint8_t *)&val, sizeof(val), &exist); if (err) { BT_ERR("Failed to load next address allocation"); @@ -891,7 +932,7 @@ static int p_prov_set(const char *name) bt_mesh_provisioner_restore_prov_info(val.primary_addr, val.alloc_addr); BT_INFO("Restored Primary Address 0x%04x, next address alloc 0x%04x", - val.primary_addr, val.alloc_addr); + val.primary_addr, val.alloc_addr); return 0; } @@ -902,6 +943,8 @@ static int p_net_idx_set(const char *name) bool exist = false; int err = 0; + BT_DBG("PvnrNetIdxSet, Name %s", name); + err = bt_mesh_load_core_settings(name, (uint8_t *)&net_idx, sizeof(net_idx), &exist); if (err) { BT_ERR("Failed to load next NetKeyIndex alloc"); @@ -925,6 +968,8 @@ static int p_app_idx_set(const char *name) bool exist = false; int err = 0; + BT_DBG("PvnrAppIdxSet, Name %s", name); + err = bt_mesh_load_core_settings(name, (uint8_t *)&app_idx, sizeof(app_idx), &exist); if (err) { BT_ERR("Failed to load next AppKeyIndex alloc"); @@ -946,6 +991,8 @@ static struct bt_mesh_subnet *p_subnet_exist(uint16_t net_idx) { int i; + BT_DBG("PvnrSubnetExist, NetIdx 0x%04x", net_idx); + for (i = 0; i < ARRAY_SIZE(bt_mesh.p_sub); i++) { if (bt_mesh.p_sub[i] && bt_mesh.p_sub[i]->net_idx == net_idx) { @@ -960,6 +1007,8 @@ static struct bt_mesh_subnet *p_subnet_alloc(void) { int i; + BT_DBG("PvnrSubnetAlloc"); + for (i = 0; i < ARRAY_SIZE(bt_mesh.p_sub); i++) { if (bt_mesh.p_sub[i] == NULL) { bt_mesh.p_sub[i] = bt_mesh_calloc(sizeof(struct bt_mesh_subnet)); @@ -979,6 +1028,8 @@ static struct bt_mesh_app_key *p_appkey_exist(uint16_t app_idx) { int i; + BT_DBG("PvnrAppKeyExist, AppIdx 0x%04x", app_idx); + for (i = 0; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) { if (bt_mesh.p_app_keys[i] && bt_mesh.p_app_keys[i]->net_idx != BLE_MESH_KEY_UNUSED && @@ -994,6 +1045,8 @@ static struct bt_mesh_app_key *p_appkey_alloc(void) { int i; + BT_DBG("PvnrAppKeyAlloc"); + for (i = 0; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) { if (bt_mesh.p_app_keys[i] == NULL) { bt_mesh.p_app_keys[i] = bt_mesh_calloc(sizeof(struct bt_mesh_app_key)); @@ -1020,6 +1073,8 @@ static int p_net_key_set(const char *name) int err = 0; int i; + BT_DBG("PvnrNetKeySet, Name %s", name); + buf = bt_mesh_get_core_settings_item(name); if (!buf) { return 0; @@ -1078,6 +1133,8 @@ static int p_app_key_set(const char *name) int err = 0; int i; + BT_DBG("PvnrAppKeySet, Name %s", name); + buf = bt_mesh_get_core_settings_item(name); if (!buf) { return 0; @@ -1124,7 +1181,7 @@ static int p_app_key_set(const char *name) bt_mesh_app_id(app->keys[1].val, &app->keys[1].id); BT_INFO("Restored AppKeyIndex 0x%03x, NetKeyIndex 0x%03x", - app->app_idx, app->net_idx); + app->app_idx, app->net_idx); BT_INFO("Restored AppKey %s", bt_hex(app->keys[0].val, 16)); } @@ -1140,6 +1197,8 @@ static int node_info_set(uint16_t addr, bool *exist) char get[16] = {'\0'}; int err = 0; + BT_DBG("NodeInfoSet, Addr 0x%04x", addr); + sprintf(get, "mesh/pn/%04x/i", addr); err = bt_mesh_load_core_settings(get, (uint8_t *)&info, sizeof(info), exist); if (err) { @@ -1180,6 +1239,8 @@ static int node_name_set(uint16_t addr) bool exist = false; int err = 0; + BT_DBG("NodeNameSet, Addr 0x%04x", addr); + sprintf(get, "mesh/pn/%04x/n", addr); err = bt_mesh_load_core_settings(get, (uint8_t *)name, BLE_MESH_NODE_NAME_SIZE, &exist); if (err) { @@ -1208,6 +1269,8 @@ static int node_comp_data_set(uint16_t addr) char get[16] = {'\0'}; int err = 0; + BT_DBG("NodeCompDataSet, Addr 0x%04x", addr); + sprintf(get, "mesh/pn/%04x/c", addr); buf = bt_mesh_get_core_settings_item(get); if (!buf) { @@ -1232,6 +1295,8 @@ static int p_node_set(const char *name) size_t length = 0U; int i; + BT_DBG("PvnrNodeSet, Name %s", name); + buf = bt_mesh_get_core_settings_item(name); if (!buf) { return 0; @@ -1286,7 +1351,7 @@ const struct bt_mesh_setting { { "mesh/vnd", vnd_mod_set }, /* For Node & Provisioner */ #if CONFIG_BLE_MESH_LABEL_COUNT > 0 { "mesh/vaddr", va_set }, /* For Node */ -#endif +#endif /* CONFIG_BLE_MESH_LABEL_COUNT > 0 */ #if CONFIG_BLE_MESH_PROVISIONER { "mesh/p_prov", p_prov_set }, /* For Provisioner */ { "mesh/p_netidx", p_net_idx_set }, /* For Provisioner */ @@ -1294,7 +1359,7 @@ const struct bt_mesh_setting { { "mesh/p_netkey", p_net_key_set }, /* For Provisioner */ { "mesh/p_appkey", p_app_key_set }, /* For Provisioner */ { "mesh/p_node", p_node_set }, /* For Provisioner */ -#endif +#endif /* CONFIG_BLE_MESH_PROVISIONER */ }; /** @@ -1316,6 +1381,8 @@ int settings_core_load(void) { int i; + BT_DBG("SettingsCoreLoad"); + for (i = 0; i < ARRAY_SIZE(settings); i++) { if ((!strcmp(settings[i].name, "mesh/net") || !strcmp(settings[i].name, "mesh/netkey") || @@ -1367,6 +1434,8 @@ static int subnet_init(struct bt_mesh_subnet *sub) { int err = 0; + BT_DBG("SubnetInit, NetIdx 0x%04x KrPhase %u", sub->net_idx, sub->kr_phase); + err = bt_mesh_net_keys_create(&sub->keys[0], sub->keys[0].net); if (err) { BT_ERR("Unable to generate keys for subnet"); @@ -1394,7 +1463,7 @@ static int subnet_init(struct bt_mesh_subnet *sub) #if CONFIG_BLE_MESH_DF_SRV bt_mesh_directed_forwarding_sub_init(sub); bt_mesh_recovery_directed_forwarding_table(sub); -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ return 0; } @@ -1402,8 +1471,10 @@ static int subnet_init(struct bt_mesh_subnet *sub) static void commit_model(struct bt_mesh_model *model, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { + BT_DBG("CommitModel, Vnd %u Primary %u", vnd, primary); + if (model->pub && model->pub->update && - model->pub->addr != BLE_MESH_ADDR_UNASSIGNED) { + model->pub->addr != BLE_MESH_ADDR_UNASSIGNED) { int32_t ms = bt_mesh_model_pub_period_get(model); if (ms) { BT_DBG("Starting publish timer (period %u ms)", ms); @@ -1418,10 +1489,13 @@ int settings_core_commit(void) int err = 0; int i; + BT_DBG("SettingsCoreCommit"); + #if CONFIG_BLE_MESH_NODE if (bt_mesh_is_node()) { if (bt_mesh.sub[0].net_idx == BLE_MESH_KEY_UNUSED) { /* Nothing to do since we're not yet provisioned */ + BT_INFO("NodeNotYetProvisioned"); return 0; } @@ -1511,20 +1585,22 @@ int settings_core_commit(void) } /* Pending flags that use K_NO_WAIT as the storage timeout */ -#define NO_WAIT_PENDING_BITS (BIT(BLE_MESH_NET_PENDING) | \ - BIT(BLE_MESH_IV_PENDING) | \ - BIT(BLE_MESH_SEQ_PENDING)) +#define NO_WAIT_PENDING_BITS (BIT(BLE_MESH_NET_PENDING) | \ + BIT(BLE_MESH_IV_PENDING) | \ + BIT(BLE_MESH_SEQ_PENDING)) /* Pending flags that use CONFIG_BLE_MESH_STORE_TIMEOUT */ -#define GENERIC_PENDING_BITS (BIT(BLE_MESH_KEYS_PENDING) | \ - BIT(BLE_MESH_HB_PUB_PENDING) | \ - BIT(BLE_MESH_CFG_PENDING) | \ - BIT(BLE_MESH_MOD_PENDING)) +#define GENERIC_PENDING_BITS (BIT(BLE_MESH_KEYS_PENDING) | \ + BIT(BLE_MESH_HB_PUB_PENDING) | \ + BIT(BLE_MESH_CFG_PENDING) | \ + BIT(BLE_MESH_MOD_PENDING)) static void schedule_store(int flag) { int32_t timeout = 0, remaining = 0; + BT_DBG("ScheduleStore, Flag %ld", flag); + bt_mesh_atomic_set_bit(bt_mesh.flags, flag); /* When Node is not provisioned OR Provisioner is disabled, @@ -1562,7 +1638,8 @@ static void schedule_store(int flag) static void clear_net(void) { - BT_DBG("Clearing Network"); + BT_DBG("ClearNet"); + bt_mesh_erase_core_settings("mesh/net"); } @@ -1570,8 +1647,9 @@ static void store_pending_net(void) { struct net_val net = {0}; - BT_DBG("Primary address 0x%04x DevKey %s", bt_mesh_primary_addr(), - bt_hex(bt_mesh.dev_key, 16)); + BT_DBG("StorePendingNet"); + BT_DBG("PrimaryAddr 0x%04x DevKey %s", + bt_mesh_primary_addr(), bt_hex(bt_mesh.dev_key, 16)); net.primary_addr = bt_mesh_primary_addr(); memcpy(net.dev_key, bt_mesh.dev_key, 16); @@ -1581,13 +1659,15 @@ static void store_pending_net(void) void bt_mesh_store_role(void) { - BT_DBG("Store, device role %lu", bt_mesh_atomic_get(bt_mesh.flags) & BLE_MESH_SETTINGS_ROLE_BIT_MASK); + BT_DBG("StoreRole %lu", bt_mesh_atomic_get(bt_mesh.flags) & BLE_MESH_SETTINGS_ROLE_BIT_MASK); bt_mesh_save_core_settings("mesh/role", (const uint8_t *)bt_mesh.flags, sizeof(bt_mesh.flags)); } void bt_mesh_store_net(void) { + BT_DBG("StoreNetSchedule"); + schedule_store(BLE_MESH_NET_PENDING); } @@ -1595,6 +1675,8 @@ static void store_pending_iv(void) { struct iv_val iv = {0}; + BT_DBG("StorePendingIV"); + iv.iv_index = bt_mesh.iv_index; iv.iv_update = bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS); iv.iv_duration = bt_mesh.ivu_duration; @@ -1604,6 +1686,8 @@ static void store_pending_iv(void) void bt_mesh_store_iv(bool only_duration) { + BT_DBG("StoreIVSchedule, OnlyDuration %u", only_duration); + schedule_store(BLE_MESH_IV_PENDING); if (!only_duration) { @@ -1614,7 +1698,8 @@ void bt_mesh_store_iv(bool only_duration) static void clear_iv(void) { - BT_DBG("Clearing IV"); + BT_DBG("ClearIV"); + bt_mesh_erase_core_settings("mesh/iv"); } @@ -1622,6 +1707,8 @@ static void store_pending_seq(void) { struct seq_val seq = {0}; + BT_DBG("StorePendingSeq, Seq 0x%06x", bt_mesh.seq); + sys_put_le24(bt_mesh.seq, seq.val); bt_mesh_save_core_settings("mesh/seq", (const uint8_t *)&seq, sizeof(seq)); @@ -1629,6 +1716,8 @@ static void store_pending_seq(void) void bt_mesh_store_seq(void) { + BT_DBG("StoreSeqSchedule, Seq 0x%06x", bt_mesh.seq); + if (CONFIG_BLE_MESH_SEQ_STORE_RATE && (bt_mesh.seq % CONFIG_BLE_MESH_SEQ_STORE_RATE)) { return; @@ -1639,7 +1728,8 @@ void bt_mesh_store_seq(void) void bt_mesh_clear_seq(void) { - BT_DBG("Clearing Seq"); + BT_DBG("ClearSeq"); + bt_mesh_erase_core_settings("mesh/seq"); } @@ -1649,7 +1739,8 @@ static void store_rpl(struct bt_mesh_rpl *entry) char name[16] = {'\0'}; int err = 0; - BT_DBG("src 0x%04x seq 0x%06x old_iv %u", entry->src, entry->seq, entry->old_iv); + BT_DBG("StoreRPL"); + BT_DBG("Src 0x%04x Seq 0x%06x OldIV %u", entry->src, entry->seq, entry->old_iv); rpl.seq = entry->seq; rpl.old_iv = entry->old_iv; @@ -1675,6 +1766,8 @@ static void clear_rpl(void) uint16_t src = 0U; int i; + BT_DBG("ClearRPL"); + buf = bt_mesh_get_core_settings_item("mesh/rpl"); if (!buf) { bt_mesh_erase_core_settings("mesh/rpl"); @@ -1704,9 +1797,14 @@ static void store_pending_rpl(void) { int i; + BT_DBG("StorePendingRPL"); + for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) { struct bt_mesh_rpl *rpl = &bt_mesh.rpl[i]; + BT_DBG("%u: Src 0x%04x Seq 0x%06x OldIV %u Store %u", + i, rpl->src, rpl->seq, rpl->old_iv, rpl->store); + if (rpl->store) { rpl->store = false; store_rpl(rpl); @@ -1719,6 +1817,8 @@ static void store_pending_hb_pub(void) struct bt_mesh_hb_pub *hb_pub = bt_mesh_hb_pub_get(); struct hb_pub_val val = {0}; + BT_DBG("StorePendingHbPub"); + if (!hb_pub) { BT_ERR("Invalid heartbeat publication"); return; @@ -1736,7 +1836,8 @@ static void store_pending_hb_pub(void) static void clear_hb_pub(void) { - BT_DBG("Clear heartbeat publication"); + BT_DBG("ClearHbPub"); + bt_mesh_erase_core_settings("mesh/hb_pub"); } @@ -1745,6 +1846,8 @@ static void store_pending_cfg(void) struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get(); struct cfg_val val = {0}; + BT_DBG("StorePendingCfg"); + if (!cfg) { BT_WARN("NULL configuration state"); return; @@ -1763,7 +1866,8 @@ static void store_pending_cfg(void) static void clear_cfg(void) { - BT_DBG("Clearing configuration"); + BT_DBG("ClearCfg"); + bt_mesh_erase_core_settings("mesh/cfg"); } @@ -1772,7 +1876,7 @@ static void clear_app_key(uint16_t app_idx) char name[16] = {'\0'}; int err = 0; - BT_DBG("AppKeyIndex 0x%03x", app_idx); + BT_DBG("ClearAppKey, AppIdx 0x%04x", app_idx); sprintf(name, "mesh/ak/%04x", app_idx); bt_mesh_erase_core_settings(name); @@ -1788,7 +1892,7 @@ static void clear_net_key(uint16_t net_idx) char name[16] = {'\0'}; int err = 0; - BT_DBG("NetKeyIndex 0x%03x", net_idx); + BT_DBG("ClearNetKey, NetIdx 0x%04x", net_idx); sprintf(name, "mesh/nk/%04x", net_idx); bt_mesh_erase_core_settings(name); @@ -1800,7 +1904,7 @@ static void clear_net_key(uint16_t net_idx) #if CONFIG_BLE_MESH_DF_SRV bt_mesh_clear_directed_forwarding_table_data(net_idx); -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ } static void store_net_key(struct bt_mesh_subnet *sub) @@ -1809,8 +1913,8 @@ static void store_net_key(struct bt_mesh_subnet *sub) char name[16] = {'\0'}; int err = 0; - BT_DBG("NetKeyIndex 0x%03x NetKey %s", sub->net_idx, - bt_hex(sub->keys[0].net, 16)); + BT_DBG("StoreNetKey, NetIdx 0x%04x KrFlag %u KrPhase %u", + sub->net_idx, sub->kr_flag, sub->kr_phase); memcpy(&key.val[0], sub->keys[0].net, 16); memcpy(&key.val[1], sub->keys[1].net, 16); @@ -1836,6 +1940,9 @@ static void store_app_key(struct bt_mesh_app_key *app) char name[16] = {'\0'}; int err = 0; + BT_DBG("StoreAppKey, NetIdx 0x%04x AppIdx 0x%04x Updated %u", + app->net_idx, app->app_idx, app->updated); + key.net_idx = app->net_idx; key.updated = app->updated; memcpy(key.val[0], app->keys[0].val, 16); @@ -1858,9 +1965,14 @@ static void store_pending_keys(void) { int i; + BT_DBG("StorePendingKeys"); + for (i = 0; i < ARRAY_SIZE(key_updates); i++) { struct key_update *update = &key_updates[i]; + BT_DBG("%u: KeyIdx 0x%04x Valid %u AppKey %u Clear %u", + i, update->key_idx, update->valid, update->app_key, update->clear); + if (!update->valid) { continue; } @@ -1874,6 +1986,7 @@ static void store_pending_keys(void) } else { if (update->app_key) { struct bt_mesh_app_key *key = NULL; + key = bt_mesh_app_key_get(update->key_idx); if (key) { store_app_key(key); @@ -1882,6 +1995,7 @@ static void store_pending_keys(void) } } else { struct bt_mesh_subnet *sub = NULL; + sub = bt_mesh_subnet_get(update->key_idx); if (sub) { store_net_key(sub); @@ -1901,6 +2015,8 @@ static void store_pending_mod_bind(struct bt_mesh_model *model, bool vnd) uint16_t model_key = 0U; int err = 0; + BT_DBG("StorePendingModBind, Vnd %u", vnd); + model_key = BLE_MESH_GET_MODEL_KEY(model->elem_idx, model->model_idx); sprintf(name, "mesh/%s/%04x/b", vnd ? "v" : "s", model_key); @@ -1913,7 +2029,7 @@ static void store_pending_mod_bind(struct bt_mesh_model *model, bool vnd) err = bt_mesh_add_core_settings_item(vnd ? "mesh/vnd" : "mesh/sig", model_key); if (err) { BT_ERR("Failed to add bound key to %s, model_key 0x%04x", - vnd ? "mesh/vnd" : "mesh/sig", model_key); + vnd ? "mesh/vnd" : "mesh/sig", model_key); } } @@ -1923,6 +2039,8 @@ static void store_pending_mod_sub(struct bt_mesh_model *model, bool vnd) uint16_t model_key = 0U; int err = 0; + BT_DBG("StorePendingModSub, Vnd %u", vnd); + model_key = BLE_MESH_GET_MODEL_KEY(model->elem_idx, model->model_idx); sprintf(name, "mesh/%s/%04x/s", vnd ? "v" : "s", model_key); @@ -1935,7 +2053,7 @@ static void store_pending_mod_sub(struct bt_mesh_model *model, bool vnd) err = bt_mesh_add_core_settings_item(vnd ? "mesh/vnd" : "mesh/sig", model_key); if (err) { BT_ERR("Failed to add subscription to %s, model_key 0x%04x", - vnd ? "mesh/vnd" : "mesh/sig", model_key); + vnd ? "mesh/vnd" : "mesh/sig", model_key); } } @@ -1946,6 +2064,8 @@ static void store_pending_mod_pub(struct bt_mesh_model *model, bool vnd) uint16_t model_key = 0U; int err = 0; + BT_DBG("StorePendingModPub, Vnd %u", vnd); + if (!model->pub) { BT_WARN("Model has no publication support"); return; @@ -1964,7 +2084,7 @@ static void store_pending_mod_pub(struct bt_mesh_model *model, bool vnd) #if CONFIG_BLE_MESH_DF_SRV pub.directed_pub_policy = model->pub->directed_pub_policy; /**< Directed publish policy */ -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ err = bt_mesh_save_core_settings(name, (const uint8_t *)&pub, sizeof(pub)); if (err) { @@ -1983,6 +2103,8 @@ static void store_pending_mod(struct bt_mesh_model *model, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { + BT_DBG("StorePendingMod, Flags %u Vnd %u", model->flags, vnd); + if (!model->flags) { return; } @@ -2008,6 +2130,8 @@ static void clear_mod_bind(struct bt_mesh_model *model, bool vnd) char name[16] = {'\0'}; uint16_t model_key = 0U; + BT_DBG("ClearModBind, Vnd %u", vnd); + model_key = BLE_MESH_GET_MODEL_KEY(model->elem_idx, model->model_idx); sprintf(name, "mesh/%s/%04x/b", vnd ? "v" : "s", model_key); @@ -2020,6 +2144,8 @@ static void clear_mod_sub(struct bt_mesh_model *model, bool vnd) char name[16] = {'\0'}; uint16_t model_key = 0U; + BT_DBG("ClearModSub, Vnd %u", vnd); + model_key = BLE_MESH_GET_MODEL_KEY(model->elem_idx, model->model_idx); sprintf(name, "mesh/%s/%04x/s", vnd ? "v" : "s", model_key); @@ -2029,8 +2155,10 @@ static void clear_mod_sub(struct bt_mesh_model *model, bool vnd) static void clear_mod_pub(struct bt_mesh_model *model, bool vnd) { - char name[16] = {'\0'}; uint16_t model_key = 0U; + char name[16] = {'\0'}; + + BT_DBG("ClearModPub, Vnd %u", vnd); model_key = BLE_MESH_GET_MODEL_KEY(model->elem_idx, model->model_idx); sprintf(name, "mesh/%s/%04x/p", vnd ? "v" : "s", model_key); @@ -2043,6 +2171,8 @@ static void clear_pending_mod(struct bt_mesh_model *model, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { + BT_DBG("ClearPendingMod, Flags 0x%04x Vnd %u", model->flags, vnd); + if (!model->flags) { return; } @@ -2066,12 +2196,14 @@ static void clear_pending_mod(struct bt_mesh_model *model, #define IS_VA_DEL(_label) ((_label)->ref == 0) static void store_pending_va(void) { + struct label *lab = NULL; struct va_val va = {0}; char name[16] = {'\0'}; - struct label *lab = NULL; uint16_t i = 0U; int err = 0; + BT_DBG("StorePendingVa"); + for (i = 0U; (lab = get_label(i)) != NULL; i++) { if (!bt_mesh_atomic_test_and_clear_bit(lab->flags, BLE_MESH_VA_CHANGED)) { @@ -2090,7 +2222,7 @@ static void store_pending_va(void) } if (err) { BT_ERR("Failed to %s virtual address %s", - IS_VA_DEL(lab) ? "delete" : "store", name); + IS_VA_DEL(lab) ? "delete" : "store", name); return; } @@ -2101,7 +2233,7 @@ static void store_pending_va(void) } if (err) { BT_ERR("Failed to %s 0x%04x in mesh/vaddr", - IS_VA_DEL(lab) ? "delete" : "store", i); + IS_VA_DEL(lab) ? "delete" : "store", i); return; } @@ -2111,6 +2243,8 @@ static void store_pending_va(void) static void store_pending(struct k_work *work) { + BT_DBG("StorePending"); + if (bt_mesh_atomic_test_and_clear_bit(bt_mesh.flags, BLE_MESH_RPL_PENDING)) { if (bt_mesh_is_provisioned() || bt_mesh_is_provisioner_en()) { store_pending_rpl(); @@ -2172,6 +2306,7 @@ static void store_pending(struct k_work *work) bt_mesh_model_foreach(store_pending_mod, NULL); } else { bt_mesh_model_foreach(clear_pending_mod, NULL); + bt_mesh_erase_core_settings("mesh/sig"); bt_mesh_erase_core_settings("mesh/vnd"); } @@ -2185,6 +2320,9 @@ static void store_pending(struct k_work *work) void bt_mesh_store_rpl(struct bt_mesh_rpl *entry) { + BT_DBG("StoreRPLSchedule"); + BT_DBG("Src 0x%04x Seq 0x%06x OldIV %u", entry->src, entry->seq, entry->old_iv); + entry->store = true; schedule_store(BLE_MESH_RPL_PENDING); } @@ -2197,6 +2335,8 @@ static struct key_update *key_update_find(bool app_key, uint16_t key_idx, *free_slot = NULL; + BT_DBG("KeyUpdateFind, KeyIdx 0x%04x AppKey %u", key_idx, app_key); + for (i = 0; i < ARRAY_SIZE(key_updates); i++) { struct key_update *update = &key_updates[i]; @@ -2222,7 +2362,7 @@ void bt_mesh_store_subnet(struct bt_mesh_subnet *sub) struct key_update *free_slot = NULL; struct key_update *update = NULL; - BT_DBG("NetKeyIndex 0x%03x", sub->net_idx); + BT_DBG("StoreSubnetSchedule, NetIdx 0x%04x", sub->net_idx); update = key_update_find(false, sub->net_idx, &free_slot); if (update) { @@ -2232,6 +2372,7 @@ void bt_mesh_store_subnet(struct bt_mesh_subnet *sub) } if (!free_slot) { + BT_DBG("NoFreeSlotForSubnet"); store_net_key(sub); return; } @@ -2249,7 +2390,7 @@ void bt_mesh_store_app_key(struct bt_mesh_app_key *key) struct key_update *free_slot = NULL; struct key_update *update = NULL; - BT_DBG("AppKeyIndex 0x%03x", key->app_idx); + BT_DBG("StoreAppKeySchedule, AppIdx 0x%04x", key->app_idx); update = key_update_find(true, key->app_idx, &free_slot); if (update) { @@ -2259,6 +2400,7 @@ void bt_mesh_store_app_key(struct bt_mesh_app_key *key) } if (!free_slot) { + BT_DBG("NoFreeSlotForAppKey"); store_app_key(key); return; } @@ -2273,22 +2415,29 @@ void bt_mesh_store_app_key(struct bt_mesh_app_key *key) void bt_mesh_store_hb_pub(void) { + BT_DBG("StoreHbPubSchedule"); + schedule_store(BLE_MESH_HB_PUB_PENDING); } void bt_mesh_store_cfg(void) { + BT_DBG("StoreCfgSchedule"); + schedule_store(BLE_MESH_CFG_PENDING); } void bt_mesh_clear_role(void) { - BT_DBG("Clear device role"); + BT_DBG("ClearRole"); + bt_mesh_erase_core_settings("mesh/role"); } void bt_mesh_clear_net(void) { + BT_DBG("ClearNetSchedule"); + schedule_store(BLE_MESH_NET_PENDING); schedule_store(BLE_MESH_IV_PENDING); schedule_store(BLE_MESH_CFG_PENDING); @@ -2299,7 +2448,7 @@ void bt_mesh_clear_subnet(struct bt_mesh_subnet *sub) struct key_update *free_slot = NULL; struct key_update *update = NULL; - BT_DBG("NetKeyIndex 0x%03x", sub->net_idx); + BT_DBG("ClearSubnetSchedule, NetIdx 0x%04x", sub->net_idx); update = key_update_find(false, sub->net_idx, &free_slot); if (update) { @@ -2326,7 +2475,7 @@ void bt_mesh_clear_app_key(struct bt_mesh_app_key *key) struct key_update *free_slot = NULL; struct key_update *update = NULL; - BT_DBG("AppKeyIndex 0x%03x", key->app_idx); + BT_DBG("ClearAppKeySchedule, AppIdx 0x%04x", key->app_idx); update = key_update_find(true, key->app_idx, &free_slot); if (update) { @@ -2353,6 +2502,8 @@ void bt_mesh_clear_rpl_single(uint16_t src) char name[16] = {'\0'}; int err = 0; + BT_DBG("ClearRPLSingle, Src 0x%04x", src); + if (!BLE_MESH_ADDR_IS_UNICAST(src)) { BT_ERR("Invalid src 0x%04x", src); return; @@ -2369,39 +2520,53 @@ void bt_mesh_clear_rpl_single(uint16_t src) void bt_mesh_clear_rpl(void) { + BT_DBG("ClearRPLSchedule"); + schedule_store(BLE_MESH_RPL_PENDING); } void bt_mesh_store_mod_bind(struct bt_mesh_model *model) { + BT_DBG("StoreModBindSchedule"); + model->flags |= BLE_MESH_MOD_BIND_PENDING; schedule_store(BLE_MESH_MOD_PENDING); } void bt_mesh_store_mod_sub(struct bt_mesh_model *model) { + BT_DBG("StoreModSubSchedule"); + model->flags |= BLE_MESH_MOD_SUB_PENDING; schedule_store(BLE_MESH_MOD_PENDING); } void bt_mesh_store_mod_pub(struct bt_mesh_model *model) { + BT_DBG("StoreModPubSchedule"); + model->flags |= BLE_MESH_MOD_PUB_PENDING; schedule_store(BLE_MESH_MOD_PENDING); } void bt_mesh_store_label(void) { + BT_DBG("StoreLabelSchedule"); + schedule_store(BLE_MESH_VA_PENDING); } void bt_mesh_store_dkca(void) { + BT_DBG("StoreDkca"); + bt_mesh_save_core_settings("mesh/dkca", bt_mesh.dev_key_ca, sizeof(bt_mesh.dev_key_ca)); } void bt_mesh_clear_dkca(void) { + BT_DBG("ClearDkca"); + bt_mesh_erase_core_settings("mesh/dkca"); } @@ -2423,7 +2588,7 @@ void bt_mesh_store_prov_info(uint16_t primary_addr, uint16_t alloc_addr) { struct prov_info val = {0}; - BT_DBG("Primary address 0x%04x, next address allocation 0x%04x", primary_addr, alloc_addr); + BT_DBG("StoreProvInfo, PrimaryAddr 0x%04x AllocAddr 0x%04x", primary_addr, alloc_addr); val.primary_addr = primary_addr; val.alloc_addr = alloc_addr; @@ -2433,7 +2598,8 @@ void bt_mesh_store_prov_info(uint16_t primary_addr, uint16_t alloc_addr) void bt_mesh_clear_prov_info(void) { - BT_DBG("Clearing prov info"); + BT_DBG("ClearProvInfo"); + bt_mesh_erase_core_settings("mesh/p_prov"); } @@ -2443,6 +2609,9 @@ static void store_p_net_key(struct bt_mesh_subnet *sub) char name[16] = {'\0'}; int err = 0; + BT_DBG("StorePvnrNetKey, NetIdx 0x%04x KrFlag %u KrPhase %u", + sub->net_idx, sub->kr_flag, sub->kr_phase); + memcpy(&key.val[0], sub->keys[0].net, 16); memcpy(&key.val[1], sub->keys[1].net, 16); key.kr_flag = sub->kr_flag; @@ -2467,6 +2636,9 @@ static void store_p_app_key(struct bt_mesh_app_key *app) char name[16] = {'\0'}; int err = 0; + BT_DBG("StorePvnrAppKey, NetIdx 0x%04x AppIdx 0x%04x Updated %u", + app->net_idx, app->app_idx, app->updated); + key.net_idx = app->net_idx; key.updated = app->updated; memcpy(key.val[0], app->keys[0].val, 16); @@ -2487,7 +2659,7 @@ static void store_p_app_key(struct bt_mesh_app_key *app) void bt_mesh_store_p_net_idx(void) { - BT_DBG("Store, p_net_idx_next 0x%03x", bt_mesh.p_net_idx_next); + BT_DBG("StorePvnrNetIdx, NetIdxNext 0x%04x", bt_mesh.p_net_idx_next); bt_mesh_save_core_settings("mesh/p_netidx", (const uint8_t *)&bt_mesh.p_net_idx_next, sizeof(bt_mesh.p_net_idx_next)); @@ -2495,13 +2667,14 @@ void bt_mesh_store_p_net_idx(void) void bt_mesh_clear_p_net_idx(void) { - BT_DBG("Clearing NetKey Index"); + BT_DBG("ClearPvnrNetIdx"); + bt_mesh_erase_core_settings("mesh/p_netidx"); } void bt_mesh_store_p_app_idx(void) { - BT_DBG("Store, p_app_idx_next 0x%03x", bt_mesh.p_app_idx_next); + BT_DBG("StorePvnrAppIdx, AppIdxNext 0x%04x", bt_mesh.p_app_idx_next); bt_mesh_save_core_settings("mesh/p_appidx", (const uint8_t *)&bt_mesh.p_app_idx_next, sizeof(bt_mesh.p_app_idx_next)); @@ -2509,32 +2682,37 @@ void bt_mesh_store_p_app_idx(void) void bt_mesh_clear_p_app_idx(void) { - BT_DBG("Clearing AppKey Index"); + BT_DBG("ClearPvnrAppIdx"); + bt_mesh_erase_core_settings("mesh/p_appidx"); } void bt_mesh_store_p_subnet(struct bt_mesh_subnet *sub) { + BT_DBG("StorePvnrSubnet"); + if (sub == NULL) { BT_ERR("Invalid subnet"); return; } - BT_DBG("NetKeyIndex 0x%03x NetKey %s", sub->net_idx, - bt_hex(sub->keys[0].net, 16)); + BT_DBG("NetIdx 0x%04x NetKey %s", + sub->net_idx, bt_hex(sub->keys[0].net, 16)); store_p_net_key(sub); } void bt_mesh_store_p_app_key(struct bt_mesh_app_key *key) { + BT_DBG("StorePvnrAppKey"); + if (key == NULL) { BT_ERR("Invalid AppKey"); return; } - BT_DBG("AppKeyIndex 0x%03x AppKey %s", key->app_idx, - bt_hex(key->keys[0].val, 16)); + BT_DBG("AppIdx 0x%03x AppKey %s", + key->app_idx, bt_hex(key->keys[0].val, 16)); store_p_app_key(key); } @@ -2544,7 +2722,7 @@ void bt_mesh_clear_p_subnet(uint16_t net_idx) char name[16] = {'\0'}; int err = 0; - BT_DBG("NetKeyIndex 0x%03x", net_idx); + BT_DBG("ClearPvnrSubnet, NetIdx 0x%04x", net_idx); sprintf(name, "mesh/pnk/%04x", net_idx); bt_mesh_erase_core_settings(name); @@ -2560,7 +2738,7 @@ void bt_mesh_clear_p_app_key(uint16_t app_idx) char name[16] = {'\0'}; int err = 0; - BT_DBG("AppKeyIndex 0x%03x", app_idx); + BT_DBG("ClearPvnrAppKey, AppIdx 0x%04x", app_idx); sprintf(name, "mesh/pak/%04x", app_idx); bt_mesh_erase_core_settings(name); @@ -2577,11 +2755,17 @@ void bt_mesh_store_node_info(struct bt_mesh_node *node) char name[16] = {'\0'}; int err = 0; + BT_DBG("StoreNodeInfo"); + if (node == NULL) { BT_ERR("Invalid node info"); return; } + BT_DBG("UnicastAddr 0x%04x ElemNum %u NetIdx 0x%04x Flags %u IVIndex %lu", + node->unicast_addr, node->element_num, + node->net_idx, node->flags, node->iv_index); + memcpy(val.addr, node->addr, BLE_MESH_ADDR_LEN); val.addr_type = node->addr_type; memcpy(val.dev_uuid, node->dev_uuid, 16); @@ -2611,6 +2795,8 @@ static void clear_node(uint16_t addr) char name[16] = {'\0'}; int err = 0; + BT_DBG("ClearNode, Addr 0x%04x", addr); + /* Clear node information */ sprintf(name, "mesh/pn/%04x/i", addr); bt_mesh_erase_core_settings(name); @@ -2631,13 +2817,13 @@ static void clear_node(uint16_t addr) void bt_mesh_clear_node_info(uint16_t unicast_addr) { + BT_DBG("ClearNodeInfo, Addr 0x%04x", unicast_addr); + if (!BLE_MESH_ADDR_IS_UNICAST(unicast_addr)) { BT_ERR("Invalid unicast address 0x%04x", unicast_addr); return; } - BT_DBG("Unicast address 0x%04x", unicast_addr); - clear_node(unicast_addr); } @@ -2647,11 +2833,15 @@ void bt_mesh_store_node_name(struct bt_mesh_node *node) char name[16] = {'\0'}; int err = 0; + BT_DBG("StoreNodeName"); + if (node == NULL) { BT_ERR("Invalid node info"); return; } + BT_DBG("UnicastAddr 0x%04x NodeName %s", node->unicast_addr, node->name); + strncpy(node_name, node->name, BLE_MESH_NODE_NAME_SIZE + 1); sprintf(name, "mesh/pn/%04x/n", node->unicast_addr); @@ -2666,11 +2856,15 @@ void bt_mesh_store_node_comp_data(struct bt_mesh_node *node) char name[16] = {'\0'}; int err = 0; + BT_DBG("StoreNodeCompData"); + if (!node || !node->comp_data || node->comp_length == 0U) { BT_ERR("Invalid node info"); return; } + BT_DBG("UnicastAddr 0x%04x CompLength %u", node->unicast_addr, node->comp_length); + sprintf(name, "mesh/pn/%04x/c", node->unicast_addr); err = bt_mesh_save_core_settings(name, (const uint8_t *)node->comp_data, node->comp_length); if (err) { @@ -2681,12 +2875,16 @@ void bt_mesh_store_node_comp_data(struct bt_mesh_node *node) int settings_core_init(void) { + BT_DBG("SettingsCoreInit"); + k_delayed_work_init(&pending_store, store_pending); return 0; } int bt_mesh_settings_init(void) { + BT_DBG("SettingsInit"); + bt_mesh_settings_mutex_new(); bt_mesh_settings_init_foreach(); return 0; @@ -2695,12 +2893,16 @@ int bt_mesh_settings_init(void) #if CONFIG_BLE_MESH_DEINIT int settings_core_deinit(void) { + BT_DBG("SettingsCoreDeinit"); + k_delayed_work_free(&pending_store); return 0; } int settings_core_erase(void) { + BT_DBG("SettingsCoreErase"); + /* Erase here must not use the pending_store timer. * This is used for erasing the information which * could not be erased during the previous deinit @@ -2714,6 +2916,8 @@ int settings_core_erase(void) int bt_mesh_settings_deinit(bool erase) { + BT_DBG("SettingsDeinit, Erase %u", erase); + bt_mesh_settings_deinit_foreach(erase); bt_mesh_settings_mutex_free(); return 0; @@ -2722,6 +2926,8 @@ int bt_mesh_settings_deinit(bool erase) void bt_mesh_settings_reset(bool erase) { + BT_DBG("SettingsReset, Erase %u", erase); + k_delayed_work_cancel(&pending_store); if (erase) { bt_mesh_clear_net(); diff --git a/components/bt/esp_ble_mesh/core/storage/settings_nvs.c b/components/bt/esp_ble_mesh/core/storage/settings_nvs.c index ca3ac144ef5d..e2f730d41aa1 100644 --- a/components/bt/esp_ble_mesh/core/storage/settings_nvs.c +++ b/components/bt/esp_ble_mesh/core/storage/settings_nvs.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,7 +17,7 @@ enum settings_type { SETTINGS_CORE, #if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE SETTINGS_UID, -#endif +#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ }; struct settings_context { @@ -62,15 +62,20 @@ static struct settings_context settings_ctx[] = { int bt_mesh_settings_nvs_open(const char* name, bt_mesh_nvs_handle_t *handle) { + assert(name); + BT_DBG("SettingsNVSOpen, Name %s", name); + #if CONFIG_BLE_MESH_SPECIFIC_PARTITION return nvs_open_from_partition(CONFIG_BLE_MESH_PARTITION_NAME, name, NVS_READWRITE, handle); -#else +#else /* CONFIG_BLE_MESH_SPECIFIC_PARTITION */ return nvs_open(name, NVS_READWRITE, handle); -#endif +#endif /* CONFIG_BLE_MESH_SPECIFIC_PARTITION */ } void bt_mesh_settings_nvs_close(bt_mesh_nvs_handle_t handle) { + BT_DBG("SettingsNVSClose, Handle %lu", handle); + nvs_close(handle); } @@ -79,6 +84,8 @@ void bt_mesh_settings_init_foreach(void) int err = 0; int i; + BT_DBG("SettingsInitForeach"); + #if CONFIG_BLE_MESH_SPECIFIC_PARTITION err = nvs_flash_init_partition(CONFIG_BLE_MESH_PARTITION_NAME); if (err != ESP_OK) { @@ -134,6 +141,8 @@ void bt_mesh_settings_deinit_foreach(bool erase) { int i; + BT_DBG("SettingsDeinitForeach, Erase %u", erase); + for (i = 0; i < ARRAY_SIZE(settings_ctx); i++) { struct settings_context *ctx = &settings_ctx[i]; @@ -152,7 +161,7 @@ void bt_mesh_settings_deinit_foreach(bool erase) #if CONFIG_BLE_MESH_SPECIFIC_PARTITION nvs_flash_deinit_partition(CONFIG_BLE_MESH_PARTITION_NAME); -#endif +#endif /* CONFIG_BLE_MESH_SPECIFIC_PARTITION */ } #endif /* CONFIG_BLE_MESH_DEINIT */ @@ -161,6 +170,8 @@ int bt_mesh_settings_direct_open(bt_mesh_nvs_handle_t *handle) int err = 0; int i; + BT_DBG("SettingsDirectOpen"); + #if CONFIG_BLE_MESH_SPECIFIC_PARTITION err = nvs_flash_init_partition(CONFIG_BLE_MESH_PARTITION_NAME); if (err != ESP_OK) { @@ -178,6 +189,8 @@ int bt_mesh_settings_direct_open(bt_mesh_nvs_handle_t *handle) return -EIO; } + BT_DBG("%u: NVSName %s Handle %lu", i, ctx->nvs_name, ctx->handle); + if (i == SETTINGS_CORE && handle) { *handle = ctx->handle; } @@ -190,25 +203,30 @@ void bt_mesh_settings_direct_close(void) { int i; + BT_DBG("SettingsDirectClose"); + for (i = 0; i < ARRAY_SIZE(settings_ctx); i++) { bt_mesh_settings_nvs_close(settings_ctx[i].handle); } #if CONFIG_BLE_MESH_SPECIFIC_PARTITION nvs_flash_deinit_partition(CONFIG_BLE_MESH_PARTITION_NAME); -#endif +#endif /* CONFIG_BLE_MESH_SPECIFIC_PARTITION */ } /* API used to get BLE Mesh related nvs handle */ static inline bt_mesh_nvs_handle_t settings_get_nvs_handle(enum settings_type type) { + BT_DBG("SettingsGetNVSHandle, Type %u", type); + #if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE if (type == SETTINGS_CORE) { extern bt_mesh_nvs_handle_t get_core_settings_handle(void); return get_core_settings_handle(); } -#endif +#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ + return settings_ctx[type].handle; } @@ -218,12 +236,8 @@ static int settings_save(bt_mesh_nvs_handle_t handle, const char *key, const uin { int err = 0; - if (key == NULL) { - BT_ERR("%s, Invalid parameter", __func__); - return -EINVAL; - } - - BT_DBG("nvs %s, key %s", val ? "set" : "erase", key); + BT_DBG("Settings%s, Handle %lu Len %lu Key %s", + val ? "Store" : "Erase", handle, len, key); if (val) { err = nvs_set_blob(handle, key, val, len); @@ -236,7 +250,7 @@ static int settings_save(bt_mesh_nvs_handle_t handle, const char *key, const uin } if (err != ESP_OK) { BT_ERR("Failed to %s %s data (err %d)", - val ? "set" : "erase", key, err); + val ? "set" : "erase", key, err); return -EIO; } @@ -262,6 +276,10 @@ int bt_mesh_save_settings(bt_mesh_nvs_handle_t handle, const char *key, int bt_mesh_save_core_settings(const char *key, const uint8_t *val, size_t len) { bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_CORE); + + assert(key); + BT_DBG("SaveCoreSettings, Handle %lu Len %lu Key %s", handle, len, key); + return bt_mesh_save_settings(handle, key, val, len); } @@ -269,26 +287,39 @@ int bt_mesh_save_core_settings(const char *key, const uint8_t *val, size_t len) int bt_mesh_save_uid_settings(const char *key, const uint8_t *val, size_t len) { bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_UID); + + assert(key); + BT_DBG("SaveUIDSettings, Handle %lu Len %lu Key %s", handle, len, key); + return bt_mesh_save_settings(handle, key, val, len); } -#endif +#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ int bt_mesh_erase_settings(bt_mesh_nvs_handle_t handle, const char *key) { + assert(key); + BT_DBG("EraseSettings, Handle %lu Key %s", handle, key); + return bt_mesh_save_settings(handle, key, NULL, 0); } int bt_mesh_erase_core_settings(const char *key) { + assert(key); + BT_DBG("EraseCoreSettings, Key %s", key); + return bt_mesh_save_core_settings(key, NULL, 0); } #if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE int bt_mesh_erase_uid_settings(const char *name) { + assert(name); + BT_DBG("EraseUIDSettings, Name %s", name); + return bt_mesh_save_uid_settings(name, NULL, 0); } -#endif +#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ /* API used to load BLE Mesh related settings */ @@ -297,10 +328,9 @@ static int settings_load(bt_mesh_nvs_handle_t handle, const char *key, { int err = 0; - if (key == NULL || buf == NULL || exist == NULL) { - BT_ERR("%s, Invalid parameter", __func__); - return -EINVAL; - } + BT_DBG("SettingsLoad, Handle %lu Key %s", handle, key); + + assert(buf && exist); err = nvs_get_blob(handle, key, buf, &buf_len); if (err != ESP_OK) { @@ -331,6 +361,10 @@ int bt_mesh_load_settings(bt_mesh_nvs_handle_t handle, const char *key, int bt_mesh_load_core_settings(const char *key, uint8_t *buf, size_t buf_len, bool *exist) { bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_CORE); + + assert(key); + BT_DBG("LoadCoreSettings, Handle %lu Key %s", handle, key); + return bt_mesh_load_settings(handle, key, buf, buf_len, exist); } @@ -338,9 +372,13 @@ int bt_mesh_load_core_settings(const char *key, uint8_t *buf, size_t buf_len, bo int bt_mesh_load_uid_settings(const char *key, uint8_t *buf, size_t buf_len, bool *exist) { bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_UID); + + assert(key); + BT_DBG("LoadUIDSettings, Handle %lu Key %s", handle, key); + return bt_mesh_load_settings(handle, key, buf, buf_len, exist); } -#endif +#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ /* API used to get length of BLE Mesh related settings */ @@ -349,10 +387,7 @@ static size_t settings_get_length(bt_mesh_nvs_handle_t handle, const char *key) size_t len = 0U; int err = 0; - if (key == NULL) { - BT_ERR("%s, Invalid parameter", __func__); - return 0; - } + BT_DBG("SettingsGetLength, Handle %lu Key %s", handle, key); err = nvs_get_blob(handle, key, NULL, &len); if (err != ESP_OK) { @@ -362,6 +397,8 @@ static size_t settings_get_length(bt_mesh_nvs_handle_t handle, const char *key) return 0; } + BT_DBG("Len %lu", len); + return len; } @@ -419,6 +456,10 @@ struct net_buf_simple *bt_mesh_get_settings_item(bt_mesh_nvs_handle_t handle, co struct net_buf_simple *bt_mesh_get_core_settings_item(const char *key) { bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_CORE); + + assert(key); + BT_DBG("GetCoreSettingsItem, Handle %lu Key %s", handle, key); + return bt_mesh_get_settings_item(handle, key); } @@ -426,9 +467,13 @@ struct net_buf_simple *bt_mesh_get_core_settings_item(const char *key) struct net_buf_simple *bt_mesh_get_uid_settings_item(const char *key) { bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_UID); + + assert(key); + BT_DBG("GetUIDSettingsItem, Handle %lu Key %s", handle, key); + return bt_mesh_get_settings_item(handle, key); } -#endif +#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ /* API used to check if the settings item exists */ @@ -438,6 +483,8 @@ bool bt_mesh_is_settings_item_exist(struct net_buf_simple *buf, const uint16_t v size_t length = 0U; int i; + BT_DBG("IsSettingsItemExist, Val 0x%04x", val); + if (!buf) { return false; } @@ -508,6 +555,10 @@ int bt_mesh_add_settings_item(bt_mesh_nvs_handle_t handle, const char *key, cons int bt_mesh_add_core_settings_item(const char *key, const uint16_t val) { bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_CORE); + + assert(key); + BT_DBG("AddCoreSettingsItem, Handle %lu Val 0x%04x Key %s", handle, val, key); + return bt_mesh_add_settings_item(handle, key, val); } @@ -515,9 +566,13 @@ int bt_mesh_add_core_settings_item(const char *key, const uint16_t val) int bt_mesh_add_uid_settings_item(const char *key, const uint16_t val) { bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_UID); + + assert(key); + BT_DBG("AddUIDSettingsItem, Handle %lu Val 0x%04x Key %s", handle, val, key); + return bt_mesh_add_settings_item(handle, key, val); } -#endif +#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ /* API used to remove the settings item */ @@ -580,6 +635,10 @@ int bt_mesh_remove_settings_item(bt_mesh_nvs_handle_t handle, const char *key, c int bt_mesh_remove_core_settings_item(const char *key, const uint16_t val) { bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_CORE); + + assert(key); + BT_DBG("RemoveCoreSettingsItem, Val 0x%04x Key %s", val, key); + return bt_mesh_remove_settings_item(handle, key, val); } @@ -587,14 +646,21 @@ int bt_mesh_remove_core_settings_item(const char *key, const uint16_t val) int bt_mesh_remove_uid_settings_item(const char *key, const uint16_t val) { bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_UID); + + assert(key); + BT_DBG("RemoveUIDSettingsItem, Val 0x%04x Key %s", val, key); + return bt_mesh_remove_settings_item(handle, key, val); } -#endif +#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ int bt_mesh_settings_erase_key(bt_mesh_nvs_handle_t handle, const char *key) { int err = 0; + assert(key); + BT_DBG("SettingsEraseKey, Handle %lu Key %s", handle, key); + err = nvs_erase_key(handle, key); if (err != ESP_OK) { if (err == ESP_ERR_NVS_NOT_FOUND) { @@ -618,6 +684,8 @@ int bt_mesh_settings_erase_all(bt_mesh_nvs_handle_t handle) { int err = 0; + BT_DBG("SettingsEraseAll, Handle %lu", handle); + err = nvs_erase_all(handle); if (err != ESP_OK) { BT_ERR("Failed to erase all (err %d)", err); @@ -632,4 +700,5 @@ int bt_mesh_settings_erase_all(bt_mesh_nvs_handle_t handle) return 0; } + #endif /* CONFIG_BLE_MESH_SETTINGS */ diff --git a/components/bt/esp_ble_mesh/core/storage/settings_uid.c b/components/bt/esp_ble_mesh/core/storage/settings_uid.c index 511709f1ecdc..e1de639722ea 100644 --- a/components/bt/esp_ble_mesh/core/storage/settings_uid.c +++ b/components/bt/esp_ble_mesh/core/storage/settings_uid.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -38,15 +38,22 @@ static int settings_direct_erase(uint8_t index); static inline bool settings_uid_empty(struct settings_uid *uid) { - return (uid->id[0] == '\0') ? true : false; + bool empty = (uid->id[0] == '\0') ? true : false; + + BT_DBG("SettingsUIDEmpty, Empty %u", empty); + + return empty; } bt_mesh_nvs_handle_t get_core_settings_handle(void) { int i; + BT_DBG("GetCoreSettingsHandle"); + for (i = 0; i < ARRAY_SIZE(user_ids); i++) { if (user_ids[i].open) { + BT_DBG("I %u Handle %lu", i, user_ids[i].handle); return user_ids[i].handle; } } @@ -59,6 +66,8 @@ int settings_uid_init(void) { int i; + BT_DBG("SettingsUIDInit"); + for (i = 0; i < ARRAY_SIZE(user_ids); i++) { memset(&user_ids[i], 0, sizeof(struct settings_uid)); user_ids[i].handle = INVALID_SETTINGS_HANDLE; @@ -76,6 +85,8 @@ int settings_uid_load(void) int err = 0; int i; + BT_DBG("SettingsUIDLoad"); + /* Before using user id to search settings, we need to * restore all the settings user_ids properly. */ @@ -114,6 +125,8 @@ int settings_uid_deinit(bool erase) { int i; + BT_DBG("SettingsUIDDeinit, Erase %u", erase); + for (i = 0; i < ARRAY_SIZE(user_ids); i++) { memset(&user_ids[i], 0, offsetof(struct settings_uid, handle)); /* Can not reset handle here, since it will be used @@ -128,6 +141,8 @@ int settings_uid_erase(void) { int i; + BT_DBG("SettingsUIDErase"); + for (i = 0; i < ARRAY_SIZE(user_ids); i++) { if (user_ids[i].open == true) { /* When a nvs namespace is open, which means it is @@ -158,6 +173,8 @@ static int settings_direct_erase(uint8_t index) char name[16] = {'\0'}; int err = 0; + BT_DBG("SettingsDirectErase, Index %u", index); + sprintf(name, "%s_%02x", "mesh_core", index); /* Get handle for core settings */ @@ -191,6 +208,8 @@ static uint8_t settings_index_get(const char *id, uint8_t *index) uint8_t idx = 0; int i; + BT_DBG("SettingsIndexGet"); + for (i = 0; i < ARRAY_SIZE(user_ids); i++) { if (strlen(user_ids[i].id) != strlen(id)) { continue; @@ -206,6 +225,8 @@ static uint8_t settings_index_get(const char *id, uint8_t *index) idx = INVALID_SETTINGS_INDEX; } + BT_DBG("Index %u", idx); + if (index) { *index = idx; } @@ -219,6 +240,8 @@ static int settings_open(uint8_t index) int err = 0; int i; + BT_DBG("SettingsOpen, Index %u UID %s", index, uid->id); + /* Check if the nvs namespace is already open */ if (uid->open == true) { BT_WARN("Settings already open, index %d", index); @@ -251,8 +274,6 @@ static int settings_open(uint8_t index) sprintf(uid->id, "%04x", index); } - BT_INFO("Open settings, index %d, uid %s", index, uid->id); - sprintf(name, "mesh/id/%04x", index); err = bt_mesh_save_uid_settings(name, (const uint8_t *)uid->id, SETTINGS_UID_SIZE); if (err) { @@ -288,6 +309,8 @@ static int settings_open(uint8_t index) int bt_mesh_provisioner_open_settings_with_index(uint8_t index) { + BT_DBG("PvnrOpenSettingsWithIndex, Index %u", index); + if (index >= ARRAY_SIZE(user_ids)) { BT_ERR("Invalid settings index %d", index); return -EINVAL; @@ -301,6 +324,8 @@ int bt_mesh_provisioner_open_settings_with_uid(const char *id, uint8_t *index) uint8_t idx = 0; int i; + BT_DBG("PvnrOpenSettingsWithUID"); + if (!id || strlen(id) > SETTINGS_UID_SIZE) { BT_ERR("Invalid settings uid"); return -EINVAL; @@ -328,6 +353,8 @@ int bt_mesh_provisioner_open_settings_with_uid(const char *id, uint8_t *index) idx = i; } + BT_DBG("Index %u", idx); + return settings_open(idx); } @@ -337,13 +364,14 @@ static int settings_close(uint8_t index, bool erase) char name[16] = {'\0'}; int err = 0; + BT_DBG("SettingsClose"); + BT_DBG("Index %u Erase %u UID %s", index, erase, uid->id); + if (uid->open == false) { BT_ERR("Settings not open, index %d", index); return -EIO; } - BT_INFO("Close settings, index %d, uid %s", index, uid->id); - /* Disable Provisioner firstly */ err = bt_mesh_provisioner_disable(BLE_MESH_PROV_ADV | BLE_MESH_PROV_GATT); if (err && err != -EALREADY) { @@ -378,6 +406,8 @@ static int settings_close(uint8_t index, bool erase) int bt_mesh_provisioner_close_settings_with_index(uint8_t index, bool erase) { + BT_DBG("PvnrCloseSettingsWithIndex, Index %u Erase %u", index, erase); + if (index >= ARRAY_SIZE(user_ids)) { BT_ERR("Invalid settings index %d", index); return -EINVAL; @@ -390,6 +420,8 @@ int bt_mesh_provisioner_close_settings_with_uid(const char *id, bool erase, uint { uint8_t idx = 0; + BT_DBG("PvnrCloseSettingsWithUID, Erase %u", erase); + if (!id || strlen(id) > SETTINGS_UID_SIZE) { BT_ERR("Invalid settings uid"); return -EINVAL; @@ -401,6 +433,8 @@ int bt_mesh_provisioner_close_settings_with_uid(const char *id, bool erase, uint return -ENODEV; } + BT_DBG("Index %u ID %s", idx, id); + return settings_close(idx, erase); } @@ -412,13 +446,13 @@ static int settings_delete(uint8_t index) */ struct settings_uid *uid = &user_ids[index]; + BT_DBG("SettingsDelete, Index %u UID %s", index, uid->id); + if (uid->open == true) { BT_ERR("Settings being used, index %d", index); return -EBUSY; } - BT_INFO("Delete settings, index %d, uid %s", index, uid->id); - settings_direct_erase(index); memset(uid, 0, sizeof(struct settings_uid)); @@ -429,6 +463,8 @@ static int settings_delete(uint8_t index) int bt_mesh_provisioner_delete_settings_with_index(uint8_t index) { + BT_DBG("PvnrDeleteSettingsWithIndex, Index %u", index); + if (index >= ARRAY_SIZE(user_ids)) { BT_ERR("Invalid settings index %d", index); return -EINVAL; @@ -441,6 +477,8 @@ int bt_mesh_provisioner_delete_settings_with_uid(const char *id, uint8_t *index) { uint8_t idx = 0; + BT_DBG("PvnrDeleteSettingsWithUID"); + if (!id || strlen(id) > SETTINGS_UID_SIZE) { BT_ERR("Invalid settings uid"); return -EINVAL; @@ -452,16 +490,22 @@ int bt_mesh_provisioner_delete_settings_with_uid(const char *id, uint8_t *index) return -ENODEV; } + BT_DBG("Index %u ID %s", idx, id); + return settings_delete(idx); } const char *bt_mesh_provisioner_get_settings_uid(uint8_t index) { + BT_DBG("PvnrGetSettingsUID, Index %u", index); + if (index >= ARRAY_SIZE(user_ids)) { BT_ERR("Invalid settings index %d", index); return NULL; } + BT_DBG("ID %s", user_ids[index].id); + return user_ids[index].id; } @@ -469,6 +513,8 @@ uint8_t bt_mesh_provisioner_get_settings_index(const char *id) { uint8_t idx = 0; + BT_DBG("PvnrGetSettingsIndex"); + if (!id || strlen(id) > SETTINGS_UID_SIZE) { BT_ERR("Invalid settings uid"); return INVALID_SETTINGS_INDEX; @@ -479,6 +525,8 @@ uint8_t bt_mesh_provisioner_get_settings_index(const char *id) BT_ERR("Settings uid %s not exists", id); } + BT_DBG("Index %u ID %s", idx, id); + return idx; } @@ -487,12 +535,16 @@ uint8_t bt_mesh_provisioner_get_free_settings_count(void) uint8_t count = 0; int i; + BT_DBG("PvnrGetFreeSettingsCount"); + for (i = 0; i < ARRAY_SIZE(user_ids); i++) { if (settings_uid_empty(&user_ids[i])) { count++; } } + BT_DBG("Count %u", count); + return count; } #endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ @@ -503,6 +555,8 @@ int bt_mesh_provisioner_direct_erase_settings(void) bt_mesh_nvs_handle_t handle = 0; int err = 0; + BT_DBG("PvnrDirectEraseSettings"); + err = bt_mesh_settings_direct_open(&handle); if (err) { return err; @@ -514,9 +568,9 @@ int bt_mesh_provisioner_direct_erase_settings(void) } bt_mesh_erase_uid_settings("mesh/uid"); -#else +#else /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ err = bt_mesh_settings_erase_all(handle); -#endif +#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ bt_mesh_settings_direct_close(); return err; diff --git a/components/bt/esp_ble_mesh/core/test.c b/components/bt/esp_ble_mesh/core/test.c index 3d3cc3bbd902..5b47258d5fab 100644 --- a/components/bt/esp_ble_mesh/core/test.c +++ b/components/bt/esp_ble_mesh/core/test.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -41,6 +41,8 @@ int bt_mesh_device_auto_enter_network(struct bt_mesh_device_network_info *info) int i, j, k; int err = 0; + BT_DBG("DeviceAutoEnterNetwork"); + if (info == NULL || !BLE_MESH_ADDR_IS_UNICAST(info->unicast_addr) || !BLE_MESH_ADDR_IS_GROUP(info->group_addr)) { return -EINVAL; @@ -139,6 +141,8 @@ int bt_mesh_test_update_white_list(struct bt_mesh_white_list *wl) { int err = 0; + BT_DBG("TestUpdateWhiteList"); + if (wl == NULL) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; @@ -157,7 +161,7 @@ int bt_mesh_test_update_white_list(struct bt_mesh_white_list *wl) int bt_mesh_test_start_scanning(bool wl_en) { - BT_INFO("Scan with filter policy %s", wl_en ? "enabled" : "disabled"); + BT_DBG("TestStartScanning, wl_en %u", wl_en); if (wl_en) { return bt_mesh_scan_with_wl_enable(); @@ -168,6 +172,8 @@ int bt_mesh_test_start_scanning(bool wl_en) int bt_mesh_test_stop_scanning(void) { + BT_DBG("TestStopScanning"); + return bt_mesh_scan_disable(); } #endif /* CONFIG_BLE_MESH_TEST_USE_WHITE_LIST */ @@ -181,6 +187,8 @@ void bt_mesh_test_register_net_pdu_cb(bt_mesh_test_net_pdu_cb_t cb) void bt_mesh_test_set_seq(uint32_t seq) { + BT_DBG("TestSetSeq, Seq 0x%06x", seq); + if (seq > 0xFFFFFF) { BT_ERR("Invalid SEQ 0x%08x", seq); return; diff --git a/components/bt/esp_ble_mesh/core/transport.c b/components/bt/esp_ble_mesh/core/transport.c index 33054e847c93..b4855c4d87d0 100644 --- a/components/bt/esp_ble_mesh/core/transport.c +++ b/components/bt/esp_ble_mesh/core/transport.c @@ -29,7 +29,7 @@ #if CONFIG_BLE_MESH_V11_SUPPORT #include "mesh_v1.1/utils.h" -#endif +#endif /* CONFIG_BLE_MESH_V11_SUPPORT */ /* The transport layer needs at least three buffers for itself to avoid * deadlocks. Ensure that there are a sufficient number of advertising @@ -58,24 +58,24 @@ _Static_assert(CONFIG_BLE_MESH_ADV_BUF_COUNT >= (CONFIG_BLE_MESH_TX_SEG_MAX + 3) /* Number of retransmit attempts (after the initial transmit) per segment */ #define SEG_RETRANSMIT_ATTEMPTS 4 +/* How long to wait for available buffers before giving up */ +#define BUF_TIMEOUT K_NO_WAIT + /* "This timer shall be set to a minimum of 200 + 50 * TTL milliseconds.". * We use 400 since 300 is a common send duration for standard HCI, and we * need to have a timeout that's bigger than that. */ #define SEG_RETRANSMIT_TIMEOUT_UNICAST(tx) (K_MSEC(400) + 50 * (tx)->ttl) + /* When sending to a group, the messages are not acknowledged, and there's no * reason to delay the repetitions significantly. Delaying by more than 0 ms * to avoid flooding the network. */ #define SEG_RETRANSMIT_TIMEOUT_GROUP K_MSEC(50) -#define SEG_RETRANSMIT_TIMEOUT(tx) \ - (BLE_MESH_ADDR_IS_UNICAST((tx)->dst) ? \ - SEG_RETRANSMIT_TIMEOUT_UNICAST(tx) : \ - SEG_RETRANSMIT_TIMEOUT_GROUP) - -/* How long to wait for available buffers before giving up */ -#define BUF_TIMEOUT K_NO_WAIT +#define SEG_RETRANSMIT_TIMEOUT(tx) (BLE_MESH_ADDR_IS_UNICAST((tx)->dst) ? \ + SEG_RETRANSMIT_TIMEOUT_UNICAST(tx) : \ + SEG_RETRANSMIT_TIMEOUT_GROUP) static struct seg_tx { struct bt_mesh_subnet *sub; @@ -145,6 +145,8 @@ static inline void bt_mesh_seg_rx_unlock(void) uint8_t bt_mesh_get_seg_rtx_num(void) { + BT_DBG("SegRTXNum %u", SEG_RETRANSMIT_ATTEMPTS); + return SEG_RETRANSMIT_ATTEMPTS; } @@ -159,75 +161,10 @@ int32_t bt_mesh_get_seg_rtx_timeout(uint16_t dst, uint8_t ttl) struct seg_tx tx = { .ttl = ttl, }; - return SEG_RETRANSMIT_TIMEOUT_UNICAST(&tx); -} -struct bt_mesh_app_key *bt_mesh_app_key_get(uint16_t app_idx) -{ - if (bt_mesh_is_provisioned()) { -#if CONFIG_BLE_MESH_NODE - if (!IS_ENABLED(CONFIG_BLE_MESH_FAST_PROV)) { - for (int i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { - if (bt_mesh.app_keys[i].net_idx != BLE_MESH_KEY_UNUSED && - bt_mesh.app_keys[i].app_idx == app_idx) { - return &bt_mesh.app_keys[i]; - } - } - } else { - return bt_mesh_fast_prov_app_key_find(app_idx); - } -#endif - } else if (bt_mesh_is_provisioner_en()) { -#if CONFIG_BLE_MESH_PROVISIONER - for (int i = 0; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) { - if (bt_mesh.p_app_keys[i] && - bt_mesh.p_app_keys[i]->net_idx != BLE_MESH_KEY_UNUSED && - bt_mesh.p_app_keys[i]->app_idx == app_idx) { - return bt_mesh.p_app_keys[i]; - } - } -#endif - } - - return NULL; -} - -int bt_mesh_upper_key_get(const struct bt_mesh_subnet *subnet, uint16_t app_idx, - const uint8_t **key, uint8_t *aid, uint16_t dst) -{ - struct bt_mesh_app_key *app_key = NULL; + BT_DBG("SegRTXTimeout, TTL %u", ttl); - if (app_idx == BLE_MESH_KEY_DEV) { - *key = bt_mesh_dev_key_get(dst); - if (!*key) { - BT_ERR("DevKey of 0x%04x not found", dst); - return -EINVAL; - } - - *aid = 0U; - return 0; - } - - if (!subnet) { - BT_ERR("Invalid subnet"); - return -EINVAL; - } - - app_key = bt_mesh_app_key_get(app_idx); - if (!app_key) { - BT_ERR("AppKey 0x%04x not found", app_idx); - return -ENOENT; - } - - if (subnet->kr_phase == BLE_MESH_KR_PHASE_2 && app_key->updated) { - *key = app_key->keys[1].val; - *aid = app_key->keys[1].id; - } else { - *key = app_key->keys[0].val; - *aid = app_key->keys[0].id; - } - - return 0; + return SEG_RETRANSMIT_TIMEOUT_UNICAST(&tx); } static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, @@ -236,8 +173,10 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, { struct net_buf *buf = NULL; - BT_DBG("src 0x%04x dst 0x%04x app_idx 0x%04x sdu_len %u", - tx->src, tx->ctx->addr, tx->ctx->app_idx, sdu->len); + BT_DBG("SendUnseg"); + BT_DBG("Src 0x%04x Dst 0x%04x AppIdx 0x%04x CtlOp 0x%02x SduLen %u", + tx->src, tx->ctx->addr, tx->ctx->app_idx, + ctl_op ? *ctl_op : 0xFF, sdu->len); buf = bt_mesh_adv_create(BLE_MESH_ADV_DATA, BUF_TIMEOUT); if (!buf) { @@ -261,13 +200,14 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, if (!bt_mesh_friend_queue_has_space(tx->sub->net_idx, tx->src, tx->ctx->addr, NULL, 1)) { + BT_WARN("NoSpaceInFrndQueue, SegCount 1"); + if (BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { - BT_ERR("Not enough space in Friend Queue"); + BT_ERR("NotSentToUnicast"); net_buf_unref(buf); return -ENOBUFS; } - BT_WARN("No space in Friend Queue"); goto send; } @@ -277,6 +217,8 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, /* PDUs for a specific Friend should only go * out through the Friend Queue. */ + BT_DBG("FrndTxEnqueued, SegCount 1"); + net_buf_unref(buf); send_cb_finalize(cb, cb_data); return 0; @@ -289,6 +231,8 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, static inline uint8_t seg_len(bool ctl) { + BT_DBG("Ctl %u", ctl); + if (ctl) { return BLE_MESH_CTL_SEG_SDU_MAX; } @@ -302,26 +246,31 @@ bool bt_mesh_tx_in_progress(void) for (i = 0; i < ARRAY_SIZE(seg_tx); i++) { if (seg_tx[i].nack_count) { + BT_DBG("SegTxInProgress"); return true; } } + BT_DBG("SegTxNotInProgress"); return false; } static void seg_tx_done(struct seg_tx *tx, uint8_t seg_idx) { + BT_DBG("SegTxDone, SegIdx %u", seg_idx); bt_mesh_adv_buf_ref_debug(__func__, tx->seg[seg_idx], 3U, BLE_MESH_BUF_REF_SMALL); - /** - * When cancelling a segment that is still in the adv sending queue, `tx->seg_pending` - * must else be decremented by one. More detailed information - * can be found in BLEMESH24-26. + /* When cancelling a segment that is still in the adv sending queue, + * the `tx->seg_pending` must be decremented by one. + * More details could be found in BLEMESH24-26. */ if (bt_mesh_atomic_cas(&BLE_MESH_ADV_BUSY(tx->seg[seg_idx]), 1, 0)) { + BT_DBG("SegPendingDec %u", tx->seg_pending); tx->seg_pending--; } + BT_DBG("NackCountDec %u", tx->nack_count); + net_buf_unref(tx->seg[seg_idx]); tx->seg[seg_idx] = NULL; tx->nack_count--; @@ -331,6 +280,8 @@ static void seg_tx_reset(struct seg_tx *tx) { int i; + BT_DBG("SegTxReset"); + bt_mesh_seg_tx_lock(tx); k_delayed_work_cancel(&tx->rtx_timer); @@ -355,6 +306,7 @@ static void seg_tx_reset(struct seg_tx *tx) if (bt_mesh_atomic_test_and_clear_bit(bt_mesh.flags, BLE_MESH_IVU_PENDING)) { BT_DBG("Proceeding with pending IV Update"); + /* bt_mesh_net_iv_update() will re-enable the flag if this * wasn't the only transfer. */ @@ -369,6 +321,8 @@ static inline void seg_tx_complete(struct seg_tx *tx, int err) const struct bt_mesh_send_cb *cb = tx->cb; void *cb_data = tx->cb_data; + BT_DBG("SegTxComplete, Err %d", err); + seg_tx_reset(tx); /* TODO: notify the completion of sending segmented message */ @@ -380,35 +334,43 @@ static inline void seg_tx_complete(struct seg_tx *tx, int err) static void schedule_retransmit(struct seg_tx *tx) { - bt_mesh_seg_tx_lock(tx); - /* It's possible that a segment broadcast hasn't finished, - * but the tx are already released. Only the seg_pending - * of this segment remains unprocessed. So, here, we - * determine if the tx are released by checking if the - * destination (dst) is unassigned, and then process - * the seg_pending of this segment. + /* It's possible that a segment broadcast hasn't finished, but the tx + * has already been released. Only the seg_pending of this segment + * remains unprocessed. + * So, here we determine if the tx are released by checking if the + * destination (dst) is unassigned, and then process the seg_pending + * of this segment. * See BLEMESH25-92 for details */ + + BT_DBG("ScheduleRetransmit, Dst 0x%04x", tx->dst); + + bt_mesh_seg_tx_lock(tx); + if (tx->dst == BLE_MESH_ADDR_UNASSIGNED) { + BT_DBG("SegPending %u", tx->seg_pending); + if (tx->seg_pending) { tx->seg_pending--; } - bt_mesh_seg_tx_unlock(tx); - return; + goto end; } + BT_DBG("SegPending %u Attempts %u", tx->seg_pending, tx->attempts); + if (--tx->seg_pending) { - bt_mesh_seg_tx_unlock(tx); - return; + goto end; } if (!BLE_MESH_ADDR_IS_UNICAST(tx->dst) && !tx->attempts) { - BT_INFO("Complete tx sdu to group"); + BT_INFO("TxSduToGroupDone"); + seg_tx_complete(tx, 0); - bt_mesh_seg_tx_unlock(tx); - return; + goto end; } k_delayed_work_submit(&tx->rtx_timer, SEG_RETRANSMIT_TIMEOUT(tx)); + +end: bt_mesh_seg_tx_unlock(tx); } @@ -416,6 +378,8 @@ static void seg_first_send_start(uint16_t duration, int err, void *user_data) { struct seg_tx *tx = user_data; + BT_DBG("SegFirstSendStart, Err %d", err); + if (tx->cb && tx->cb->start) { tx->cb->start(duration, err, tx->cb_data); } @@ -425,6 +389,8 @@ static void seg_send_start(uint16_t duration, int err, void *user_data) { struct seg_tx *tx = user_data; + BT_DBG("SegSendStart, Err %d", err); + /* If there's an error in transmitting the 'sent' callback will never * be called. Make sure that we kick the retransmit timer also in this * case since otherwise we risk the transmission of becoming stale. @@ -438,6 +404,8 @@ static void seg_sent(int err, void *user_data) { struct seg_tx *tx = user_data; + BT_DBG("SegSent, Err %d", err); + schedule_retransmit(tx); } @@ -455,17 +423,19 @@ static void seg_tx_send_unacked(struct seg_tx *tx) { int i, err = 0; + BT_DBG("SegTxSendUnacked, Attempts %u", tx->attempts); + bt_mesh_seg_tx_lock(tx); if (!(tx->attempts--)) { BT_WARN("Ran out of retransmit attempts"); + bt_mesh_seg_tx_unlock(tx); + seg_tx_complete(tx, -ETIMEDOUT); return; } - BT_INFO("Attempts: %u", tx->attempts); - for (i = 0; i <= tx->seg_n; i++) { struct net_buf *seg = tx->seg[i]; @@ -478,9 +448,10 @@ static void seg_tx_send_unacked(struct seg_tx *tx) continue; } - tx->seg_pending++; + BT_INFO("SegPendingInc %u", tx->seg_pending); + BT_INFO("SegResend %u/%u Cred %u", i, tx->seg_n, tx->cred); - BT_INFO("Resending %u/%u, cred 0x%02x", i, tx->seg_n, tx->cred); + tx->seg_pending++; /* TODO: * tx->new_key should be replaced with sub->kr_flag, @@ -491,8 +462,10 @@ static void seg_tx_send_unacked(struct seg_tx *tx) &tx->cred, tx->tag, &seg_sent_cb, tx); if (err) { - BT_ERR("Sending segment failed"); + BT_ERR("ResendSegFailed, Err %d", err); + bt_mesh_seg_tx_unlock(tx); + seg_tx_complete(tx, -EIO); return; } @@ -505,6 +478,8 @@ static void seg_retransmit(struct k_work *work) { struct seg_tx *tx = CONTAINER_OF(work, struct seg_tx, rtx_timer); + BT_DBG("SegRetransmit"); + seg_tx_send_unacked(tx); } @@ -519,20 +494,24 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, int err = 0; int i; - BT_DBG("src 0x%04x dst 0x%04x app_idx 0x%04x aszmic %u sdu_len %u", + BT_DBG("SendSeg"); + BT_DBG("Src 0x%04x Dst 0x%04x AppIdx 0x%04x Aszmic %u SduLen %u", net_tx->src, net_tx->ctx->addr, net_tx->ctx->app_idx, net_tx->aszmic, sdu->len); for (tx = NULL, i = 0; i < ARRAY_SIZE(seg_tx); i++) { - if (!seg_tx[i].nack_count && - /* In some critical conditions, the tx might be - * reset before a segment broadcast is finished. - * If this happens, the seg_pending of the segment - * hasn't been processed. To avoid assigning this - * uncleared tx to a new message, extra checks for - * seg_pending being 0 are added. See BLEMESH25-92 - * for details.*/ - !seg_tx[i].seg_pending) { + /* In some critical conditions, the tx might be reset before + * a segment transmission is finished. + * If this happens, the seg_pending of the segment will not + * be processed. + * And to avoid assigning this uncleared tx to a new message, + * extra checks for seg_pending being 0 are added. + * See BLEMESH25-92 for details. + */ + BT_DBG("Seg%u: NackCount %u SegPending %u", + i, seg_tx[i].nack_count, seg_tx[i].seg_pending); + + if (!seg_tx[i].nack_count && !seg_tx[i].seg_pending) { tx = &seg_tx[i]; break; } @@ -576,15 +555,16 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, seq_zero = tx->seq_auth & TRANS_SEQ_ZERO_MASK; - BT_DBG("SeqZero 0x%04x", seq_zero); + BT_DBG("SegHdr 0x%02x SegN %u NackCount %u NewKey %u TTL %u SeqZero 0x%04x", + seg_hdr, tx->seg_n, tx->nack_count, tx->new_key, tx->ttl, seq_zero); if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && !bt_mesh_friend_queue_has_space(tx->sub->net_idx, net_tx->src, tx->dst, &tx->seq_auth, tx->seg_n + 1) && BLE_MESH_ADDR_IS_UNICAST(tx->dst)) { - BT_ERR("Not enough space in Friend Queue for %u segments", - tx->seg_n + 1); + BT_WARN("NoSpaceInFrndQueue, SegCount %u", tx->seg_n + 1); + seg_tx_reset(tx); return -ENOBUFS; } @@ -621,6 +601,8 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, type = BLE_MESH_FRIEND_PDU_PARTIAL; } + BT_DBG("FrndPDUType %u", type); + if (bt_mesh_friend_enqueue_tx(net_tx, type, &tx->seq_auth, tx->seg_n + 1, @@ -629,6 +611,8 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, /* PDUs for a specific Friend should only go * out through the Friend Queue. */ + BT_DBG("FrndTxEnqueued, SegCount %u", tx->seg_n + 1); + net_buf_unref(seg); continue; } @@ -636,14 +620,16 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, tx->seg[seg_o] = net_buf_ref(seg); - BT_DBG("Sending %u/%u", seg_o, tx->seg_n); + BT_INFO("SegPendingInc %u", tx->seg_pending); + BT_INFO("SegSend %u/%u Cred %u", seg_o, tx->seg_n, tx->cred); + tx->seg_pending++; err = bt_mesh_net_send(net_tx, seg, seg_o ? &seg_sent_cb : &first_sent_cb, tx); if (err) { - BT_ERR("Sending segment failed (err %d)", err); + BT_ERR("SendSegFailed, Err %d", err); break; } @@ -652,6 +638,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, * which will be used for retransmission later. */ if (tx->cred != net_tx->ctx->send_cred) { + BT_INFO("OldCred %u NewCred %u", tx->cred, net_tx->ctx->send_cred); tx->cred = net_tx->ctx->send_cred; } } @@ -665,7 +652,10 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, /* This can happen if segments only went into the Friend Queue */ if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && !tx->seg[0]) { + BT_DBG("OnlyToFrndQueue"); + seg_tx_reset(tx); + /* If there was a callback notify sending immediately since * there's no other way to track this (at least currently) * with the Friend Queue. @@ -689,6 +679,8 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, uint8_t aid = 0U; int err = 0; + BT_DBG("transcend"); + if (msg->len < 1) { BT_ERR("Zero-length SDU not allowed"); return -EINVAL; @@ -698,9 +690,9 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED; } - BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx->sub->net_idx, - tx->ctx->app_idx, tx->ctx->addr); - BT_DBG("len %u: %s", msg->len, bt_hex(msg->data, msg->len)); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Dst 0x%04x", + tx->sub->net_idx, tx->ctx->app_idx, tx->ctx->addr); + BT_DBG("Len %u: %s", msg->len, bt_hex(msg->data, msg->len)); err = bt_mesh_upper_key_get(tx->sub, tx->ctx->app_idx, &key, &aid, tx->ctx->addr); @@ -718,7 +710,7 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, tx->aszmic = 1U; } - BT_INFO("%s, send_tag 0x%02x, send_szmic %d, aszmic %d", + BT_INFO("%s, Tag 0x%02x Szmic %u Aszmic %u", bt_mesh_tag_send_segmented(tx->ctx->send_tag) ? "Seg" : "Unseg", tx->ctx->send_tag, tx->ctx->send_szmic, tx->aszmic); @@ -733,7 +725,7 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, tx->ctx->addr, bt_mesh.seq, BLE_MESH_NET_IVI_TX); if (err) { - BT_ERR("Encrypt failed (err %d)", err); + BT_ERR("AppEncryptFailed, Err %d", err); return err; } @@ -747,7 +739,7 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, static void revoke_dev_key(const uint8_t *dev_key) { if (!memcmp(dev_key, bt_mesh.dev_key_ca, 16)) { - BT_INFO("Revoke Device Key"); + BT_INFO("RevokeDevKey"); memcpy(bt_mesh.dev_key, bt_mesh.dev_key_ca, 16); memset(bt_mesh.dev_key_ca, 0, 16); @@ -768,8 +760,9 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr, size_t i = 0U; int err = 0; - BT_DBG("ASZMIC %u AKF %u AID 0x%02x", aszmic, AKF(&hdr), AID(&hdr)); - BT_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("SduRecv"); + BT_DBG("Aszmic %u AKF %u AID 0x%02x", aszmic, AKF(&hdr), AID(&hdr)); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); if (buf->len < 1 + APP_MIC_LEN(aszmic)) { BT_ERR("Too short SDU + MIC (len %u)", buf->len); @@ -808,7 +801,7 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr, dev_key = bt_mesh_rx_devkey_get(i, rx->ctx.addr); if (!dev_key) { - BT_DBG("DevKey not found"); + BT_DBG("DevKeyNotFound"); continue; } @@ -819,6 +812,7 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr, rx->ctx.recv_dst, seq, BLE_MESH_NET_IVI_RX(rx)); if (err) { + BT_DBG("DevKeyNotDecrypt"); continue; } @@ -844,6 +838,7 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr, } BT_WARN("Unable to decrypt with DevKey"); + bt_mesh_free_buf(sdu); return -ENODEV; } @@ -856,7 +851,7 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr, key = bt_mesh_rx_appkey_get(i); if (!key) { - BT_DBG("AppKey not found"); + BT_DBG("AppKeyNotFound"); continue; } @@ -890,8 +885,7 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr, bt_hex(sdu->data, sdu->len)); if (err) { - BT_DBG("Unable to decrypt with AppKey 0x%03x", - key->app_idx); + BT_DBG("AppKeyNotDecrypt, AppIdx 0x%04x", key->app_idx); continue; } @@ -903,8 +897,9 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr, } if (rx->local_match) { - BT_WARN("No matching AppKey"); + BT_WARN("NoMatchAppKey"); } + bt_mesh_free_buf(sdu); return 0; } @@ -914,6 +909,8 @@ static struct seg_tx *seg_tx_lookup(uint16_t seq_zero, uint8_t obo, uint16_t add struct seg_tx *tx = NULL; int i; + BT_DBG("SegTxLookup, SeqZero 0x%04x OBO %u Addr 0x%04x", seq_zero, obo, addr); + for (i = 0; i < ARRAY_SIZE(seg_tx); i++) { tx = &seg_tx[i]; @@ -922,6 +919,7 @@ static struct seg_tx *seg_tx_lookup(uint16_t seq_zero, uint8_t obo, uint16_t add } if (tx->dst == addr) { + BT_DBG("SegTxFound, Dst 0x%04x", addr); return tx; } @@ -931,6 +929,7 @@ static struct seg_tx *seg_tx_lookup(uint16_t seq_zero, uint8_t obo, uint16_t add * responding and therefore accept the message. */ if (obo && tx->nack_count == tx->seg_n + 1) { + BT_DBG("SegTxOboFound, Dst 0x%04x", addr); tx->dst = addr; return tx; } @@ -943,11 +942,13 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, struct net_buf_simple *buf, uint64_t *seq_auth) { struct seg_tx *tx = NULL; + uint16_t seq_zero = 0U; unsigned int bit = 0; uint32_t ack = 0U; - uint16_t seq_zero = 0U; uint8_t obo = 0U; + BT_DBG("TransAck"); + if (buf->len != 6) { BT_ERR("Malformed Segment Ack (len %u)", buf->len); return -EINVAL; @@ -966,7 +967,7 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, ack = net_buf_simple_pull_be32(buf); - BT_DBG("OBO %u seq_zero 0x%04x ack 0x%08x", obo, seq_zero, ack); + BT_DBG("OBO %u SeqZero 0x%04x Ack 0x%08lx", obo, seq_zero, ack); tx = seg_tx_lookup(seq_zero, obo, rx->ctx.addr); if (!tx) { @@ -997,6 +998,7 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, while ((bit = find_lsb_set(ack))) { if (tx->seg[bit - 1]) { BT_INFO("Seg %u/%u acked", bit - 1, tx->seg_n); + bt_mesh_seg_tx_lock(tx); seg_tx_done(tx, bit - 1); bt_mesh_seg_tx_unlock(tx); @@ -1021,6 +1023,8 @@ static int trans_heartbeat(struct bt_mesh_net_rx *rx, uint8_t init_ttl = 0U, hops = 0U; uint16_t feat = 0U; + BT_DBG("TransHeartbeat"); + if (buf->len != 3) { BT_ERR("Malformed heartbeat message (len %u)", buf->len); return -EINVAL; @@ -1037,9 +1041,8 @@ static int trans_heartbeat(struct bt_mesh_net_rx *rx, hops = (init_ttl - rx->ctx.recv_ttl + 1); - BT_INFO("src 0x%04x TTL %u InitTTL %u (%u hop%s) feat 0x%04x", - rx->ctx.addr, rx->ctx.recv_ttl, init_ttl, hops, - (hops == 1U) ? "" : "s", feat); + BT_INFO("Src 0x%04x TTL %u InitTTL %u Hops %u Feat 0x%04x", + rx->ctx.addr, rx->ctx.recv_ttl, init_ttl, hops, feat); if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { bt_mesh_heartbeat_recv(rx->ctx.addr, rx->ctx.recv_dst, hops, feat); @@ -1057,7 +1060,7 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, uint8_t hdr, { uint8_t ctl_op = TRANS_CTL_OP(&hdr); - BT_DBG("OpCode 0x%02x len %u", ctl_op, buf->len); + BT_DBG("CTLRecv, OpCode 0x%02x Len %u", ctl_op, buf->len); BT_BQB(BLE_MESH_BQB_TEST_LOG_LEVEL_PRIMARY_ID_NODE | \ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_TNPT, @@ -1074,6 +1077,7 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, uint8_t hdr, /* Only acks and heartbeats may need processing without local_match */ if (!rx->local_match) { + BT_DBG("LocalNotMatch"); return 0; } @@ -1088,7 +1092,7 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, uint8_t hdr, case TRANS_CTL_OP_PATH_REQ_SOLIC: return bt_mesh_directed_forwarding_ctl_recv(ctl_op, rx, buf); } -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && !bt_mesh_lpn_established()) { switch (ctl_op) { @@ -1141,7 +1145,7 @@ static int trans_unseg(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx, { uint8_t hdr = 0U; - BT_DBG("AFK %u AID 0x%02x", AKF(buf->data), AID(buf->data)); + BT_DBG("TransUnseg, AKF %u AID 0x%02x", AKF(buf->data), AID(buf->data)); if (buf->len < 1) { BT_ERR("Too small unsegmented PDU"); @@ -1149,7 +1153,7 @@ static int trans_unseg(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx, } if (bt_mesh_rpl_check(rx, NULL)) { - BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", + BT_WARN("Replay, Src 0x%04x Dst 0x%04x Seq 0x%06x", rx->ctx.addr, rx->ctx.recv_dst, rx->seq); return -EINVAL; } @@ -1162,6 +1166,7 @@ static int trans_unseg(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx, /* SDUs must match a local element or an LPN of this Friend. */ if (!rx->local_match && !rx->friend_match) { + BT_DBG("LocalAndFrndNotMatch"); return 0; } @@ -1187,6 +1192,8 @@ static inline int32_t ack_timeout(struct seg_rx *rx) /* 100 ms for every not yet received segment */ to += K_MSEC(((rx->seg_n + 1) - popcount(rx->block)) * 100U); + BT_DBG("AckTimeout, TTL %u TO %ld", ttl, to); + /* Make sure we don't send more frequently than the duration for * each packet (default is 300ms). */ @@ -1199,6 +1206,8 @@ int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, uint8_t ctl_op, void *data, { struct net_buf_simple buf = {0}; + BT_DBG("CtlSend"); + net_buf_simple_init_with_data(&buf, data, data_len); if (data_len > BLE_MESH_SDU_UNSEG_MAX) { @@ -1208,9 +1217,9 @@ int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, uint8_t ctl_op, void *data, /* Set app_idx to unused here since CTL is only encrypted with NetKey */ tx->ctx->app_idx = BLE_MESH_KEY_UNUSED; - BT_DBG("src 0x%04x dst 0x%04x ttl 0x%02x ctl 0x%02x", tx->src, - tx->ctx->addr, tx->ctx->send_ttl, ctl_op); - BT_DBG("len %zu: %s", data_len, bt_hex(data, data_len)); + BT_DBG("Src 0x%04x Dst 0x%04x TTL 0x%02x CTL 0x%02x", + tx->src, tx->ctx->addr, tx->ctx->send_ttl, ctl_op); + BT_DBG("Len %u: %s", data_len, bt_hex(data, data_len)); if (bt_mesh_tag_send_segmented(tx->ctx->send_tag)) { return send_seg(tx, &buf, cb, cb_data, &ctl_op); @@ -1242,7 +1251,7 @@ static int send_ack(struct bt_mesh_subnet *sub, uint16_t src, uint16_t dst, uint16_t seq_zero = *seq_auth & TRANS_SEQ_ZERO_MASK; uint8_t buf[6] = {0}; - BT_DBG("SeqZero 0x%04x Block 0x%08x OBO %u", seq_zero, block, obo); + BT_DBG("SendAck, SeqZero 0x%04x Block 0x%08lx OBO %u", seq_zero, block, obo); if (bt_mesh_lpn_established()) { BT_WARN("Not sending ack when LPN is enabled"); @@ -1266,6 +1275,8 @@ static int send_ack(struct bt_mesh_subnet *sub, uint16_t src, uint16_t dst, static void seg_rx_reset(struct seg_rx *rx, bool full_reset) { + BT_DBG("SegRxReset, FullReset %u", full_reset); + bt_mesh_seg_rx_lock(); k_delayed_work_cancel(&rx->ack_timer); @@ -1310,6 +1321,8 @@ static uint32_t incomplete_timeout(struct seg_rx *rx) /* The less segments being received, the shorter timeout will be used. */ timeout += K_MSEC(ttl * popcount(rx->block) * 100U); + BT_DBG("IncompleteTimeout %lu", timeout); + return MIN(timeout, K_SECONDS(60)); } @@ -1317,11 +1330,15 @@ static void seg_ack(struct k_work *work) { struct seg_rx *rx = CONTAINER_OF(work, struct seg_rx, ack_timer); + BT_DBG("SegAck, Last %lu", rx->last); + bt_mesh_seg_rx_lock(); if (k_uptime_get_32() - rx->last > incomplete_timeout(rx)) { BT_WARN("Incomplete timer expired"); + bt_mesh_seg_rx_unlock(); + seg_rx_reset(rx, false); return; } @@ -1365,9 +1382,9 @@ static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx, */ #if CONFIG_BLE_MESH_DISCARD_OLD_SEQ_AUTH if (rx->seq_auth >= *seq_auth) { -#else +#else /* CONFIG_BLE_MESH_DISCARD_OLD_SEQ_AUTH */ if (rx->seq_auth == *seq_auth) { -#endif +#endif /* CONFIG_BLE_MESH_DISCARD_OLD_SEQ_AUTH */ return rx; } @@ -1390,6 +1407,8 @@ static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx, static bool seg_rx_is_valid(struct seg_rx *rx, struct bt_mesh_net_rx *net_rx, const uint8_t *hdr, uint8_t seg_n) { + BT_DBG("IsSegRxValid"); + if (rx->hdr != *hdr || rx->seg_n != seg_n) { BT_ERR("Invalid segment for ongoing session"); return false; @@ -1454,18 +1473,20 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, uint8_t seg_o = 0U; int err = 0; + BT_DBG("TransSeg"); + if (buf->len < 5) { BT_ERR("Too short segmented message (len %u)", buf->len); return -EINVAL; } if (bt_mesh_rpl_check(net_rx, &rpl)) { - BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", + BT_WARN("Replay, Src 0x%04x Dst 0x%04x Seq 0x%06x", net_rx->ctx.addr, net_rx->ctx.recv_dst, net_rx->seq); return -EINVAL; } - BT_DBG("ASZMIC %u AKF %u AID 0x%02x", ASZMIC(hdr), AKF(hdr), AID(hdr)); + BT_DBG("Aszmic %u AKF %u AID 0x%02x", ASZMIC(hdr), AKF(hdr), AID(hdr)); net_buf_simple_pull(buf, 1); @@ -1502,13 +1523,15 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, *seg_count = seg_n + 1; + BT_DBG("Src 0x%04x Dst 0x%04x SeqAuth 0x%llx SegCount %u", + net_rx->ctx.addr, net_rx->ctx.recv_dst, *seq_auth, *seg_count); + /* Look for old RX sessions */ rx = seg_rx_find(net_rx, seq_auth); if (rx) { /* Discard old SeqAuth packet */ if (rx->seq_auth > *seq_auth) { - BT_WARN("Ignoring old SeqAuth, src 0x%04x, dst 0x%04x", - rx->src, rx->dst); + BT_WARN("SeqAuth 0x%llx vs. 0x%llx", rx->seq_auth, *seq_auth); return -EINVAL; } @@ -1523,6 +1546,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, if (rx->block == BLOCK_COMPLETE(rx->seg_n)) { BT_INFO("Got segment for already complete SDU"); + send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr, net_rx->ctx.send_ttl, seq_auth, rx->block, rx->obo); @@ -1560,10 +1584,11 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, net_rx->ctx.addr, net_rx->ctx.recv_dst, seq_auth, *seg_count)) { - BT_ERR("No space in Friend Queue for %u segments", *seg_count); - send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr, - net_rx->ctx.send_ttl, seq_auth, 0, - net_rx->friend_match); + BT_WARN("NoSpaceInFrndQueue, SegCount %u", *seg_count); + + send_ack(net_rx->sub, net_rx->ctx.recv_dst, + net_rx->ctx.addr, net_rx->ctx.send_ttl, + seq_auth, 0, net_rx->friend_match); return -ENOBUFS; } @@ -1574,7 +1599,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, * eventually be freed up and we'll be able to process * this one. */ - BT_WARN("No free slots for new incoming segmented messages, src: %04x", net_rx->ctx.addr); + BT_WARN("SegRxFull, Src %04x", net_rx->ctx.addr); return -ENOMEM; } @@ -1601,7 +1626,9 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr, net_rx->ctx.send_ttl, seq_auth, 0, rx->obo); + seg_rx_reset(rx, true); + return -EMSGSIZE; } } else { @@ -1628,6 +1655,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, rx->block |= BIT(seg_o); if (rx->block != BLOCK_COMPLETE(seg_n)) { + BT_DBG("FrndPDUPartial"); *pdu_type = BLE_MESH_FRIEND_PDU_PARTIAL; return 0; } @@ -1648,8 +1676,8 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, if (net_rx->ctl) { err = ctl_recv(net_rx, *hdr, &rx->buf, seq_auth); } else { - err = sdu_recv(net_rx, (rx->seq_auth & 0xffffff), *hdr, - ASZMIC(hdr), &rx->buf); + err = sdu_recv(net_rx, (rx->seq_auth & 0xffffff), + *hdr, ASZMIC(hdr), &rx->buf); } seg_rx_reset(rx, false); @@ -1659,12 +1687,14 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) { - uint64_t seq_auth = TRANS_SEQ_AUTH_NVAL; enum bt_mesh_friend_pdu_type pdu_type = BLE_MESH_FRIEND_PDU_SINGLE; struct net_buf_simple_state state = {0}; + uint64_t seq_auth = TRANS_SEQ_AUTH_NVAL; uint8_t seg_count = 0U; int err = 0; + BT_DBG("TransRecv"); + if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) { rx->friend_match = bt_mesh_friend_match(rx->sub->net_idx, rx->ctx.recv_dst); @@ -1672,20 +1702,21 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) rx->friend_match = false; } - BT_DBG("src 0x%04x dst 0x%04x seq 0x%08x friend_match %u", + BT_DBG("Src 0x%04x Dst 0x%04x Seq 0x%06x FrndMatch %u", rx->ctx.addr, rx->ctx.recv_dst, rx->seq, rx->friend_match); /* Remove network headers */ net_buf_simple_pull(buf, BLE_MESH_NET_HDR_LEN); - BT_DBG("Payload %s", bt_hex(buf->data, buf->len)); + BT_DBG("PDU %u %s", buf->len, bt_hex(buf->data, buf->len)); /* If LPN mode is enabled messages are only accepted when we've * requested the Friend to send them. The messages must also * be encrypted using the Friend Credentials. */ if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) && - bt_mesh_lpn_established() && rx->net_if == BLE_MESH_NET_IF_ADV && + bt_mesh_lpn_established() && + rx->net_if == BLE_MESH_NET_IF_ADV && (!bt_mesh_lpn_waiting_update() || rx->ctx.recv_cred != BLE_MESH_FRIENDSHIP_CRED)) { BT_WARN("Ignoring unexpected message in Low Power mode"); @@ -1702,12 +1733,14 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) * LPN of this Friend. */ if (!rx->local_match && !rx->friend_match) { + BT_DBG("LocalAndFrndNotMatch"); return 0; } err = trans_seg(buf, rx, &pdu_type, &seq_auth, &seg_count); } else { seg_count = 1U; + err = trans_unseg(buf, rx, &seq_auth); } @@ -1747,6 +1780,8 @@ void bt_mesh_rx_reset(void) { int i; + BT_DBG("RxReset"); + for (i = 0; i < ARRAY_SIZE(seg_rx); i++) { seg_rx_reset(&seg_rx[i], true); } @@ -1756,6 +1791,8 @@ void bt_mesh_tx_reset(void) { int i; + BT_DBG("TxReset"); + for (i = 0; i < ARRAY_SIZE(seg_tx); i++) { seg_tx_reset(&seg_tx[i]); } @@ -1765,6 +1802,8 @@ void bt_mesh_rx_reset_single(uint16_t src) { int i; + BT_DBG("RxResetSingle, Src 0x%04x", src); + if (!BLE_MESH_ADDR_IS_UNICAST(src)) { return; } @@ -1781,6 +1820,8 @@ void bt_mesh_tx_reset_single(uint16_t dst) { int i; + BT_DBG("TxResetSingle, Dst 0x%04x", dst); + if (!BLE_MESH_ADDR_IS_UNICAST(dst)) { return; } diff --git a/components/bt/esp_ble_mesh/core/transport.enh.c b/components/bt/esp_ble_mesh/core/transport.enh.c index a4a5130e2150..00caddac31a8 100644 --- a/components/bt/esp_ble_mesh/core/transport.enh.c +++ b/components/bt/esp_ble_mesh/core/transport.enh.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -141,121 +141,93 @@ static inline void bt_mesh_seg_rx_unlock(void) uint8_t bt_mesh_seg_send_interval(void) { - return (bt_mesh_get_sar_sis() + 1) * 10; + uint8_t interval = (bt_mesh_get_sar_sis() + 1) * 10; + + BT_DBG("SegSendInterval %u", interval); + + return interval; } uint8_t bt_mesh_get_seg_rtx_num(void) { - return bt_mesh_get_sar_urc(); + uint8_t num = bt_mesh_get_sar_urc(); + + BT_DBG("SegRTXNum %u", num); + + return num; } int32_t bt_mesh_seg_rtx_interval(uint16_t dst, uint8_t ttl) { + int32_t interval = 0; + if (BLE_MESH_ADDR_IS_UNICAST(dst)) { if (ttl == 0) { - return (bt_mesh_get_sar_uris() + 1) * 25; + interval = (bt_mesh_get_sar_uris() + 1) * 25; + } else { + interval = ((bt_mesh_get_sar_uris() + 1) * 25 + + (bt_mesh_get_sar_urii() + 1) * 25 * (ttl - 1)); } - - return ((bt_mesh_get_sar_uris() + 1) * 25 + - (bt_mesh_get_sar_urii() + 1) * 25 * (ttl - 1)); + } else { + interval = (bt_mesh_get_sar_mris() + 1) * 25; } - return (bt_mesh_get_sar_mris() + 1) * 25; + BT_DBG("SegRTXInterval %ld, Dst 0x%04x TTL %u", interval, dst, ttl); + + return interval; } int32_t bt_mesh_get_seg_rtx_timeout(uint16_t dst, uint8_t ttl) { - return bt_mesh_seg_rtx_interval(dst, ttl); + int32_t timeout = bt_mesh_seg_rtx_interval(dst, ttl); + + BT_DBG("SegRTXTimeout %ld, Dst 0x%04x TTL %u", timeout, dst, ttl); + + return timeout; } uint32_t bt_mesh_seg_discard_timeout(void) { - return K_SECONDS((bt_mesh_get_sar_dt() + 1) * 5); + uint32_t timeout = K_SECONDS((bt_mesh_get_sar_dt() + 1) * 5); + + BT_DBG("SegDiscardTimeout %lu", timeout); + + return timeout; } uint32_t bt_mesh_seg_rx_interval(void) { - return (bt_mesh_get_sar_rsis() + 1) * 10; + uint32_t interval = (bt_mesh_get_sar_rsis() + 1) * 10; + + BT_DBG("SegRxInterval %lu", interval); + + return interval; } uint32_t bt_mesh_seg_ack_timeout(uint8_t seg_n) { - float min = MIN((float)seg_n + 0.5, (float)bt_mesh_get_sar_adi() + 1.5); - return (uint32_t)(min * bt_mesh_seg_rx_interval()); -} + uint32_t timeout = 0U; + float min = 0.0; -uint32_t bt_mesh_seg_ack_period(void) -{ - float val = (float)bt_mesh_get_sar_adi() + 1.5; - return (uint32_t)(val * bt_mesh_seg_rx_interval()); -} + min = MIN((float)seg_n + 0.5, (float)bt_mesh_get_sar_adi() + 1.5); + timeout = (uint32_t)(min * bt_mesh_seg_rx_interval()); -struct bt_mesh_app_key *bt_mesh_app_key_get(uint16_t app_idx) -{ - if (bt_mesh_is_provisioned()) { -#if CONFIG_BLE_MESH_NODE - if (!IS_ENABLED(CONFIG_BLE_MESH_FAST_PROV)) { - for (int i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { - if (bt_mesh.app_keys[i].net_idx != BLE_MESH_KEY_UNUSED && - bt_mesh.app_keys[i].app_idx == app_idx) { - return &bt_mesh.app_keys[i]; - } - } - } else { - return bt_mesh_fast_prov_app_key_find(app_idx); - } -#endif - } else if (bt_mesh_is_provisioner_en()) { -#if CONFIG_BLE_MESH_PROVISIONER - for (int i = 0; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) { - if (bt_mesh.p_app_keys[i] && - bt_mesh.p_app_keys[i]->net_idx != BLE_MESH_KEY_UNUSED && - bt_mesh.p_app_keys[i]->app_idx == app_idx) { - return bt_mesh.p_app_keys[i]; - } - } -#endif - } + BT_DBG("SegAckTimeout %lu, Min %f", timeout, min); - return NULL; + return timeout; } -int bt_mesh_upper_key_get(const struct bt_mesh_subnet *subnet, uint16_t app_idx, - const uint8_t **key, uint8_t *aid, uint16_t dst) +uint32_t bt_mesh_seg_ack_period(void) { - struct bt_mesh_app_key *app_key = NULL; + uint32_t period = 0U; + float val = 0.0; - if (app_idx == BLE_MESH_KEY_DEV) { - *key = bt_mesh_dev_key_get(dst); - if (!*key) { - BT_ERR("DevKey of 0x%04x not found", dst); - return -EINVAL; - } - - *aid = 0U; - return 0; - } - - if (!subnet) { - BT_ERR("Invalid subnet"); - return -EINVAL; - } - - app_key = bt_mesh_app_key_get(app_idx); - if (!app_key) { - BT_ERR("AppKey 0x%04x not found", app_idx); - return -ENOENT; - } + val = (float)bt_mesh_get_sar_adi() + 1.5; + period = (uint32_t)(val * bt_mesh_seg_rx_interval()); - if (subnet->kr_phase == BLE_MESH_KR_PHASE_2 && app_key->updated) { - *key = app_key->keys[1].val; - *aid = app_key->keys[1].id; - } else { - *key = app_key->keys[0].val; - *aid = app_key->keys[0].id; - } + BT_DBG("SegAckPeriod %lu, Val %f", period, val); - return 0; + return period; } static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, @@ -264,8 +236,10 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, { struct net_buf *buf = NULL; - BT_DBG("src 0x%04x dst 0x%04x app_idx 0x%04x sdu_len %u", - tx->src, tx->ctx->addr, tx->ctx->app_idx, sdu->len); + BT_DBG("SendUnseg"); + BT_DBG("Src 0x%04x Dst 0x%04x AppIdx 0x%04x CtlOp 0x%02x SduLen %u", + tx->src, tx->ctx->addr, tx->ctx->app_idx, + ctl_op ? *ctl_op : 0xFF, sdu->len); buf = bt_mesh_adv_create(BLE_MESH_ADV_DATA, BUF_TIMEOUT); if (!buf) { @@ -289,13 +263,14 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, if (!bt_mesh_friend_queue_has_space(tx->sub->net_idx, tx->src, tx->ctx->addr, NULL, 1)) { + BT_WARN("NoSpaceInFrndQueue, SegCount 1"); + if (BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { - BT_ERR("Not enough space in Friend Queue"); + BT_ERR("NotSentToUnicast"); net_buf_unref(buf); return -ENOBUFS; } - BT_WARN("No space in Friend Queue"); goto send; } @@ -305,6 +280,8 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, /* PDUs for a specific Friend should only go * out through the Friend Queue. */ + BT_DBG("FrndTxEnqueued, SegCount 1"); + net_buf_unref(buf); send_cb_finalize(cb, cb_data); return 0; @@ -317,6 +294,8 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, static inline uint8_t seg_len(bool ctl) { + BT_DBG("Ctl %u", ctl); + if (ctl) { return BLE_MESH_CTL_SEG_SDU_MAX; } @@ -330,20 +309,28 @@ bool bt_mesh_tx_in_progress(void) for (i = 0; i < ARRAY_SIZE(seg_tx); i++) { if (seg_tx[i].nack_count) { + BT_DBG("SegTxInProgress"); return true; } } + BT_DBG("SegTxNotInProgress"); return false; } static bool seg_tx_blocks(struct seg_tx *tx, uint16_t src, uint16_t dst) { + BT_DBG("SegTxBlocks"); + BT_DBG("Src 0x%04x vs. 0x%04x", tx->src, src); + BT_DBG("Dst 0x%04x vs. 0x%04x", tx->dst, dst); + return (tx->src == src) && (tx->dst == dst); } static void seg_tx_done(struct seg_tx *tx, uint8_t seg_idx) { + BT_DBG("SegTxDone, SegIdx %u", seg_idx); + /* If the segments are sent from local network interface, buf->ref * should be smaller than 4. * For other network interfaces, buf->ref should be smaller than 3. @@ -353,12 +340,16 @@ static void seg_tx_done(struct seg_tx *tx, uint8_t seg_idx) bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(tx->seg[seg_idx]), 0); net_buf_unref(tx->seg[seg_idx]); + BT_DBG("NackCountDec %u", tx->nack_count); + tx->seg[seg_idx] = NULL; tx->nack_count--; } static void seg_tx_reset(struct seg_tx *tx) { + BT_DBG("SegTxReset"); + bt_mesh_seg_tx_lock(); k_delayed_work_free(&tx->seg_timer); @@ -390,6 +381,7 @@ static void seg_tx_reset(struct seg_tx *tx) if (bt_mesh_atomic_test_and_clear_bit(bt_mesh.flags, BLE_MESH_IVU_PENDING)) { BT_DBG("Proceeding with pending IV Update"); + /* bt_mesh_net_iv_update() will re-enable the flag if this * wasn't the only transfer. */ @@ -404,6 +396,8 @@ static void seg_tx_complete(struct seg_tx *tx, int err) const struct bt_mesh_send_cb *cb = tx->cb; void *cb_data = tx->cb_data; + BT_DBG("SegTxComplete, Err %d", err); + seg_tx_reset(tx); /* TODO: notify the completion of sending segmented message */ @@ -420,10 +414,15 @@ static bool all_seg_acked(struct seg_tx *tx, uint8_t *seg_n) if (seg_n) { *seg_n = i; } + + BT_DBG("NotAllSegAcked, SegN %u", i); + return false; } } + BT_DBG("AllSegAcked"); + return true; } @@ -447,6 +446,10 @@ static bool send_next_segment(struct seg_tx *tx, int *result) struct net_buf *seg = NULL; int err = 0; + BT_DBG("SendNextSeg"); + BT_DBG("Src 0x%04x Dst 0x%04x LastSegN %u SegN %u LSNUpdated %u", + tx->src, tx->dst, tx->last_seg_n, tx->seg_n, tx->lsn_updated); + /* Check if all the segments are acknowledged. This could happen * when the complete Segment ACK (i.e. with all ack bits set) is * received before sending the next segment, which will cause the @@ -478,6 +481,8 @@ static bool send_next_segment(struct seg_tx *tx, int *result) * not been acknowledged. */ if (tx->seg[i]) { + BT_DBG("SegFound %u", i); + tx->last_seg_n = i; seg = tx->seg[i]; break; @@ -499,16 +504,19 @@ static bool send_next_segment(struct seg_tx *tx, int *result) * Segment Retransmission timer is expired earlier. */ if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(seg))) { + BT_DBG("SegSentBusy"); return false; } - BT_INFO("Send next seg %u, cred %u", tx->last_seg_n, tx->cred); + BT_INFO("LastSegN %u Cred %u", tx->last_seg_n, tx->cred); if (tx->resend) { err = bt_mesh_net_resend(tx->sub, seg, tx->new_key, &tx->cred, tx->tag, &seg_sent_cb, tx); if (err) { - BT_ERR("Resend seg %u failed (err %d)", tx->last_seg_n, err); + BT_ERR("ResendSegFailed, LastSegN %u Err %d", + tx->last_seg_n, err); + *result = -EIO; return true; } @@ -517,15 +525,16 @@ static bool send_next_segment(struct seg_tx *tx, int *result) net_tx.ctx->net_idx = tx->sub->net_idx; - /** - * Add one to the ref count only if the segment can be further + /* Add one to the ref count only if the segment can be further * processed by the network. */ seg = net_buf_ref(seg); err = bt_mesh_net_send(&net_tx, seg, &seg_sent_cb, tx); if (err) { - BT_ERR("Send seg %u failed (err %d)", tx->last_seg_n, err); + BT_ERR("SendSegFailed, LastSegN %u Err %d", + tx->last_seg_n, err); + *result = -EIO; return true; } @@ -535,7 +544,9 @@ static bool send_next_segment(struct seg_tx *tx, int *result) * which will be used for retransmission later. */ if (tx->cred != net_tx.ctx->send_cred) { - BT_ERR("Mismatch seg cred %u/%u", tx->cred, net_tx.ctx->send_cred); + BT_ERR("MismatchSegCred %u vs. %u", + tx->cred, net_tx.ctx->send_cred); + *result = -EIO; return true; } @@ -553,6 +564,8 @@ static void send_next_seg(struct k_work *work) tx_complete = send_next_segment(tx, &result); bt_mesh_seg_tx_unlock(); + BT_DBG("SendNextSeg, TxComplete %u", tx_complete); + if (tx_complete) { seg_tx_complete(tx, result); } @@ -564,6 +577,8 @@ static void prepare_next_seg(struct seg_tx *tx) uint8_t seg_n = 0; uint8_t xmit = 0; + BT_DBG("PrepareNextSeg"); + /* Check if all the segments are acknowledged. This could happen * when the complete Segment ACK (i.e. with all ack bits set) is * received before the completion of sending last segment, which @@ -574,6 +589,8 @@ static void prepare_next_seg(struct seg_tx *tx) return; } + BT_DBG("LastSegN %u SegN %u SegNGet %u", tx->last_seg_n, tx->seg_n, seg_n); + /* The last_seg_n must not be larger than the seg_n */ assert(tx->last_seg_n <= tx->seg_n && "Too large last_seg_n"); @@ -607,7 +624,7 @@ static void prepare_next_seg(struct seg_tx *tx) interval = bt_mesh_seg_send_interval(); - BT_INFO("Send next segment %u after %dms", i, interval); + BT_INFO("SendNextSeg %u, Interval %ld", i, interval); k_delayed_work_submit(&tx->seg_timer, interval); return; @@ -619,6 +636,7 @@ static void prepare_next_seg(struct seg_tx *tx) * we need to decrypt it firstly. */ if (tx->resend == 0) { + BT_DBG("TxResendMarked"); tx->resend = 1; } @@ -629,7 +647,7 @@ static void prepare_next_seg(struct seg_tx *tx) /* Start the SAR retransmission timer */ interval = bt_mesh_seg_rtx_interval(tx->dst, tx->ttl); - BT_INFO("All segments sent, resend after %dms", interval); + BT_INFO("AllSegsSent, SegN %u Interval %ld", seg_n, interval); k_delayed_work_submit(&tx->rtx_timer, interval); } @@ -638,6 +656,8 @@ static void seg_send_start(uint16_t duration, int err, void *user_data) { struct seg_tx *tx = user_data; + BT_DBG("SegSendStart, Err %d", err); + /* If there's an error in transmitting the 'sent' callback will never * be called. Make sure that we kick the retransmit timer also in this * case since otherwise we risk the transmission of becoming stale. @@ -647,6 +667,8 @@ static void seg_send_start(uint16_t duration, int err, void *user_data) return; } + BT_DBG("TxResend %u LastSegN %u", tx->resend, tx->last_seg_n); + if (tx->resend == 0 && tx->last_seg_n == 0) { /* Start sending the multi-segment message */ if (tx->cb && tx->cb->start) { @@ -663,6 +685,8 @@ static void seg_send_end(int err, void *user_data) { struct seg_tx *tx = user_data; + BT_DBG("SegSendEnd, Err %d", err); + if (err) { seg_tx_complete(tx, -EIO); } @@ -678,6 +702,10 @@ static bool resend_unacked_seg(struct seg_tx *tx, int *result) struct net_buf *seg = NULL; int err = 0; + BT_DBG("ResendUnackedSeg"); + BT_DBG("Dst 0x%04x Surc %u Surwpc %u Smrc %u", + tx->dst, tx->surc, tx->surwpc, tx->smrc); + /* Check if all the segments are acknowledged. This could happen * when the complete Segment ACK(i.e. with all ack bits set) is * received before the completion of sending last segment, which @@ -747,6 +775,8 @@ static bool resend_unacked_seg(struct seg_tx *tx, int *result) */ for (size_t i = tx->last_seg_n; i <= tx->seg_n; i++) { if (tx->seg[i]) { + BT_DBG("SegFound %u", i); + tx->last_seg_n = i; seg = tx->seg[i]; break; @@ -769,10 +799,11 @@ static bool resend_unacked_seg(struct seg_tx *tx, int *result) * find that the "busy" flag of Segment A is 1. */ if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(seg))) { + BT_DBG("SegSentBusy"); return false; } - BT_INFO("Resend seg %u, cred %u", tx->last_seg_n, tx->cred); + BT_INFO("LastSegN %u Cred %u", tx->last_seg_n, tx->cred); /* TODO: * The "tx->new_key" should be replaced with sub->kr_flag, @@ -783,7 +814,9 @@ static bool resend_unacked_seg(struct seg_tx *tx, int *result) &tx->cred, tx->tag, &seg_sent_cb, tx); if (err) { - BT_ERR("Resend seg %u failed (err %d)", tx->last_seg_n, err); + BT_ERR("ResendSegFailed, LastSegN %u Err %d", + tx->last_seg_n, err); + *result = -EIO; return true; } @@ -803,6 +836,8 @@ static void seg_retransmit(struct k_work *work) tx_complete = resend_unacked_seg(tx, &err); bt_mesh_seg_tx_unlock(); + BT_DBG("SendRetransmit, TxComplete %u", tx_complete); + if (tx_complete) { seg_tx_complete(tx, err); } @@ -818,11 +853,14 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, int err = 0; size_t i; - BT_DBG("src 0x%04x dst 0x%04x app_idx 0x%04x aszmic %u sdu_len %u", + BT_DBG("SendSeg"); + BT_DBG("Src 0x%04x Dst 0x%04x AppIdx 0x%04x Aszmic %u SduLen %u", net_tx->src, net_tx->ctx->addr, net_tx->ctx->app_idx, net_tx->aszmic, sdu->len); for (i = 0; i < ARRAY_SIZE(seg_tx); i++) { + BT_DBG("Seg%u: NackCount %u", i, seg_tx[i].nack_count); + if (seg_tx[i].nack_count) { /* The lower transport layer shall not transmit segmented messages * for more than one Upper Transport PDU to the same destination @@ -837,6 +875,8 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, for (tx = NULL, i = 0; i < ARRAY_SIZE(seg_tx); i++) { if (!seg_tx[i].nack_count) { + BT_DBG("SegTxFound %u", i); + tx = &seg_tx[i]; break; } @@ -916,15 +956,18 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, seq_zero = tx->seq_auth & TRANS_SEQ_ZERO_MASK; - BT_DBG("SeqZero 0x%04x (segs: %u)", seq_zero, tx->nack_count); + BT_DBG("SegHdr 0x%02x SegN %u NackCount %u NewKey %u TTL %u", + tx->hdr, tx->seg_n, tx->nack_count, tx->new_key, tx->ttl); + BT_DBG("SeqZero 0x%04x Surc %u Surwpc %u Smrc %u", + seq_zero, tx->surc, tx->surwpc, tx->smrc); if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && !bt_mesh_friend_queue_has_space(tx->sub->net_idx, net_tx->src, tx->dst, &tx->seq_auth, tx->seg_n + 1) && BLE_MESH_ADDR_IS_UNICAST(tx->dst)) { - BT_ERR("Not enough space in Friend Queue for %u segments", - tx->seg_n + 1); + BT_WARN("NoSpaceInFrndQueue, SegCount %u", tx->seg_n + 1); + seg_tx_reset(tx); return -ENOBUFS; } @@ -959,6 +1002,8 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, type = BLE_MESH_FRIEND_PDU_PARTIAL; } + BT_DBG("FrndPDUType %u", type); + if (bt_mesh_friend_enqueue_tx(net_tx, type, &tx->seq_auth, tx->seg_n + 1, @@ -967,39 +1012,40 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, /* PDUs for a specific Friend should only go * out through the Friend Queue. */ + BT_DBG("FrndTxEnqueued, SegCount %u", tx->seg_n + 1); + net_buf_unref(seg); continue; } } - /** - * If the net buffer allocation of the subsequent - * segments of this segment message fails, it will - * cause the ref count of the previously allocated - * successful segments to not be unref, which will - * cause the net buffer leakage to occur, so it is - * necessary to wait until all the segments have been - * allocated, and then when the segment is confirmed - * that it will be network layer for further processing, - * then ref of the net buffer should be plus one. + /* If the net buffer allocation of the subsequent segments of + * this segment message fails, it will cause the ref count of + * the previously allocated successful segments to not be unref, + * which will cause the net buffer leakage to occur, so it is + * necessary to wait until all the segments have been allocated, + * and then when the segment is confirmed that it will be network + * layer for further processing, then ref of the net buffer should + * be plus one. */ tx->seg[seg_o] = seg; - BT_DBG("Seg %u/%u prepared", seg_o, tx->seg_n); + BT_DBG("SegPrepared %u/%u", seg_o, tx->seg_n); } /* If all the segments are enqueued in the friend queue, then the * tx->seg[0] will be NULL here. */ if (tx->seg[0]) { - /** - * Add one to the ref count only if the segment can be further + /* Add one to the ref count only if the segment can be further * processed by the network. */ tx->seg[0] = net_buf_ref(tx->seg[0]); + err = bt_mesh_net_send(net_tx, tx->seg[0], &seg_sent_cb, tx); if (err) { - BT_ERR("Send 1st seg failed (err %d)", err); + BT_ERR("SendFirstSegFailed, Err %d", err); + seg_tx_reset(tx); return err; } @@ -1009,13 +1055,17 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, * which will be used for retransmission later. */ if (tx->cred != net_tx->ctx->send_cred) { + BT_INFO("OldCred %u NewCred %u", tx->cred, net_tx->ctx->send_cred); tx->cred = net_tx->ctx->send_cred; } } /* This can happen if segments only went into the Friend Queue */ if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && !tx->seg[0]) { + BT_DBG("OnlyToFrndQueue"); + seg_tx_reset(tx); + /* If there was a callback notify sending immediately since * there's no other way to track this (at least currently) * with the Friend Queue. @@ -1039,6 +1089,8 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, uint8_t aid = 0U; int err = 0; + BT_DBG("transcend"); + if (msg->len < 1) { BT_ERR("Zero-length SDU not allowed"); return -EINVAL; @@ -1048,9 +1100,9 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED; } - BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx->sub->net_idx, - tx->ctx->app_idx, tx->ctx->addr); - BT_DBG("len %u: %s", msg->len, bt_hex(msg->data, msg->len)); + BT_DBG("NetIdx 0x%04x AppIdx 0x%04x Dst 0x%04x", + tx->sub->net_idx, tx->ctx->app_idx, tx->ctx->addr); + BT_DBG("Len %u: %s", msg->len, bt_hex(msg->data, msg->len)); err = bt_mesh_upper_key_get(tx->sub, tx->ctx->app_idx, &key, &aid, tx->ctx->addr); @@ -1068,7 +1120,7 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, tx->aszmic = 1U; } - BT_INFO("%s, send_tag 0x%02x, send_szmic %d, aszmic %d", + BT_INFO("%s, Tag 0x%02x Szmic %u Aszmic %u", bt_mesh_tag_send_segmented(tx->ctx->send_tag) ? "Seg" : "Unseg", tx->ctx->send_tag, tx->ctx->send_szmic, tx->aszmic); @@ -1083,7 +1135,7 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, tx->ctx->addr, bt_mesh.seq, BLE_MESH_NET_IVI_TX); if (err) { - BT_ERR("Encrypt failed (err %d)", err); + BT_ERR("AppEncryptFailed, Err %d", err); return err; } @@ -1097,7 +1149,7 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, static void revoke_dev_key(const uint8_t *dev_key) { if (!memcmp(dev_key, bt_mesh.dev_key_ca, 16)) { - BT_INFO("Revoke Device Key"); + BT_INFO("RevokeDevKey"); memcpy(bt_mesh.dev_key, bt_mesh.dev_key_ca, 16); memset(bt_mesh.dev_key_ca, 0, 16); @@ -1118,8 +1170,9 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr, size_t i = 0U; int err = 0; - BT_DBG("ASZMIC %u AKF %u AID 0x%02x", aszmic, AKF(&hdr), AID(&hdr)); - BT_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_DBG("SduRecv"); + BT_DBG("Aszmic %u AKF %u AID 0x%02x", aszmic, AKF(&hdr), AID(&hdr)); + BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); if (buf->len < 1 + APP_MIC_LEN(aszmic)) { BT_ERR("Too short SDU + MIC (len %u)", buf->len); @@ -1158,7 +1211,7 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr, dev_key = bt_mesh_rx_devkey_get(i, rx->ctx.addr); if (!dev_key) { - BT_DBG("DevKey not found"); + BT_DBG("DevKeyNotFound"); continue; } @@ -1169,6 +1222,7 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr, rx->ctx.recv_dst, seq, BLE_MESH_NET_IVI_RX(rx)); if (err) { + BT_DBG("DevKeyNotDecrypt"); continue; } @@ -1194,6 +1248,7 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr, } BT_WARN("Unable to decrypt with DevKey"); + bt_mesh_free_buf(sdu); return -ENODEV; } @@ -1206,7 +1261,7 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr, key = bt_mesh_rx_appkey_get(i); if (!key) { - BT_DBG("AppKey not found"); + BT_DBG("AppKeyNotFound"); continue; } @@ -1240,8 +1295,7 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr, bt_hex(sdu->data, sdu->len)); if (err) { - BT_DBG("Unable to decrypt with AppKey 0x%03x", - key->app_idx); + BT_DBG("AppKeyNotDecrypt, AppIdx 0x%04x", key->app_idx); continue; } @@ -1253,10 +1307,10 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr, } if (rx->local_match) { - BT_WARN("No matching AppKey"); + BT_WARN("NoMatchAppKey"); } - bt_mesh_free_buf(sdu); + bt_mesh_free_buf(sdu); return 0; } @@ -1266,6 +1320,8 @@ static struct seg_tx *seg_tx_lookup(uint16_t seq_zero, uint8_t obo, struct seg_tx *tx = NULL; int i; + BT_DBG("SegTxLookup, SeqZero 0x%04x OBO %u Addr 0x%04x", seq_zero, obo, addr); + for (i = 0; i < ARRAY_SIZE(seg_tx); i++) { tx = &seg_tx[i]; @@ -1281,6 +1337,7 @@ static struct seg_tx *seg_tx_lookup(uint16_t seq_zero, uint8_t obo, } if (tx->dst == addr) { + BT_DBG("SegTxFound, Dst 0x%04x", addr); return tx; } @@ -1290,6 +1347,7 @@ static struct seg_tx *seg_tx_lookup(uint16_t seq_zero, uint8_t obo, * responding and therefore accept the message. */ if (obo && tx->nack_count == tx->seg_n + 1) { + BT_DBG("SegTxOboFound, Dst 0x%04x", addr); tx->dst = addr; return tx; } @@ -1316,6 +1374,8 @@ static int recv_seg_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, *tx_complete = false; *result = 0; + BT_DBG("RecvSegAck"); + if (buf->len != 6) { BT_ERR("Malformed Segment Ack (len %u)", buf->len); return -EINVAL; @@ -1334,7 +1394,7 @@ static int recv_seg_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, ack = net_buf_simple_pull_be32(buf); - BT_DBG("OBO %u seq_zero 0x%04x ack 0x%08x", obo, seq_zero, ack); + BT_DBG("OBO %u SeqZero 0x%04x Ack 0x%08lx", obo, seq_zero, ack); tx = seg_tx_lookup(seq_zero, obo, rx->ctx.addr, rx->ctx.net_idx); if (!tx) { @@ -1392,6 +1452,8 @@ static int recv_seg_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, return 0; } + BT_DBG("NewlyMarked"); + /* If at least one segment is newly marked as acknowledged as * a result of receiving the Segment Acknowledgment message, * the lower transport layer shall set the remaining number of @@ -1401,9 +1463,12 @@ static int recv_seg_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, tx->surwpc = bt_mesh_get_sar_urwpc(); } + BT_DBG("Surc %u Surwpc %u", tx->surc, tx->surwpc); + if (tx->surc == 0 || tx->surwpc == 0) { BT_WARN("Ran out of retransmission to 0x%04x (%u/%u)", tx->dst, tx->surc, tx->surwpc); + *tx_complete = true; *result = -ETIMEDOUT; return 0; @@ -1411,6 +1476,8 @@ static int recv_seg_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, assert(all_seg_acked(tx, &seg_n) == false && "All segments acked"); + BT_DBG("SegN %u TxResend %u", seg_n, tx->resend); + if (tx->resend == 1) { /* Only update the last_seg_n to the first unacked SegN while * the first round transmission is finished, because we need @@ -1439,7 +1506,7 @@ static int recv_seg_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, /* Restart the SAR Unicast Retransmission timer */ interval = bt_mesh_seg_rtx_interval(tx->dst, tx->ttl); - BT_INFO("Resend segments after %dms", interval); + BT_INFO("ResendSeg, Interval %ld", interval); k_delayed_work_submit(&tx->rtx_timer, interval); @@ -1458,6 +1525,8 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, err = recv_seg_ack(rx, hdr, buf, seq_auth, &tx, &tx_complete, &result); bt_mesh_seg_tx_unlock(); + BT_DBG("TransAck, TxComplete %u", tx_complete); + if (tx_complete) { seg_tx_complete(tx, result); } @@ -1471,6 +1540,8 @@ static int trans_heartbeat(struct bt_mesh_net_rx *rx, uint8_t init_ttl = 0U, hops = 0U; uint16_t feat = 0U; + BT_DBG("TransHeartbeat"); + if (buf->len != 3) { BT_ERR("Malformed heartbeat message (len %u)", buf->len); return -EINVAL; @@ -1487,9 +1558,8 @@ static int trans_heartbeat(struct bt_mesh_net_rx *rx, hops = (init_ttl - rx->ctx.recv_ttl + 1); - BT_INFO("src 0x%04x TTL %u InitTTL %u (%u hop%s) feat 0x%04x", - rx->ctx.addr, rx->ctx.recv_ttl, init_ttl, hops, - (hops == 1U) ? "" : "s", feat); + BT_INFO("Src 0x%04x TTL %u InitTTL %u Hops %u Feat 0x%04x", + rx->ctx.addr, rx->ctx.recv_ttl, init_ttl, hops, feat); if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { bt_mesh_heartbeat_recv(rx->ctx.addr, rx->ctx.recv_dst, hops, feat); @@ -1507,7 +1577,7 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, uint8_t hdr, { uint8_t ctl_op = TRANS_CTL_OP(&hdr); - BT_DBG("OpCode 0x%02x len %u", ctl_op, buf->len); + BT_DBG("CTLRecv, OpCode 0x%02x Len %u", ctl_op, buf->len); BT_BQB(BLE_MESH_BQB_TEST_LOG_LEVEL_PRIMARY_ID_NODE | \ BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_TNPT, @@ -1524,21 +1594,22 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, uint8_t hdr, /* Only acks and heartbeats may need processing without local_match */ if (!rx->local_match) { + BT_DBG("LocalNotMatch"); return 0; } - if (IS_ENABLED(CONFIG_BLE_MESH_DF_SRV)) { - switch (ctl_op) { - case TRANS_CTL_OP_PATH_REQ: - case TRANS_CTL_OP_PATH_REPLY: - case TRANS_CTL_OP_PATH_CFM: - case TRANS_CTL_OP_PATH_ECHO_REQ: - case TRANS_CTL_OP_PATH_ECHO_REPLY: - case TRANS_CTL_OP_DEP_NODE_UPDATE: - case TRANS_CTL_OP_PATH_REQ_SOLIC: - return bt_mesh_directed_forwarding_ctl_recv(ctl_op, rx, buf); - } +#if CONFIG_BLE_MESH_DF_SRV + switch (ctl_op) { + case TRANS_CTL_OP_PATH_REQ: + case TRANS_CTL_OP_PATH_REPLY: + case TRANS_CTL_OP_PATH_CFM: + case TRANS_CTL_OP_PATH_ECHO_REQ: + case TRANS_CTL_OP_PATH_ECHO_REPLY: + case TRANS_CTL_OP_DEP_NODE_UPDATE: + case TRANS_CTL_OP_PATH_REQ_SOLIC: + return bt_mesh_directed_forwarding_ctl_recv(ctl_op, rx, buf); } +#endif /* CONFIG_BLE_MESH_DF_SRV */ if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && !bt_mesh_lpn_established()) { switch (ctl_op) { @@ -1591,7 +1662,7 @@ static int trans_unseg(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx, { uint8_t hdr = 0U; - BT_DBG("AFK %u AID 0x%02x", AKF(buf->data), AID(buf->data)); + BT_DBG("TransUnseg, AKF %u AID 0x%02x", AKF(buf->data), AID(buf->data)); if (buf->len < 1) { BT_ERR("Too small unsegmented PDU"); @@ -1599,7 +1670,7 @@ static int trans_unseg(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx, } if (bt_mesh_rpl_check(rx, NULL)) { - BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", + BT_WARN("Replay, Src 0x%04x Dst 0x%04x Seq 0x%06x", rx->ctx.addr, rx->ctx.recv_dst, rx->seq); return -EINVAL; } @@ -1612,6 +1683,7 @@ static int trans_unseg(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx, /* SDUs must match a local element or an LPN of this Friend. */ if (!rx->local_match && !rx->friend_match) { + BT_DBG("LocalAndFrndNotMatch"); return 0; } @@ -1624,6 +1696,8 @@ int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, uint8_t ctl_op, void *data, { struct net_buf_simple buf = {0}; + BT_DBG("CtlSend"); + net_buf_simple_init_with_data(&buf, data, data_len); if (data_len > BLE_MESH_SDU_UNSEG_MAX) { @@ -1633,9 +1707,9 @@ int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, uint8_t ctl_op, void *data, /* Set app_idx to unused here since CTL is only encrypted with NetKey */ tx->ctx->app_idx = BLE_MESH_KEY_UNUSED; - BT_DBG("src 0x%04x dst 0x%04x ttl 0x%02x ctl 0x%02x", tx->src, - tx->ctx->addr, tx->ctx->send_ttl, ctl_op); - BT_DBG("len %zu: %s", data_len, bt_hex(data, data_len)); + BT_DBG("Src 0x%04x Dst 0x%04x TTL 0x%02x CTL 0x%02x", + tx->src, tx->ctx->addr, tx->ctx->send_ttl, ctl_op); + BT_DBG("Len %u: %s", data_len, bt_hex(data, data_len)); if (bt_mesh_tag_send_segmented(tx->ctx->send_tag)) { return send_seg(tx, &buf, cb, cb_data, &ctl_op); @@ -1648,18 +1722,21 @@ static void seg_ack_send_start(uint16_t duration, int err, void *user_data) { struct seg_rx *rx = user_data; - BT_INFO("Send segment ack start (err %d)", err); + BT_INFO("SegAckSendStart, Err %d", err); if (err) { rx->last_ack = k_uptime_get_32(); + + BT_DBG("LastAck %lu", rx->last_ack); } } static void seg_ack_send_end(int err, void *user_data) { struct seg_rx *rx = user_data; + uint32_t interval = 0U; - BT_INFO("Send segment ack end"); + BT_INFO("SegAckSendEnd, InUse %u Err %d", rx->in_use, err); /* This could happen when during the Segment ACK transaction, * the seg_rx is been reset. @@ -1670,6 +1747,9 @@ static void seg_ack_send_end(int err, void *user_data) rx->last_ack = k_uptime_get_32(); + BT_DBG("LastAck %lu SegN %u Sarc %u NewSeg %u", + rx->last_ack, rx->seg_n, rx->sarc, rx->new_seg); + /* If the seg_rx is in use, we will restart the SAR ACK timer if * the SegN is greater than the SAR Segments Threshold. * Note: @@ -1687,10 +1767,12 @@ static void seg_ack_send_end(int err, void *user_data) /* Decrement the SAR ACK Retransmissions Count */ rx->sarc -= 1; - BT_INFO("Resend segment ack after %dms", bt_mesh_seg_rx_interval()); + interval = bt_mesh_seg_rx_interval(); + + BT_INFO("ResendSeg, Interval %lu", interval); /* Introduce a delay for the Segment ACK retransmission */ - k_delayed_work_submit(&rx->ack_timer, bt_mesh_seg_rx_interval()); + k_delayed_work_submit(&rx->ack_timer, interval); } } @@ -1728,7 +1810,7 @@ static int send_ack(struct bt_mesh_subnet *sub, uint16_t src, uint16_t dst, uint16_t seq_zero = *seq_auth & TRANS_SEQ_ZERO_MASK; uint8_t buf[6] = {0}; - BT_DBG("SeqZero 0x%04x Block 0x%08x OBO %u", seq_zero, block, obo); + BT_DBG("SendAck, SeqZero 0x%04x Block 0x%08lx OBO %u", seq_zero, block, obo); if (bt_mesh_lpn_established()) { BT_WARN("Not sending ack when LPN is enabled"); @@ -1752,6 +1834,8 @@ static int send_ack(struct bt_mesh_subnet *sub, uint16_t src, uint16_t dst, static void seg_rx_reset(struct seg_rx *rx, bool full_reset) { + BT_DBG("SegRxReset, FullReset %u", full_reset); + bt_mesh_seg_rx_lock(); k_delayed_work_free(&rx->dis_timer); @@ -1792,6 +1876,8 @@ static void send_seg_ack(struct k_work *work) { struct seg_rx *rx = CONTAINER_OF(work, struct seg_rx, ack_timer); + BT_DBG("SendSegAck, Sub %p", rx->sub); + bt_mesh_seg_rx_lock(); /* This could happen when the SAR ACK timer expired, and a BTC @@ -1818,6 +1904,9 @@ static void send_seg_ack(struct k_work *work) static void discard_msg(struct k_work *work) { struct seg_rx *rx = CONTAINER_OF(work, struct seg_rx, dis_timer); + uint32_t timeout = 0U; + + BT_DBG("DiscardMsg, InUse %u Dst 0x%04x", rx->in_use, rx->dst); /* This could happen when the SAR Discard timer expired, and a * BTC event is posted to the BTC queue. @@ -1835,22 +1924,27 @@ static void discard_msg(struct k_work *work) k_delayed_work_cancel(&rx->ack_timer); } - BT_WARN("Discard timer expired (%dms)", bt_mesh_seg_discard_timeout()); + timeout = bt_mesh_seg_discard_timeout(); + + BT_WARN("DiscardTimerExpired, timeout %lu", timeout); - /* Not fully reset the seg_rx, in case any segment of this - * message is received later. + /* Not fully reset the seg_rx, in case any segment of + * this message is received later. */ seg_rx_reset(rx, false); } static inline bool sdu_len_is_ok(bool ctl, uint8_t seg_n) { + BT_DBG("IsSduLenOK,Len:%u,SegN:%u", seg_len, seg_n); return ((seg_n + 1) * seg_len(ctl) <= CONFIG_BLE_MESH_RX_SDU_MAX); } static void seg_rx_reset_pending(struct bt_mesh_net_rx *net_rx, const uint64_t *seq_auth) { + BT_DBG("SegRxResetPending, SeqAuth 0x%llx", *seq_auth); + for (size_t i = 0; i < ARRAY_SIZE(seg_rx); i++) { struct seg_rx *rx = &seg_rx[i]; @@ -1870,9 +1964,13 @@ static void seg_rx_reset_pending(struct bt_mesh_net_rx *net_rx, static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx, const uint64_t *seq_auth) { + BT_DBG("SegRxFind, SeqAuth 0x%llx", *seq_auth); for (size_t i = 0; i < ARRAY_SIZE(seg_rx); i++) { struct seg_rx *rx = &seg_rx[i]; + BT_DBG("Seg%u/%u: Src 0x%04x Dst 0x%04x SeqAuth 0x%llx", + i,rx->seg_n, rx->src, rx->dst, rx->seq_auth); + if (rx->src == net_rx->ctx.addr && rx->dst == net_rx->ctx.recv_dst && rx->seq_auth >= *seq_auth) { @@ -1886,6 +1984,8 @@ static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx, static bool seg_rx_is_valid(struct seg_rx *rx, struct bt_mesh_net_rx *net_rx, const uint8_t *hdr, uint8_t seg_n) { + BT_DBG("IsSegRxValid"); + if (rx->hdr != *hdr || rx->seg_n != seg_n) { BT_ERR("Invalid segment for ongoing session"); return false; @@ -1905,8 +2005,42 @@ static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx, { int err = 0; +<<<<<<< HEAD +<<<<<<< HEAD for (size_t i = 0; i < ARRAY_SIZE(seg_rx); i++) { struct seg_rx *rx = &seg_rx[i]; +======= +<<<<<<< HEAD +======= +>>>>>>> 9fc4381f187 (fix(ble_mesh): resolve miscellaneous logging issues) + /* By default, traditional seg_rx is used for allocation. + * If the first segment received is the last segment of + * the long packet, and its length is the length of the traditional packet, + * Since it is impossible to determine whether it is a long packet + * under the current situation, can only copy the rx information + * into the ext_rx buffer when the next segment received and can be + * confirmed to be a long packet*/ + struct seg_rx *seg_rx_buf = seg_rx; + uint16_t rx_buf_size = ARRAY_SIZE(seg_rx); + +#if CONFIG_BLE_MESH_LONG_PACKET + if (net_rx->ctx.enh.long_pkt_cfg_used) { + seg_rx_buf = ext_seg_rx; + rx_buf_size = ARRAY_SIZE(ext_seg_rx); + } +#endif + + for (size_t i = 0; i < rx_buf_size; i++) { + struct seg_rx *rx = &seg_rx_buf[i]; + +<<<<<<< HEAD + for (size_t i = 0; i < ARRAY_SIZE(seg_rx); i++) { + struct seg_rx *rx = &seg_rx[i]; +>>>>>>> 7652269a401 (feat(ble_mesh): Miscellaneous log enhancement for BLE Mesh) +>>>>>>> bdcd87e62fa (feat(ble_mesh): Miscellaneous log enhancement for BLE Mesh) +======= + BT_DBG("SegRxAlloc, SegN %u", seg_n); +>>>>>>> 9fc4381f187 (fix(ble_mesh): resolve miscellaneous logging issues) if (rx->in_use) { continue; @@ -1922,7 +2056,7 @@ static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx, err = k_delayed_work_init(&rx->ack_timer, send_seg_ack); if (err) { BT_ERR("No free ack_timer for new incoming segmented message"); - k_delayed_work_free(&rx->dis_timer); /* Must do */ + k_delayed_work_free(&rx->dis_timer); return NULL; } } @@ -1946,7 +2080,6 @@ static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx, return rx; } - BT_WARN("No free slots for new incoming segmented messages"); return NULL; } @@ -1962,18 +2095,20 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, uint8_t seg_o = 0U; int err = 0; + BT_DBG("TransSeg"); + if (buf->len < 5) { BT_ERR("Too short segmented message (len %u)", buf->len); return -EINVAL; } if (bt_mesh_rpl_check(net_rx, &rpl)) { - BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", + BT_WARN("Replay, Src 0x%04x Dst 0x%04x Seq 0x%06x", net_rx->ctx.addr, net_rx->ctx.recv_dst, net_rx->seq); return -EINVAL; } - BT_DBG("ASZMIC %u AKF %u AID 0x%02x", ASZMIC(hdr), AKF(hdr), AID(hdr)); + BT_DBG("Aszmic %u AKF %u AID 0x%02x", ASZMIC(hdr), AKF(hdr), AID(hdr)); net_buf_simple_pull(buf, 1); @@ -2000,6 +2135,9 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, *seg_count = seg_n + 1; + BT_DBG("Src 0x%04x Dst 0x%04x SeqAuth 0x%llx SegCount %u", + net_rx->ctx.addr, net_rx->ctx.recv_dst, *seq_auth, *seg_count); + /* If this is the first segment, check if any pending reassembly * exists. If yes, we need to discard the pending reassembly. * Note: @@ -2013,8 +2151,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, if (rx) { /* Processing result is SeqAuth Error, ignore the segment */ if (rx->seq_auth > *seq_auth) { - BT_WARN("Ignoring old SeqAuth, src 0x%04x, dst 0x%04x", - rx->src, rx->dst); + BT_WARN("SeqAuth 0x%llx vs. 0x%llx", rx->seq_auth, *seq_auth); return -EINVAL; } @@ -2079,7 +2216,8 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, net_rx->ctx.addr, net_rx->ctx.recv_dst, seq_auth, *seg_count)) { - BT_ERR("No space in Friend Queue for %u segments", *seg_count); + BT_ERR("NoSpaceInFrndQueue, SegCount %u", *seg_count); + send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr, net_rx->ctx.send_ttl, seq_auth, 0, net_rx->friend_match, NULL); @@ -2089,6 +2227,8 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, /* Look for free slot for a new RX session */ rx = seg_rx_alloc(net_rx, hdr, seq_auth, seg_n); if (!rx) { + BT_WARN("SegRxFull, Src %04x", net_rx->ctx.addr); + /* Processing result is Message Rejected, respond with a Segment * ACK with the AckedSegments field set to 0x00000000. */ @@ -2118,7 +2258,15 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, /* Set the expected final buffer length */ rx->buf.len = seg_n * seg_len(rx->ctl) + buf->len; +<<<<<<< HEAD +<<<<<<< HEAD BT_DBG("Target len %u * %u + %u = %u", seg_n, seg_len(rx->ctl), +======= +<<<<<<< HEAD +======= +>>>>>>> 9fc4381f187 (fix(ble_mesh): resolve miscellaneous logging issues) + BT_DBG("Target len %u * %u + %u = %u", seg_n, seg_len(&si), +>>>>>>> bdcd87e62fa (feat(ble_mesh): Miscellaneous log enhancement for BLE Mesh) buf->len, rx->buf.len); /* This should not happen, since we have made sure the whole @@ -2126,13 +2274,26 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, * But if the peer device sends the segments of a segmented * message with different CTL, then the following could happen. */ +<<<<<<< HEAD +<<<<<<< HEAD if (rx->buf.len > CONFIG_BLE_MESH_RX_SDU_MAX) { +======= +<<<<<<< HEAD +======= +>>>>>>> 9fc4381f187 (fix(ble_mesh): resolve miscellaneous logging issues) + if ((!rx->ext && rx->buf.len > CONFIG_BLE_MESH_RX_SDU_MAX) +#if CONFIG_BLE_MESH_LONG_PACKET + || (rx->ext && rx->buf.len > BLE_MESH_EXT_RX_SDU_MAX) +#endif + ) { +>>>>>>> bdcd87e62fa (feat(ble_mesh): Miscellaneous log enhancement for BLE Mesh) BT_ERR("Too large SDU len %u/%u", rx->buf.len, CONFIG_BLE_MESH_RX_SDU_MAX); send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr, net_rx->ctx.send_ttl, seq_auth, 0, rx->obo, NULL); + seg_rx_reset(rx, true); return -EMSGSIZE; @@ -2180,6 +2341,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, rx->block |= BIT(seg_o); if (rx->block != BLOCK_COMPLETE(seg_n)) { + BT_DBG("FrndPDUPartial"); *pdu_type = BLE_MESH_FRIEND_PDU_PARTIAL; return 0; } @@ -2203,8 +2365,8 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, if (net_rx->ctl) { err = ctl_recv(net_rx, *hdr, &rx->buf, seq_auth); } else { - err = sdu_recv(net_rx, (rx->seq_auth & 0xffffff), *hdr, - ASZMIC(hdr), &rx->buf); + err = sdu_recv(net_rx, (rx->seq_auth & 0xffffff), + *hdr, ASZMIC(hdr), &rx->buf); } seg_rx_reset(rx, false); @@ -2214,12 +2376,14 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) { - uint64_t seq_auth = TRANS_SEQ_AUTH_NVAL; enum bt_mesh_friend_pdu_type pdu_type = BLE_MESH_FRIEND_PDU_SINGLE; struct net_buf_simple_state state = {0}; + uint64_t seq_auth = TRANS_SEQ_AUTH_NVAL; uint8_t seg_count = 0U; int err = 0; + BT_DBG("TransRecv"); + if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) { rx->friend_match = bt_mesh_friend_match(rx->sub->net_idx, rx->ctx.recv_dst); @@ -2227,20 +2391,21 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) rx->friend_match = false; } - BT_DBG("src 0x%04x dst 0x%04x seq 0x%08x friend_match %u", + BT_DBG("Src 0x%04x Dst 0x%04x Seq 0x%06x FrndMatch %u", rx->ctx.addr, rx->ctx.recv_dst, rx->seq, rx->friend_match); /* Remove network headers */ net_buf_simple_pull(buf, BLE_MESH_NET_HDR_LEN); - BT_DBG("Payload %s", bt_hex(buf->data, buf->len)); + BT_DBG("PDU %s", bt_hex(buf->data, buf->len)); /* If LPN mode is enabled messages are only accepted when we've * requested the Friend to send them. The messages must also * be encrypted using the Friend Credentials. */ if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) && - bt_mesh_lpn_established() && rx->net_if == BLE_MESH_NET_IF_ADV && + bt_mesh_lpn_established() && + rx->net_if == BLE_MESH_NET_IF_ADV && (!bt_mesh_lpn_waiting_update() || rx->ctx.recv_cred != BLE_MESH_FRIENDSHIP_CRED)) { BT_WARN("Ignoring unexpected message in Low Power mode"); @@ -2257,12 +2422,14 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) * LPN of this Friend. */ if (!rx->local_match && !rx->friend_match) { + BT_DBG("LocalAndFrndNotMatch"); return 0; } err = trans_seg(buf, rx, &pdu_type, &seq_auth, &seg_count); } else { seg_count = 1U; + err = trans_unseg(buf, rx, &seq_auth); } @@ -2300,6 +2467,8 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) void bt_mesh_rx_reset(void) { + BT_DBG("RxReset"); + for (size_t i = 0; i < ARRAY_SIZE(seg_rx); i++) { seg_rx_reset(&seg_rx[i], true); } @@ -2307,6 +2476,8 @@ void bt_mesh_rx_reset(void) void bt_mesh_tx_reset(void) { + BT_DBG("TxReset"); + for (size_t i = 0; i < ARRAY_SIZE(seg_tx); i++) { seg_tx_reset(&seg_tx[i]); } @@ -2314,6 +2485,8 @@ void bt_mesh_tx_reset(void) void bt_mesh_rx_reset_single(uint16_t src) { + BT_DBG("RxResetSingle, Src 0x%04x", src); + if (!BLE_MESH_ADDR_IS_UNICAST(src)) { return; } @@ -2328,6 +2501,8 @@ void bt_mesh_rx_reset_single(uint16_t src) void bt_mesh_tx_reset_single(uint16_t dst) { + BT_DBG("TxResetSingle, Dst 0x%04x", dst); + if (!BLE_MESH_ADDR_IS_UNICAST(dst)) { return; } diff --git a/components/bt/esp_ble_mesh/models/client/client_common.c b/components/bt/esp_ble_mesh/models/client/client_common.c index 7e5448707d96..211e4d84356e 100644 --- a/components/bt/esp_ble_mesh/models/client/client_common.c +++ b/components/bt/esp_ble_mesh/models/client/client_common.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,18 +16,22 @@ #if CONFIG_BLE_MESH_V11_SUPPORT #include "mesh_v1.1/utils.h" -#endif +#endif /* CONFIG_BLE_MESH_V11_SUPPORT */ #define HCI_TIME_FOR_START_ADV K_MSEC(5) /* Three adv related hci commands may take 4 ~ 5ms */ -static bt_mesh_client_node_t *bt_mesh_client_pick_node(sys_slist_t *list, uint16_t tx_dst) +static bt_mesh_client_node_t *client_pick_node(sys_slist_t *list, uint16_t tx_dst) { bt_mesh_client_node_t *node = NULL; sys_snode_t *cur = NULL; + BT_DBG("ClientPickNode, Dst 0x%04x", tx_dst); + bt_mesh_list_lock(); + if (sys_slist_is_empty(list)) { bt_mesh_list_unlock(); + BT_DBG("ListEmpty"); return NULL; } @@ -36,22 +40,28 @@ static bt_mesh_client_node_t *bt_mesh_client_pick_node(sys_slist_t *list, uint16 node = (bt_mesh_client_node_t *)cur; if (node->ctx.addr == tx_dst) { bt_mesh_list_unlock(); + BT_DBG("ListNodeFound"); return node; } } bt_mesh_list_unlock(); + + BT_DBG("ListNodeNotFound"); return NULL; } bt_mesh_client_node_t *bt_mesh_is_client_recv_publish_msg(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, bool need_pub) + struct net_buf_simple *buf, + bool need_pub) { bt_mesh_client_internal_data_t *data = NULL; bt_mesh_client_user_data_t *cli = NULL; bt_mesh_client_node_t *node = NULL; + BT_DBG("ClientRecvPublishMsg"); + if (!model || !ctx || !buf) { BT_ERR("%s, Invalid parameter", __func__); return NULL; @@ -63,22 +73,25 @@ bt_mesh_client_node_t *bt_mesh_is_client_recv_publish_msg(struct bt_mesh_model * return NULL; } - /** If the received message address is not a unicast address, - * the address may be a group/virtual address, and we push - * this message to the application layer. + BT_DBG("Src 0x%04x Dst 0x%04x RecvOp 0x%08lx", + ctx->addr, ctx->recv_dst, ctx->recv_op); + + /* If the received message address is not a unicast address, + * the address may be a group/virtual address, and we push + * this message to the application layer. */ if (!BLE_MESH_ADDR_IS_UNICAST(ctx->recv_dst)) { - BT_DBG("Unexpected status message 0x%08x", ctx->recv_op); + BT_DBG("MsgToNonUnicastDst"); if (cli->publish_status && need_pub) { cli->publish_status(ctx->recv_op, model, ctx, buf); } return NULL; } - /** If the source address of the received status message is - * different with the destination address of the sending - * message, then the message is from another element and - * push it to application layer. + /* If the source address of the received status message is + * different with the destination address of the sending + * message, then the message is from another element and + * push it to application layer. */ data = (bt_mesh_client_internal_data_t *)cli->internal_data; if (!data) { @@ -86,8 +99,8 @@ bt_mesh_client_node_t *bt_mesh_is_client_recv_publish_msg(struct bt_mesh_model * return NULL; } - if ((node = bt_mesh_client_pick_node(&data->queue, ctx->addr)) == NULL) { - BT_DBG("Unexpected status message 0x%08x", ctx->recv_op); + if ((node = client_pick_node(&data->queue, ctx->addr)) == NULL) { + BT_DBG("MsgFromUnknownSrc"); if (cli->publish_status && need_pub) { cli->publish_status(ctx->recv_op, model, ctx, buf); } @@ -95,7 +108,7 @@ bt_mesh_client_node_t *bt_mesh_is_client_recv_publish_msg(struct bt_mesh_model * } if (node->op_pending != ctx->recv_op) { - BT_DBG("Unexpected status message 0x%08x", ctx->recv_op); + BT_DBG("MsgWithUnknownOp"); if (cli->publish_status && need_pub) { cli->publish_status(ctx->recv_op, model, ctx, buf); } @@ -103,7 +116,7 @@ bt_mesh_client_node_t *bt_mesh_is_client_recv_publish_msg(struct bt_mesh_model * } if (k_delayed_work_remaining_get(&node->timer) == 0) { - BT_DBG("Unexpected status message 0x%08x", ctx->recv_op); + BT_DBG("MsgWithTimerExpired"); if (cli->publish_status && need_pub) { cli->publish_status(ctx->recv_op, model, ctx, buf); } @@ -113,33 +126,12 @@ bt_mesh_client_node_t *bt_mesh_is_client_recv_publish_msg(struct bt_mesh_model * return node; } -static bool bt_mesh_client_check_node_in_list(sys_slist_t *list, uint16_t tx_dst) +static uint32_t client_get_status_op(const bt_mesh_client_op_pair_t *op_pair, + int size, uint32_t opcode) { - bt_mesh_client_node_t *node = NULL; - sys_snode_t *cur = NULL; - - bt_mesh_list_lock(); - if (sys_slist_is_empty(list)) { - bt_mesh_list_unlock(); - return false; - } + BT_DBG("ClientGetStatusOp"); + BT_DBG("OpPair %p Size %u OpCode 0x%08lx", op_pair, size, opcode); - for (cur = sys_slist_peek_head(list); - cur != NULL; cur = sys_slist_peek_next(cur)) { - node = (bt_mesh_client_node_t *)cur; - if (node->ctx.addr == tx_dst) { - bt_mesh_list_unlock(); - return true; - } - } - - bt_mesh_list_unlock(); - return false; -} - -static uint32_t bt_mesh_client_get_status_op(const bt_mesh_client_op_pair_t *op_pair, - int size, uint32_t opcode) -{ if (!op_pair || size == 0) { return 0; } @@ -147,15 +139,18 @@ static uint32_t bt_mesh_client_get_status_op(const bt_mesh_client_op_pair_t *op_ const bt_mesh_client_op_pair_t *op = op_pair; for (int i = 0; i < size; i++) { if (op->cli_op == opcode) { + BT_DBG("OpCodeFound"); return op->status_op; } + op++; } + BT_DBG("OpCodeNotFound"); return 0; } -static int32_t bt_mesh_get_adv_duration(struct bt_mesh_msg_ctx *ctx) +static int32_t client_get_adv_duration(struct bt_mesh_msg_ctx *ctx) { uint16_t duration = 0, adv_int = 0; uint8_t xmit = 0; @@ -163,23 +158,28 @@ static int32_t bt_mesh_get_adv_duration(struct bt_mesh_msg_ctx *ctx) /* Initialize with network transmission */ xmit = bt_mesh_net_transmit_get(); + BT_DBG("ClientGetAdvDuration, Xmit 0x%02x", xmit); + if (bt_mesh_tag_immutable_cred(ctx->send_tag)) { #if CONFIG_BLE_MESH_DF_SRV if (ctx->send_cred == BLE_MESH_DIRECTED_CRED) { xmit = bt_mesh_direct_net_transmit_get(); /* Directed network transmission */ + BT_DBG("UseDFXmit 0x%02x", xmit); } -#endif +#endif /* CONFIG_BLE_MESH_DF_SRV */ } adv_int = BLE_MESH_TRANSMIT_INT(xmit); duration = (BLE_MESH_TRANSMIT_COUNT(xmit) + 1) * (adv_int + 10); + BT_DBG("Duration %ld", (int32_t)duration); + return (int32_t)duration; } -static int32_t bt_mesh_client_calc_timeout(struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *msg, - uint32_t opcode, int32_t timeout) +static int32_t client_calc_timeout(struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *msg, + uint32_t opcode, int32_t timeout) { int32_t seg_rtx_to = 0, duration = 0, time = 0; uint8_t seg_count = 0, seg_rtx_num = 0; @@ -195,6 +195,8 @@ static int32_t bt_mesh_client_calc_timeout(struct bt_mesh_msg_ctx *ctx, net_buf_simple_tailroom(msg) >= BLE_MESH_MIC_LONG) ? BLE_MESH_MIC_LONG : BLE_MESH_MIC_SHORT; + BT_DBG("NeedSeg %u MicSize %u", need_seg, mic_size); + if (need_seg) { /* Based on the message length, calculate how many segments are needed. * All the messages sent from here are access messages. @@ -203,7 +205,7 @@ static int32_t bt_mesh_client_calc_timeout(struct bt_mesh_msg_ctx *ctx, seg_rtx_to = bt_mesh_get_seg_rtx_timeout(ctx->addr, ctx->send_ttl); seg_count = (msg->len + mic_size - 1) / 12U + 1U; - duration = bt_mesh_get_adv_duration(ctx); + duration = client_get_adv_duration(ctx); /* Currently only consider the time consumption of the same segmented * messages, but if there are other messages between any two retrans- @@ -242,7 +244,7 @@ static void msg_send_start(uint16_t duration, int err, void *cb_data) { bt_mesh_client_node_t *node = cb_data; - BT_DBG("%s, duration %ums", __func__, duration); + BT_DBG("MsgSendStart, Duration %u Err %d", duration, err); if (err) { if (!k_delayed_work_free(&node->timer)) { @@ -268,6 +270,8 @@ int bt_mesh_client_send_msg(bt_mesh_client_common_param_t *param, bt_mesh_client_node_t *node = NULL; int err = 0; + BT_DBG("ClientSendMsg, NeedAck %u", need_ack); + if (!param || !param->model || !msg) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; @@ -309,7 +313,7 @@ int bt_mesh_client_send_msg(bt_mesh_client_common_param_t *param, return -EINVAL; } - if (bt_mesh_client_check_node_in_list(&internal->queue, param->ctx.addr)) { + if (client_pick_node(&internal->queue, param->ctx.addr)) { BT_ERR("Busy sending message to DST 0x%04x", param->ctx.addr); return -EBUSY; } @@ -324,14 +328,15 @@ int bt_mesh_client_send_msg(bt_mesh_client_common_param_t *param, memcpy(&node->ctx, ¶m->ctx, sizeof(struct bt_mesh_msg_ctx)); node->model = param->model; node->opcode = param->opcode; - node->op_pending = bt_mesh_client_get_status_op(client->op_pair, client->op_pair_size, param->opcode); + node->op_pending = client_get_status_op(client->op_pair, client->op_pair_size, param->opcode); if (node->op_pending == 0U) { BT_ERR("Status opcode not found in op_pair list, opcode 0x%08x", param->opcode); bt_mesh_free(node); return -EINVAL; } - node->timeout = bt_mesh_client_calc_timeout(¶m->ctx, msg, param->opcode, - param->msg_timeout ? param->msg_timeout : CONFIG_BLE_MESH_CLIENT_MSG_TIMEOUT); + node->timeout = client_calc_timeout(¶m->ctx, msg, param->opcode, + (param->msg_timeout ? param->msg_timeout : + CONFIG_BLE_MESH_CLIENT_MSG_TIMEOUT)); if (k_delayed_work_init(&node->timer, timer_handler)) { BT_ERR("Failed to create a timer"); @@ -374,6 +379,8 @@ int bt_mesh_client_init(struct bt_mesh_model *model) bt_mesh_client_internal_data_t *internal = NULL; bt_mesh_client_user_data_t *client = NULL; + BT_DBG("ClientInit"); + if (!model || !model->op) { BT_ERR("Invalid vendor client model"); return -EINVAL; @@ -411,6 +418,8 @@ int bt_mesh_client_deinit(struct bt_mesh_model *model) { bt_mesh_client_user_data_t *client = NULL; + BT_DBG("ClientDeinit"); + if (!model) { BT_ERR("Invalid vendor client model"); return -EINVAL; @@ -442,6 +451,8 @@ int bt_mesh_client_free_node(bt_mesh_client_node_t *node) bt_mesh_client_internal_data_t *internal = NULL; bt_mesh_client_user_data_t *client = NULL; + BT_DBG("ClientFreeNode"); + if (!node || !node->model) { BT_ERR("Invalid client list item"); return -EINVAL; @@ -459,12 +470,10 @@ int bt_mesh_client_free_node(bt_mesh_client_node_t *node) return -EINVAL; } - // Release the client node from the queue bt_mesh_list_lock(); sys_slist_find_and_remove(&internal->queue, &node->client_node); bt_mesh_list_unlock(); - // Free the node bt_mesh_free(node); return 0; @@ -475,6 +484,8 @@ int bt_mesh_client_clear_list(void *data) bt_mesh_client_internal_data_t *internal = NULL; bt_mesh_client_node_t *node = NULL; + BT_DBG("ClientClearList"); + if (!data) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; @@ -483,11 +494,13 @@ int bt_mesh_client_clear_list(void *data) internal = (bt_mesh_client_internal_data_t *)data; bt_mesh_list_lock(); + while (!sys_slist_is_empty(&internal->queue)) { node = (void *)sys_slist_get_not_empty(&internal->queue); k_delayed_work_free(&node->timer); bt_mesh_free(node); } + bt_mesh_list_unlock(); return 0; diff --git a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c index 5a23a6f51ac6..bee0babc2435 100644 --- a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c +++ b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_av.c @@ -137,6 +137,7 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *data); static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *data); static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *data); static void clean_up(int service_id); +static BOOLEAN btc_a2d_deinit_if_ongoing(void); #if BTC_AV_SRC_INCLUDED static bt_status_t btc_a2d_src_init(void); @@ -310,11 +311,13 @@ static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data) switch (event) { case BTC_SM_ENTER_EVT: - /* clear the peer_bda */ - memset(&btc_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t)); - btc_av_cb.flags = 0; - btc_av_cb.edr = 0; - btc_a2dp_on_idle(); + if (btc_a2d_deinit_if_ongoing() == FALSE) { + /* clear the peer_bda */ + memset(&btc_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t)); + btc_av_cb.flags = 0; + btc_av_cb.edr = 0; + btc_a2dp_on_idle(); + } break; case BTC_SM_EXIT_EVT: @@ -480,22 +483,18 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data) /* change state to open/idle based on the status */ btc_sm_change_state(btc_av_cb.sm_handle, av_state); - if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) { - /* if queued PLAY command, send it now */ - /* necessary to add this? - btc_rc_check_handle_pending_play(p_bta_data->open.bd_addr, - (p_bta_data->open.status == BTA_AV_SUCCESS)); - */ - } else if (btc_av_cb.peer_sep == AVDT_TSEP_SRC && - (p_bta_data->open.status == BTA_AV_SUCCESS)) { - /* Bring up AVRCP connection too if AVRC Initialized */ - if(g_av_with_rc) { - BTA_AvOpenRc(btc_av_cb.bta_handle); - } else { - BTC_TRACE_WARNING("AVRC not Init, not using it."); + if (p_bta_data->open.status == BTA_AV_SUCCESS && !btc_a2d_deinit_if_ongoing()) { + if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) { + /* Bring up AVRCP connection too if AVRC Initialized */ + if(g_av_with_rc) { + BTA_AvOpenRc(btc_av_cb.bta_handle); + } else { + BTC_TRACE_WARNING("AVRC not Init, not using it."); + } } } btc_queue_advance(); + } break; case BTC_AV_SINK_CONFIG_REQ_EVT: { @@ -773,12 +772,6 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data) /* change state to idle, send acknowledgement if start is pending */ btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); - - if (g_a2dp_source_ongoing_deinit) { - clean_up(BTA_A2DP_SOURCE_SERVICE_ID); - } else if (g_a2dp_sink_ongoing_deinit) { - clean_up(BTA_A2DP_SINK_SERVICE_ID); - } break; } @@ -982,11 +975,6 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data) close->disc_rsn); btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE); - if (g_a2dp_source_ongoing_deinit) { - clean_up(BTA_A2DP_SOURCE_SERVICE_ID); - } else if (g_a2dp_sink_ongoing_deinit) { - clean_up(BTA_A2DP_SINK_SERVICE_ID); - } break; CHECK_RC_EVENT(event, p_data); @@ -1707,13 +1695,17 @@ static void btc_a2d_sink_get_delay_value(void) static void btc_a2d_sink_deinit(void) { + // Cleanup will only occur when the state is IDLE. + // If connected, it will first disconnect and then wait for the state to change to IDLE before performing cleanup. + // If in any other state, it will wait for the process to complete and then call btc_a2d_sink_deinit again. g_a2dp_sink_ongoing_deinit = true; if (btc_av_is_connected()) { BTA_AvClose(btc_av_cb.bta_handle); if (btc_av_cb.peer_sep == AVDT_TSEP_SRC && g_av_with_rc == true) { BTA_AvCloseRc(btc_av_cb.bta_handle); } - } else { + } else if (btc_sm_get_state(btc_av_cb.sm_handle) == BTC_AV_STATE_IDLE) { + /* Only clean up when idle */ clean_up(BTA_A2DP_SINK_SERVICE_ID); } } @@ -1740,13 +1732,16 @@ static bt_status_t btc_a2d_src_init(void) static void btc_a2d_src_deinit(void) { + // Cleanup will only occur when the state is IDLE. + // If connected, it will first disconnect and then wait for the state to change to IDLE before performing cleanup. + // If in any other state, it will wait for the process to complete and then call btc_a2d_src_deinit again. g_a2dp_source_ongoing_deinit = true; if (btc_av_is_connected()) { BTA_AvClose(btc_av_cb.bta_handle); if (btc_av_cb.peer_sep == AVDT_TSEP_SNK && g_av_with_rc == true) { BTA_AvCloseRc(btc_av_cb.bta_handle); } - } else { + } else if (btc_sm_get_state(btc_av_cb.sm_handle) == BTC_AV_STATE_IDLE) { clean_up(BTA_A2DP_SOURCE_SERVICE_ID); } } @@ -1761,4 +1756,21 @@ static bt_status_t btc_a2d_src_connect(bt_bdaddr_t *remote_bda) #endif /* BTC_AV_SRC_INCLUDED */ +static BOOLEAN btc_a2d_deinit_if_ongoing(void) +{ +#if BTC_AV_SRC_INCLUDED + if (g_a2dp_source_ongoing_deinit) { + btc_a2d_src_deinit(); + return TRUE; + } +#endif +#if BTC_AV_SINK_INCLUDED + if (g_a2dp_sink_ongoing_deinit) { + btc_a2d_sink_deinit(); + return TRUE; + } +#endif + return FALSE; +} + #endif /* #if BTC_AV_INCLUDED */ diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index 18b1bdef4e04..622eb4d71754 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -247,8 +247,7 @@ menu "GAP / GATT / Device Settings" config BT_NIMBLE_MAX_CONNECTIONS int "Maximum number of concurrent connections" range 1 2 if IDF_TARGET_ESP32C2 - range 1 70 if IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C61 - range 1 35 if IDF_TARGET_ESP32H2 + range 1 70 if SOC_ESP_NIMBLE_CONTROLLER range 1 9 default 2 if IDF_TARGET_ESP32C2 default 3 diff --git a/components/esp_driver_i2s/i2s_common.c b/components/esp_driver_i2s/i2s_common.c index a6ad14f15f21..732a2133122a 100644 --- a/components/esp_driver_i2s/i2s_common.c +++ b/components/esp_driver_i2s/i2s_common.c @@ -303,6 +303,40 @@ static esp_err_t i2s_register_channel(i2s_controller_t *i2s_obj, i2s_dir_t dir, return ret; } +#if SOC_I2S_HW_VERSION_1 +esp_err_t i2s_channel_change_port(i2s_chan_handle_t handle, int id) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + ESP_RETURN_ON_FALSE(id >= 0 && id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid I2S port id"); + if (id == handle->controller->id) { + return ESP_OK; + } + i2s_controller_t *i2s_obj = i2s_acquire_controller_obj(id); + if (!i2s_obj || !i2s_take_available_channel(i2s_obj, handle->dir)) { + return ESP_ERR_NOT_FOUND; + } + i2s_controller_t *old_i2s_obj = handle->controller; + portENTER_CRITICAL(&g_i2s.spinlock); + if (handle->dir == I2S_DIR_TX) { + i2s_obj->tx_chan = handle; + i2s_obj->chan_occupancy |= I2S_DIR_TX; + old_i2s_obj->tx_chan = NULL; + old_i2s_obj->full_duplex = false; + old_i2s_obj->chan_occupancy &= ~I2S_DIR_TX; + } else { + i2s_obj->rx_chan = handle; + i2s_obj->chan_occupancy |= I2S_DIR_RX; + old_i2s_obj->rx_chan = NULL; + old_i2s_obj->full_duplex = false; + old_i2s_obj->chan_occupancy &= ~I2S_DIR_RX; + } + handle->controller = i2s_obj; + portEXIT_CRITICAL(&g_i2s.spinlock); + + return ESP_OK; +} +#endif + #ifndef __cplusplus /* To make sure the i2s_event_callbacks_t is same size as i2s_event_callbacks_internal_t */ _Static_assert(sizeof(i2s_event_callbacks_t) == sizeof(i2s_event_callbacks_internal_t), "Invalid size of i2s_event_callbacks_t structure"); @@ -901,6 +935,7 @@ esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t * ESP_GOTO_ON_ERROR(i2s_register_channel(i2s_obj, I2S_DIR_TX, chan_cfg->dma_desc_num), err, TAG, "register I2S tx channel failed"); i2s_obj->tx_chan->role = chan_cfg->role; + i2s_obj->tx_chan->is_port_auto = id == I2S_NUM_AUTO; i2s_obj->tx_chan->intr_prio_flags = chan_cfg->intr_priority ? BIT(chan_cfg->intr_priority) : ESP_INTR_FLAG_LOWMED; i2s_obj->tx_chan->dma.auto_clear_after_cb = chan_cfg->auto_clear_after_cb; i2s_obj->tx_chan->dma.auto_clear_before_cb = chan_cfg->auto_clear_before_cb; @@ -916,6 +951,7 @@ esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t * ESP_GOTO_ON_ERROR(i2s_register_channel(i2s_obj, I2S_DIR_RX, chan_cfg->dma_desc_num), err, TAG, "register I2S rx channel failed"); i2s_obj->rx_chan->role = chan_cfg->role; + i2s_obj->rx_chan->is_port_auto = id == I2S_NUM_AUTO; i2s_obj->rx_chan->intr_prio_flags = chan_cfg->intr_priority ? BIT(chan_cfg->intr_priority) : ESP_INTR_FLAG_LOWMED; i2s_obj->rx_chan->dma.desc_num = chan_cfg->dma_desc_num; i2s_obj->rx_chan->dma.frame_num = chan_cfg->dma_frame_num; diff --git a/components/esp_driver_i2s/i2s_private.h b/components/esp_driver_i2s/i2s_private.h index 1675baf9f395..d91248cbdfde 100644 --- a/components/esp_driver_i2s/i2s_private.h +++ b/components/esp_driver_i2s/i2s_private.h @@ -136,6 +136,7 @@ struct i2s_channel_obj_t { int intr_prio_flags;/*!< i2s interrupt priority flags */ void *mode_info; /*!< Slot, clock and gpio information of each mode */ bool full_duplex_slave; /*!< whether the channel is forced to switch to slave role for full duplex */ + bool is_port_auto; /*!< Whether the port is auto-assigned */ #if SOC_I2S_SUPPORTS_APLL bool apll_en; /*!< Flag of whether APLL enabled */ #endif @@ -274,6 +275,19 @@ void i2s_output_gpio_reserve(i2s_chan_handle_t handle, int gpio_num); */ void i2s_output_gpio_revoke(i2s_chan_handle_t handle, uint64_t gpio_mask); +#if SOC_I2S_HW_VERSION_1 +/** + * @brief Change the port of the I2S channel + * + * @param handle I2S channel handle + * @param id I2S port id + * @return + * - ESP_OK Change port success + * - ESP_ERR_NOT_FOUND No available I2S port found + */ +esp_err_t i2s_channel_change_port(i2s_chan_handle_t handle, int id); +#endif + #ifdef __cplusplus } #endif diff --git a/components/esp_driver_i2s/i2s_std.c b/components/esp_driver_i2s/i2s_std.c index 9e3cc017cdc4..c5256b6616ba 100644 --- a/components/esp_driver_i2s/i2s_std.c +++ b/components/esp_driver_i2s/i2s_std.c @@ -237,13 +237,34 @@ static esp_err_t s_i2s_channel_try_to_constitude_std_duplex(i2s_chan_handle_t ha if (memcmp(another_handle->mode_info, &curr_cfg, sizeof(i2s_std_config_t)) == 0) { handle->controller->full_duplex = true; ESP_LOGD(TAG, "Constitude full-duplex on port %d", handle->controller->id); - } + } else { #if SOC_I2S_HW_VERSION_1 - else { - ESP_LOGE(TAG, "Can't set different channel configurations on a same port"); - return ESP_ERR_INVALID_ARG; - } + bool port_changed = false; + if (handle->is_port_auto) { + ESP_LOGD(TAG, "TX & RX on I2S%d are simplex", handle->controller->id); + for (int i = 0; i < SOC_I2S_NUM; i++) { + if (i == handle->controller->id) { + continue; + } + ESP_LOGD(TAG, "Trying to move %s channel from port %d to %d", + handle->dir == I2S_DIR_TX ? "TX" : "RX", handle->controller->id, i); + if (i2s_channel_change_port(handle, i) == ESP_OK) { + ESP_LOGD(TAG, "Move success!"); + port_changed = true; + break; + } else { + ESP_LOGD(TAG, "Move failed..."); + } + } + } + if (!port_changed) { + ESP_LOGE(TAG, "Can't set different channel configurations on a same port"); + return ESP_ERR_INVALID_ARG; + } +#else + ESP_LOGD(TAG, "TX & RX on I2S%d are simplex", handle->controller->id); #endif + } } /* Switch to the slave role if needed */ if (handle->controller->full_duplex && diff --git a/components/esp_driver_i2s/i2s_tdm.c b/components/esp_driver_i2s/i2s_tdm.c index 19ad9c977471..374a190188e3 100644 --- a/components/esp_driver_i2s/i2s_tdm.c +++ b/components/esp_driver_i2s/i2s_tdm.c @@ -245,6 +245,8 @@ static void s_i2s_channel_try_to_constitude_tdm_duplex(i2s_chan_handle_t handle, if (memcmp(another_handle->mode_info, &curr_cfg, sizeof(i2s_tdm_config_t)) == 0) { handle->controller->full_duplex = true; ESP_LOGD(TAG, "Constitude full-duplex on port %d", handle->controller->id); + } else { + ESP_LOGD(TAG, "TX & RX on I2S%d are simplex", handle->controller->id); } } /* Switch to the slave role if needed */ diff --git a/components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c b/components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c index 6339056686e5..cf40ad0a6f12 100644 --- a/components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c +++ b/components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c @@ -263,6 +263,8 @@ TEST_CASE("I2S_basic_channel_allocation_reconfig_deleting_test", "[i2s]") } static volatile bool task_run_flag; +static volatile bool read_task_success = true; +static volatile bool write_task_success = true; #define TEST_I2S_DATA 0x78 @@ -295,6 +297,7 @@ static void i2s_read_task(void *args) ret = i2s_channel_read(rx_handle, recv_buf, 2000, &recv_size, 300); if (ret == ESP_ERR_TIMEOUT) { printf("Read timeout count: %"PRIu32"\n", cnt++); + read_task_success = false; } } @@ -316,6 +319,7 @@ static void i2s_write_task(void *args) ret = i2s_channel_write(tx_handle, send_buf, 2000, &send_size, 300); if (ret == ESP_ERR_TIMEOUT) { printf("Write timeout count: %"PRIu32"\n", cnt++); + write_task_success = false; } } @@ -456,6 +460,7 @@ TEST_CASE("I2S_lazy_duplex_test", "[i2s]") }, }, }; + /* Part 1: test common lazy duplex mode */ TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); TEST_ESP_OK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); TEST_ESP_OK(i2s_channel_enable(tx_handle)); @@ -476,7 +481,70 @@ TEST_CASE("I2S_lazy_duplex_test", "[i2s]") xTaskCreate(i2s_read_check_task, "i2s_read_check_task", 4096, rx_handle, 5, NULL); printf("RX started\n"); - /* Wait 3 seconds to see if any failures occur */ + /* Wait 1 seconds to see if any failures occur */ + vTaskDelay(pdMS_TO_TICKS(1000)); + printf("Finished\n"); + + /* Stop those three tasks */ + task_run_flag = false; + + /* Wait for the three thread deleted */ + vTaskDelay(pdMS_TO_TICKS(1000)); + + /* Disable the channels, they will keep waiting until the current reading / writing finished */ + TEST_ESP_OK(i2s_channel_disable(tx_handle)); + TEST_ESP_OK(i2s_channel_disable(rx_handle)); + /* Delete the channels */ + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); + + /* Part 2: Test no lazy duplex mode with port auto assignment */ + chan_cfg.id = I2S_NUM_AUTO; + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); + TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); + + /* Change the config to not constitute full-duplex */ + std_cfg.gpio_cfg.mclk = I2S_GPIO_UNUSED; + std_cfg.gpio_cfg.bclk = I2S_GPIO_UNUSED; + std_cfg.gpio_cfg.ws = I2S_GPIO_UNUSED; + std_cfg.gpio_cfg.dout = I2S_GPIO_UNUSED; + std_cfg.gpio_cfg.din = I2S_GPIO_UNUSED; +#if CONFIG_IDF_TARGET_ESP32S2 + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, i2s_channel_init_std_mode(tx_handle, &std_cfg)); + /* Delete the channels */ + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); + return; +#else + TEST_ESP_OK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); +#endif + +#if CONFIG_IDF_TARGET_ESP32 + /* On ESP32, if failed to constitute full-duplex with `I2S_NUM_AUTO`, + the channel will be re-assigned to the next availableport */ + i2s_chan_info_t chan_info; + TEST_ESP_OK(i2s_channel_get_info(rx_handle, &chan_info)); + TEST_ASSERT(chan_info.id == I2S_NUM_0); + TEST_ESP_OK(i2s_channel_get_info(tx_handle, &chan_info)); + TEST_ASSERT(chan_info.id == I2S_NUM_1); +#endif + + TEST_ESP_OK(i2s_channel_enable(tx_handle)); + TEST_ESP_OK(i2s_channel_enable(rx_handle)); + + task_run_flag = true; + read_task_success = true; + write_task_success = true; + /* writing task to keep writing */ + xTaskCreate(i2s_write_task, "i2s_write_task", 4096, tx_handle, 5, NULL); + printf("TX started\n"); + vTaskDelay(pdMS_TO_TICKS(1000)); + /* reading task to keep reading */ + xTaskCreate(i2s_read_task, "i2s_read_task", 4096, rx_handle, 5, NULL); + printf("RX started\n"); + + /* Wait 1 seconds to see if any failures occur */ vTaskDelay(pdMS_TO_TICKS(1000)); printf("Finished\n"); @@ -492,6 +560,9 @@ TEST_CASE("I2S_lazy_duplex_test", "[i2s]") /* Delete the channels */ TEST_ESP_OK(i2s_del_channel(tx_handle)); TEST_ESP_OK(i2s_del_channel(rx_handle)); + /* Check if the reading and writing tasks are successful */ + TEST_ASSERT(read_task_success); + TEST_ASSERT(write_task_success); } static bool whether_contains_exapected_data(uint16_t *src, uint32_t src_len, uint32_t src_step, uint32_t start_val, uint32_t val_step) diff --git a/examples/bluetooth/esp_ble_mesh/remote_provisioning/rpr_client/main/main.c b/examples/bluetooth/esp_ble_mesh/remote_provisioning/rpr_client/main/main.c index 6b816d6d846f..dcfdab25ae20 100644 --- a/examples/bluetooth/esp_ble_mesh/remote_provisioning/rpr_client/main/main.c +++ b/examples/bluetooth/esp_ble_mesh/remote_provisioning/rpr_client/main/main.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -353,26 +353,22 @@ static void example_ble_mesh_parse_node_comp_data(esp_ble_mesh_node_info_t* node node->sig_model_num = (uint8_t *)calloc(node->elem_num, sizeof(uint8_t)); if (!node->sig_model_num) { - ESP_LOGW(TAG, "No Free memory to store composition data"); - return; + goto calloc_fail; } node->vnd_model_num = (uint8_t *)calloc(node->elem_num, sizeof(uint8_t)); if (!node->vnd_model_num) { - ESP_LOGW(TAG, "No Free memory to store composition data"); - return; + goto vnd_model_num_fail; } node->sig_models = (uint16_t **)calloc(node->elem_num, sizeof(uint16_t*)); if (!node->sig_models) { - ESP_LOGW(TAG, "No Free memory to store composition data"); - return; + goto sig_models_fail; } node->vnd_models = (uint32_t **)calloc(node->elem_num, sizeof(uint32_t*)); - if (!node->sig_models) { - ESP_LOGW(TAG, "No Free memory to store composition data"); - return; + if (!node->vnd_models) { + goto vnd_models_fail; } ESP_LOGI(TAG, "********************** Composition Data Start **********************"); @@ -387,8 +383,7 @@ static void example_ble_mesh_parse_node_comp_data(esp_ble_mesh_node_info_t* node if (nums) { node->sig_models[seq] = (uint16_t *)calloc(nums, sizeof(uint16_t)); if (!(node->sig_models[seq])) { - ESP_LOGW(TAG, "No Free memory to store composition data"); - return; + goto sig_mode_seq_fail; } } else { node->sig_models[seq] = NULL; @@ -397,8 +392,7 @@ static void example_ble_mesh_parse_node_comp_data(esp_ble_mesh_node_info_t* node if (numv) { node->vnd_models[seq] = (uint32_t *)calloc(numv, sizeof(uint32_t)); if (!(node->vnd_models[seq])) { - ESP_LOGW(TAG, "No Free memory to store composition data"); - return; + goto vnd_model_seq_fail; } } else { node->vnd_models[seq] = NULL; @@ -422,6 +416,32 @@ static void example_ble_mesh_parse_node_comp_data(esp_ble_mesh_node_info_t* node seq++; } ESP_LOGI(TAG, "*********************** Composition Data End ***********************"); + return; + +vnd_model_seq_fail: + free(node->sig_models[seq]); + node->sig_models[seq] = NULL; +sig_mode_seq_fail: + for (int j = 0; j < seq; j++) { + free(node->sig_models[j]); + free(node->vnd_models[j]); + node->sig_models[j] = NULL; + node->vnd_models[j] = NULL; + } + free(node->vnd_models); + node->vnd_models = NULL; +vnd_models_fail: + free(node->sig_models); + node->sig_models = NULL; +sig_models_fail: + free(node->vnd_model_num); + node->vnd_model_num = NULL; +vnd_model_num_fail: + free(node->sig_model_num); + node->sig_model_num = NULL; +calloc_fail: + ESP_LOGW(TAG, "No Free memory to store composition data"); + return; } static bool example_ble_mesh_query_element_have_model(uint16_t elem_addr, uint16_t model_id, uint16_t company_id) @@ -435,6 +455,10 @@ static bool example_ble_mesh_query_element_have_model(uint16_t elem_addr, uint16 elem_idx = elem_addr - node->unicast; + if (node->sig_model_num == NULL) { + return false; + } + if (company_id == CID_NVAL) { model_num = node->sig_model_num[elem_idx]; for (i = 0; i < model_num; i++) { diff --git a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_cent/sdkconfig.defaults.esp32h2 b/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_cent/sdkconfig.defaults.esp32h2 deleted file mode 100644 index e30be10c13e9..000000000000 --- a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_cent/sdkconfig.defaults.esp32h2 +++ /dev/null @@ -1,6 +0,0 @@ -# This file was generated using idf.py save-defconfig. It can be edited manually. -# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration -# -CONFIG_BT_NIMBLE_MAX_CONNECTIONS=35 -CONFIG_BT_NIMBLE_GATT_MAX_PROCS=35 -CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=50 diff --git a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/sdkconfig.defaults.esp32h2 b/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/sdkconfig.defaults.esp32h2 deleted file mode 100644 index f0cb07854e15..000000000000 --- a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/sdkconfig.defaults.esp32h2 +++ /dev/null @@ -1,5 +0,0 @@ -# This file was generated using idf.py save-defconfig. It can be edited manually. -# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration -# -CONFIG_BT_NIMBLE_MAX_CONNECTIONS=34 -CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=50 diff --git a/tools/test_idf_tools/test_idf_tools.py b/tools/test_idf_tools/test_idf_tools.py index d81d0609a612..68f7e40f221d 100755 --- a/tools/test_idf_tools/test_idf_tools.py +++ b/tools/test_idf_tools/test_idf_tools.py @@ -111,7 +111,7 @@ class TestUsageBase(unittest.TestCase): @classmethod def setUpClass(cls): - with open(os.path.join(os.getenv('IDF_PATH'), 'tools/tools.json'), 'r') as json_file: + with open(os.path.join(os.getenv('IDF_PATH'), 'tools/tools.json')) as json_file: tools_dict = json.load(json_file) cls.tools_dict = tools_dict @@ -133,7 +133,7 @@ def setUpClass(cls): cls.temp_tools_dir = tempfile.mkdtemp(prefix='idf_tools_tmp') - print('Using IDF_TOOLS_PATH={}'.format(cls.temp_tools_dir)) + print(f'Using IDF_TOOLS_PATH={cls.temp_tools_dir}') os.environ['IDF_TOOLS_PATH'] = cls.temp_tools_dir cls.idf_env_json = os.path.join(cls.temp_tools_dir, 'idf-env.json') @@ -154,13 +154,13 @@ def tearDown(self): def assert_tool_installed(self, output, tool, tool_version, tool_archive_name=None): if tool_archive_name is None: tool_archive_name = tool - self.assertIn('Installing %s@' % tool + tool_version, output) + self.assertIn(f'Installing {tool}@{tool_version}', output) self.assertRegex(output, re.compile(rf'Downloading \S+{tool_archive_name}')) def assert_tool_not_installed(self, output, tool, tool_version, tool_archive_name=None): if tool_archive_name is None: tool_archive_name = tool - self.assertNotIn('Installing %s@' % tool + tool_version, output) + self.assertNotIn(f'Installing {tool}@{tool_version}', output) self.assertNotRegex(output, re.compile(rf'Downloading \S+{tool_archive_name}')) def run_idf_tools_with_action(self, action): @@ -265,8 +265,8 @@ def test_deactivate(self): output = self.run_idf_tools_with_action(['export']) self.assertIn('export IDF_DEACTIVATE_FILE_PATH=', output, 'No IDF_DEACTIVATE_FILE_PATH exported into environment') deactivate_file = re.findall(r'(?:IDF_DEACTIVATE_FILE_PATH=")(.*)(?:")', output)[0] - self.assertTrue(os.path.isfile(deactivate_file), 'File {} was not found. '.format(deactivate_file)) - self.assertNotEqual(os.stat(self.idf_env_json).st_size, 0, 'File {} is empty. '.format(deactivate_file)) + self.assertTrue(os.path.isfile(deactivate_file), f'File {deactivate_file} was not found. ') + self.assertNotEqual(os.stat(self.idf_env_json).st_size, 0, f'File {deactivate_file} is empty. ') def test_export_recommended_version(self): always_install_and_recommended_tools = [] @@ -345,14 +345,14 @@ class TestUsageUnix(TestUsage): def test_usage_basic(self): output = self.run_idf_tools_with_action(['list']) - self.assertIn('* %s:' % ESP32ULP, output) - self.assertIn('- %s (recommended)' % ESP32ULP_VERSION, output) - self.assertIn('* %s:' % OPENOCD, output) - self.assertIn('- %s (recommended)' % OPENOCD_VERSION, output) - self.assertIn('* %s:' % RISCV_ELF, output) - self.assertIn('- %s (recommended)' % RISCV_ELF_VERSION, output) - self.assertIn('* %s:' % XTENSA_ELF, output) - self.assertIn('- %s (recommended)' % XTENSA_ELF_VERSION, output) + self.assertIn(f'* {ESP32ULP}:', output) + self.assertIn(f'- {ESP32ULP_VERSION} (recommended)', output) + self.assertIn(f'* {OPENOCD}:', output) + self.assertIn(f'- {OPENOCD_VERSION} (recommended)', output) + self.assertIn(f'* {RISCV_ELF}:', output) + self.assertIn(f'- {RISCV_ELF_VERSION} (recommended)', output) + self.assertIn(f'* {XTENSA_ELF}:', output) + self.assertIn(f'- {XTENSA_ELF_VERSION} (recommended)', output) required_tools_installed = 7 output = self.run_idf_tools_with_action(['install']) @@ -372,20 +372,19 @@ def test_usage_basic(self): self.assertIn('version installed in tools directory: ' + tool_version, output) output = self.run_idf_tools_with_action(['export']) - self.assertIn('%s/tools/esp32ulp-elf/%s/esp32ulp-elf/bin' % - (self.temp_tools_dir, ESP32ULP_VERSION), output) - self.assertIn('%s/tools/xtensa-esp-elf/%s/xtensa-esp-elf/bin' % - (self.temp_tools_dir, XTENSA_ELF_VERSION), output) - self.assertIn('%s/tools/openocd-esp32/%s/openocd-esp32/bin' % - (self.temp_tools_dir, OPENOCD_VERSION), output) - self.assertIn('%s/tools/riscv32-esp-elf/%s/riscv32-esp-elf/bin' % - (self.temp_tools_dir, RISCV_ELF_VERSION), output) - self.assertIn('%s/tools/xtensa-esp-elf-gdb/%s/xtensa-esp-elf-gdb/bin' % - (self.temp_tools_dir, XTENSA_ESP_GDB_VERSION), output) - self.assertIn('%s/tools/riscv32-esp-elf-gdb/%s/riscv32-esp-elf-gdb/bin' % - (self.temp_tools_dir, RISCV_ESP_GDB_VERSION), output) - self.assertIn('%s/tools/esp-rom-elfs/%s/' % - (self.temp_tools_dir, ESP_ROM_ELFS_VERSION), output) + self.assertIn(f'{self.temp_tools_dir}/tools/esp32ulp-elf/{ESP32ULP_VERSION}/esp32ulp-elf/bin', output) + self.assertIn(f'{self.temp_tools_dir}/tools/xtensa-esp-elf/{XTENSA_ELF_VERSION}/xtensa-esp-elf/bin', output) + self.assertIn(f'{self.temp_tools_dir}/tools/openocd-esp32/{OPENOCD_VERSION}/openocd-esp32/bin', output) + self.assertIn(f'{self.temp_tools_dir}/tools/riscv32-esp-elf/{RISCV_ELF_VERSION}/riscv32-esp-elf/bin', output) + self.assertIn( + f'{self.temp_tools_dir}/tools/xtensa-esp-elf-gdb/{XTENSA_ESP_GDB_VERSION}/xtensa-esp-elf-gdb/bin', + output, + ) + self.assertIn( + f'{self.temp_tools_dir}/tools/riscv32-esp-elf-gdb/{RISCV_ESP_GDB_VERSION}/riscv32-esp-elf-gdb/bin', + output, + ) + self.assertIn(f'{self.temp_tools_dir}/tools/esp-rom-elfs/{ESP_ROM_ELFS_VERSION}/', output) output = self.run_idf_tools_with_action(['list', '--outdated']) self.assertEqual('', output) @@ -437,20 +436,19 @@ def test_tools_for_esp32(self): self.assertIn('version installed in tools directory: ' + tool_version, output) output = self.run_idf_tools_with_action(['export']) - self.assertIn('%s/tools/esp32ulp-elf/%s/esp32ulp-elf/bin' % - (self.temp_tools_dir, ESP32ULP_VERSION), output) - self.assertIn('%s/tools/xtensa-esp-elf/%s/xtensa-esp-elf/bin' % - (self.temp_tools_dir, XTENSA_ELF_VERSION), output) - self.assertIn('%s/tools/openocd-esp32/%s/openocd-esp32/bin' % - (self.temp_tools_dir, OPENOCD_VERSION), output) - self.assertIn('%s/tools/xtensa-esp-elf-gdb/%s/xtensa-esp-elf-gdb/bin' % - (self.temp_tools_dir, XTENSA_ESP_GDB_VERSION), output) - self.assertNotIn('%s/tools/riscv32-esp-elf/%s/riscv32-esp-elf/bin' % - (self.temp_tools_dir, RISCV_ELF_VERSION), output) - self.assertNotIn('%s/tools/riscv32-esp-elf-gdb/%s/riscv32-esp-elf-gdb/bin' % - (self.temp_tools_dir, RISCV_ESP_GDB_VERSION), output) - self.assertIn('%s/tools/esp-rom-elfs/%s/' % - (self.temp_tools_dir, ESP_ROM_ELFS_VERSION), output) + self.assertIn(f'{self.temp_tools_dir}/tools/esp32ulp-elf/{ESP32ULP_VERSION}/esp32ulp-elf/bin', output) + self.assertIn(f'{self.temp_tools_dir}/tools/xtensa-esp-elf/{XTENSA_ELF_VERSION}/xtensa-esp-elf/bin', output) + self.assertIn(f'{self.temp_tools_dir}/tools/openocd-esp32/{OPENOCD_VERSION}/openocd-esp32/bin', output) + self.assertIn( + f'{self.temp_tools_dir}/tools/xtensa-esp-elf-gdb/{XTENSA_ESP_GDB_VERSION}/xtensa-esp-elf-gdb/bin', + output, + ) + self.assertNotIn(f'{self.temp_tools_dir}/tools/riscv32-esp-elf/{RISCV_ELF_VERSION}/riscv32-esp-elf/bin', output) + self.assertNotIn( + f'{self.temp_tools_dir}/tools/riscv32-esp-elf-gdb/{RISCV_ESP_GDB_VERSION}/riscv32-esp-elf-gdb/bin', + output, + ) + self.assertIn(f'{self.temp_tools_dir}/tools/esp-rom-elfs/{ESP_ROM_ELFS_VERSION}/', output) def test_tools_for_esp32c3(self): required_tools_installed = 4 @@ -470,18 +468,15 @@ def test_tools_for_esp32c3(self): self.assertIn('version installed in tools directory: ' + tool_version, output) output = self.run_idf_tools_with_action(['export']) - self.assertIn('%s/tools/openocd-esp32/%s/openocd-esp32/bin' % - (self.temp_tools_dir, OPENOCD_VERSION), output) - self.assertIn('%s/tools/riscv32-esp-elf/%s/riscv32-esp-elf/bin' % - (self.temp_tools_dir, RISCV_ELF_VERSION), output) - self.assertNotIn('%s/tools/esp32ulp-elf/%s/esp32ulp-elf/bin' % - (self.temp_tools_dir, ESP32ULP_VERSION), output) - self.assertNotIn('%s/tools/xtensa-esp-elf/%s/xtensa-esp-elf/bin' % - (self.temp_tools_dir, XTENSA_ELF_VERSION), output) - self.assertNotIn('%s/tools/xtensa-esp-elf-gdb/%s/xtensa-esp-elf-gdb/bin' % - (self.temp_tools_dir, XTENSA_ESP_GDB_VERSION), output) - self.assertIn('%s/tools/esp-rom-elfs/%s/' % - (self.temp_tools_dir, ESP_ROM_ELFS_VERSION), output) + self.assertIn(f'{self.temp_tools_dir}/tools/openocd-esp32/{OPENOCD_VERSION}/openocd-esp32/bin', output) + self.assertIn(f'{self.temp_tools_dir}/tools/riscv32-esp-elf/{RISCV_ELF_VERSION}/riscv32-esp-elf/bin', output) + self.assertNotIn(f'{self.temp_tools_dir}/tools/esp32ulp-elf/{ESP32ULP_VERSION}/esp32ulp-elf/bin', output) + self.assertNotIn(f'{self.temp_tools_dir}/tools/xtensa-esp-elf/{XTENSA_ELF_VERSION}/xtensa-esp-elf/bin', output) + self.assertNotIn( + f'{self.temp_tools_dir}/tools/xtensa-esp-elf-gdb/{XTENSA_ESP_GDB_VERSION}/xtensa-esp-elf-gdb/bin', + output, + ) + self.assertIn(f'{self.temp_tools_dir}/tools/esp-rom-elfs/{ESP_ROM_ELFS_VERSION}/', output) def test_tools_for_esp32s2(self): required_tools_installed = 6 @@ -501,20 +496,19 @@ def test_tools_for_esp32s2(self): self.assertIn('version installed in tools directory: ' + tool_version, output) output = self.run_idf_tools_with_action(['export']) - self.assertIn('%s/tools/xtensa-esp-elf/%s/xtensa-esp-elf/bin' % - (self.temp_tools_dir, XTENSA_ELF_VERSION), output) - self.assertIn('%s/tools/openocd-esp32/%s/openocd-esp32/bin' % - (self.temp_tools_dir, OPENOCD_VERSION), output) - self.assertIn('%s/tools/esp32ulp-elf/%s/esp32ulp-elf/bin' % - (self.temp_tools_dir, ESP32ULP_VERSION), output) - self.assertIn('%s/tools/riscv32-esp-elf/%s/riscv32-esp-elf/bin' % - (self.temp_tools_dir, RISCV_ELF_VERSION), output) - self.assertIn('%s/tools/xtensa-esp-elf-gdb/%s/xtensa-esp-elf-gdb/bin' % - (self.temp_tools_dir, XTENSA_ESP_GDB_VERSION), output) - self.assertNotIn('%s/tools/riscv32-esp-elf-gdb/%s/riscv32-esp-elf-gdb/bin' % - (self.temp_tools_dir, RISCV_ESP_GDB_VERSION), output) - self.assertIn('%s/tools/esp-rom-elfs/%s/' % - (self.temp_tools_dir, ESP_ROM_ELFS_VERSION), output) + self.assertIn(f'{self.temp_tools_dir}/tools/xtensa-esp-elf/{XTENSA_ELF_VERSION}/xtensa-esp-elf/bin', output) + self.assertIn(f'{self.temp_tools_dir}/tools/openocd-esp32/{OPENOCD_VERSION}/openocd-esp32/bin', output) + self.assertIn(f'{self.temp_tools_dir}/tools/esp32ulp-elf/{ESP32ULP_VERSION}/esp32ulp-elf/bin', output) + self.assertIn(f'{self.temp_tools_dir}/tools/riscv32-esp-elf/{RISCV_ELF_VERSION}/riscv32-esp-elf/bin', output) + self.assertIn( + f'{self.temp_tools_dir}/tools/xtensa-esp-elf-gdb/{XTENSA_ESP_GDB_VERSION}/xtensa-esp-elf-gdb/bin', + output, + ) + self.assertNotIn( + f'{self.temp_tools_dir}/tools/riscv32-esp-elf-gdb/{RISCV_ESP_GDB_VERSION}/riscv32-esp-elf-gdb/bin', + output, + ) + self.assertIn(f'{self.temp_tools_dir}/tools/esp-rom-elfs/{ESP_ROM_ELFS_VERSION}/', output) def test_tools_for_esp32s3(self): required_tools_installed = 6 @@ -535,20 +529,19 @@ def test_tools_for_esp32s3(self): self.assertIn('version installed in tools directory: ' + tool_version, output) output = self.run_idf_tools_with_action(['export']) - self.assertIn('%s/tools/openocd-esp32/%s/openocd-esp32/bin' % - (self.temp_tools_dir, OPENOCD_VERSION), output) - self.assertIn('%s/tools/xtensa-esp-elf/%s/xtensa-esp-elf/bin' % - (self.temp_tools_dir, XTENSA_ELF_VERSION), output) - self.assertIn('%s/tools/esp32ulp-elf/%s/esp32ulp-elf/bin' % - (self.temp_tools_dir, ESP32ULP_VERSION), output) - self.assertIn('%s/tools/riscv32-esp-elf/%s/riscv32-esp-elf/bin' % - (self.temp_tools_dir, RISCV_ELF_VERSION), output) - self.assertIn('%s/tools/xtensa-esp-elf-gdb/%s/xtensa-esp-elf-gdb/bin' % - (self.temp_tools_dir, XTENSA_ESP_GDB_VERSION), output) - self.assertNotIn('%s/tools/riscv32-esp-elf-gdb/%s/riscv32-esp-elf-gdb/bin' % - (self.temp_tools_dir, RISCV_ESP_GDB_VERSION), output) - self.assertIn('%s/tools/esp-rom-elfs/%s/' % - (self.temp_tools_dir, ESP_ROM_ELFS_VERSION), output) + self.assertIn(f'{self.temp_tools_dir}/tools/openocd-esp32/{OPENOCD_VERSION}/openocd-esp32/bin', output) + self.assertIn(f'{self.temp_tools_dir}/tools/xtensa-esp-elf/{XTENSA_ELF_VERSION}/xtensa-esp-elf/bin', output) + self.assertIn(f'{self.temp_tools_dir}/tools/esp32ulp-elf/{ESP32ULP_VERSION}/esp32ulp-elf/bin', output) + self.assertIn(f'{self.temp_tools_dir}/tools/riscv32-esp-elf/{RISCV_ELF_VERSION}/riscv32-esp-elf/bin', output) + self.assertIn( + f'{self.temp_tools_dir}/tools/xtensa-esp-elf-gdb/{XTENSA_ESP_GDB_VERSION}/xtensa-esp-elf-gdb/bin', + output, + ) + self.assertNotIn( + f'{self.temp_tools_dir}/tools/riscv32-esp-elf-gdb/{RISCV_ESP_GDB_VERSION}/riscv32-esp-elf-gdb/bin', + output, + ) + self.assertIn(f'{self.temp_tools_dir}/tools/esp-rom-elfs/{ESP_ROM_ELFS_VERSION}/', output) def test_tools_for_esp32p4(self): required_tools_installed = 4 @@ -605,14 +598,14 @@ class TestUsageWin(TestUsage): def test_usage_basic_win(self): output = self.run_idf_tools_with_action(['list']) - self.assertIn('* %s:' % ESP32ULP, output) - self.assertIn('- %s (recommended)' % ESP32ULP_VERSION, output) - self.assertIn('* %s:' % OPENOCD, output) - self.assertIn('- %s (recommended)' % OPENOCD_VERSION, output) - self.assertIn('* %s:' % RISCV_ELF, output) - self.assertIn('- %s (recommended)' % RISCV_ELF_VERSION, output) - self.assertIn('* %s:' % XTENSA_ELF, output) - self.assertIn('- %s (recommended)' % XTENSA_ELF_VERSION, output) + self.assertIn(f'* {ESP32ULP}:', output) + self.assertIn(f'- {ESP32ULP_VERSION} (recommended)', output) + self.assertIn(f'* {OPENOCD}:', output) + self.assertIn(f'- {OPENOCD_VERSION} (recommended)', output) + self.assertIn(f'* {RISCV_ELF}:', output) + self.assertIn(f'- {RISCV_ELF_VERSION} (recommended)', output) + self.assertIn(f'* {XTENSA_ELF}:', output) + self.assertIn(f'- {XTENSA_ELF_VERSION} (recommended)', output) required_tools_installed = 12 output = self.run_idf_tools_with_action(['install']) @@ -669,7 +662,7 @@ def test_usage_basic_win(self): self.assertIn(os.path.join(self.temp_tools_dir, 'tools', NINJA, NINJA_VERSION), output) self.assertIn(os.path.join(self.temp_tools_dir, 'tools', IDF_EXE, IDF_EXE_VERSION), output) self.assertIn( - os.path.join(self.temp_tools_dir, 'tools', CCACHE, CCACHE_VERSION, 'ccache-4.11.2-windows-x86_64'), output + os.path.join(self.temp_tools_dir, 'tools', CCACHE, CCACHE_VERSION, 'ccache-4.12.1-windows-x86_64'), output ) self.assertIn( os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output @@ -770,7 +763,7 @@ def test_tools_for_esp32_win(self): self.assertIn(os.path.join(self.temp_tools_dir, 'tools', NINJA, NINJA_VERSION), output) self.assertIn(os.path.join(self.temp_tools_dir, 'tools', IDF_EXE, IDF_EXE_VERSION), output) self.assertIn( - os.path.join(self.temp_tools_dir, 'tools', CCACHE, CCACHE_VERSION, 'ccache-4.11.2-windows-x86_64'), output + os.path.join(self.temp_tools_dir, 'tools', CCACHE, CCACHE_VERSION, 'ccache-4.12.1-windows-x86_64'), output ) self.assertNotIn( os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output @@ -834,7 +827,7 @@ def test_tools_for_esp32c3_win(self): self.assertIn(os.path.join(self.temp_tools_dir, 'tools', NINJA, NINJA_VERSION), output) self.assertIn(os.path.join(self.temp_tools_dir, 'tools', IDF_EXE, IDF_EXE_VERSION), output) self.assertIn( - os.path.join(self.temp_tools_dir, 'tools', CCACHE, CCACHE_VERSION, 'ccache-4.11.2-windows-x86_64'), output + os.path.join(self.temp_tools_dir, 'tools', CCACHE, CCACHE_VERSION, 'ccache-4.12.1-windows-x86_64'), output ) self.assertNotIn( os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output @@ -903,7 +896,7 @@ def test_tools_for_esp32s2_win(self): self.assertIn(os.path.join(self.temp_tools_dir, 'tools', NINJA, NINJA_VERSION), output) self.assertIn(os.path.join(self.temp_tools_dir, 'tools', IDF_EXE, IDF_EXE_VERSION), output) self.assertIn( - os.path.join(self.temp_tools_dir, 'tools', CCACHE, CCACHE_VERSION, 'ccache-4.11.2-windows-x86_64'), output + os.path.join(self.temp_tools_dir, 'tools', CCACHE, CCACHE_VERSION, 'ccache-4.12.1-windows-x86_64'), output ) self.assertIn( os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output @@ -974,7 +967,7 @@ def test_tools_for_esp32s3_win(self): self.assertIn(os.path.join(self.temp_tools_dir, 'tools', NINJA, NINJA_VERSION), output) self.assertIn(os.path.join(self.temp_tools_dir, 'tools', IDF_EXE, IDF_EXE_VERSION), output) self.assertIn( - os.path.join(self.temp_tools_dir, 'tools', CCACHE, CCACHE_VERSION, 'ccache-4.11.2-windows-x86_64'), output + os.path.join(self.temp_tools_dir, 'tools', CCACHE, CCACHE_VERSION, 'ccache-4.12.1-windows-x86_64'), output ) self.assertIn( os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output @@ -1011,7 +1004,7 @@ def test_tools_for_esp32p4_win(self): self.assertIn(os.path.join(self.temp_tools_dir, 'tools', NINJA, NINJA_VERSION), output) self.assertIn(os.path.join(self.temp_tools_dir, 'tools', IDF_EXE, IDF_EXE_VERSION), output) self.assertIn( - os.path.join(self.temp_tools_dir, 'tools', CCACHE, CCACHE_VERSION, 'ccache-4.11.2-windows-x86_64'), output + os.path.join(self.temp_tools_dir, 'tools', CCACHE, CCACHE_VERSION, 'ccache-4.12.1-windows-x86_64'), output ) self.assertNotIn( os.path.join(self.temp_tools_dir, 'tools', XTENSA_ELF, XTENSA_ELF_VERSION, XTENSA_ELF, 'bin'), output @@ -1064,16 +1057,16 @@ def test_validation(self): def test_json_rewrite(self): idf_tools.main(['rewrite']) - with open(self.tools_old, 'r') as f: + with open(self.tools_old) as f: json_old = f.read() - with open(self.tools_new, 'r') as f: + with open(self.tools_new) as f: json_new = f.read() self.assertEqual(json_old, json_new, "Please check 'tools/tools.new.json' to find a cause!") def add_version_get_expected_json(self, addition_file, replace=False): - with open(self.tools_old, 'r') as f: + with open(self.tools_old) as f: expected_json = json.load(f) - with open(addition_file, 'r') as f: + with open(addition_file) as f: addition_json = json.load(f) for tool in expected_json['tools']: if tool['name'] == self.test_tool_name: @@ -1086,7 +1079,7 @@ def add_version_get_expected_json(self, addition_file, replace=False): def test_add_version_artifact_addition(self): filenames = [] - with open('add_version/artifact_input.json', 'r') as f: + with open('add_version/artifact_input.json') as f: add_tools_info = json.load(f) for tool in add_tools_info: filenames.append(tool['filename']) @@ -1106,7 +1099,7 @@ def test_add_version_artifact_addition(self): ] + filenames ) expected_json = self.add_version_get_expected_json('add_version/artifact_expected_addition.json') - with open(self.tools_new, 'r') as f1: + with open(self.tools_new) as f1: self.assertEqual(json.load(f1), expected_json, "Please check 'tools/tools.new.json' to find a cause!") def test_add_version_checksum_addition(self): @@ -1124,7 +1117,7 @@ def test_add_version_checksum_addition(self): ] ) expected_json = self.add_version_get_expected_json('add_version/checksum_expected_addition.json') - with open(self.tools_new, 'r') as f1: + with open(self.tools_new) as f1: self.assertEqual(json.load(f1), expected_json, "Please check 'tools/tools.new.json' to find a cause!") def test_add_version_checksum_with_override(self): @@ -1143,7 +1136,7 @@ def test_add_version_checksum_with_override(self): ] ) expected_json = self.add_version_get_expected_json('add_version/checksum_expected_override.json', True) - with open(self.tools_new, 'r') as f1: + with open(self.tools_new) as f1: self.assertEqual(json.load(f1), expected_json, "Please check 'tools/tools.new.json' to find a cause!") diff --git a/tools/tools.json b/tools/tools.json index f07880279ad2..5561be17087a 100644 --- a/tools/tools.json +++ b/tools/tools.json @@ -759,7 +759,7 @@ "description": "Ccache (compiler cache)", "export_paths": [ [ - "ccache-4.11.2-windows-x86_64" + "ccache-4.12.1-windows-x86_64" ] ], "export_vars": { @@ -787,12 +787,12 @@ "version_regex": "ccache version ([0-9.]+)", "versions": [ { - "name": "4.11.2", + "name": "4.12.1", "status": "recommended", "win64": { - "sha256": "1f39f3ad5aae3fe915e99ad1302633bc8f6718e58fa7c0de2b0ba7e080f0f08c", - "size": 1642225, - "url": "https://github.com/ccache/ccache/releases/download/v4.11.2/ccache-4.11.2-windows-x86_64.zip" + "sha256": "98aea520d66905b8ba7a8e648a4cc0ca941d5e119d441f1e879a4a9045bf18f6", + "size": 1710234, + "url": "https://github.com/ccache/ccache/releases/download/v4.12.1/ccache-4.12.1-windows-x86_64.zip" } } ]