Merge branch 'espressif:release/v5.5' into release/v5.5

This commit is contained in:
Jason2866
2026-01-04 13:03:02 +01:00
committed by GitHub
494 changed files with 26165 additions and 3634 deletions
+2 -2
View File
@@ -118,7 +118,7 @@ build_docs_html_full:
paths:
- docs/_build/*/*/*.txt
- docs/_build/*/*/html/*
expire_in: 4 days
expire_in: 12 hrs
variables:
DOC_BUILDERS: "html"
@@ -131,7 +131,7 @@ build_docs_html_partial:
paths:
- docs/_build/*/*/*.txt
- docs/_build/*/*/html/*
expire_in: 4 days
expire_in: 12 hrs
variables:
DOC_BUILDERS: "html"
parallel:
+4 -5
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -295,10 +295,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;
}
@@ -113,10 +113,6 @@ esp_err_t esp_ota_begin(const esp_partition_t* partition, size_t image_size, esp
* Unlike esp_ota_begin(), this function does not erase the partition which receives the OTA update, but rather expects that part of the image
* has already been written correctly, and it resumes writing from the given offset.
*
* @note When flash encryption is enabled, data writes must be 16-byte aligned.
* Any leftover (non-aligned) data is temporarily cached and may be lost after reboot.
* Therefore, during resumption, ensure that image offset is always 16-byte aligned.
*
* @param partition Pointer to info for the partition which is receiving the OTA update. Required.
* @param erase_size Specifies how much flash memory to erase before resuming OTA, depending on whether a sequential write or a bulk erase is being used.
* @param image_offset Offset from where to resume the OTA process. Should be set to the number of bytes already written.
@@ -519,7 +519,7 @@ static esp_err_t bootloader_flash_read_allow_decrypt(size_t src_addr, void *dest
Cache_Read_Enable(0);
#else
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
cache_ll_invalidate_addr(CACHE_LL_LEVEL_ALL, CACHE_TYPE_ALL, CACHE_LL_ID_ALL, FLASH_MMAP_VADDR, actual_mapped_len);
cache_ll_invalidate_addr(CACHE_LL_LEVEL_ALL, CACHE_TYPE_ALL, CACHE_LL_ID_ALL, FLASH_READ_VADDR, actual_mapped_len);
#endif
#if !ESP_TEE_BUILD
cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL);
@@ -24,6 +24,7 @@
#include "hal/cache_ll.h"
#include "spi_flash_mmap.h"
#include "hal/efuse_hal.h"
#include "sdkconfig.h"
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
@@ -141,6 +142,22 @@ static bool is_bootloader(uint32_t offset)
);
}
#if BOOTLOADER_BUILD && (SECURE_BOOT_CHECK_SIGNATURE == 1)
#if CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
static bool skip_verify(esp_image_load_mode_t mode, bool verify_sha)
{
// Multi level check to ensure that its a legit exit from deep sleep case
return (esp_rom_get_reset_reason(0) == RESET_REASON_CORE_DEEP_SLEEP &&
mode == ESP_IMAGE_LOAD_NO_VALIDATE &&
!verify_sha) ? true : false;
}
#else
#define skip_verify(mode, verify_sha) (false)
#endif
#endif // BOOTLOADER_BUILD && (SECURE_BOOT_CHECK_SIGNATURE == 1)
static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
{
#ifdef BOOTLOADER_BUILD
@@ -236,9 +253,9 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
"only verify signature in bootloader" into the macro so it's tested multiple times.
*/
#if CONFIG_SECURE_BOOT_V2_ENABLED
ESP_FAULT_ASSERT(!esp_secure_boot_enabled() || memcmp(image_digest, verified_digest, ESP_SECURE_BOOT_DIGEST_LEN) == 0);
ESP_FAULT_ASSERT(!esp_secure_boot_enabled() || skip_verify(mode, verify_sha) || memcmp(image_digest, verified_digest, ESP_SECURE_BOOT_DIGEST_LEN) == 0);
#else // Secure Boot V1 on ESP32, only verify signatures for apps not bootloaders
ESP_FAULT_ASSERT(is_bootloader(data->start_addr) || memcmp(image_digest, verified_digest, HASH_LEN) == 0);
ESP_FAULT_ASSERT(is_bootloader(data->start_addr) || skip_verify(mode, verify_sha) || memcmp(image_digest, verified_digest, HASH_LEN) == 0);
#endif
#endif // SECURE_BOOT_CHECK_SIGNATURE
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -13,12 +13,17 @@
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/ecp.h"
#include "rom/ecdsa.h"
#include "sdkconfig.h"
#include "secure_boot_signature_priv.h"
static const char *TAG = "secure_boot_v2_ecdsa";
#if CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS
#define ECDSA_INTEGER_LEN 48
#else
#define ECDSA_INTEGER_LEN 32
#endif /* CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS */
esp_err_t verify_ecdsa_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, const ets_secure_boot_sig_block_t *trusted_block)
{
@@ -48,6 +53,12 @@ esp_err_t verify_ecdsa_signature_block(const ets_secure_boot_signature_t *sig_bl
key_size = 32;
mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1);
break;
#if CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS
case ECDSA_CURVE_P384:
key_size = 48;
mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP384R1);
break;
#endif /* CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS */
default:
ESP_LOGE(TAG, "Invalid curve ID");
return ESP_ERR_INVALID_ARG;
+22 -5
View File
@@ -47,6 +47,9 @@ set(ble_mesh_v11_include_dirs
"esp_ble_mesh/v1.1/api/core/include"
"esp_ble_mesh/v1.1/api/models/include"
"esp_ble_mesh/v1.1/btc/include"
"esp_ble_mesh/v1.1/include"
"esp_ble_mesh/v1.1/dfu"
"esp_ble_mesh/v1.1/mbt"
)
if(CONFIG_IDF_DOC_BUILD)
@@ -571,7 +574,6 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/core/storage/settings.c"
"esp_ble_mesh/core/access.c"
"esp_ble_mesh/core/adv_common.c"
"esp_ble_mesh/core/ble_adv.c"
"esp_ble_mesh/core/beacon.c"
"esp_ble_mesh/core/cfg_cli.c"
"esp_ble_mesh/core/cfg_srv.c"
@@ -623,9 +625,13 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_sar_model_api.c"
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_srpl_model_api.c"
"esp_ble_mesh/v1.1/api/models/esp_ble_mesh_mbt_model_api.c"
"esp_ble_mesh/v1.1/api/models/esp_ble_mesh_dfu_model_api.c"
"esp_ble_mesh/v1.1/api/models/esp_ble_mesh_dfu_slot_api.c"
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_agg_model.c"
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_brc_model.c"
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_df_model.c"
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_dfu_model.c"
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_dfu_slot.c"
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_lcd_model.c"
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_mbt_model.c"
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_odp_model.c"
@@ -633,25 +639,36 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_rpr_model.c"
"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/v1.1/mbt/blob_srv.c"
"esp_ble_mesh/v1.1/mbt/blob_cli.c"
"esp_ble_mesh/v1.1/dfu/dfu_cli.c"
"esp_ble_mesh/v1.1/dfu/dfu_srv.c"
"esp_ble_mesh/v1.1/dfu/dfu_slot.c"
"esp_ble_mesh/v1.1/dfu/dfu_metadata.c"
"esp_ble_mesh/v1.1/dfu/dfd_srv.c"
"esp_ble_mesh/v1.1/dfu/dfd_cli.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()
if(CONFIG_BLE_MESH_SUPPORT_MULTI_ADV)
list(APPEND srcs "esp_ble_mesh/core/ext_adv.c")
else()
list(APPEND srcs "esp_ble_mesh/core/adv.c")
endif()
if(CONFIG_BLE_MESH_SUPPORT_BLE_ADV)
list(APPEND srcs "esp_ble_mesh/core/ble_adv.c")
endif()
endif()
if(CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT)
list(APPEND srcs
"porting/npl/freertos/src/npl_os_freertos.c"
+6
View File
@@ -91,6 +91,12 @@ if BLE_LOG_ENABLED
checksum of frame head and payload all together by default, or only
calculate the checksum of frame head to minimize performance decrease
config BLE_LOG_XOR_CHECKSUM_ENABLED
bool "Enable XOR checksum for BLE Log payload integrity check"
default y
help
XOR checksum is introduced for integrity check performance optimization.
config BLE_LOG_ENH_STAT_ENABLED
bool "Enable enhanced statistics for BLE Log"
default n
@@ -198,6 +198,7 @@ bool ble_log_lbm_init(void)
/* Initialize lock types for spin pool */
for (int i = 0; i < BLE_LOG_LBM_SPIN_MAX; i++) {
lbm_ctx->spin_pool[i].lock_type = BLE_LOG_LBM_LOCK_SPIN;
portMUX_INITIALIZE(&(lbm_ctx->spin_pool[i].spin_lock));
}
#if CONFIG_BLE_LOG_LL_ENABLED
@@ -421,6 +422,7 @@ deref:
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);
@@ -60,7 +60,9 @@ BLE_LOG_IRAM_ATTR BLE_LOG_STATIC void ble_log_rt_task(void *pvParameters)
if (rt_ts_enabled) {
ble_log_ts_info_t *ts_info = NULL;
ble_log_ts_info_update(&ts_info);
ble_log_write_hex(BLE_LOG_SRC_INTERNAL, (const uint8_t *)ts_info, sizeof(ble_log_ts_info_t));
if (ts_info) {
ble_log_write_hex(BLE_LOG_SRC_INTERNAL, (const uint8_t *)ts_info, sizeof(ble_log_ts_info_t));
}
}
#endif /* CONFIG_BLE_LOG_TS_ENABLED */
@@ -139,6 +141,7 @@ bool ble_log_sync_enable(bool enable)
return false;
}
rt_ts_enabled = enable;
ble_log_ts_reset(enable);
return true;
}
#endif /* CONFIG_BLE_LOG_TS_ENABLED */
@@ -63,6 +63,10 @@ void ble_log_ts_deinit(void)
void ble_log_ts_info_update(ble_log_ts_info_t **info)
{
if (!ts_inited) {
return;
}
BLE_LOG_ENTER_CRITICAL();
ts_info->io_level = !ts_info->io_level;
gpio_set_level(CONFIG_BLE_LOG_SYNC_IO_NUM, ts_info->io_level);
@@ -73,3 +77,16 @@ void ble_log_ts_info_update(ble_log_ts_info_t **info)
*info = ts_info;
}
void ble_log_ts_reset(bool status)
{
if (!ts_inited) {
return;
}
if (!status && !ts_info->io_level) {
gpio_set_level(CONFIG_BLE_LOG_SYNC_IO_NUM, 1);
}
ts_info->io_level = 0;
gpio_set_level(CONFIG_BLE_LOG_SYNC_IO_NUM, 0);
}
@@ -17,7 +17,60 @@ portMUX_TYPE ble_log_spin_lock = portMUX_INITIALIZER_UNLOCKED;
#endif /* !UNIT_TEST */
/* INTERNAL INTERFACE */
BLE_LOG_IRAM_ATTR uint32_t ble_log_fast_checksum(const uint8_t *data, size_t len)
#if CONFIG_BLE_LOG_XOR_CHECKSUM_ENABLED
#include "esp_compiler.h"
static inline uint32_t ror32(uint32_t word, uint32_t shift)
{
if (unlikely(shift == 0)) {
return word;
}
return (word >> shift) | (word << ((32 - shift) & 0x1F));
}
__attribute__((optimize("-O3")))
BLE_LOG_IRAM_ATTR
uint32_t ble_log_fast_checksum(const uint8_t *data, size_t len)
{
/* Validate input length */
if (unlikely(len == 0)) {
return 0;
}
/* Step 1: Force 32-bit align read and calculate offset */
const uint32_t start_offset_shift = ((uintptr_t)data & 0x3) << 3;
const uint32_t *p_aligned = (const uint32_t *)((uintptr_t)data & ~0x3);
const uint32_t *p_end_aligned = (const uint32_t *)((uintptr_t)(data + len) & ~0x3);
/* Step 2: Handle first word with mask (Little endian) */
uint32_t checksum = (*p_aligned) & (0xFFFFFFFFU << start_offset_shift);
/* Step 3: Check if first word is last word */
const uint32_t end_offset_shift = ((uintptr_t)(data + len) & 0x3) << 3;
const uint32_t end_offset_shift_mask = ~(0xFFFFFFFFU << end_offset_shift);
if (unlikely(p_aligned == p_end_aligned)) {
if (end_offset_shift) {
checksum &= end_offset_shift_mask;
}
} else {
/* Step 4: Handle word in the middle */
p_aligned++;
while (p_aligned < p_end_aligned) {
checksum ^= *p_aligned++;
}
/* Step 5: Handle last word with mask (Little endian) */
if (end_offset_shift) {
checksum ^= (*p_aligned) & end_offset_shift_mask;
}
}
/* Step 6: Rotate the final result */
return ror32(checksum, start_offset_shift);
}
#else /* !CONFIG_BLE_LOG_XOR_CHECKSUM_ENABLED */
BLE_LOG_IRAM_ATTR
uint32_t ble_log_fast_checksum(const uint8_t *data, size_t len)
{
uint32_t sum = 0;
size_t i = 0;
@@ -46,3 +99,4 @@ BLE_LOG_IRAM_ATTR uint32_t ble_log_fast_checksum(const uint8_t *data, size_t len
return sum;
}
#endif /* CONFIG_BLE_LOG_XOR_CHECKSUM_ENABLED */
@@ -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 */
@@ -53,5 +53,6 @@ typedef struct {
bool ble_log_ts_init(void);
void ble_log_ts_deinit(void);
void ble_log_ts_info_update(ble_log_ts_info_t **ts_info);
void ble_log_ts_reset(bool status);
#endif /* __BLE_LOG_TS_H__ */
@@ -130,7 +130,7 @@ bool ble_log_cas_acquire(volatile bool *cas_lock);
void ble_log_cas_release(volatile bool *cas_lock);
#endif /* UNIT_TEST */
#define BLE_LOG_VERSION (2)
#define BLE_LOG_VERSION (3)
/* TYPEDEF */
typedef enum {
+1 -1
View File
@@ -12,7 +12,7 @@ void btc_alarm_handler(btc_msg_t *msg)
{
btc_alarm_args_t *arg = (btc_alarm_args_t *)msg->arg;
BTC_TRACE_DEBUG("%s act %d\n", __FUNCTION__, msg->act);
BTC_TRACE_DEBUG("%s act %d", __func__, msg->act);
if (arg->cb) {
arg->cb(arg->cb_data);
+7
View File
@@ -89,6 +89,7 @@
#include "btc_ble_mesh_rpr_model.h"
#include "btc_ble_mesh_sar_model.h"
#include "btc_ble_mesh_srpl_model.h"
#include "btc_ble_mesh_dfu_model.h"
#endif /* CONFIG_BLE_MESH_V11_SUPPORT */
#endif /* #if CONFIG_BLE_MESH */
@@ -262,6 +263,12 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = {
#if CONFIG_BLE_MESH_MBT_SRV
[BTC_PID_MBT_SERVER] = {btc_ble_mesh_mbt_server_call_handler, btc_ble_mesh_mbt_server_cb_handler },
#endif /* CONFIG_BLE_MESH_MBT_SRV */
#if CONFIG_BLE_MESH_DFU_CLI
[BTC_PID_DFU_CLIENT] = {btc_ble_mesh_dfu_client_call_handler, btc_ble_mesh_dfu_client_cb_handler},
#endif /* CONFIG_BLE_MESH_DFU_CLI */
#if CONFIG_BLE_MESH_DFD_CLI
[BTC_PID_DFD_CLIENT] = {btc_ble_mesh_dfd_client_call_handler, btc_ble_mesh_dfd_client_cb_handler},
#endif /* CONFIG_BLE_MESH_DFD_CLI */
#if CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50
[BTC_PID_BLE_MESH_BLE_COEX] = {btc_ble_mesh_ble_call_handler, btc_ble_mesh_ble_cb_handler },
#endif /* CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50 */
@@ -106,6 +106,12 @@ typedef enum {
BTC_PID_TIME_SCENE_SERVER,
BTC_PID_MBT_CLIENT,
BTC_PID_MBT_SERVER,
BTC_PID_BLOB_CLIENT,
BTC_PID_BLOB_SERVER,
BTC_PID_DFU_CLIENT,
BTC_PID_DFU_SERVER,
BTC_PID_DFD_CLIENT,
BTC_PID_DFD_SERVER,
BTC_PID_BLE_MESH_BLE_COEX,
#endif /* CONFIG_BLE_MESH */
#if (BLE_FEAT_ISO_EN == TRUE)
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -32,6 +32,7 @@
#include "esp_bt_device.h"
#include "esp_err.h"
#include "esp_blufi.h"
#include <esp_gap_ble_api.h>
#if (BLUFI_INCLUDED == TRUE)
@@ -70,12 +71,155 @@ static esp_ble_adv_params_t blufi_adv_params = {
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};
#ifdef CONFIG_BT_BLUFI_BLE_SMP_ENABLE
static char *esp_auth_req_to_str(esp_ble_auth_req_t auth_req)
{
char *auth_str = NULL;
switch(auth_req) {
case ESP_LE_AUTH_NO_BOND:
auth_str = "ESP_LE_AUTH_NO_BOND";
break;
case ESP_LE_AUTH_BOND:
auth_str = "ESP_LE_AUTH_BOND";
break;
case ESP_LE_AUTH_REQ_MITM:
auth_str = "ESP_LE_AUTH_REQ_MITM";
break;
case ESP_LE_AUTH_REQ_BOND_MITM:
auth_str = "ESP_LE_AUTH_REQ_BOND_MITM";
break;
case ESP_LE_AUTH_REQ_SC_ONLY:
auth_str = "ESP_LE_AUTH_REQ_SC_ONLY";
break;
case ESP_LE_AUTH_REQ_SC_BOND:
auth_str = "ESP_LE_AUTH_REQ_SC_BOND";
break;
case ESP_LE_AUTH_REQ_SC_MITM:
auth_str = "ESP_LE_AUTH_REQ_SC_MITM";
break;
case ESP_LE_AUTH_REQ_SC_MITM_BOND:
auth_str = "ESP_LE_AUTH_REQ_SC_MITM_BOND";
break;
default:
auth_str = "INVALID BLE AUTH REQ";
break;
}
return auth_str;
}
static char *esp_key_type_to_str(esp_ble_key_type_t key_type)
{
char *key_str = NULL;
switch(key_type) {
case ESP_LE_KEY_NONE:
key_str = "ESP_LE_KEY_NONE";
break;
case ESP_LE_KEY_PENC:
key_str = "ESP_LE_KEY_PENC";
break;
case ESP_LE_KEY_PID:
key_str = "ESP_LE_KEY_PID";
break;
case ESP_LE_KEY_PCSRK:
key_str = "ESP_LE_KEY_PCSRK";
break;
case ESP_LE_KEY_PLK:
key_str = "ESP_LE_KEY_PLK";
break;
case ESP_LE_KEY_LLK:
key_str = "ESP_LE_KEY_LLK";
break;
case ESP_LE_KEY_LENC:
key_str = "ESP_LE_KEY_LENC";
break;
case ESP_LE_KEY_LID:
key_str = "ESP_LE_KEY_LID";
break;
case ESP_LE_KEY_LCSRK:
key_str = "ESP_LE_KEY_LCSRK";
break;
default:
key_str = "INVALID BLE KEY TYPE";
break;
}
return key_str;
}
#endif
void esp_blufi_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
BLUFI_TRACE_DEBUG("GAP_EVT, event %d", event);
switch (event) {
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
esp_ble_gap_start_advertising(&blufi_adv_params);
break;
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
//advertising start complete event to indicate advertising start successfully or failed
if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("Advertising start failed, status %x", param->adv_start_cmpl.status);
break;
}
BLUFI_TRACE_API("Advertising start successfully");
break;
#ifdef CONFIG_BT_BLUFI_BLE_SMP_ENABLE
case ESP_GAP_BLE_PASSKEY_REQ_EVT: /* passkey request event */
BLUFI_TRACE_API("Passkey request");
break;
case ESP_GAP_BLE_OOB_REQ_EVT: {
BLUFI_TRACE_API("OOB request");
uint8_t tk[16] = {1}; //If you paired with OOB, both devices need to use the same tk
esp_ble_oob_req_reply(param->ble_security.ble_req.bd_addr, tk, sizeof(tk));
break;
}
case ESP_GAP_BLE_LOCAL_IR_EVT: /* BLE local IR event */
BLUFI_TRACE_API("Local identity root");
break;
case ESP_GAP_BLE_LOCAL_ER_EVT: /* BLE local ER event */
BLUFI_TRACE_API("Local encryption root");
break;
case ESP_GAP_BLE_NC_REQ_EVT:
/* The app will receive this evt when the IO has DisplayYesNO capability and the peer device IO also has DisplayYesNo capability.
show the passkey number to the user to confirm it with the number displayed by peer device. */
esp_ble_confirm_reply(param->ble_security.ble_req.bd_addr, true);
BLUFI_TRACE_WARNING("Numeric Comparison request, passkey %" PRIu32, param->ble_security.key_notif.passkey);
break;
case ESP_GAP_BLE_SEC_REQ_EVT:
/* send the positive(true) security response to the peer device to accept the security request.
If not accept the security request, should send the security response with negative(false) accept value*/
esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true);
break;
case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: ///the app will receive this evt when the IO has Output capability and the peer device IO has Input capability.
///show the passkey number to the user to input it in the peer device.
BLUFI_TRACE_WARNING("Passkey notify, passkey %06" PRIu32, param->ble_security.key_notif.passkey);
break;
case ESP_GAP_BLE_KEY_EVT:
//shows the ble key info share with peer device to the user.
BLUFI_TRACE_API("Key exchanged, key_type %s", esp_key_type_to_str(param->ble_security.ble_key.key_type));
break;
case ESP_GAP_BLE_AUTH_CMPL_EVT: {
esp_bd_addr_t bd_addr;
memcpy(bd_addr, param->ble_security.auth_cmpl.bd_addr, sizeof(esp_bd_addr_t));
BLUFI_TRACE_API("Authentication complete, addr_type %u, addr "ESP_BD_ADDR_STR"",
param->ble_security.auth_cmpl.addr_type, ESP_BD_ADDR_HEX(bd_addr));
if(!param->ble_security.auth_cmpl.success) {
BLUFI_TRACE_WARNING("Pairing failed, reason 0x%x",param->ble_security.auth_cmpl.fail_reason);
} else {
BLUFI_TRACE_WARNING("Pairing successfully, auth_mode %s",esp_auth_req_to_str(param->ble_security.auth_cmpl.auth_mode));
}
break;
}
case ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT: {
BLUFI_TRACE_DEBUG("Bond device remove, status %d, device "ESP_BD_ADDR_STR"",
param->remove_bond_dev_cmpl.status, ESP_BD_ADDR_HEX(param->remove_bond_dev_cmpl.bd_addr));
break;
}
case ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT:
if (param->local_privacy_cmpl.status != ESP_BT_STATUS_SUCCESS){
BLUFI_TRACE_WARNING("Local privacy config failed, status %x", param->local_privacy_cmpl.status);
}
break;
#endif // CONFIG_BT_BLUFI_BLE_SMP_ENABLE
default:
break;
}
@@ -251,10 +395,16 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
break;
case BTA_GATTS_CREATE_EVT:
blufi_env.handle_srvc = p_data->create.service_id;
#if CONFIG_BT_BLUFI_BLE_SMP_ENABLE
BLUFI_TRACE_WARNING("BLE SMP support in BLUFI is ENABLED!");
#endif // CONFIG_BT_BLUFI_BLE_SMP_ENABLE
//add the first blufi characteristic --> write characteristic
BTA_GATTS_AddCharacteristic(blufi_env.handle_srvc, &blufi_char_uuid_p2e,
(GATT_PERM_WRITE),
#if CONFIG_BT_BLUFI_BLE_SMP_ENABLE
GATT_PERM_WRITE_ENC_MITM,
#else
GATT_PERM_WRITE,
#endif
(GATT_CHAR_PROP_BIT_WRITE),
NULL, NULL);
break;
@@ -398,6 +548,16 @@ void esp_blufi_adv_stop(void)
esp_ble_gap_stop_advertising();
}
esp_err_t esp_blufi_start_security_request(esp_blufi_bd_addr_t remote_bda)
{
#ifdef CONFIG_BT_BLUFI_BLE_SMP_ENABLE
return esp_ble_set_encryption(remote_bda, ESP_BLE_SEC_ENCRYPT_MITM);
#else
return ESP_ERR_INVALID_STATE;
#endif // CONFIG_BT_BLUFI_BLE_SMP_ENABLE
}
void esp_blufi_send_encap(void *arg)
{
struct blufi_hdr *hdr = (struct blufi_hdr *)arg;
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -90,6 +90,22 @@ void esp_blufi_adv_start_with_name(const char *name);
void esp_blufi_send_encap(void *arg);
/*
* @brief Initiate BLE security request with the connected peer device.
*
* This function triggers the BLE Security Manager Protocol (SMP) procedure
* to establish a secure, encrypted connection with the specified remote device.
* It should be called after a BLE connection is established.
*
* @param[in] remote_bda Bluetooth device address of the connected peer.
*
* @return
* - ESP_OK: Security request initiated successfully
* - ESP_FAIL: Security request failed
* - ESP_ERR_INVALID_STATE: BluFi BLE SMP is not enabled
*/
esp_err_t esp_blufi_start_security_request(esp_blufi_bd_addr_t remote_bda);
#ifdef CONFIG_BT_NIMBLE_ENABLED
/**
* @brief Handle gap event for BluFi.
+2
View File
@@ -141,7 +141,9 @@
#define LOG_LOCAL_LEVEL_MAPPING LOG_LOCAL_LEVEL
#endif
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
#define BT_LOG_LEVEL_CHECK(LAYER, LEVEL) (MAX(LAYER##_INITIAL_TRACE_LEVEL, LOG_LOCAL_LEVEL_MAPPING) >= BT_TRACE_LEVEL_##LEVEL)
+10 -2
View File
@@ -191,14 +191,14 @@ config BT_LE_MAX_PERIODIC_ADVERTISER_LIST
config BT_LE_POWER_CONTROL_ENABLED
bool "Enable controller support for BLE Power Control"
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED && IDF_TARGET_ESP32C6
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED
default n
help
Set this option to enable the Power Control feature on controller
config BT_LE_PERIODIC_ADV_WITH_RESPONSE_ENABLED
bool "Enable BLE periodic advertising with response"
depends on BT_LE_50_FEATURE_SUPPORT
depends on BT_LE_50_FEATURE_SUPPORT && SOC_BLE_PERIODIC_ADV_WITH_RESPONSE
default n
help
This enables BLE periodic advertising with response feature
@@ -943,3 +943,11 @@ menu "Scheduling Priority Level Config"
default 2 if BT_LE_SYNC_SCHED_PRIO_HIGH_LEVEL
default 1
endmenu
config BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN
bool "Enable Peripheral fast PDU reception during latency"
default n
help
When this option is enabled, the Controller continues receiving PDUs
In the next connection event instead of entering latency
After a data packet is received.
+3 -3
View File
@@ -155,7 +155,7 @@ extern void esp_unregister_npl_funcs (void);
extern void npl_freertos_mempool_deinit(void);
extern uint32_t r_os_cputime_get32(void);
extern uint32_t r_os_cputime_ticks_to_usecs(uint32_t ticks);
extern void r_ble_lll_rfmgmt_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg,
extern void r_ble_lll_sleep_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg,
void *w_arg, uint32_t us_to_enabled);
extern void r_ble_rtc_wake_up_state_clr(void);
extern int os_msys_init(void);
@@ -788,10 +788,10 @@ esp_err_t controller_sleep_init(void)
#ifdef CONFIG_BT_LE_SLEEP_ENABLE
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "BLE modem sleep is enabled");
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0,
r_ble_lll_sleep_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0,
BLE_RTC_DELAY_US_LIGHT_SLEEP);
#else
r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0,
r_ble_lll_sleep_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0,
BLE_RTC_DELAY_US_MODEM_SLEEP);
#endif /* FREERTOS_USE_TICKLESS_IDLE */
#endif // CONFIG_BT_LE_SLEEP_ENABLE
@@ -209,6 +209,12 @@ extern "C" {
#define DEFAULT_BT_LE_CTRL_FAST_CONN_DATA_TX_EN (0)
#endif
#if defined(CONFIG_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN)
#define DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN (CONFIG_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN)
#else
#define DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN (0)
#endif
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART
#define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART
#else
+10 -2
View File
@@ -222,7 +222,7 @@ config BT_LE_MAX_PERIODIC_ADVERTISER_LIST
config BT_LE_POWER_CONTROL_ENABLED
bool "Enable controller support for BLE Power Control"
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED && IDF_TARGET_ESP32C6
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED
default n
help
Set this option to enable the Power Control feature on controller
@@ -239,7 +239,7 @@ config BT_LE_CTE_FEATURE_ENABLED
config BT_LE_PERIODIC_ADV_WITH_RESPONSE_ENABLED
bool "Enable BLE periodic advertising with response"
depends on BT_LE_50_FEATURE_SUPPORT
depends on BT_LE_50_FEATURE_SUPPORT && SOC_BLE_PERIODIC_ADV_WITH_RESPONSE
default n
help
This enables BLE periodic advertising with response feature
@@ -977,3 +977,11 @@ menu "Scheduling Priority Level Config"
default 2 if BT_LE_SYNC_SCHED_PRIO_HIGH_LEVEL
default 1
endmenu
config BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN
bool "Enable Peripheral fast PDU reception during latency"
default n
help
When this option is enabled, the Controller continues receiving PDUs
In the next connection event instead of entering latency
After a data packet is received.
+3 -3
View File
@@ -167,7 +167,7 @@ extern void esp_unregister_npl_funcs (void);
extern void npl_freertos_mempool_deinit(void);
extern uint32_t r_os_cputime_get32(void);
extern uint32_t r_os_cputime_ticks_to_usecs(uint32_t ticks);
extern void r_ble_lll_rfmgmt_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg,
extern void r_ble_lll_sleep_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg,
void *w_arg, uint32_t us_to_enabled);
extern void r_ble_rtc_wake_up_state_clr(void);
extern int os_msys_init(void);
@@ -848,10 +848,10 @@ esp_err_t controller_sleep_init(void)
#ifdef CONFIG_BT_LE_SLEEP_ENABLE
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "BLE modem sleep is enabled");
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0,
r_ble_lll_sleep_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0,
BLE_RTC_DELAY_US_LIGHT_SLEEP);
#else
r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0,
r_ble_lll_sleep_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0,
BLE_RTC_DELAY_US_MODEM_SLEEP);
#endif /* FREERTOS_USE_TICKLESS_IDLE */
#endif // CONFIG_BT_LE_SLEEP_ENABLE
@@ -212,6 +212,12 @@ extern "C" {
#define DEFAULT_BT_LE_CTRL_FAST_CONN_DATA_TX_EN (0)
#endif
#if defined(CONFIG_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN)
#define DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN (CONFIG_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN)
#else
#define DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN (0)
#endif
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART
#define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART
#else
+10 -2
View File
@@ -242,7 +242,7 @@ config BT_LE_CTE_FEATURE_ENABLED
config BT_LE_PERIODIC_ADV_WITH_RESPONSE_ENABLED
bool "Enable BLE periodic advertising with response"
depends on BT_LE_50_FEATURE_SUPPORT
depends on BT_LE_50_FEATURE_SUPPORT && SOC_BLE_PERIODIC_ADV_WITH_RESPONSE
default n
help
This enables BLE periodic advertising with response feature
@@ -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
@@ -981,3 +981,11 @@ menu "Scheduling Priority Level Config"
default 2 if BT_LE_SYNC_SCHED_PRIO_HIGH_LEVEL
default 1
endmenu
config BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN
bool "Enable Peripheral fast PDU reception during latency"
default n
help
When this option is enabled, the Controller continues receiving PDUs
In the next connection event instead of entering latency
After a data packet is received.
+3 -3
View File
@@ -159,7 +159,7 @@ extern void esp_unregister_npl_funcs (void);
extern void npl_freertos_mempool_deinit(void);
extern uint32_t r_os_cputime_get32(void);
extern uint32_t r_os_cputime_ticks_to_usecs(uint32_t ticks);
extern void r_ble_lll_rfmgmt_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg,
extern void r_ble_lll_sleep_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg,
void *w_arg, uint32_t us_to_enabled);
extern void r_ble_rtc_wake_up_state_clr(void);
extern int os_msys_init(void);
@@ -816,10 +816,10 @@ esp_err_t controller_sleep_init(void)
#ifdef CONFIG_BT_LE_SLEEP_ENABLE
ESP_LOGW(NIMBLE_PORT_LOG_TAG, "BLE modem sleep is enabled");
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0,
r_ble_lll_sleep_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0,
BLE_RTC_DELAY_US_LIGHT_SLEEP);
#else
r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0,
r_ble_lll_sleep_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0,
BLE_RTC_DELAY_US_MODEM_SLEEP);
#endif /* FREERTOS_USE_TICKLESS_IDLE */
#endif // CONFIG_BT_LE_SLEEP_ENABLE
@@ -209,6 +209,12 @@ extern "C" {
#define DEFAULT_BT_LE_CTRL_FAST_CONN_DATA_TX_EN (0)
#endif
#if defined(CONFIG_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN)
#define DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN (CONFIG_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN)
#else
#define DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN (0)
#endif
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART
#define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART
#else
+252 -2
View File
@@ -1636,11 +1636,13 @@ if BLE_MESH
Enable support for Lighting server models.
config BLE_MESH_MBT_CLI
bool "BLOB Transfer Client model"
bool "BLOB Transfer Client model(Deprecated)"
depends on BLE_MESH_V11_SUPPORT
default n
help
Enable support for BLOB Transfer Client model.
Warn: This version of the Mesh Binary Large Object Transfer Model will be deprecated,
and a new version will be released in the future.
if BLE_MESH_MBT_CLI
@@ -1655,11 +1657,259 @@ if BLE_MESH
endif # BLE_MESH_MBT_CLI
config BLE_MESH_MBT_SRV
bool "BLOB Transfer Server model"
bool "BLOB Transfer Server model(Deprecated)"
depends on BLE_MESH_V11_SUPPORT
default n
help
Enable support for BLOB Transfer Server model.
Warn: This version of the Mesh Binary Large Object Transfer Model will be deprecated,
and a new version will be released in the future.
menu "Binary Larger Object Transfer model"
config BLE_MESH_BLOB_SRV
bool "Support for BLOB Transfer Server model"
depends on BLE_MESH_V11_SUPPORT
help
Enable the Binary Large Object (BLOB) Transfer Server model.
if BLE_MESH_BLOB_SRV
config BLE_MESH_BLOB_SRV_PULL_REQ_COUNT
int "Number of chunks to request for each pull"
default 4
range 1 16
help
In Pull mode (Pull BLOB Transfer Mode), the BLOB Transfer Server
requests a fixed number of chunks from the Client. Use this option to
control the chunk count in the request. If the BLOB Transfer Server
is instantiated on a Low Power node, the pull request count will be
trimmed to not overflow the Friend queue.
config BLE_MESH_BLOB_SIZE_MAX
int "Largest BLOB size in bytes"
default 524288
range 1 3257617792
help
The maximum object size a BLOB Transfer Server can receive.
config BLE_MESH_BLOB_BLOCK_SIZE_MIN
int "Minimum block size"
default 4096
range 64 1048576 # 2^6 - 2^20
help
Minimum acceptable block size in a BLOB transfer. The transfer block
size will be some number that is a power of two, and is between block
size min and block size max. If no such number exists, a compile
time warning will be issued.
config BLE_MESH_BLOB_BLOCK_SIZE_MAX
int "Maximum block size"
default 4096
range BLE_MESH_BLOB_BLOCK_SIZE_MIN 1048576
help
Maximum acceptable block size in a BLOB transfer. The transfer block
size will be some number that is a power of two, and is between block
size min and block size max. If no such number exists, a compile
time warning will be issued.
config BLE_MESH_BLOB_REPORT_TIMEOUT
int "Partial Block Report interval in Pull mode"
default 10
range 1 31
help
The timer value that Pull BLOB Transfer Server uses to report missed chunks.
config BLE_MESH_RX_BLOB_CHUNK_SIZE
depends on !BLE_MESH_ALIGN_CHUNK_SIZE_TO_MAX_SEGMENT
int "BLOB Server chunk size"
default 8
range 8 377
help
Set the chunk size for the BLOB Server.
The actual maximum chunk size depends on how many segments are
possible and will be clamped to the max possible if set above.
see also: BLE_MESH_RX_SEG_MAX,
and the maximum SDU a node can receive.
endif # BLE_MESH_BLOB_SRV
config BLE_MESH_BLOB_CLI
bool "Support for BLOB Transfer Client model"
depends on BLE_MESH_V11_SUPPORT
help
Enable the Binary Large Object (BLOB) Transfer Client model.
if BLE_MESH_BLOB_CLI
config BLE_MESH_BLOB_CLI_BLOCK_RETRIES
int "Number of retries per block"
default 5
help
Controls the number of times the client will attempt to resend missing
chunks to the BLOB receivers for every block.
config BLE_MESH_TX_BLOB_CHUNK_SIZE
depends on !BLE_MESH_ALIGN_CHUNK_SIZE_TO_MAX_SEGMENT
int "BLOB Client chunk size"
default 8
range 1 377
help
Set the chunk size for the BLOB Client.
The actual maximum chunk size depends on how many segments are
possible and will be clamped to the max possible if set above.
see also: BLE_MESH_TX_SEG_MAX,
and the maximum SDU a node can receive.
config BLE_MESH_TX_BLOB_CHUNK_SEND_INTERVAL
int "BLOB Client chunk send interval"
default 0
range 0 2147483647
help
Set the interval in milliseconds in which chunks are sent during the BLOB transfer.
Note: Without a delay between each sent chunk, the network might become too busy with the
BLOB transfer for other communications to succeed.
Note: Timing restrictions, like the timeout base, should be considered or changed
accordingly when setting this interval. Otherwise, the interval might be too big for the
timeout settings and cause timeouts.
endif # BLE_MESH_BLOB_CLI
menu "BLOB models common configuration"
visible if BLE_MESH_BLOB_SRV || BLE_MESH_BLOB_CLI
config BLE_MESH_BLOB_CHUNK_COUNT_MAX
int "Maximum chunk count per block"
default 256
range 1 2992
help
A BLOB transfer contains several blocks. Each block is made up of
several chunks. This option controls the maximum chunk count per
block.
config BLE_MESH_ALIGN_CHUNK_SIZE_TO_MAX_SEGMENT
bool "Align chunk size to max segmented message size"
default y
endmenu #BLOB models common configuration
endmenu # Binary Larger Object Transfer model
menu "Device Firmware Update model"
config BLE_MESH_DFU_SRV
bool "Support for Firmware Update Server model"
depends on BLE_MESH_BLOB_SRV
help
Enable the Firmware Update Server model.
config BLE_MESH_DFU_CLI
bool "Support for Firmware Update Client model"
depends on BLE_MESH_BLOB_CLI
help
Enable the Firmware Update Client model.
menu "Firmware Update model configuration"
visible if BLE_MESH_DFU_SRV || BLE_MESH_DFU_CLI
config BLE_MESH_DFU_FWID_MAXLEN
int "DFU FWID max length"
default 16
range 0 106
help
This value defines the maximum length of an image's firmware ID.
config BLE_MESH_DFU_METADATA_MAXLEN
int "DFU metadata max length"
default 32
range 18 255 if BLE_MESH_DFU_METADATA
range 0 255
help
This value defines the maximum length of an image's metadata.
config BLE_MESH_DFU_METADATA
bool "Support for the default metadata format"
help
This option adds a set of functions that can be used to encode and decode a firmware
metadata using the format defined in the Bluetooth mesh DFU subsystem.
config BLE_MESH_DFU_URI_MAXLEN
int "DFU URI max length"
default 32
range 0 255
help
This value defines the maximum length of an image's URI, not including
a string terminator.
endmenu #Firmware Update model configuration
config BLE_MESH_DFU_SLOTS
bool "Firmware image slot manager"
default y if BLE_MESH_DFU_CLI
help
Enable the DFU image slot manager, for managing firmware distribution slots
for the Firmware Update Client model.
if BLE_MESH_DFU_SLOTS
config BLE_MESH_DFU_SLOT_CNT
int "Number of firmware image slots"
default 1
range 1 32767
help
This value defines the number of firmware slots the DFU image slot manager
can keep simultaneously.
endif #BLE_MESH_DFU_SLOTS
config BLE_MESH_DFD_CLI
bool "Support for Device Distribution Client model"
help
Enable the Device Distribution Client model
config BLE_MESH_DFD_SRV
bool "Support for Firmware Distribution Server model"
depends on BLE_MESH_BLOB_SRV
depends on BLE_MESH_DFU_CLI
help
Enable the Firmware Distribution Server model.
if BLE_MESH_DFD_SRV
config BLE_MESH_DFD_SRV_SLOT_MAX_SIZE
int "Largest DFU image that can be stored"
default BLE_MESH_BLOB_SIZE_MAX
range 0 BLE_MESH_BLOB_SIZE_MAX
help
This value defines the largest DFU image a single slot can store.
config BLE_MESH_DFD_SRV_SLOT_SPACE
int "Total DFU image storage space"
default BLE_MESH_DFD_SRV_SLOT_MAX_SIZE
range 0 4294967295
help
This value defines the total storage space dedicated to storing DFU
images on the Firmware Distribution Server.
config BLE_MESH_DFD_SRV_TARGETS_MAX
int "Maximum Target node count"
default 8
range 1 65535
help
This value defines the maximum number of Target nodes the Firmware
Distribution Server can target simultaneously.
config BLE_MESH_DFD_SRV_OOB_UPLOAD
bool "Support for DFU image OOB upload"
help
This enables support for OOB upload of firmware images for
distribution. This makes several callbacks and use of the init
macro BLE_MESH_DFD_SRV_INIT_OOB mandatory. See the API documentation
for bt_mesh_dfd_srv_cb for details about the mandatory callbacks.
endif #BLE_MESH_DFD_SRV
endmenu # Device Firmware Update model
endmenu #Support for BLE Mesh Client/Server models
@@ -97,6 +97,9 @@ typedef union {
#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED
/**
* @brief Event parameters of ESP_BLE_MESH_NIMBLE_GAP_EVENT_EVT
* @note The execution environment of this event is different
* from other BLE Mesh events, as it runs in the NimBLE Host's
* execution environment.
*/
struct ble_mesh_nimble_gap_event_evt_param {
struct ble_gap_event event; /*!< GAP event parameters for NimBLE Host */
@@ -1982,9 +1982,14 @@ typedef union {
#define ESP_BLE_MESH_MODEL_ID_LIGHT_LC_SRV 0x130f
#define ESP_BLE_MESH_MODEL_ID_LIGHT_LC_SETUP_SRV 0x1310
#define ESP_BLE_MESH_MODEL_ID_LIGHT_LC_CLI 0x1311
#define ESP_BLE_MESH_MODEL_ID_MBT_SRV 0x1400
#define ESP_BLE_MESH_MODEL_ID_MBT_CLI 0x1401
#define ESP_BLE_MESH_MODEL_ID_MBT_SRV 0x14fe
#define ESP_BLE_MESH_MODEL_ID_MBT_CLI 0x14ff
#define ESP_BLE_MESH_MODEL_ID_BLOB_SRV 0x1400
#define ESP_BLE_MESH_MODEL_ID_BLOB_CLI 0x1401
#define ESP_BLE_MESH_MODEL_ID_DFU_SRV 0x1402
#define ESP_BLE_MESH_MODEL_ID_DFU_CLI 0x1403
#define ESP_BLE_MESH_MODEL_ID_DFD_SRV 0x1404
#define ESP_BLE_MESH_MODEL_ID_DFD_CLI 0x1405
/**
* esp_ble_mesh_opcode_config_client_get_t belongs to esp_ble_mesh_opcode_t, this typedef is only
* used to locate the opcodes used by esp_ble_mesh_config_client_get_state.
@@ -14,6 +14,8 @@
#include "esp_ble_mesh_ble_api.h"
#if (CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50)
static inline void btc_ble_mesh_ble_cb_to_app(esp_ble_mesh_ble_cb_event_t event,
esp_ble_mesh_ble_cb_param_t *param);
static void btc_ble_mesh_ble_copy_req_data(btc_msg_t *msg, void *p_dst, void *p_src)
{
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
@@ -99,7 +101,7 @@ void bt_mesh_ble_nimble_evt_to_btc(struct ble_gap_event *event, void *arg)
memcpy(&param.nimble_gap_evt.event, event, sizeof(struct ble_gap_event));
param.nimble_gap_evt.arg = arg;
btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_NIMBLE_GAP_EVENT_EVT);
btc_ble_mesh_ble_cb_to_app(ESP_BLE_MESH_NIMBLE_GAP_EVENT_EVT, &param);
}
#endif /* CONFIG_BT_NIMBLE_ENABLED && CONFIG_BLE_MESH_USE_BLE_50 */
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1410,6 +1410,31 @@ typedef bt_mesh_client_user_data_t bt_mesh_mbt_client_t;
extern const struct bt_mesh_model_op bt_mesh_mbt_cli_op[];
extern const struct bt_mesh_model_cb bt_mesh_mbt_cli_cb;
#endif /* CONFIG_BLE_MESH_MBT_CLI */
#if CONFIG_BLE_MESH_BLOB_SRV
extern const struct bt_mesh_model_op _bt_mesh_blob_srv_op[];
extern const struct bt_mesh_model_cb _bt_mesh_blob_srv_cb;
#endif /* CONFIG_BLE_MESH_BLOB_SRV */
#if CONFIG_BLE_MESH_BLOB_CLI
typedef bt_mesh_client_user_data_t bt_mesh_blob_client_t;
extern const struct bt_mesh_model_op _bt_mesh_blob_cli_op[];
extern const struct bt_mesh_model_cb _bt_mesh_blob_cli_cb;
#endif /* CONFIG_BLE_MESH_BLOB_CLI */
#if CONFIG_BLE_MESH_DFU_SRV
extern const struct bt_mesh_model_op _bt_mesh_dfu_srv_op[];
extern const struct bt_mesh_model_cb _bt_mesh_dfu_srv_cb;
#endif /* CONFIG_BLE_MESH_DFU_SRV */
#if CONFIG_BLE_MESH_DFU_CLI
extern const struct bt_mesh_model_op _bt_mesh_dfu_cli_op[];
extern const struct bt_mesh_model_cb _bt_mesh_dfu_cli_cb;
#endif /* CONFIG_BLE_MESH_DFU_CLI */
#if CONFIG_BLE_MESH_DFD_SRV
extern const struct bt_mesh_model_op _bt_mesh_dfd_srv_op[];
extern const struct bt_mesh_model_cb _bt_mesh_dfd_srv_cb;
#endif /* CONFIG_BLE_MESH_DFD_SRV */
#if CONFIG_BLE_MESH_DFD_CLI
extern const struct bt_mesh_model_op _bt_mesh_dfd_cli_op[];
extern const struct bt_mesh_model_cb _bt_mesh_dfd_cli_cb;
#endif /* CONFIG_BLE_MESH_DFD_CLI */
static void btc_ble_mesh_model_op_set(esp_ble_mesh_model_t *model)
{
@@ -2205,9 +2230,9 @@ static void btc_ble_mesh_model_op_set(esp_ble_mesh_model_t *model)
case BLE_MESH_MODEL_ID_MBT_CLI:
model->op = (esp_ble_mesh_model_op_t *)bt_mesh_mbt_cli_op;
model->cb = (esp_ble_mesh_model_cbs_t *)&bt_mesh_mbt_cli_cb;
bt_mesh_mbt_client_t *cli = (bt_mesh_mbt_client_t *)model->user_data;
if (cli) {
cli->publish_status = btc_ble_mesh_mbt_client_publish_callback;
bt_mesh_mbt_client_t *mbt_cli = (bt_mesh_mbt_client_t *)model->user_data;
if (mbt_cli) {
mbt_cli->publish_status = btc_ble_mesh_mbt_client_publish_callback;
}
break;
#endif /* CONFIG_BLE_MESH_MBT_CLI */
@@ -2220,6 +2245,61 @@ static void btc_ble_mesh_model_op_set(esp_ble_mesh_model_t *model)
}
break;
#endif /* CONFIG_BLE_MESH_MBT_SRV */
#if CONFIG_BLE_MESH_BLOB_CLI
case BLE_MESH_MODEL_ID_BLOB_CLI:
model->op = (esp_ble_mesh_model_op_t *)_bt_mesh_blob_cli_op;
model->cb = (esp_ble_mesh_model_cbs_t *)&_bt_mesh_blob_cli_cb;
bt_mesh_blob_client_t *blob_cli = (bt_mesh_blob_client_t *)model->user_data;
if (blob_cli) {
/* TBD: do we need publish callback for Blob Transfer Client model? */
}
break;
#endif /* CONFIG_BLE_MESH_BLOB_CLI */
#if CONFIG_BLE_MESH_BLOB_SRV
case BLE_MESH_MODEL_ID_BLOB_SRV:
model->op = (esp_ble_mesh_model_op_t *)_bt_mesh_blob_srv_op;
model->cb = (esp_ble_mesh_model_cbs_t *)&_bt_mesh_blob_srv_cb;
if (model->pub) {
model->pub->update = (esp_ble_mesh_cb_t)btc_ble_mesh_model_publish_update;
}
break;
#endif /* CONFIG_BLE_MESH_BLOB_SRV */
#if CONFIG_BLE_MESH_DFU_CLI
case BLE_MESH_MODEL_ID_DFU_CLI:
model->op = (esp_ble_mesh_model_op_t *)_bt_mesh_dfu_cli_op;
model->cb = (esp_ble_mesh_model_cbs_t *)&_bt_mesh_dfu_cli_cb;
if (model->pub) {
model->pub->update = (esp_ble_mesh_cb_t)btc_ble_mesh_model_publish_update;
}
break;
#endif /* CONFIG_BLE_MESH_DFU_CLI */
#if CONFIG_BLE_MESH_DFU_SRV
case BLE_MESH_MODEL_ID_DFU_SRV:
model->op = (esp_ble_mesh_model_op_t *)_bt_mesh_dfu_srv_op;
model->cb = (esp_ble_mesh_model_cbs_t *)&_bt_mesh_dfu_srv_cb;
if (model->pub) {
model->pub->update = (esp_ble_mesh_cb_t)btc_ble_mesh_model_publish_update;
}
break;
#endif /* CONFIG_BLE_MESH_DFU_SRV */
#if CONFIG_BLE_MESH_DFD_SRV
case BLE_MESH_MODEL_ID_DFD_SRV:
model->op = (esp_ble_mesh_model_op_t *)_bt_mesh_dfd_srv_op;
model->cb = (esp_ble_mesh_model_cbs_t *)&_bt_mesh_dfd_srv_cb;
if (model->pub) {
model->pub->update = (esp_ble_mesh_cb_t)btc_ble_mesh_model_publish_update;
}
break;
#endif /* CONFIG_BLE_MESH_DFD_SRV */
#if CONFIG_BLE_MESH_DFD_CLI
case BLE_MESH_MODEL_ID_DFD_CLI:
model->op = (esp_ble_mesh_model_op_t *)_bt_mesh_dfd_cli_op;
model->cb = (esp_ble_mesh_model_cbs_t *)&_bt_mesh_dfd_cli_cb;
if (model->pub) {
model->pub->update = (esp_ble_mesh_cb_t)btc_ble_mesh_model_publish_update;
}
break;
#endif /* CONFIG_BLE_MESH_DFD_SRV */
default:
goto set_vnd_op;
}
@@ -17,6 +17,45 @@
extern "C" {
#endif
static inline void btc_ble_mesh_msg_ctx_copy(struct bt_mesh_msg_ctx *dst,
const struct bt_mesh_msg_ctx *src,
bool use_dev_key)
{
if (dst == NULL ||
src == NULL) {
return;
}
dst->net_idx = src->net_idx;
dst->app_idx = use_dev_key ? BLE_MESH_KEY_DEV : src->app_idx;
dst->addr = src->addr;
dst->send_szmic = src->send_szmic;
dst->send_ttl = src->send_ttl;
dst->send_cred = src->send_cred;
dst->send_tag = src->send_tag;
if (src->enh.adv_cfg_used) {
dst->enh.adv_cfg_used = src->enh.adv_cfg_used;
dst->enh.adv_cfg.adv_cnt = src->enh.adv_cfg.adv_cnt;
dst->enh.adv_cfg.adv_itvl = src->enh.adv_cfg.adv_itvl;
dst->enh.adv_cfg.channel_map = src->enh.adv_cfg.channel_map;
}
#if CONFIG_BLE_MESH_EXT_ADV
if (src->enh.ext_adv_cfg_used) {
dst->enh.ext_adv_cfg_used = src->enh.ext_adv_cfg_used;
dst->enh.ext_adv_cfg.primary_phy = src->enh.ext_adv_cfg.primary_phy;
dst->enh.ext_adv_cfg.secondary_phy = src->enh.ext_adv_cfg.secondary_phy;
dst->enh.ext_adv_cfg.include_tx_power = src->enh.ext_adv_cfg.include_tx_power;
dst->enh.ext_adv_cfg.tx_power = src->enh.ext_adv_cfg.tx_power;
}
#if CONFIG_BLE_MESH_LONG_PACKET
if (src->enh.long_pkt_cfg_used) {
dst->enh.long_pkt_cfg_used = src->enh.long_pkt_cfg_used;
dst->enh.long_pkt_cfg = src->enh.long_pkt_cfg;
}
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
#endif /* CONFIG_BLE_MESH_EXT_ADV */
}
static inline void btc_ble_mesh_set_client_common_param(esp_ble_mesh_client_common_param_t *input,
bt_mesh_client_common_param_t *output,
bool use_dev_key)
@@ -24,35 +63,8 @@ static inline void btc_ble_mesh_set_client_common_param(esp_ble_mesh_client_comm
if (input && output) {
output->opcode = input->opcode;
output->model = (struct bt_mesh_model *)input->model;
output->ctx.net_idx = input->ctx.net_idx;
output->ctx.app_idx = use_dev_key ? BLE_MESH_KEY_DEV : input->ctx.app_idx;
output->ctx.addr = input->ctx.addr;
output->ctx.send_szmic = input->ctx.send_szmic;
output->ctx.send_ttl = input->ctx.send_ttl;
output->ctx.send_cred = input->ctx.send_cred;
output->ctx.send_tag = input->ctx.send_tag;
output->msg_timeout = input->msg_timeout;
if (input->ctx.enh.adv_cfg_used) {
output->ctx.enh.adv_cfg_used = input->ctx.enh.adv_cfg_used;
output->ctx.enh.adv_cfg.adv_cnt = input->ctx.enh.adv_cfg.adv_cnt;
output->ctx.enh.adv_cfg.adv_itvl = input->ctx.enh.adv_cfg.adv_itvl;
output->ctx.enh.adv_cfg.channel_map = input->ctx.enh.adv_cfg.channel_map;
}
#if CONFIG_BLE_MESH_EXT_ADV
if (input->ctx.enh.ext_adv_cfg_used) {
output->ctx.enh.ext_adv_cfg_used = input->ctx.enh.ext_adv_cfg_used;
output->ctx.enh.ext_adv_cfg.primary_phy = input->ctx.enh.ext_adv_cfg.primary_phy;
output->ctx.enh.ext_adv_cfg.secondary_phy = input->ctx.enh.ext_adv_cfg.secondary_phy;
output->ctx.enh.ext_adv_cfg.include_tx_power = input->ctx.enh.ext_adv_cfg.include_tx_power;
output->ctx.enh.ext_adv_cfg.tx_power = input->ctx.enh.ext_adv_cfg.tx_power;
}
#if CONFIG_BLE_MESH_LONG_PACKET
if (input->ctx.enh.long_pkt_cfg_used) {
output->ctx.enh.long_pkt_cfg_used = input->ctx.enh.long_pkt_cfg_used;
output->ctx.enh.long_pkt_cfg = input->ctx.enh.long_pkt_cfg;
}
#endif
#endif
btc_ble_mesh_msg_ctx_copy(&output->ctx, (const struct bt_mesh_msg_ctx *)&input->ctx, use_dev_key);
}
}
@@ -37,7 +37,7 @@ extern "C" {
#endif
#endif
#define BLE_MESH_ADV_TASK_STACK_SIZE 3072
#define BLE_MESH_ADV_TASK_STACK_SIZE (3072)
#define BLE_MESH_ADV_TASK_NAME "mesh_adv_task"
#define BLE_MESH_ADV_TASK_PRIO (configMAX_PRIORITIES - 5)
@@ -1,6 +1,6 @@
/*
* SPDX-FileCopyrightText: 2016 Wind River Systems, Inc.
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -49,6 +49,8 @@ struct k_work;
*/
typedef void (*k_work_handler_t)(struct k_work *work);
typedef int32_t k_timeout_t;
struct k_work {
k_work_handler_t handler;
int index;
@@ -141,6 +143,65 @@ struct k_work {
*/
#define K_FOREVER (-1)
/**
* @brief Define for delayable work type.
*
* This macro maps the Zephyr delayable work type `k_work_delayable`
* to the ESP-IDF type `k_delayed_work`.
*/
#define k_work_delayable k_delayed_work
/**
* @brief Reschedule a delayable work item.
*
* This macro maps to `k_delayed_work_submit`, which cancels
* any existing pending submission of the work item and reschedules
* it with the new timeout delay.
*
* @param work Pointer to delayable work item.
* @param delay Timeout delay value.
* @return See implementation of `k_delayed_work_submit`.
*/
#define k_work_reschedule k_delayed_work_submit
/**
* @brief Schedule a delayable work item.
*
* This macro maps to `k_delayed_work_submit`,
* which schedules a work item to be processed
* after the specified timeout delay. If the work
* is already pending, the new delay is applied.
*
* @param work Pointer to delayable work item.
* @param delay Timeout delay value.
* @return See implementation of `k_delayed_work_submit`.
*/
#define k_work_schedule k_delayed_work_submit
/**
* @brief Cancel a delayable work item.
*
* This macro maps to `k_delayed_work_cancel`,
* which cancels a pending work submission
* associated with a delayable work item.
*
* @param work Pointer to delayable work item.
* @return See implementation of `k_delayed_work_cancel`.
*/
#define k_work_cancel_delayable k_delayed_work_cancel
/**
* @brief Initialize a delayable work item.
*
* This macro maps to `k_delayed_work_init`,
* which initializes a delayable work item with
* the provided handler function.
*
* @param work Pointer to delayable work item.
* @param handler Work item handler function.
*/
#define k_work_init_delayable k_delayed_work_init
/**
* @brief Get system uptime (32-bit version).
*
@@ -160,6 +221,27 @@ struct k_delayed_work {
struct k_work work;
};
#define _K_DELAYABLE_WORK_INITIALIZER(work_handler) { \
.work = { \
.handler = work_handler, \
}, \
}
/**
* @brief Convert a work item to its containing delayable work structure.
*
* This function uses container_of to derive the address of the containing
* k_work_delayable structure from the address of the embedded k_work structure.
*
* @param work Pointer to the embedded k_work structure within a k_work_delayable.
* @return Pointer to the containing k_work_delayable structure.
*/
static inline struct k_work_delayable *
k_work_delayable_from_work(struct k_work *work)
{
return CONTAINER_OF(work, struct k_work_delayable, work);
}
/**
* @brief Submit a delayed work item to the system workqueue.
*
@@ -209,6 +291,21 @@ int k_delayed_work_submit_periodic(struct k_delayed_work *work, int32_t period);
*/
int32_t k_delayed_work_remaining_get(struct k_delayed_work *work);
/**
* @brief Check if a delayable work item is pending execution.
*
* This function checks whether a delayable work item has been scheduled
* and is waiting to be processed. It returns true if the work item is in
* pending state (waiting for timeout expiration or being in work queue).
*
* @param dwork Pointer to delayable work item.
* @return true if work is pending, false otherwise.
*/
static inline bool k_work_delayable_is_pending(struct k_work_delayable *dwork)
{
return k_delayed_work_remaining_get(dwork);
}
/**
* @brief Submit a work item to the system workqueue.
*
@@ -267,10 +364,45 @@ int k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler);
* @return Current uptime.
*/
int64_t k_uptime_get(void);
int64_t k_uptime_delta(int64_t *reftime);
void bt_mesh_timer_init(void);
void bt_mesh_timer_deinit(void);
/**
* @brief Initialize a statically-defined work item.
*
* This macro can be used to initialize a statically-defined workqueue work
* item, prior to its first use. For example,
*
* @code static K_WORK_DEFINE(<work>, <work_handler>); @endcode
*
* @param work Symbol name for work item object
* @param work_handler Function to invoke each time work item is processed.
*/
#define K_WORK_DEFINE(work, work_handler) \
struct k_work work = _K_WORK_INITIALIZER(work_handler)
/**
* @brief Initialize a statically-defined delayable work item.
*
* This macro can be used to initialize a statically-defined delayable
* work item, prior to its first use. For example,
*
* @code static K_WORK_DELAYABLE_DEFINE(<dwork>, <work_handler>); @endcode
*
* Note that if the runtime dependencies support initialization with
* k_work_init_delayable() using that will eliminate the initialized
* object in ROM that is produced by this macro and copied in at
* system startup.
*
* @param work Symbol name for delayable work item object
* @param work_handler Function to invoke each time work item is processed.
*/
#define K_WORK_DELAYABLE_DEFINE(work, work_handler) \
struct k_delayed_work work \
= _K_DELAYABLE_WORK_INITIALIZER(work_handler)
#ifdef __cplusplus
}
#endif
@@ -15,6 +15,8 @@
#define _BLE_MESH_UTILS_H_
#include <stddef.h>
#include <sys/cdefs.h>
#include <errno.h>
#include "esp_bit_defs.h"
#include "mesh/types.h"
#include "utils_loops.h"
@@ -94,6 +96,81 @@ extern "C" {
#define WB_DN(x) ROUND_DOWN(x, sizeof(void *))
#endif
/**
* @brief Whether @p ptr is an element of @p array
*
* This macro can be seen as a slightly stricter version of @ref PART_OF_ARRAY
* in that it also ensures that @p ptr is aligned to an array-element boundary
* of @p array.
*
* In C, passing a pointer as @p array causes a compile error.
*
* @param array the array in question
* @param ptr the pointer to check
*
* @return 1 if @p ptr is part of @p array, 0 otherwise
*/
#define IS_ARRAY_ELEMENT(array, ptr) \
((ptr) && POINTER_TO_UINT(array) <= POINTER_TO_UINT(ptr) && \
POINTER_TO_UINT(ptr) < POINTER_TO_UINT(&(array)[ARRAY_SIZE(array)]) && \
(POINTER_TO_UINT(ptr) - POINTER_TO_UINT(array)) % sizeof((array)[0]) == 0)
/**
* @brief Index of @p ptr within @p array
*
* With `CONFIG_ASSERT=y`, this macro will trigger a runtime assertion
* when @p ptr does not fall into the range of @p array or when @p ptr
* is not aligned to an array-element boundary of @p array.
*
* In C, passing a pointer as @p array causes a compile error.
*
* @param array the array in question
* @param ptr pointer to an element of @p array
*
* @return the array index of @p ptr within @p array, on success
*/
#define ARRAY_INDEX(array, ptr) \
({ \
__ASSERT_NO_MSG(IS_ARRAY_ELEMENT(array, ptr)); \
(__typeof__((array)[0]) *)(ptr) - (array); \
})
/**
* @brief Divide and round up.
*
* Example:
* @code{.c}
* DIV_ROUND_UP(1, 2); // 1
* DIV_ROUND_UP(3, 2); // 2
* @endcode
*
* @param n Numerator.
* @param d Denominator.
*
* @return The result of @p n / @p d, rounded up.
*/
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
/**
* @brief Divide and round to the nearest integer.
*
* Example:
* @code{.c}
* DIV_ROUND_CLOSEST(5, 2); // 3
* DIV_ROUND_CLOSEST(5, -2); // -3
* DIV_ROUND_CLOSEST(5, 3); // 2
* @endcode
*
* @param n Numerator.
* @param d Denominator.
*
* @return The result of @p n / @p d, rounded to the nearest integer.
*/
#define DIV_ROUND_CLOSEST(n, d) \
((((n) < 0) ^ ((d) < 0)) ? ((n) - ((d) / 2)) / (d) : \
((n) + ((d) / 2)) / (d))
#ifndef ceiling_fraction
#define ceiling_fraction(numerator, divider) \
(((numerator) + ((divider) - 1)) / (divider))
@@ -125,6 +202,21 @@ extern "C" {
#define BIT(n) (1UL << (n))
#endif
/**
* @brief Set or clear a bit depending on a boolean value
*
* The argument @p var is a variable whose value is written to as a
* side effect.
*
* @param var Variable to be altered
* @param bit Bit number
* @param set if 0, clears @p bit in @p var; any other value sets @p bit
*/
#ifndef WRITE_BIT
#define WRITE_BIT(var, bit, set) \
((var) = (set) ? ((var) | BIT(bit)) : ((var) & ~BIT(bit)))
#endif
#ifndef BIT_MASK
#define BIT_MASK(n) (BIT(n) - 1)
#endif
@@ -219,6 +311,20 @@ const char *bt_hex(const void *buf, size_t len);
void mem_rcopy(uint8_t *dst, uint8_t const *src, uint16_t len);
/**
* @brief Checks if a value is within range.
*
* @note @p val is evaluated twice.
*
* @param val Value to be checked.
* @param min Lower bound (inclusive).
* @param max Upper bound (inclusive).
*
* @retval true If value is within range
* @retval false If the value is not within range
*/
#define IN_RANGE(val, min, max) ((val) >= (min) && (val) <= (max))
#ifdef __cplusplus
}
#endif
+23 -1
View File
@@ -1,7 +1,7 @@
/*
* SPDX-FileCopyrightText: 2016 Intel Corporation
* SPDX-FileCopyrightText: 2016 Wind River Systems, Inc.
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -43,6 +43,28 @@ uint32_t k_uptime_get_32(void)
return (uint32_t)(esp_timer_get_time() / 1000);
}
/**
* @brief Get elapsed time.
*
* This routine computes the elapsed time between the current system uptime
* and an earlier reference time, in milliseconds.
*
* @param reftime Pointer to a reference time, which is updated to the current
* uptime upon return.
*
* @return Elapsed time.
*/
int64_t k_uptime_delta(int64_t *reftime)
{
int64_t uptime, delta;
uptime = k_uptime_get();
delta = uptime - *reftime;
*reftime = uptime;
return delta;
}
void bt_mesh_timer_init(void)
{
bm_alarm_hash_map = hash_map_new(BLE_MESH_ALARM_HASH_MAP_SIZE,
+272 -55
View File
@@ -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
@@ -37,7 +37,7 @@
extern const struct bt_mesh_comp *comp_0;
static uint16_t dev_primary_addr;
static int model_send(struct bt_mesh_model *model,
static int model_send(const struct bt_mesh_model *model,
struct bt_mesh_net_tx *tx, bool implicit_bind,
struct net_buf_simple *msg,
const struct bt_mesh_send_cb *cb, void *cb_data);
@@ -50,6 +50,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;
@@ -58,15 +60,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);
}
}
@@ -76,6 +84,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;
@@ -103,6 +113,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;
}
@@ -115,19 +128,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");
@@ -143,7 +159,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");
@@ -156,8 +172,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);
}
}
@@ -167,6 +184,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;
@@ -196,6 +215,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;
@@ -224,9 +245,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) {
@@ -246,8 +272,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);
}
@@ -261,7 +290,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);
@@ -289,6 +319,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;
@@ -300,8 +331,10 @@ static void mod_publish(struct k_work *work)
}
}
struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod)
struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod)
{
BT_DBG("ModelElem, ElemIdx %u", mod->elem_idx);
return &comp_0->elem[mod->elem_idx];
}
@@ -309,6 +342,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;
@@ -344,6 +379,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;
@@ -373,6 +410,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;
}
@@ -386,6 +425,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;
@@ -405,6 +446,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;
@@ -443,6 +486,8 @@ int bt_mesh_comp_deregister(void)
{
int err = 0;
BT_DBG("CompDeregister");
if (comp_0 == NULL) {
return -EINVAL;
}
@@ -461,25 +506,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;
}
@@ -487,12 +536,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;
}
@@ -503,6 +556,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];
@@ -528,6 +583,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) {
@@ -548,15 +605,38 @@ struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr)
return NULL;
}
bool bt_mesh_has_addr(uint16_t addr)
{
uint16_t index;
if (BLE_MESH_ADDR_IS_UNICAST(addr)) {
return bt_mesh_elem_find(addr) != NULL;
}
for (index = 0; index < comp_0->elem_count; index++) {
struct bt_mesh_elem *elem = &comp_0->elem[index];
if (bt_mesh_elem_find_group(elem, addr)) {
return true;
}
}
return false;
}
uint8_t bt_mesh_elem_count(void)
{
BT_DBG("ElemCount %u", comp_0->elem_count);
return comp_0->elem_count;
}
static bool model_has_key(struct bt_mesh_model *mod, uint16_t key)
static bool model_has_key(const 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;
@@ -570,6 +650,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);
}
@@ -588,6 +670,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;
@@ -606,6 +690,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:
@@ -635,7 +721,7 @@ static int get_opcode(struct net_buf_simple *buf, uint32_t *opcode, bool pull_bu
if (pull_buf) {
*opcode = net_buf_simple_pull_u8(buf) << 16;
/* Using LE for the CID since the model layer is defined as
* little-endian in the mesh spec and using BT_MESH_MODEL_OP_3
* little-endian in the mesh spec and using BLE_MESH_MODEL_OP_3
* will declare the opcode in this way.
*/
*opcode |= net_buf_simple_pull_le16(buf);
@@ -651,6 +737,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;
@@ -661,6 +749,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:
@@ -682,12 +772,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;
}
@@ -700,16 +792,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];
@@ -734,10 +827,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;
}
@@ -781,6 +876,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)) {
@@ -793,7 +890,7 @@ void bt_mesh_model_msg_init(struct net_buf_simple *msg, uint32_t opcode)
case 3:
net_buf_simple_add_u8(msg, ((opcode >> 16) & 0xff));
/* Using LE for the CID since the model layer is defined as
* little-endian in the mesh spec and using BT_MESH_MODEL_OP_3
* little-endian in the mesh spec and using BLE_MESH_MODEL_OP_3
* will declare the opcode in this way.
*/
net_buf_simple_add_le16(msg, opcode & 0xffff);
@@ -806,6 +903,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;
}
@@ -813,7 +912,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;
@@ -825,15 +924,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;
}
@@ -848,6 +951,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;
}
@@ -876,22 +982,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 {
@@ -916,14 +1027,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.
*
@@ -943,24 +1053,26 @@ 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 */
static int model_send(struct bt_mesh_model *model,
static int model_send(const struct bt_mesh_model *model,
struct bt_mesh_net_tx *tx, bool implicit_bind,
struct net_buf_simple *msg,
const struct bt_mesh_send_cb *cb, void *cb_data)
{
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");
@@ -1013,7 +1125,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;
}
@@ -1025,9 +1137,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;
}
@@ -1041,16 +1155,18 @@ int bt_mesh_model_send_implicit(struct bt_mesh_model *model,
return model_send(model, &tx, implicit_bind, msg, cb, cb_data);
}
int bt_mesh_model_send(struct bt_mesh_model *model,
int bt_mesh_model_send(const struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *msg,
const struct bt_mesh_send_cb *cb, void *cb_data)
{
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;
}
@@ -1077,6 +1193,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;
@@ -1125,12 +1243,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) {
@@ -1154,6 +1272,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) {
@@ -1168,6 +1288,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];
@@ -1179,6 +1301,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;
}
@@ -1196,6 +1320,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;
}
@@ -1207,20 +1333,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;
}
@@ -1233,13 +1361,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)) {
@@ -1247,7 +1375,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;
}
@@ -1271,7 +1402,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;
@@ -1283,7 +1414,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;
}
@@ -1300,13 +1433,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) {
@@ -1324,11 +1457,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;
}
@@ -1341,20 +1476,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;
}
@@ -1367,13 +1504,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)) {
@@ -1381,7 +1518,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;
}
+2
View File
@@ -29,6 +29,8 @@ uint8_t bt_mesh_elem_count(void);
/* Find local element based on unicast or group address */
struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr);
bool bt_mesh_has_addr(uint16_t addr);
uint16_t *bt_mesh_model_find_group(struct bt_mesh_model *mod, uint16_t addr);
int bt_mesh_get_opcode(struct net_buf_simple *buf,
+73 -71
View File
@@ -29,32 +29,11 @@
static struct bt_mesh_adv_queue *adv_queue;
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
#define BLE_MESH_RELAY_QUEUE_SIZE CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT
static QueueSetHandle_t mesh_queue_set;
#define BLE_MESH_QUEUE_SET_SIZE (BLE_MESH_ADV_QUEUE_SIZE + BLE_MESH_RELAY_QUEUE_SIZE)
#define BLE_MESH_QUEUE_SET_SIZE (bt_mesh_adv_buf_count_get() + bt_mesh_relay_adv_buf_count_get())
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
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);
}
}
static inline int adv_send(struct net_buf *buf)
static int adv_send(struct net_buf *buf)
{
const struct bt_mesh_send_cb *cb = BLE_MESH_ADV(buf)->cb;
void *cb_data = BLE_MESH_ADV(buf)->cb_data;
@@ -64,8 +43,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) {
@@ -133,10 +112,12 @@ 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),
};
#if CONFIG_BLE_MESH_USE_BLE_50
param.primary_phy = BLE_MESH_ADV_PHY_1M;
param.secondary_phy = BLE_MESH_ADV_PHY_1M;
@@ -145,9 +126,10 @@ static inline int adv_send(struct net_buf *buf)
err = bt_le_adv_start(&param, solic_ad, ARRAY_SIZE(solic_ad), NULL, 0);
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
} else
#endif
#endif /* CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX */
{
bt_mesh_adv_buf_ref_debug(__func__, buf, 4U, BLE_MESH_BUF_REF_SMALL);
#if CONFIG_BLE_MESH_USE_BLE_50
param.primary_phy = BLE_MESH_ADV_PHY_1M;
param.secondary_phy = BLE_MESH_ADV_PHY_1M;
@@ -168,8 +150,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) {
@@ -192,6 +174,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);
@@ -201,17 +184,15 @@ static inline int adv_send(struct net_buf *buf)
BT_DBG("Advertising started. Sleeping %u ms", duration);
#if CONFIG_BLE_MESH_USE_BLE_50
if (!ble_mesh_adv_task_wait(UINT32_MAX, K_FOREVER, NULL)) {
if (!bt_mesh_adv_task_wait(UINT32_MAX, K_FOREVER, NULL)) {
BT_WARN("Advertising didn't finish on time");
bt_le_ext_adv_stop(CONFIG_BLE_MESH_ADV_INST_ID);
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
ble_mesh_adv_task_wait(K_MSEC(duration));
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
bt_mesh_adv_task_wait(K_MSEC(duration));
#if !CONFIG_BLE_MESH_USE_BLE_50
err = bt_le_adv_stop();
#endif
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
adv_send_end(err, cb, cb_data);
if (err) {
@@ -223,36 +204,63 @@ static inline int adv_send(struct net_buf *buf)
return 0;
}
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
static QueueHandle_t relay_adv_handle_get(void)
{
struct bt_mesh_adv_type_manager *adv_type = NULL;
BT_DBG("RelayAdvHandleGet");
adv_type = bt_mesh_adv_types_mgmt_get(BLE_MESH_ADV_RELAY_DATA);
if (adv_type->adv_q == NULL) {
BT_DBG("HandleNotFound");
return NULL;
}
return adv_type->adv_q->q.handle;
}
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
static void adv_thread(void *p)
{
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
QueueHandle_t relay_adv_handle = NULL;
QueueSetMemberHandle_t handle = NULL;
QueueHandle_t relay_adv_handle =
bt_mesh_adv_types_mgnt_get(BLE_MESH_ADV_RELAY_DATA)->adv_q->q.handle;
#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->q.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->q.handle, &msg, K_WAIT(timeout));
BT_DBG("Mesh Proxy Advertising stop");
bt_mesh_proxy_server_adv_stop();
}
#else
#else /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */
xQueueReceive(adv_queue->q.handle, &msg, portMAX_DELAY);
#endif /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */
#else /* !CONFIG_BLE_MESH_RELAY_ADV_BUF */
@@ -268,12 +276,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->q.handle)) {
xQueueReceive(adv_queue->q.handle, &msg, K_NO_WAIT);
@@ -283,7 +296,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->q.handle)) {
@@ -311,6 +324,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)) {
@@ -323,33 +337,13 @@ static void adv_thread(void *p)
net_buf_unref(*buf);
}
BT_DBG("Yield");
/* Give other threads a chance to run */
taskYIELD();
}
}
void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit,
const struct bt_mesh_send_cb *cb,
void *cb_data)
{
bt_mesh_msg_t msg = {
.relay = false,
};
BT_DBG("type 0x%02x len %u: %s", BLE_MESH_ADV(buf)->type, 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);
bt_mesh_task_post(&msg, portMAX_DELAY, false);
}
void bt_mesh_adv_update(void)
{
bt_mesh_msg_t msg = {
@@ -357,11 +351,14 @@ void bt_mesh_adv_update(void)
.arg = NULL,
};
BT_DBG("LegacyAdvUpdate");
bt_mesh_task_post(&msg, K_NO_WAIT, false);
}
void bt_mesh_adv_init(void)
{
BT_DBG("LegacyAdvInit");
bt_mesh_adv_common_init();
adv_queue = bt_mesh_adv_queue_get();
@@ -369,20 +366,22 @@ void bt_mesh_adv_init(void)
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
bt_mesh_relay_adv_init();
#endif
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
bt_mesh_ble_adv_init();
#endif
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
QueueHandle_t relay_adv_handle = relay_adv_handle_get();
assert(relay_adv_handle);
#if CONFIG_BLE_MESH_RELAY_ADV_BUF && !CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
QueueHandle_t relay_adv_handle =
bt_mesh_adv_types_mgnt_get(BLE_MESH_ADV_RELAY_DATA)->adv_q->q.handle;
mesh_queue_set = xQueueCreateSet(BLE_MESH_QUEUE_SET_SIZE);
__ASSERT(mesh_queue_set, "Failed to create queue set");
assert(mesh_queue_set);
xQueueAddToSet(adv_queue->q.handle, mesh_queue_set);
xQueueAddToSet(relay_adv_handle, mesh_queue_set);
#endif
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
bt_mesh_adv_task_init(adv_thread);
}
@@ -390,15 +389,18 @@ void bt_mesh_adv_init(void)
#if CONFIG_BLE_MESH_DEINIT
void bt_mesh_adv_deinit(void)
{
BT_DBG("LegacyAdvDeinit");
/* Adv task must be deinit first */
bt_mesh_adv_task_deinit();
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
QueueHandle_t relay_adv_handle =
bt_mesh_adv_types_mgnt_get(BLE_MESH_ADV_RELAY_DATA)->adv_q->q.handle;
QueueHandle_t relay_adv_handle = relay_adv_handle_get();
assert(relay_adv_handle);
xQueueRemoveFromSet(adv_queue->q.handle, mesh_queue_set);
xQueueRemoveFromSet(relay_adv_handle, mesh_queue_set);
vQueueDelete(mesh_queue_set);
mesh_queue_set = NULL;
+3 -4
View File
@@ -23,17 +23,16 @@
extern "C" {
#endif
void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit,
const struct bt_mesh_send_cb *cb,
void *cb_data);
void bt_mesh_adv_update(void);
void bt_mesh_adv_init(void);
void bt_mesh_adv_deinit(void);
#ifdef __cplusplus
}
#endif
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
#endif /* _ADV_H_ */
+231 -176
View File
@@ -31,8 +31,7 @@ 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
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
static bt_mesh_mutex_t adv_buf_alloc_lock;
#if CONFIG_BLE_MESH_EXT_ADV
@@ -76,16 +75,8 @@ static inline void init_adv_with_defaults(struct bt_mesh_adv *adv,
NET_BUF_POOL_FIXED_DEFINE(friend_buf_pool, FRIEND_BUF_COUNT,
BLE_MESH_ADV_DATA_SIZE, NULL);
bt_mesh_friend_adv_t frnd_adv_pool[FRIEND_BUF_COUNT];
struct bt_mesh_adv *bt_mesh_frnd_adv_buf_get(int idx, enum bt_mesh_adv_type type)
{
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;
}
#endif
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;
@@ -98,47 +89,51 @@ struct bt_mesh_adv_task {
};
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_INS] = {
[BLE_MESH_ADV_INST] = {
.id = CONFIG_BLE_MESH_ADV_INST_ID,
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
.busy = false,
#endif
#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_INS] = {
[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_INS] = {
[BLE_MESH_RELAY_ADV_INST] = {
.id = CONFIG_BLE_MESH_RELAY_ADV_INST_ID,
.busy = false,
},
#endif
#endif /* CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE */
#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
[BLE_MESH_BLE_ADV_INS] = {
[BLE_MESH_BLE_ADV_INST] = {
.id = CONFIG_BLE_MESH_BLE_ADV_INST_ID,
.busy = false,
},
#endif
#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;
}
@@ -147,47 +142,57 @@ struct bt_mesh_adv_inst *bt_mesh_get_adv_insts_set(void)
return adv_insts;
}
bool bt_mesh_is_adv_inst_used(uint8_t adv_inst_id)
bool bt_mesh_is_adv_inst_used(uint8_t inst_id)
{
return (find_adv_inst_with_inst_id(adv_inst_id) != NULL);
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)
{
if (inst_type >= BLE_MESH_ADV_INS_TYPES_NUM) {
BT_ERR("Invalid instance type %d", inst_type);
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_INS_UNUSED) {
BT_ERR("Invalid instance id %d", inst_id);
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)
{
if (inst_type >= BLE_MESH_ADV_INS_TYPES_NUM) {
BT_ERR("Invalid instance type %d", 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_INS_UNUSED;
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
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
return 0;
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
struct bt_mesh_adv *adv_alloc(int id, enum bt_mesh_adv_type type)
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];
}
@@ -238,8 +243,10 @@ struct bt_mesh_adv *ext_long_relay_adv_alloc(int id, enum bt_mesh_adv_type type)
#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_mgnt_get(enum bt_mesh_adv_type adv_type)
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];
}
@@ -251,6 +258,8 @@ void bt_mesh_adv_buf_ref_debug(const char *func, struct net_buf *buf,
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) {
@@ -268,11 +277,13 @@ void bt_mesh_adv_buf_ref_debug(const char *func, struct net_buf *buf,
}
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
void bt_mesh_adv_inst_supported_adv_type_add(enum bt_mesh_adv_inst_type inst_type,
enum bt_mesh_adv_type adv_type)
void bt_mesh_adv_inst_type_add(enum bt_mesh_adv_inst_type inst_type,
enum bt_mesh_adv_type adv_type)
{
if (inst_type >= BLE_MESH_ADV_INS_TYPES_NUM) {
BT_ERR("Invalid instance type %d", inst_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;
}
@@ -284,11 +295,13 @@ void bt_mesh_adv_inst_supported_adv_type_add(enum bt_mesh_adv_inst_type inst_typ
adv_insts[inst_type].spt_mask |= BIT(adv_type);
}
void bt_mesh_adv_inst_supported_adv_type_rm(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)
{
if (inst_type >= BLE_MESH_ADV_INS_TYPES_NUM) {
BT_ERR("Invalid instance type %d", inst_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;
}
@@ -300,11 +313,13 @@ void bt_mesh_adv_inst_supported_adv_type_rm(enum bt_mesh_adv_inst_type inst_type
adv_insts[inst_type].spt_mask &= ~BIT(adv_type);
}
void bt_mesh_adv_inst_supported_adv_type_clear(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)
{
if (inst_type >= BLE_MESH_ADV_INS_TYPES_NUM) {
BT_ERR("Invalid instance type %d", inst_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;
}
@@ -315,18 +330,19 @@ void bt_mesh_adv_inst_supported_adv_type_clear(enum bt_mesh_adv_inst_type inst_t
adv_insts[inst_type].spt_mask = 0;
}
#endif
#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("Invalid param %s", __func__);
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;
@@ -334,13 +350,14 @@ int bt_mesh_adv_queue_init(struct bt_mesh_adv_queue *adv_queue, uint16_t queue_s
int bt_mesh_adv_queue_deinit(struct bt_mesh_adv_queue *adv_queue)
{
BT_DBG("AdvQueueDeinit");
if (!adv_queue) {
BT_ERR("Invalid param %s", __func__);
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
bt_mesh_queue_deinit(&adv_queue->q);
adv_queue->send = NULL;
return 0;
@@ -351,13 +368,15 @@ void bt_mesh_adv_type_init(enum bt_mesh_adv_type adv_type,
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);
BT_ERR("%s, Invalid adv type %d", __func__, adv_type);
return;
}
if (!adv_queue || !buf_pool || !adv_alloc) {
BT_ERR("Invalid parameters %s", __func__);
BT_ERR("%s, Invalid parameter", __func__);
return;
}
@@ -368,8 +387,10 @@ void bt_mesh_adv_type_init(enum bt_mesh_adv_type adv_type,
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);
BT_ERR("%s, Invalid adv type %d", __func__, adv_type);
return;
}
@@ -379,19 +400,25 @@ void bt_mesh_adv_type_deinit(enum bt_mesh_adv_type adv_type)
}
#if CONFIG_BLE_MESH_USE_BLE_50
int ble_mesh_adv_task_wakeup(uint32_t evt)
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 ble_mesh_adv_task_wait(uint32_t wait_bits, uint32_t timeout, uint32_t *notify)
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 ble_mesh_adv_task_wait(uint32_t timeout)
bool bt_mesh_adv_task_wait(uint32_t timeout)
{
BT_DBG("AdvTypeWait, Timeout %lu", timeout);
vTaskDelay(K_WAIT(timeout));
return true;
}
@@ -405,45 +432,58 @@ uint16_t bt_mesh_pdu_duration(uint8_t xmit)
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 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;
struct net_buf_pool *pool = adv_types[type].pool;
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 (!pool || !adv_types[type].pool_allocator) {
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(pool, timeout);
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);
BT_WARN("Buf alloc failed");
return NULL;
}
BT_DBG("pool %p, buf_count %d, uinit_count %d, ref %d",
buf->pool, pool->buf_count, pool->uninit_count, buf->ref);
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;
@@ -451,6 +491,9 @@ void bt_mesh_unref_buf_from_pool(struct net_buf_pool *pool)
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;
}
@@ -460,11 +503,15 @@ void bt_mesh_unref_buf_from_pool(struct net_buf_pool *pool)
void bt_mesh_unref_buf(bt_mesh_msg_t *msg)
{
struct net_buf *buf = NULL;
struct net_buf *buf = msg->arg;
BT_DBG("UnRefBuf %p", buf);
if (buf) {
BT_DBG("Ref %u", buf->ref);
if (msg->arg) {
buf = (struct net_buf *)msg->arg;
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 0);
if (buf->ref > 1U) {
buf->ref = 1U;
}
@@ -481,8 +528,10 @@ void bt_mesh_generic_adv_send(struct net_buf *buf, uint8_t xmit,
.relay = false, /* useless flag in multi-instance mode */
};
BT_DBG("type 0x%02x len %u: %s", BLE_MESH_ADV(buf)->type, buf->len,
bt_hex(buf->data, buf->len));
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;
@@ -499,16 +548,19 @@ void bt_mesh_generic_adv_send(struct net_buf *buf, uint8_t xmit,
msg.src = src;
msg.dst = dst;
msg.timestamp = k_uptime_get_32();
}
#endif
assert(adv_types[BLE_MESH_ADV(buf)->type].adv_q && adv_types[BLE_MESH_ADV(buf)->type].adv_q->send);
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
ble_mesh_adv_task_wakeup(ADV_TASK_PKT_SEND_EVT);
#endif
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)
@@ -518,6 +570,8 @@ struct bt_mesh_adv_queue *bt_mesh_adv_queue_get(void)
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;
@@ -548,26 +602,25 @@ bool bt_mesh_ignore_relay_packet(uint32_t timestamp)
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];
}
struct net_buf *bt_mesh_relay_adv_create(enum bt_mesh_adv_type type, int32_t timeout)
{
return bt_mesh_adv_create_from_pool(type, timeout);
}
static void ble_mesh_relay_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front)
static void bt_mesh_relay_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front)
{
bt_mesh_msg_t old_msg = {0};
ARG_UNUSED(front);
BT_DBG("RelayTaskPost, Front %u", front);
if (relay_adv_queue.q.handle == NULL) {
BT_ERR("Invalid relay queue");
@@ -583,14 +636,17 @@ static void ble_mesh_relay_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool
*/
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");
@@ -605,28 +661,18 @@ static void ble_mesh_relay_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool
uint16_t bt_mesh_get_stored_relay_count(void)
{
return (uint16_t)uxQueueMessagesWaiting(relay_adv_queue.q.handle);
}
uint16_t count = (uint16_t)uxQueueMessagesWaiting(relay_adv_queue.q.handle);
static ALWAYS_INLINE
uint16_t ble_mesh_relay_adv_buf_count_get(void)
{
uint16_t relay_adv_count = 2 + CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT;
BT_DBG("StoredRelayCount %u", 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;
return count;
}
void bt_mesh_relay_adv_init(void)
{
bt_mesh_adv_queue_init(&relay_adv_queue, ble_mesh_relay_adv_buf_count_get(),
ble_mesh_relay_task_post);
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
@@ -634,69 +680,74 @@ void bt_mesh_relay_adv_init(void)
&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 */
&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_INS,
bt_mesh_adv_inst_init(BLE_MESH_RELAY_ADV_INST,
CONFIG_BLE_MESH_RELAY_ADV_INST_ID);
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_RELAY_ADV_INS, BLE_MESH_ADV_RELAY_DATA);
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_supported_adv_type_add(BLE_MESH_RELAY_ADV_INS, BLE_MESH_ADV_EXT_RELAY_DATA);
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_supported_adv_type_add(BLE_MESH_RELAY_ADV_INS, BLE_MESH_ADV_EXT_LONG_RELAY_DATA);
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
#else /* CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE */
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_RELAY_DATA);
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_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_RELAY_DATA);
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_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_LONG_RELAY_DATA);
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
#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_supported_adv_type_rm(BLE_MESH_RELAY_ADV_INS, BLE_MESH_ADV_RELAY_DATA);
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_supported_adv_type_rm(BLE_MESH_RELAY_ADV_INS, BLE_MESH_ADV_EXT_RELAY_DATA);
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_supported_adv_type_rm(BLE_MESH_RELAY_ADV_INS, BLE_MESH_ADV_EXT_LONG_RELAY_DATA);
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_INS);
#else
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_supported_adv_type_rm(BLE_MESH_ADV_INS, BLE_MESH_ADV_RELAY_DATA);
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_supported_adv_type_rm(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_RELAY_DATA);
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_supported_adv_type_rm(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_LONG_RELAY_DATA);
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));
}
@@ -704,25 +755,35 @@ void bt_mesh_relay_adv_deinit(void)
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
#if CONFIG_BLE_MESH_FRIEND
struct net_buf_pool *bt_mesh_frnd_adv_pool_get(void)
static struct bt_mesh_adv *bt_mesh_frnd_adv_buf_get(int idx, enum bt_mesh_adv_type type)
{
return &friend_buf_pool;
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_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_FRIEND);
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_supported_adv_type_rm(BLE_MESH_ADV_INS, BLE_MESH_ADV_FRIEND);
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);
@@ -730,72 +791,61 @@ void bt_mesh_frnd_adv_deinit(void)
}
#endif /* CONFIG_BLE_MESH_FRIEND */
static ALWAYS_INLINE
uint16_t ble_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
#endif
#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
#endif
#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))
{
BT_DBG("AdvTaskInit");
if (!adv_thread) {
BT_ERR("Invalid param %s", __func__);
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_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, "Failed to create adv thread 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, "Failed to create adv thread 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, "Failed to create static adv thread");
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);
__ASSERT(ret == pdTRUE, "Failed to create adv thread");
(void)ret;
#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, ble_mesh_adv_buf_count_get(), bt_mesh_task_post);
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
#endif /* CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX */
#if CONFIG_BLE_MESH_USE_BLE_50
bt_mesh_adv_inst_init(BLE_MESH_ADV_INS, CONFIG_BLE_MESH_ADV_INST_ID);
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);
@@ -813,29 +863,28 @@ void bt_mesh_adv_common_init(void)
#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,
/* 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_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_PROV);
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_DATA);
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_BEACON);
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_URI);
* 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_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_PROV);
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_DATA);
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_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_RELAY_DATA);
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_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_LONG_PROV);
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_LONG_DATA);
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_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_LONG_RELAY_DATA);
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 */
@@ -845,6 +894,8 @@ void bt_mesh_adv_common_init(void)
#if CONFIG_BLE_MESH_DEINIT
void bt_mesh_adv_task_deinit(void)
{
BT_DBG("AdvTaskDeinit");
vTaskDelete(adv_task.handle);
adv_task.handle = NULL;
@@ -860,6 +911,8 @@ void bt_mesh_adv_task_deinit(void)
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);
@@ -885,12 +938,14 @@ void bt_mesh_adv_common_deinit(void)
#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_INS);
#endif
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 */
+112 -33
View File
@@ -31,9 +31,9 @@ extern "C" {
#endif
/* Convert from ms to 0.625ms units */
#define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5)
#define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5)
/* Convert from 0.625ms units to interval(ms) */
#define ADV_SCAN_INT(val) ((val) * 5 / 8)
#define ADV_SCAN_INT(val) ((val) * 5 / 8)
/* Maximum advertising data payload for a single data type */
#define BLE_MESH_ADV_DATA_SIZE 29
@@ -46,7 +46,7 @@ extern "C" {
#define BLE_MESH_MSG_NET_BUF(msg) ((struct net_buf *)(msg->arg))
#define BLE_MESH_ADV_INS_UNUSED 0xFF
#define BLE_MESH_ADV_INST_UNUSED 0xFF
struct bt_mesh_adv {
const struct bt_mesh_send_cb *cb;
@@ -75,15 +75,13 @@ typedef struct {
#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
#endif /* CONFIG_BLE_MESH_FRIEND */
enum {
#if CONFIG_BLE_MESH_USE_BLE_50
@@ -103,12 +101,15 @@ enum {
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,
};
@@ -124,11 +125,12 @@ typedef struct bt_mesh_msg {
struct bt_mesh_adv_inst {
uint8_t id;
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
bool busy;
struct net_buf *sending_buf;
/* indicates that which adv_type is supported by this instance */
/* Indicate which adv_type is supported by this instance */
uint32_t spt_mask;
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
};
@@ -184,13 +186,13 @@ static const uint8_t adv_type[] = {
#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,
[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,
[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);
@@ -212,10 +214,26 @@ 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);
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)
{
@@ -225,14 +243,22 @@ static inline struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, int
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_mgnt_get(enum bt_mesh_adv_type adv_type);
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,
@@ -242,35 +268,54 @@ int bt_mesh_adv_queue_init(struct bt_mesh_adv_queue *adv_queue,
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);
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);
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_supported_adv_type_add(enum bt_mesh_adv_inst_type inst_type,
enum bt_mesh_adv_type adv_type);
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_supported_adv_type_rm(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_supported_adv_type_clear(enum bt_mesh_adv_inst_type inst_type,
enum bt_mesh_adv_type adv_type);
#endif
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);
struct net_buf *bt_mesh_relay_adv_create(enum bt_mesh_adv_type type, int32_t timeout);
static inline void bt_mesh_relay_adv_send(struct net_buf *buf, uint8_t xmit,
uint16_t src, uint16_t dst,
@@ -288,31 +333,65 @@ void bt_mesh_relay_adv_deinit(void);
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
#if CONFIG_BLE_MESH_FRIEND
struct bt_mesh_adv *bt_mesh_frnd_adv_buf_get(int id, enum bt_mesh_adv_type type);
struct net_buf_pool *bt_mesh_frnd_adv_pool_get(void);
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
bool bt_mesh_is_adv_inst_used(uint8_t adv_inst_id);
bool ble_mesh_adv_task_wait(uint32_t wait_bits, TickType_t timeout, uint32_t *notify);
int ble_mesh_adv_task_wakeup(uint32_t evt);
#else
bool ble_mesh_adv_task_wait(uint32_t timeout);
#endif
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);
+84 -29
View File
@@ -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);
}
+56 -29
View File
@@ -14,14 +14,14 @@
#include "mesh/common.h"
#include "mesh/buf.h"
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
#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;
#define BLE_MESH_BLE_ADV_QUEUE_SIZE (CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT + 1)
/* 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);
@@ -30,10 +30,11 @@ 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
#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];
@@ -43,7 +44,7 @@ static struct bt_mesh_adv *ble_adv_alloc(int id, enum bt_mesh_adv_type type)
/* 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("%s", __func__);
BT_DBG("BLETaskPost, Front %u", front);
if (p_ble_adv_queue->q.handle == NULL) {
BT_ERR("Invalid adv queue");
@@ -64,20 +65,12 @@ static void bt_mesh_ble_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool fro
}
#endif
static struct net_buf *bt_mesh_ble_adv_create(enum bt_mesh_adv_type type, int32_t timeout)
{
return bt_mesh_adv_create_from_pool(type, timeout);
}
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);
}
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;
}
@@ -85,7 +78,13 @@ static void ble_adv_tx_reset(struct bt_mesh_ble_adv_tx *tx, bool unref)
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);
@@ -97,7 +96,7 @@ 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("%s, duration %d, err %d", __func__, duration, err);
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
@@ -112,13 +111,15 @@ static void ble_adv_send_end(int err, void *cb_data)
{
struct bt_mesh_ble_adv_tx *tx = cb_data;
BT_DBG("%s, err %d", __func__, err);
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);
@@ -140,12 +141,18 @@ 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) {
@@ -165,6 +172,8 @@ int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param,
struct net_buf *buf = NULL;
bool front = false;
BT_DBG("StartBLEAdv");
if (param == NULL || index == NULL) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
@@ -211,12 +220,18 @@ int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param,
return -EINVAL;
}
buf = bt_mesh_ble_adv_create(BLE_MESH_ADV_BLE, K_NO_WAIT);
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) {
@@ -237,6 +252,7 @@ int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *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
@@ -244,10 +260,12 @@ int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param,
* 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 */
@@ -262,6 +280,8 @@ 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;
@@ -274,6 +294,10 @@ int bt_mesh_stop_ble_advertising(uint8_t 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;
*/
@@ -299,16 +323,17 @@ struct bt_mesh_adv_queue *bt_mesh_ble_adv_queue_get(void)
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_INS, CONFIG_BLE_MESH_BLE_ADV_INST_ID);
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_BLE_ADV_INS, BLE_MESH_ADV_BLE);
#else
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_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_BLE);
#endif
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 */
}
@@ -316,10 +341,12 @@ void bt_mesh_ble_adv_init(void)
#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++) {
struct bt_mesh_ble_adv_tx *tx = &ble_adv_tx[i];
ble_adv_tx_reset(tx, false);
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));
@@ -329,16 +356,16 @@ void bt_mesh_ble_adv_deinit(void)
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_INS);
bt_mesh_adv_inst_supported_adv_type_rm(BLE_MESH_BLE_ADV_INS, BLE_MESH_ADV_BLE);
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_supported_adv_type_rm(BLE_MESH_ADV_INS, BLE_MESH_ADV_BLE);
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 */
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
@@ -396,11 +396,11 @@ void ble_mesh_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
goto transfer_to_user;
}
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(params->adv_term.adv_handle));
bt_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(params->adv_term.adv_handle));
#else /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
if (params->adv_term.status == 0x43 || /* Limit reached */
params->adv_term.status == 0x3C) { /* Advertising timeout */
ble_mesh_adv_task_wakeup(ADV_TASK_MESH_ADV_INST_EVT);
bt_mesh_adv_task_wakeup(ADV_TASK_MESH_ADV_INST_EVT);
}
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
/**
@@ -423,7 +423,7 @@ void ble_mesh_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
* could lead to resource contention issues.
*/
bt_mesh_unset_ble_adv_running();
ble_mesh_adv_task_wakeup(ADV_TASK_MESH_ADV_INST_EVT);
bt_mesh_adv_task_wakeup(ADV_TASK_MESH_ADV_INST_EVT);
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
@@ -655,7 +655,7 @@ static void bt_mesh_scan_result_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARC
static struct {
bool set;
tBTA_DM_BLE_GAP_EXT_ADV_PARAMS param;
} last_param[BLE_MESH_ADV_INS_TYPES_NUM];
} last_param[BLE_MESH_ADV_INST_TYPES_NUM];
int bt_le_ext_adv_start(const uint8_t inst_id,
const struct bt_mesh_adv_param *param,
@@ -1615,7 +1615,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:
@@ -1803,7 +1803,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;
@@ -1872,9 +1872,10 @@ int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, uint16_t service_uuid)
conn_1m_param.max_ce_len = 0;
BTA_GATTC_Enh_Open(bt_mesh_gattc_if, bt_mesh_gattc_info[i].addr.val,
bt_mesh_gattc_info[i].addr.type, true, BTA_GATT_TRANSPORT_LE, TRUE, BLE_ADDR_UNKNOWN_TYPE,
BTA_BLE_PHY_1M_MASK, &conn_1m_param, NULL, NULL);
#else
bt_mesh_gattc_info[i].addr.type, true,
BTA_GATT_TRANSPORT_LE, TRUE, BLE_ADDR_UNKNOWN_TYPE,
BTA_BLE_PHY_1M_MASK, &conn_1m_param, NULL, NULL);
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
/* Min_interval: 15ms
* Max_interval: 15ms
* Slave_latency: 0x0
@@ -1886,9 +1887,10 @@ int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, uint16_t service_uuid)
conn_1m_param.supervision_timeout = 0x64;
BTA_GATTC_Enh_Open(bt_mesh_gattc_if, bt_mesh_gattc_info[i].addr.val,
bt_mesh_gattc_info[i].addr.type, true, BTA_GATT_TRANSPORT_LE, FALSE, BLE_ADDR_UNKNOWN_TYPE,
BTA_BLE_PHY_1M_MASK, &conn_1m_param, NULL, NULL);
#endif
bt_mesh_gattc_info[i].addr.type, true,
BTA_GATT_TRANSPORT_LE, FALSE, BLE_ADDR_UNKNOWN_TYPE,
BTA_BLE_PHY_1M_MASK, &conn_1m_param, NULL, NULL);
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
return 0;
}
+236 -56
View File
@@ -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;
File diff suppressed because it is too large Load Diff
+32 -21
View File
@@ -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));
+129 -102
View File
@@ -28,28 +28,9 @@
#include "adv_common.h"
#include "ble_adv.h"
static struct bt_mesh_adv_queue *adv_queue;
static struct bt_mesh_adv_inst *adv_insts;
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);
}
}
static inline int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration)
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;
@@ -63,8 +44,8 @@ static inline int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration
uint8_t is_ext_adv = false;
#endif
BT_DBG("type %u len %u: %s", BLE_MESH_ADV(buf)->type,
buf->len, bt_hex(buf->data, buf->len));
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
@@ -84,13 +65,13 @@ static inline int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration
case BLE_MESH_ADV_DATA:
#if CONFIG_BLE_MESH_FRIEND
case BLE_MESH_ADV_FRIEND:
#endif
#endif /* CONFIG_BLE_MESH_FRIEND */
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
case BLE_MESH_ADV_RELAY_DATA:
#endif
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX
case BLE_MESH_ADV_PROXY_SOLIC:
#endif
#endif /* CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX */
case BLE_MESH_ADV_BEACON:
case BLE_MESH_ADV_URI: {
#if CONFIG_BLE_MESH_EXT_ADV
@@ -146,19 +127,24 @@ static inline int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration
#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, &param, solic_ad, ARRAY_SIZE(solic_ad), NULL, 0);
err = bt_le_ext_adv_start(CONFIG_BLE_MESH_ADV_INST_ID, &param,
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_ext_adv_start(inst->id, &param, &ad, 1, NULL, 0);
}
}
break;
}
break;
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
case BLE_MESH_ADV_BLE:
struct bt_mesh_ble_adv_data data = {0};
@@ -171,8 +157,8 @@ static inline int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration
}
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) {
@@ -188,9 +174,10 @@ static inline int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration
err = bt_mesh_ble_ext_adv_start(inst->id, &tx->param, &data);
break;
#endif
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
default:
BT_ERR("Error Type");
BT_ERR("InvalidAdvType %u", BLE_MESH_ADV(buf)->type);
break;
}
@@ -201,54 +188,64 @@ static inline int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration
}
*adv_duration = duration;
BT_DBG("Advertising started. %u ms", duration);
return 0;
}
static inline int find_valid_msg_from_queue(bt_mesh_queue_t *msg_queue, bt_mesh_msg_t *msg)
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. */
/* 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);
/* If the message is canceled for advertising,
* then continue to retrieve the next message
* from that queue. */
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.
* 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. */
/* 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 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
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
break;
}
@@ -259,38 +256,43 @@ static inline int find_valid_msg_from_queue(bt_mesh_queue_t *msg_queue, bt_mesh_
return 0;
}
static inline int active_idle_adv_instance(uint32_t *update_evts, uint16_t *min_duration)
static int activate_idle_adv_instance(uint32_t *update_evts, uint16_t *min_duration)
{
uint32_t evts = 0;
uint16_t duration = K_FOREVER;
uint16_t cur_min_duration = K_FOREVER;
enum bt_mesh_adv_type adv_type = 0;
struct bt_mesh_adv_inst *instance = NULL;
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_INS].busy) {
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_INS].busy = true;
evts |= ADV_TASK_ADV_INST_EVT(adv_insts[BLE_MESH_ADV_PROXY_INS].id);
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_INS; i < BLE_MESH_ADV_INS_TYPES_NUM; i++) {
instance = &adv_insts[i];
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)
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;
}
@@ -300,30 +302,38 @@ static inline int active_idle_adv_instance(uint32_t *update_evts, uint16_t *min_
while(spt_mask) {
adv_type = find_lsb_set(spt_mask) - 1;
spt_mask &= ~BIT(adv_type);
msg_queue = &(bt_mesh_adv_types_mgnt_get(adv_type)->adv_q->q);
msg_queue = &(bt_mesh_adv_types_mgmt_get(adv_type)->adv_q->q);
/* When there is no new message in the queue, *buf (aka: msg.arg)
* will be empty. */
/* 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("no valid message for instance %d", instance->id);
BT_DBG("NoMsgForAdvInst, InstID %u", instance->id);
continue;
}
instance->sending_buf = (struct net_buf *)msg.arg;
if (adv_send(instance, &duration)) {
BT_ERR("adv start failed");
/* 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;
/* 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. */
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;
}
@@ -331,14 +341,17 @@ static inline int active_idle_adv_instance(uint32_t *update_evts, uint16_t *min_
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. */
/* 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;
@@ -347,30 +360,36 @@ static inline int active_idle_adv_instance(uint32_t *update_evts, uint16_t *min_
static uint32_t received_adv_evts_handle(uint32_t recv_evts)
{
uint32_t evt = 0;
BT_DBG("RecvAdvEvtsHandle, RecvEvts 0x%08lx", recv_evts);
if (!recv_evts) {
return 0;
}
for (int i = 0; recv_evts && i < BLE_MESH_ADV_INS_TYPES_NUM; i++) {
evt = ADV_TASK_ADV_INST_EVT(adv_insts[i].id);
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_INS)) {
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 maybe*/
adv_send_end(0, BLE_MESH_ADV(adv_insts[i].sending_buf)->cb, BLE_MESH_ADV(adv_insts[i].sending_buf)->cb_data);
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;
}
}
@@ -384,30 +403,31 @@ static void adv_thread(void *p)
uint32_t recv_evts = 0;
uint32_t wait_evts = 0;
BT_DBG("%s, starts", __func__);
BT_DBG("ExtAdvThread");
while (1) {
adv_duration = K_FOREVER;
wait_evts |= ADV_TASK_PKT_SEND_EVT;
active_idle_adv_instance(&wait_evts, &adv_duration);
activate_idle_adv_instance(&wait_evts, &adv_duration);
ble_mesh_adv_task_wait(wait_evts, adv_duration, &recv_evts);
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_INS].busy = false;
adv_insts[BLE_MESH_ADV_PROXY_INST].busy = false;
recv_evts &= ~ADV_TASK_PROXY_ADV_UPD_EVT;
}
#endif
/**
* `recv_evts == ADV_TASK_PKT_SEND_EVT` indicates that new packets
* have been placed into the queue, and the advertising instances started
* previous have not yet stopped.
/* 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;
@@ -420,37 +440,42 @@ static void adv_thread(void *p)
recv_evts = received_adv_evts_handle(recv_evts);
if (recv_evts) {
BT_ERR("Remain evts %08x to handle", 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_INS].busy) {
ble_mesh_adv_task_wakeup(ADV_TASK_PROXY_ADV_UPD_EVT);
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();
adv_queue = bt_mesh_adv_queue_get();
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
bt_mesh_relay_adv_init();
#endif
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
bt_mesh_ble_adv_init();
#endif
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
bt_mesh_adv_task_init(adv_thread);
}
@@ -458,6 +483,8 @@ void bt_mesh_adv_init(void)
#if CONFIG_BLE_MESH_DEINIT
void bt_mesh_adv_deinit(void)
{
BT_DBG("ExtAdvDeinit");
bt_mesh_adv_task_deinit();
bt_mesh_adv_common_deinit();
@@ -466,10 +493,10 @@ void bt_mesh_adv_deinit(void)
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
bt_mesh_relay_adv_deinit();
#endif
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
bt_mesh_ble_adv_deinit();
#endif
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
}
#endif /* CONFIG_BLE_MESH_DEINIT */
+2 -8
View File
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -20,16 +20,10 @@
extern "C" {
#endif
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_adv_update(void);
void bt_mesh_adv_init(void);
void bt_mesh_adv_deinit(void);
#ifdef __cplusplus
@@ -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 */
@@ -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,
+229 -87
View File
@@ -69,6 +69,9 @@ static struct bt_mesh_subnet *friend_subnet_get(uint16_t net_idx)
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;
}
@@ -81,11 +84,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;
}
@@ -108,11 +116,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;
@@ -127,18 +139,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);
@@ -160,9 +175,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);
@@ -177,6 +196,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;
}
@@ -194,11 +215,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;
}
@@ -213,11 +236,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;
}
@@ -257,19 +282,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;
}
@@ -305,6 +332,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;
@@ -318,6 +347,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;
@@ -332,6 +363,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;
@@ -346,7 +379,9 @@ static struct net_buf *create_friend_pdu(struct bt_mesh_friend *frnd,
{
struct net_buf *buf = NULL;
buf = bt_mesh_adv_create_from_pool(BLE_MESH_ADV_FRIEND, K_NO_WAIT);
BT_DBG("CreatFrndPDU");
buf = bt_mesh_adv_create(BLE_MESH_ADV_FRIEND, K_NO_WAIT);
if (!buf) {
return NULL;
}
@@ -385,6 +420,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");
@@ -393,6 +432,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) {
@@ -423,6 +463,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,
@@ -439,6 +481,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,
@@ -451,6 +495,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;
}
@@ -464,6 +512,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;
}
@@ -491,8 +540,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;
}
@@ -502,7 +554,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;
}
}
@@ -515,6 +567,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;
}
}
@@ -529,15 +582,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;
}
@@ -550,7 +603,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));
@@ -564,21 +617,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);
@@ -596,7 +653,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);
@@ -614,7 +671,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);
}
@@ -624,9 +681,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,
@@ -635,6 +695,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;
@@ -642,7 +704,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;
}
@@ -666,6 +728,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;
}
@@ -676,9 +739,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,
@@ -687,6 +750,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;
@@ -694,7 +759,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;
}
@@ -713,7 +778,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;
}
@@ -727,6 +792,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++;
}
@@ -735,6 +802,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");
@@ -749,6 +818,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;
@@ -756,7 +827,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;
}
@@ -770,12 +841,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);
@@ -783,7 +855,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) {
@@ -794,8 +867,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");
}
}
@@ -806,6 +879,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];
@@ -821,6 +896,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;
@@ -852,6 +929,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;
@@ -863,13 +942,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;
@@ -881,11 +962,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);
}
@@ -896,6 +979,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;
@@ -933,6 +1018,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));
@@ -977,7 +1065,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);
@@ -986,7 +1074,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);
@@ -1002,13 +1090,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;
}
@@ -1035,7 +1125,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;
@@ -1070,11 +1160,10 @@ init_friend:
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 nodes own unicast address, then the Friend node shall
@@ -1086,11 +1175,9 @@ init_friend:
}
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);
@@ -1104,6 +1191,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;
}
@@ -1125,6 +1214,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];
@@ -1150,15 +1242,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) {
@@ -1184,7 +1279,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;
@@ -1199,7 +1294,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");
@@ -1207,47 +1302,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;
}
@@ -1260,8 +1356,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:
@@ -1279,6 +1376,8 @@ int bt_mesh_friend_init(void)
{
int i;
BT_DBG("FrndInit");
if (friend_init == true) {
BT_WARN("%s, Already", __func__);
return -EALREADY;
@@ -1312,6 +1411,8 @@ int bt_mesh_friend_deinit(void)
{
int i;
BT_DBG("FrndDeinit");
if (friend_init == false) {
BT_WARN("%s, Already", __func__);
return -EALREADY;
@@ -1341,6 +1442,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;
}
@@ -1350,23 +1453,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;
@@ -1377,17 +1484,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;
@@ -1406,6 +1514,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.
@@ -1414,8 +1525,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);
}
@@ -1443,7 +1552,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);
}
@@ -1456,7 +1565,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);
@@ -1488,7 +1597,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,
@@ -1496,6 +1605,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;
}
@@ -1521,12 +1634,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;
}
}
@@ -1540,6 +1654,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;
@@ -1565,6 +1681,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;
}
@@ -1573,8 +1693,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;
}
@@ -1582,6 +1702,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
@@ -1596,6 +1718,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];
@@ -1614,6 +1740,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;
}
@@ -1631,6 +1758,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;
}
@@ -1646,6 +1776,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++;
@@ -1668,15 +1801,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];
@@ -1691,8 +1828,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);
}
}
@@ -1704,14 +1840,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];
@@ -1738,6 +1875,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;
@@ -1766,6 +1906,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);
+38 -12
View File
@@ -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;
+66 -11
View File
@@ -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) {
+34 -10
View File
@@ -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);
}
@@ -14,6 +14,7 @@
#include "mesh/config.h"
#include "mesh/buf.h"
#include "mesh/timer.h"
#include "sys/types.h"
/**
* @brief Bluetooth Mesh Access Layer
@@ -151,8 +152,15 @@ struct bt_mesh_elem {
#define BLE_MESH_MODEL_ID_LIGHT_LC_SRV 0x130f
#define BLE_MESH_MODEL_ID_LIGHT_LC_SETUP_SRV 0x1310
#define BLE_MESH_MODEL_ID_LIGHT_LC_CLI 0x1311
#define BLE_MESH_MODEL_ID_MBT_SRV 0x1400
#define BLE_MESH_MODEL_ID_MBT_CLI 0x1401
#define BLE_MESH_MODEL_ID_BLOB_SRV 0x1400
#define BLE_MESH_MODEL_ID_BLOB_CLI 0x1401
#define BLE_MESH_MODEL_ID_DFU_SRV 0x1402
#define BLE_MESH_MODEL_ID_DFU_CLI 0x1403
#define BLE_MESH_MODEL_ID_DFD_SRV 0x1404
#define BLE_MESH_MODEL_ID_DFD_CLI 0x1405
#define BLE_MESH_MODEL_ID_MBT_SRV BLE_MESH_MODEL_ID_BLOB_SRV
#define BLE_MESH_MODEL_ID_MBT_CLI BLE_MESH_MODEL_ID_BLOB_CLI
typedef struct {
uint32_t adv_itvl;
@@ -520,6 +528,8 @@ struct bt_mesh_model_pub {
.update = _update, \
}
typedef ssize_t (*settings_read_cb)(void *cb_arg, void *data, size_t len);
/** Model callback functions. */
struct bt_mesh_model_cb {
/** @brief Model init callback.
@@ -613,7 +623,7 @@ void bt_mesh_model_msg_init(struct net_buf_simple *msg, uint32_t opcode);
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_model_send(struct bt_mesh_model *model,
int bt_mesh_model_send(const struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *msg,
const struct bt_mesh_send_cb *cb,
@@ -642,7 +652,7 @@ int bt_mesh_model_publish(struct bt_mesh_model *model);
*
* @return Pointer to the element that the given model belongs to.
*/
struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod);
struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod);
/** @brief Find a SIG model.
*
@@ -512,20 +512,20 @@ struct bt_mesh_adv_param {
#define ADV_TASK_ADV_INST_EVT(inst_id) BIT(inst_id)
enum bt_mesh_adv_inst_type {
BLE_MESH_ADV_INS,
BLE_MESH_ADV_INST,
#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_INS,
BLE_MESH_ADV_PROXY_INST,
#endif
#if CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE
BLE_MESH_RELAY_ADV_INS,
BLE_MESH_RELAY_ADV_INST,
#endif
#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
BLE_MESH_BLE_ADV_INS,
BLE_MESH_BLE_ADV_INST,
#endif
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
BLE_MESH_ADV_INS_TYPES_NUM,
BLE_MESH_ADV_INST_TYPES_NUM,
};
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+59 -38
View File
@@ -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 */
+109 -47
View File
@@ -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);
+73 -25
View File
@@ -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);
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -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);
@@ -993,16 +993,16 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
return 0;
case BLE_GAP_EVENT_ADV_COMPLETE:
BT_DBG("advertise complete; reason=%d",
event->adv_complete.reason);
BT_DBG("advertise complete; reason=%d", event->adv_complete.reason);
#if CONFIG_BLE_MESH_USE_BLE_50
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
bt_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
#else /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
assert(CONFIG_BLE_MESH_ADV_INST_ID == event->adv_complete.instance);
/* Limit Reached (0x43) and Advertising Timeout (0x3C) will cause BLE_HS_ETIMEOUT to be set. */
if (event->adv_complete.reason == BLE_HS_ETIMEOUT) {
ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
bt_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
}
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
/**
@@ -1020,12 +1020,12 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
*/
if (bt_mesh_is_ble_adv_running() &&
event->adv_complete.reason == 0) {
/* The unset operation must be performed before waking up the
* adv task; performing the unset after waking up the adv task
* could lead to resource contention issues.
*/
/* The unset operation must be performed before waking up the
* adv task; performing the unset after waking up the adv task
* could lead to resource contention issues.
*/
bt_mesh_unset_ble_adv_running();
ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
bt_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
@@ -1124,12 +1124,12 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
BT_DBG("Provisioner advertise complete; reason=%d",
event->adv_complete.reason);
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
bt_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
#else /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
assert(CONFIG_BLE_MESH_ADV_INST_ID == event->adv_complete.instance);
/* Limit Reached (0x43) and Advertising Timeout (0x3C) will cause BLE_HS_ETIMEOUT to be set. */
if (event->adv_complete.reason == BLE_HS_ETIMEOUT) {
ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(CONFIG_BLE_MESH_ADV_INST_ID));
bt_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(CONFIG_BLE_MESH_ADV_INST_ID));
}
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
/**
@@ -1152,7 +1152,7 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
* could lead to resource contention issues.
*/
bt_mesh_unset_ble_adv_running();
ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(CONFIG_BLE_MESH_ADV_INST_ID));
bt_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(CONFIG_BLE_MESH_ADV_INST_ID));
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
@@ -1167,7 +1167,7 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
static struct {
bool set;
struct ble_gap_ext_adv_params param;
} last_param[BLE_MESH_ADV_INS_TYPES_NUM];
} last_param[BLE_MESH_ADV_INST_TYPES_NUM];
int bt_le_ext_adv_start(const uint8_t inst_id,
const struct bt_mesh_adv_param *param,
@@ -2516,8 +2516,7 @@ void bt_mesh_gatt_init(void)
static bool init = false;
if (init == false) {
__ASSERT(g_gatts_svcs_add, "func bt_mesh_gatts_svcs_add should be called before mesh init");
assert(g_gatts_svcs_add);
ble_gatts_svc_set_visibility(prov_svc_start_handle, 1);
ble_gatts_svc_set_visibility(proxy_svc_start_handle, 0);
+31 -9
View File
@@ -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);
}
+25 -9
View File
@@ -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
*/
@@ -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");
+39 -9
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -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 @@ start:
}
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;
}
+112 -49
View File
@@ -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);
@@ -861,6 +907,8 @@ uint16_t bt_mesh_proxy_client_get_conn_count(void)
count++;
}
BT_DBG("ProxyClientGetConnCount, Count %u", count);
return count;
}
@@ -870,6 +918,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);
@@ -900,12 +950,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);
}
@@ -919,6 +972,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
@@ -975,6 +1030,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);
@@ -1038,6 +1095,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;
}
@@ -1072,11 +1130,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;
}
@@ -1095,13 +1152,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);
@@ -1113,7 +1171,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;
}
@@ -1125,16 +1183,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);
@@ -1143,7 +1204,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;
}
@@ -1153,6 +1214,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];
File diff suppressed because it is too large Load Diff
@@ -58,7 +58,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;
+27 -2
View File
@@ -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) {
+166 -90
View File
@@ -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
@@ -43,18 +43,18 @@
static struct bt_mesh_scan_param scan_param = {
#if CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN
.type = BLE_MESH_SCAN_ACTIVE,
#else
.type = BLE_MESH_SCAN_PASSIVE,
#endif
.type = BLE_MESH_SCAN_ACTIVE,
#else /* CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN */
.type = BLE_MESH_SCAN_PASSIVE,
#endif /* CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN */
#if CONFIG_BLE_MESH_USE_DUPLICATE_SCAN
.filter_dup = BLE_MESH_SCAN_FILTER_DUP_ENABLE,
#else
.filter_dup = BLE_MESH_SCAN_FILTER_DUP_DISABLE,
#endif
.interval = SCAN_INTERVAL,
.window = SCAN_WINDOW,
.scan_fil_policy = BLE_MESH_SP_ADV_ALL,
.filter_dup = BLE_MESH_SCAN_FILTER_DUP_ENABLE,
#else /* CONFIG_BLE_MESH_USE_DUPLICATE_SCAN */
.filter_dup = BLE_MESH_SCAN_FILTER_DUP_DISABLE,
#endif /* CONFIG_BLE_MESH_USE_DUPLICATE_SCAN */
.interval = SCAN_INTERVAL,
.window = SCAN_WINDOW,
.scan_fil_policy = BLE_MESH_SP_ADV_ALL,
};
#if (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV)
@@ -76,6 +76,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;
}
@@ -100,9 +105,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");
@@ -111,42 +118,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;
@@ -170,6 +184,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;
}
@@ -180,19 +197,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;
@@ -200,7 +220,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);
@@ -210,6 +230,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;
@@ -217,40 +239,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;
}
@@ -263,6 +287,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;
@@ -270,7 +296,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;
}
@@ -292,8 +318,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 */
@@ -316,7 +347,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)) {
@@ -327,7 +359,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;
}
@@ -342,6 +375,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;
@@ -354,6 +389,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;
@@ -366,6 +403,8 @@ int bt_mesh_stop_ble_scan(void)
bool bt_mesh_ble_scan_state_get(void)
{
BT_DBG("BLEScanEn %u", ble_scan_en);
return ble_scan_en;
}
@@ -375,6 +414,7 @@ static void inline callback_ble_adv_pkt(const bt_mesh_addr_t *addr,
{
#if !CONFIG_BLE_MESH_USE_BLE_50
bt_mesh_ble_adv_report_t adv_rpt = {0};
if (ble_scan_en) {
memcpy(adv_rpt.addr, addr->val, BD_ADDR_LEN);
adv_rpt.addr_type = addr->type;
@@ -382,9 +422,12 @@ static void inline callback_ble_adv_pkt(const bt_mesh_addr_t *addr,
adv_rpt.length = length;
adv_rpt.data = length ? data : NULL;
adv_rpt.rssi = rssi;
BT_DBG("CallbackBLEAdvPkt, AdvType 0x%02x Len %u", adv_type, length);
bt_mesh_ble_scan_cb_evt_to_btc(&adv_rpt);
}
#endif
#endif /* !CONFIG_BLE_MESH_USE_BLE_50 */
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
@@ -395,6 +438,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;
}
@@ -408,19 +453,19 @@ static bool rpr_ext_scan_handle_adv_pkt(const bt_mesh_addr_t *addr,
static void bt_mesh_scan_cb(struct bt_mesh_adv_report *adv_rpt)
{
struct net_buf_simple_state buf_state = {0};
struct net_buf_simple *buf = &adv_rpt->adv_data;
struct net_buf_simple_state buf_state = {0};
#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) */
net_buf_simple_save(buf, &buf_state);
@@ -429,41 +474,42 @@ static void bt_mesh_scan_cb(struct bt_mesh_adv_report *adv_rpt)
adv_rpt->adv_type != 0 &&
#endif
adv_rpt->adv_type != BLE_MESH_ADV_NONCONN_IND &&
adv_rpt->adv_type != BLE_MESH_ADV_IND
adv_rpt->adv_type != BLE_MESH_ADV_IND
#if CONFIG_BLE_MESH_EXT_ADV
&& adv_rpt->adv_type != BLE_MESH_EXT_ADV_NONCONN_IND
&& adv_rpt->adv_type != BLE_MESH_EXT_ADV_NONCONN_IND
#endif
#if CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN
&& adv_rpt->adv_type != BLE_MESH_ADV_SCAN_RSP
#endif
) {
&& adv_rpt->adv_type != BLE_MESH_ADV_SCAN_RSP
#endif /* CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN */
) {
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
net_buf_simple_restore(buf, &buf_state);
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 = &adv_rpt->addr;
current_adv_type = adv_rpt->adv_type;
#endif
#endif /* (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV) */
#if CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN
if (adv_rpt->adv_type == BLE_MESH_ADV_SCAN_RSP) {
/**
* scan response is only visible for remote provisioning extend scan.
*/
/* scan response is only visible for remote provisioning extend scan */
if (rpr_ext_scan_handle_adv_pkt(&adv_rpt->addr, adv_data, adv_len)) {
return;
} else {
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
net_buf_simple_restore(buf, &buf_state);
}
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
net_buf_simple_restore(buf, &buf_state);
}
#endif /* CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN */
@@ -472,20 +518,24 @@ static void bt_mesh_scan_cb(struct bt_mesh_adv_report *adv_rpt)
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
callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
net_buf_simple_restore(buf, &buf_state);
return;
}
if (len > buf->len) {
BT_DBG("AD malformed");
BT_DBG("MalformedAD");
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
net_buf_simple_restore(buf, &buf_state);
return;
}
@@ -496,13 +546,15 @@ static void bt_mesh_scan_cb(struct bt_mesh_adv_report *adv_rpt)
buf->len = len - 1;
if ((type == BLE_MESH_DATA_MESH_PROV || type == BLE_MESH_DATA_MESH_MESSAGE ||
type == BLE_MESH_DATA_MESH_BEACON) && (adv_rpt->adv_type != BLE_MESH_ADV_NONCONN_IND
if ((type == BLE_MESH_DATA_MESH_PROV ||
type == BLE_MESH_DATA_MESH_MESSAGE ||
type == BLE_MESH_DATA_MESH_BEACON) &&
(adv_rpt->adv_type != BLE_MESH_ADV_NONCONN_IND
#if CONFIG_BLE_MESH_EXT_ADV
&& adv_rpt->adv_type != BLE_MESH_EXT_ADV_NONCONN_IND
&& adv_rpt->adv_type != BLE_MESH_EXT_ADV_NONCONN_IND
#endif
)) {
BT_DBG("Ignore mesh packet (type 0x%02x) with adv_type 0x%02x", type, adv_rpt->adv_type);
BT_DBG("IgnorePkt, Type 0x%02x AdvType 0x%02x", type, adv_rpt->adv_type);
return;
}
@@ -526,36 +578,44 @@ static void bt_mesh_scan_cb(struct bt_mesh_adv_report *adv_rpt)
#endif /* CONFIG_BLE_MESH_EXT_ADV */
bt_mesh_generic_net_recv(buf, &rx, 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, adv_rpt->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(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
net_buf_simple_restore(buf, &buf_state);
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(&adv_rpt->addr, adv_data, adv_len)) {
/* If handled as extended scan report successfully, then not
@@ -563,18 +623,25 @@ static void bt_mesh_scan_cb(struct bt_mesh_adv_report *adv_rpt)
*/
return;
}
#endif
#endif /* CONFIG_BLE_MESH_RPR_SRV */
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
net_buf_simple_restore(buf, &buf_state);
return;
}
break;
case BLE_MESH_DATA_SVC_DATA16:
handle_adv_service_data(buf, &adv_rpt->addr, uuid, adv_rpt->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(&adv_rpt->addr, adv_data, adv_len)) {
@@ -583,10 +650,12 @@ static void bt_mesh_scan_cb(struct bt_mesh_adv_report *adv_rpt)
*/
return;
}
#endif
#endif /* CONFIG_BLE_MESH_RPR_SRV */
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
net_buf_simple_restore(buf, &buf_state);
return;
}
@@ -600,9 +669,11 @@ int bt_mesh_scan_enable(void)
{
int err = 0;
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;
}
@@ -613,9 +684,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;
}
@@ -629,9 +702,13 @@ int bt_mesh_scan_param_update(struct bt_mesh_scan_param *param)
if (param == NULL ||
param->interval == 0 ||
param->interval < param->window) {
BT_ERR("InvalidScanParam");
return -EINVAL;
}
BT_DBG("ScanParamUpdate, Type %u Interval %u Window %u",
param->type, param->interval, param->window);
scan_param.interval = param->interval;
scan_param.window = param->window;
@@ -641,24 +718,22 @@ int bt_mesh_scan_param_update(struct bt_mesh_scan_param *param)
BT_INFO("New scan parameters will take effect after scan starts");
return 0;
}
BT_ERR("Failed to stop scan (err %d)", err);
BT_ERR("StopScanFailed, Err %d", err);
return err;
}
/**
* Since the user only needs to set the scan interval
* and scan window parameters, only the interval and
* window parameters in the `param` are correct.
/* Since the user only needs to set the scan interval and scan window,
* only the interval and window parameters in the `param` are correct.
*
* For the aforementioned reason, when updating the scan
* parameters, the other parameters also need to be set
* correctly, and these other parameters are saved in the
* `scan_param`. Therefore, `scan_param` must be used instead
* of `param` here.
* For the aforementioned reason, when updating the scan parameters,
* the other parameters also need to be set correctly, and these other
* parameters are saved in the `scan_param`. Therefore, `scan_param`
* must be used instead of `param` here.
*/
err = bt_le_scan_start(&scan_param, bt_mesh_scan_cb);
if (err && err != -EALREADY) {
BT_ERR("Failed to start scan (err %d)", err);
BT_ERR("StartScanFailed, Err %d", err);
return err;
}
@@ -668,23 +743,24 @@ int bt_mesh_scan_param_update(struct bt_mesh_scan_param *param)
#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;
}
File diff suppressed because it is too large Load Diff
@@ -35,6 +35,10 @@ void bt_mesh_store_mod_sub(struct bt_mesh_model *mod);
void bt_mesh_store_mod_pub(struct bt_mesh_model *mod);
void bt_mesh_store_label(void);
int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd,
const char *name, const void *data,
size_t data_len);
void bt_mesh_clear_role(void);
void bt_mesh_clear_net(void);
void bt_mesh_clear_subnet(struct bt_mesh_subnet *sub);
@@ -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 */
@@ -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;
+9 -1
View File
@@ -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;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -11,6 +11,7 @@
#define _TRANSPORT_H_
#include "net.h"
#include "access.h"
#ifdef __cplusplus
extern "C" {
@@ -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_DBG("ClientGetStatusOp");
BT_DBG("OpPair %p Size %u OpCode 0x%08lx", op_pair, size, opcode);
bt_mesh_list_lock();
if (sys_slist_is_empty(list)) {
bt_mesh_list_unlock();
return false;
}
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;
@@ -211,6 +211,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.
@@ -228,7 +230,7 @@ static int32_t bt_mesh_client_calc_timeout(struct bt_mesh_msg_ctx *ctx,
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-
@@ -267,7 +269,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)) {
@@ -293,6 +295,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;
@@ -334,7 +338,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;
}
@@ -349,14 +353,15 @@ int bt_mesh_client_send_msg(bt_mesh_client_common_param_t *param,
memcpy(&node->ctx, &param->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(&param->ctx, msg, param->opcode,
param->msg_timeout ? param->msg_timeout : CONFIG_BLE_MESH_CLIENT_MSG_TIMEOUT);
node->timeout = client_calc_timeout(&param->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");
@@ -399,6 +404,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;
@@ -436,6 +443,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;
@@ -467,6 +476,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;
@@ -484,12 +495,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;
@@ -500,6 +509,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;
@@ -508,11 +519,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;
@@ -0,0 +1,249 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "btc/btc_manage.h"
#include "btc_ble_mesh_dfu_model.h"
#include "esp_ble_mesh_dfu_model_api.h"
#if CONFIG_BLE_MESH_DFU_CLI
static bool is_get_param_needed(esp_ble_mesh_opcode_t opcode)
{
switch (opcode) {
case ESP_BLE_MESH_DFU_OP_UPDATE_INFO_GET:
case ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK:
case ESP_BLE_MESH_DFU_OP_UPDATE_START:
return true;
default:
return false;
}
}
esp_err_t esp_ble_mesh_dfu_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_dfu_client_get_t *get)
{
btc_ble_mesh_dfu_client_args_t arg = {0};
btc_msg_t msg = {0};
if (params == NULL || params->model == NULL ||
params->ctx.net_idx == ESP_BLE_MESH_KEY_UNUSED ||
!ESP_BLE_MESH_ADDR_IS_UNICAST(params->ctx.addr) ||
(is_get_param_needed(params->opcode) && get == NULL)) {
return ESP_ERR_INVALID_ARG;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_DFU_CLIENT;
msg.act = BTC_BLE_MESH_ACT_DFU_CLIENT_GET_STATE;
arg.dfu_get.params = params;
arg.dfu_get.get = get;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_dfu_client_args_t),
btc_ble_mesh_dfu_client_arg_deep_copy,
btc_ble_mesh_dfu_client_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_dfu_cli_img_send(esp_ble_mesh_dfu_cli_t *cli,
esp_ble_mesh_blob_cli_inputs_t *inputs,
esp_ble_mesh_blob_io_t *io,
esp_ble_mesh_dfu_cli_xfer_t *xfer)
{
btc_ble_mesh_dfu_client_args_t arg = {0};
btc_msg_t msg = {0};
if (cli == NULL || inputs == NULL ||
io == NULL || xfer == NULL) {
return ESP_ERR_INVALID_ARG;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_DFU_CLIENT;
msg.act = BTC_BLE_MESH_ACT_DFU_CLIENT_IMG_SEND;
arg.send_arg.cli = cli;
arg.send_arg.inputs = inputs;
arg.send_arg.io = io;
arg.send_arg.xfer = xfer;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_dfu_client_args_t),
NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
uint8_t esp_ble_mesh_dfu_cli_progress(esp_ble_mesh_dfu_cli_t *cli)
{
if (!cli) {
return 0;
}
return btc_ble_mesh_dfu_cli_progress(cli);
}
esp_err_t esp_ble_mesh_register_dfu_client_callback(esp_ble_mesh_dfu_client_cb_t callback)
{
return (btc_profile_cb_set(BTC_PID_DFU_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
}
#endif /* CONFIG_BLE_MESH_DFU_CLI */
#if CONFIG_BLE_MESH_DFU_SRV
void esp_ble_mesh_dfu_srv_verified(esp_ble_mesh_dfu_srv_t *srv)
{
if (!srv) {
return;
}
btc_ble_mesh_dfu_srv_verified(srv);
}
void esp_ble_mesh_dfu_srv_rejected(esp_ble_mesh_dfu_srv_t *srv)
{
if (!srv) {
return;
}
btc_ble_mesh_dfu_srv_rejected(srv);
}
void esp_ble_mesh_dfu_srv_cancel(esp_ble_mesh_dfu_srv_t *srv)
{
if (!srv) {
return;
}
btc_ble_mesh_dfu_srv_cancel(srv);
}
void esp_ble_mesh_dfu_srv_applied(esp_ble_mesh_dfu_srv_t *srv)
{
if (!srv) {
return;
}
btc_ble_mesh_dfu_srv_applied(srv);
}
bool esp_ble_mesh_dfu_srv_is_busy(const esp_ble_mesh_dfu_srv_t *srv)
{
if (!srv) {
return false;
}
return btc_ble_mesh_dfu_srv_is_busy(srv);
}
uint8_t esp_ble_mesh_dfu_srv_progress(const esp_ble_mesh_dfu_srv_t *srv)
{
if (!srv) {
return 0;
}
return btc_ble_mesh_dfu_srv_progress(srv);
}
#endif /* CONFIG_BLE_MESH_DFU_SRV */
#if CONFIG_BLE_MESH_DFD_CLI
esp_err_t esp_ble_mesh_register_dfd_cli_callback(esp_ble_mesh_dfd_client_cb_t callback)
{
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_DFD_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
}
static bool dfd_client_opcode_need_param(esp_ble_mesh_opcode_t opcode)
{
switch (opcode)
{
/* Get opcode */
case ESP_BLE_MESH_DFD_OP_RECEIVERS_GET:
case ESP_BLE_MESH_DFD_OP_FW_GET:
case ESP_BLE_MESH_DFD_OP_FW_GET_BY_INDEX:
/* Set opcode */
case ESP_BLE_MESH_DFD_OP_RECEIVERS_ADD:
case ESP_BLE_MESH_DFD_OP_START:
case ESP_BLE_MESH_DFD_OP_UPLOAD_START:
case ESP_BLE_MESH_DFD_OP_UPLOAD_START_OOB:
case ESP_BLE_MESH_DFD_OP_FW_DELETE:
return true;
default:
return false;
}
}
esp_err_t esp_ble_mesh_dfd_cli_get(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_dfd_client_get_param_t *get_param)
{
btc_ble_mesh_dfd_client_args_t arg = {0};
btc_msg_t msg = {0};
if (params == NULL || params->model == NULL ||
params->ctx.net_idx == ESP_BLE_MESH_KEY_UNUSED ||
!ESP_BLE_MESH_ADDR_IS_UNICAST(params->ctx.addr) ||
(dfd_client_opcode_need_param(params->opcode) && get_param == NULL)) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_DFD_CLIENT;
msg.act = ESP_BLE_MESH_ACT_DFD_CLIENT_GET;
arg.dfd_client_get.params = params;
arg.dfd_client_get.get = get_param;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_dfd_client_args_t), btc_ble_mesh_dfd_client_arg_deep_copy,
btc_ble_mesh_dfd_client_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_dfd_cli_set(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_dfd_client_set_param_t *set_param)
{
btc_ble_mesh_dfd_client_args_t arg = {0};
btc_msg_t msg = {0};
if (params == NULL || params->model == NULL ||
params->ctx.net_idx == ESP_BLE_MESH_KEY_UNUSED ||
!ESP_BLE_MESH_ADDR_IS_UNICAST(params->ctx.addr) ||
(dfd_client_opcode_need_param(params->opcode) && set_param == NULL)) {
return ESP_ERR_INVALID_ARG;
}
switch (params->opcode) {
case ESP_BLE_MESH_DFD_OP_RECEIVERS_ADD:
if (set_param->receivers_add.receivers_cnt == 0) {
return ESP_ERR_INVALID_ARG;
}
break;
case ESP_BLE_MESH_DFD_OP_UPLOAD_START:
if (set_param->dist_upload_start.fw_size == 0) {
return ESP_ERR_INVALID_ARG;
}
if (set_param->dist_upload_start.fwid == NULL) {
return ESP_ERR_INVALID_ARG;
}
break;
case ESP_BLE_MESH_DFD_OP_UPLOAD_START_OOB:
if (set_param->dist_upload_oob_start.url == NULL) {
return ESP_ERR_INVALID_ARG;
}
break;
}
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_DFD_CLIENT;
msg.act = ESP_BLE_MESH_ACT_DFD_CLIENT_SET;
arg.dfd_client_set.params = params;
arg.dfd_client_set.set = set_param;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_dfd_client_args_t), btc_ble_mesh_dfd_client_arg_deep_copy,
btc_ble_mesh_dfd_client_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#endif /* CONFIG_BLE_MESH_DFD_CLI */
@@ -0,0 +1,102 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "esp_ble_mesh_dfu_slot_api.h"
#include "btc_ble_mesh_dfu_slot.h"
int esp_ble_mesh_dfu_slot_count(void)
{
return btc_ble_mesh_dfu_slot_count();
}
esp_ble_mesh_dfu_slot_t *esp_ble_mesh_dfu_slot_reserve(void)
{
return btc_ble_mesh_dfu_slot_reserve();
}
int esp_ble_mesh_dfu_slot_info_set(esp_ble_mesh_dfu_slot_t *dfu_slot, size_t size,
const uint8_t *metadata, size_t metadata_len)
{
if (!dfu_slot || !metadata ||
metadata_len == 0 ||
metadata_len > CONFIG_BLE_MESH_DFU_METADATA_MAXLEN) {
return ESP_ERR_INVALID_ARG;
}
return btc_ble_mesh_dfu_slot_info_set(dfu_slot, size,
metadata, metadata_len);
}
int esp_ble_mesh_dfu_slot_fwid_set(esp_ble_mesh_dfu_slot_t *dfu_slot,
const uint8_t *fwid, size_t fwid_len)
{
if (!dfu_slot || !fwid || fwid_len == 0 ||
fwid_len > CONFIG_BLE_MESH_DFU_FWID_MAXLEN) {
return ESP_ERR_INVALID_ARG;
}
return btc_ble_mesh_dfu_slot_fwid_set(dfu_slot, fwid,
fwid_len);
}
int esp_ble_mesh_dfu_slot_commit(esp_ble_mesh_dfu_slot_t *dfu_slot)
{
if (!dfu_slot) {
return ESP_ERR_INVALID_ARG;
}
return btc_ble_mesh_dfu_slot_commit(dfu_slot);
}
void esp_ble_mesh_dfu_slot_release(const esp_ble_mesh_dfu_slot_t *dfu_slot)
{
if (!dfu_slot) {
return;
}
btc_ble_mesh_dfu_slot_release(dfu_slot);
}
int esp_ble_mesh_dfu_slot_del(const esp_ble_mesh_dfu_slot_t *slot)
{
if (!slot) {
return ESP_ERR_INVALID_ARG;
}
return btc_ble_mesh_dfu_slot_del(slot);
}
void esp_ble_mesh_dfu_slot_del_all(void)
{
btc_ble_mesh_dfu_slot_del_all();
}
const esp_ble_mesh_dfu_slot_t *esp_ble_mesh_dfu_slot_at(uint16_t img_idx)
{
return btc_ble_mesh_dfu_slot_at(img_idx);
}
int esp_ble_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, esp_ble_mesh_dfu_slot_t **slot)
{
if (!fwid || fwid_len == 0 ||
fwid_len > CONFIG_BLE_MESH_DFU_FWID_MAXLEN ||
!slot || !*slot) {
return ESP_ERR_INVALID_ARG;
}
return btc_ble_mesh_dfu_slot_get(fwid, fwid_len, slot);
}
int esp_ble_mesh_dfu_slot_img_idx_get(const esp_ble_mesh_dfu_slot_t *slot)
{
if (!slot) {
return ESP_ERR_INVALID_ARG;
}
return btc_ble_mesh_dfu_slot_img_idx_get(slot);
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -20,20 +20,20 @@ extern int bt_mesh_get_transfer_progress(void *model, uint16_t unicast_addr,
uint8_t *block_percent, uint8_t *chunk_percent);
extern int bt_mesh_get_blob_reception_progress(void *model, uint8_t *reception_progress);
esp_err_t esp_ble_mesh_register_mbt_client_callback(esp_ble_mesh_mbt_client_cb_t callback)
esp_err_t esp_ble_mesh_register_mbt_client_callback(esp_ble_mesh_mbt_client_cb_t callback) __attribute__((deprecated))
{
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_MBT_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_mbt_client_retrieve_capabilities(esp_ble_mesh_retrieve_capabilities_t *input)
esp_err_t esp_ble_mesh_mbt_client_retrieve_capabilities(esp_ble_mesh_retrieve_capabilities_t *input) __attribute__((deprecated))
{
btc_ble_mesh_mbt_client_args_t arg = {0};
btc_msg_t msg = {0};
if (input == NULL || input->model == NULL ||
(input->unicast_addr_count && input->unicast_addr == NULL)) {
(input->unicast_addr_count && input->unicast_addr == NULL)) {
return ESP_ERR_INVALID_ARG;
}
@@ -51,14 +51,14 @@ esp_err_t esp_ble_mesh_mbt_client_retrieve_capabilities(esp_ble_mesh_retrieve_ca
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_mbt_client_transfer_blob(esp_ble_mesh_transfer_blob_t *input)
esp_err_t esp_ble_mesh_mbt_client_transfer_blob(esp_ble_mesh_transfer_blob_t *input) __attribute__((deprecated))
{
btc_ble_mesh_mbt_client_args_t arg = {0};
btc_msg_t msg = {0};
if (input == NULL || input->model == NULL ||
(input->unicast_addr_count && input->unicast_addr == NULL) ||
input->blob_data == NULL) {
(input->unicast_addr_count && input->unicast_addr == NULL) ||
input->blob_data == NULL) {
return ESP_ERR_INVALID_ARG;
}
@@ -76,7 +76,7 @@ esp_err_t esp_ble_mesh_mbt_client_transfer_blob(esp_ble_mesh_transfer_blob_t *in
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_mbt_client_send_block(esp_ble_mesh_send_block_t *input)
esp_err_t esp_ble_mesh_mbt_client_send_block(esp_ble_mesh_send_block_t *input) __attribute__((deprecated))
{
btc_ble_mesh_mbt_client_args_t arg = {0};
btc_msg_t msg = {0};
@@ -97,7 +97,7 @@ esp_err_t esp_ble_mesh_mbt_client_send_block(esp_ble_mesh_send_block_t *input)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_mbt_client_send_data(esp_ble_mesh_send_data_t *input)
esp_err_t esp_ble_mesh_mbt_client_send_data(esp_ble_mesh_send_data_t *input) __attribute__((deprecated))
{
btc_ble_mesh_mbt_client_args_t arg = {0};
btc_msg_t msg = {0};
@@ -118,7 +118,7 @@ esp_err_t esp_ble_mesh_mbt_client_send_data(esp_ble_mesh_send_data_t *input)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_mbt_client_determine_block_status(esp_ble_mesh_determine_block_status_t *input)
esp_err_t esp_ble_mesh_mbt_client_determine_block_status(esp_ble_mesh_determine_block_status_t *input) __attribute__((deprecated))
{
btc_ble_mesh_mbt_client_args_t arg = {0};
btc_msg_t msg = {0};
@@ -139,13 +139,13 @@ esp_err_t esp_ble_mesh_mbt_client_determine_block_status(esp_ble_mesh_determine_
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_mbt_client_determine_transfer_status(esp_ble_mesh_determine_transfer_status_t *input)
esp_err_t esp_ble_mesh_mbt_client_determine_transfer_status(esp_ble_mesh_determine_transfer_status_t *input) __attribute__((deprecated))
{
btc_ble_mesh_mbt_client_args_t arg = {0};
btc_msg_t msg = {0};
if (input == NULL || input->model == NULL ||
(input->unicast_addr_count && input->unicast_addr == NULL)) {
(input->unicast_addr_count && input->unicast_addr == NULL)) {
return ESP_ERR_INVALID_ARG;
}
@@ -163,13 +163,13 @@ esp_err_t esp_ble_mesh_mbt_client_determine_transfer_status(esp_ble_mesh_determi
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_mbt_client_cancel_transfer(esp_ble_mesh_cancel_transfer_t *input)
esp_err_t esp_ble_mesh_mbt_client_cancel_transfer(esp_ble_mesh_cancel_transfer_t *input) __attribute__((deprecated))
{
btc_ble_mesh_mbt_client_args_t arg = {0};
btc_msg_t msg = {0};
if (input == NULL || input->model == NULL ||
(input->unicast_addr_count && input->unicast_addr == NULL)) {
(input->unicast_addr_count && input->unicast_addr == NULL)) {
return ESP_ERR_INVALID_ARG;
}
@@ -188,13 +188,13 @@ esp_err_t esp_ble_mesh_mbt_client_cancel_transfer(esp_ble_mesh_cancel_transfer_t
}
const esp_ble_mesh_blob_receiver_t *esp_ble_mesh_mbt_client_get_blob_receiver(esp_ble_mesh_model_t *model,
uint16_t unicast_addr)
uint16_t unicast_addr) __attribute__((deprecated))
{
return (const esp_ble_mesh_blob_receiver_t *)bt_mesh_get_blob_receiver((struct bt_mesh_model *)model,
unicast_addr);
}
const esp_ble_mesh_blob_receiver_t **esp_ble_mesh_mbt_client_get_active_blob_receiver(esp_ble_mesh_model_t *model)
const esp_ble_mesh_blob_receiver_t **esp_ble_mesh_mbt_client_get_active_blob_receiver(esp_ble_mesh_model_t *model) __attribute__((deprecated))
{
return (const esp_ble_mesh_blob_receiver_t **)bt_mesh_get_active_blob_receiver((struct bt_mesh_model *)model);
}
@@ -202,14 +202,14 @@ const esp_ble_mesh_blob_receiver_t **esp_ble_mesh_mbt_client_get_active_blob_rec
esp_err_t esp_ble_mesh_mbt_client_get_transfer_progress(esp_ble_mesh_model_t *model,
uint16_t unicast_addr,
uint8_t *block_percent,
uint8_t *chunk_percent)
uint8_t *chunk_percent) __attribute__((deprecated))
{
return (bt_mesh_get_transfer_progress((struct bt_mesh_model *)model, unicast_addr,
block_percent, chunk_percent) == 0 ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_mbt_client_set_transfer_ttl(esp_ble_mesh_model_t *model,
uint8_t transfer_ttl)
uint8_t transfer_ttl) __attribute__((deprecated))
{
btc_ble_mesh_mbt_client_args_t arg = {0};
btc_msg_t msg = {0};
@@ -231,7 +231,7 @@ esp_err_t esp_ble_mesh_mbt_client_set_transfer_ttl(esp_ble_mesh_model_t *model,
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_mbt_client_clear_transfer_ttl(esp_ble_mesh_model_t *model)
esp_err_t esp_ble_mesh_mbt_client_clear_transfer_ttl(esp_ble_mesh_model_t *model) __attribute__((deprecated))
{
btc_ble_mesh_mbt_client_args_t arg = {0};
btc_msg_t msg = {0};
@@ -253,7 +253,7 @@ esp_err_t esp_ble_mesh_mbt_client_clear_transfer_ttl(esp_ble_mesh_model_t *model
}
esp_err_t esp_ble_mesh_mbt_client_set_app_idx(esp_ble_mesh_model_t *model,
uint16_t app_idx)
uint16_t app_idx) __attribute__((deprecated))
{
btc_ble_mesh_mbt_client_args_t arg = {0};
btc_msg_t msg = {0};
@@ -275,7 +275,7 @@ esp_err_t esp_ble_mesh_mbt_client_set_app_idx(esp_ble_mesh_model_t *model,
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_mbt_client_clear_app_idx(esp_ble_mesh_model_t *model)
esp_err_t esp_ble_mesh_mbt_client_clear_app_idx(esp_ble_mesh_model_t *model) __attribute__((deprecated))
{
btc_ble_mesh_mbt_client_args_t arg = {0};
btc_msg_t msg = {0};
@@ -297,7 +297,7 @@ esp_err_t esp_ble_mesh_mbt_client_clear_app_idx(esp_ble_mesh_model_t *model)
}
esp_err_t esp_ble_mesh_mbt_client_set_multicast_addr(esp_ble_mesh_model_t *model,
uint16_t multicast_addr)
uint16_t multicast_addr) __attribute__((deprecated))
{
btc_ble_mesh_mbt_client_args_t arg = {0};
btc_msg_t msg = {0};
@@ -319,7 +319,7 @@ esp_err_t esp_ble_mesh_mbt_client_set_multicast_addr(esp_ble_mesh_model_t *model
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_mbt_client_clear_multicast_addr(esp_ble_mesh_model_t *model)
esp_err_t esp_ble_mesh_mbt_client_clear_multicast_addr(esp_ble_mesh_model_t *model) __attribute__((deprecated))
{
btc_ble_mesh_mbt_client_args_t arg = {0};
btc_msg_t msg = {0};
@@ -342,14 +342,14 @@ esp_err_t esp_ble_mesh_mbt_client_clear_multicast_addr(esp_ble_mesh_model_t *mod
#endif /* CONFIG_BLE_MESH_MBT_CLI */
#if CONFIG_BLE_MESH_MBT_SRV
esp_err_t esp_ble_mesh_register_mbt_server_callback(esp_ble_mesh_mbt_server_cb_t callback)
esp_err_t esp_ble_mesh_register_mbt_server_callback(esp_ble_mesh_mbt_server_cb_t callback) __attribute__((deprecated))
{
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_MBT_SERVER, callback) == 0 ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_mbt_server_initialize_blob_receive(esp_ble_mesh_initialize_blob_receive_t *input)
esp_err_t esp_ble_mesh_mbt_server_initialize_blob_receive(esp_ble_mesh_initialize_blob_receive_t *input) __attribute__((deprecated))
{
btc_ble_mesh_mbt_server_args_t arg = {0};
btc_msg_t msg = {0};
@@ -370,7 +370,7 @@ esp_err_t esp_ble_mesh_mbt_server_initialize_blob_receive(esp_ble_mesh_initializ
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_mbt_server_cancel_blob_receive(esp_ble_mesh_cancel_blob_receive_t *input)
esp_err_t esp_ble_mesh_mbt_server_cancel_blob_receive(esp_ble_mesh_cancel_blob_receive_t *input) __attribute__((deprecated))
{
btc_ble_mesh_mbt_server_args_t arg = {0};
btc_msg_t msg = {0};
@@ -391,7 +391,7 @@ esp_err_t esp_ble_mesh_mbt_server_cancel_blob_receive(esp_ble_mesh_cancel_blob_r
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_mbt_server_set_blob_capabilities(esp_ble_mesh_set_blob_capabilities_t *input)
esp_err_t esp_ble_mesh_mbt_server_set_blob_capabilities(esp_ble_mesh_set_blob_capabilities_t *input) __attribute__((deprecated))
{
btc_ble_mesh_mbt_server_args_t arg = {0};
btc_msg_t msg = {0};
@@ -413,7 +413,7 @@ esp_err_t esp_ble_mesh_mbt_server_set_blob_capabilities(esp_ble_mesh_set_blob_ca
}
esp_err_t esp_ble_mesh_mbt_server_get_blob_reception_progress(esp_ble_mesh_model_t *model,
uint8_t *reception_progress)
uint8_t *reception_progress) __attribute__((deprecated))
{
return (bt_mesh_get_blob_reception_progress((struct bt_mesh_model *)model,
reception_progress) == 0 ? ESP_OK : ESP_FAIL);
@@ -0,0 +1,696 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP_BLE_MESH_BLOB_MODEL_API_H_
#define _ESP_BLE_MESH_BLOB_MODEL_API_H_
#include "esp_ble_mesh_defs.h"
#include "esp_ble_mesh_blob_model_api.h"
#if CONFIG_BLE_MESH_BLOB_CLI || CONFIG_BLE_MESH_BLOB_SRV
#ifndef _BLE_MESH_BLOB_DEPRECATE_WARN
#define _BLE_MESH_BLOB_DEPRECATE_WARN
#warning Please note: All APIs published in this document are in Preview version and may undergo significant changes in the future.
#endif
#endif /* CONFIG_BLE_MESH_BLOB_CLI || CONFIG_BLE_MESH_BLOB_SRV */
#ifdef __cplusplus
extern "C" {
#endif
#define ESP_BLE_MESH_BLOB_ID_SIZE 8
/** @def ESP_BLE_MESH_MODEL_BLOB_CLI
*
* @brief Define a new BLOB Transfer Client model.
*
* @note This API needs to be called for each element on which
* the application needs to have a BLOB Transfer Client model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New BLOB Transfer Client model instance.
*/
#define ESP_BLE_MESH_MODEL_BLOB_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_BLOB_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_BLOB_SRV
*
* @brief Define a new BLOB Transfer Server model.
*
* @note This API needs to be called for each element on which
* the application needs to have a BLOB Transfer Server model.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_blob_trans_srv_t.
*
* @return New BLOB Transfer Server model instance.
*/
#define ESP_BLE_MESH_MODEL_BLOB_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_BLOB_SRV, \
NULL, srv_pub, srv_data)
/** BLOB stream. */
typedef struct esp_ble_mesh_blob_io esp_ble_mesh_blob_io_t;
/** @brief BLOB Transfer Server instance. */
typedef struct esp_ble_mesh_blob_srv esp_ble_mesh_blob_srv_t;
/** @brief BLOB Transfer Server model event handlers. */
typedef struct esp_ble_mesh_blob_srv_cb esp_ble_mesh_blob_srv_cb_t;
/** Target node's Pull mode (Pull BLOB Transfer Mode) context used
* while sending chunks to the Target node.
*/
typedef struct esp_ble_mesh_blob_target_pull esp_ble_mesh_blob_target_pull_t;
/** BLOB Transfer Client Target node. */
typedef struct esp_ble_mesh_blob_target esp_ble_mesh_blob_target_t;
/** BLOB transfer information. */
typedef struct esp_ble_mesh_blob_xfer_info esp_ble_mesh_blob_xfer_info_t;
/** BLOB Transfer Client transfer inputs. */
typedef struct esp_ble_mesh_blob_cli_inputs esp_ble_mesh_blob_cli_inputs_t;
/** Transfer capabilities of a Target node. */
typedef struct esp_ble_mesh_blob_cli_caps esp_ble_mesh_blob_cli_caps_t;
/**
* @brief BLOB Transfer Client model instance.
* @note Preview version, the contents of this struct may change in the future.
*/
typedef struct esp_ble_mesh_blob_cli esp_ble_mesh_blob_cli_t;
/** Event handler callbacks for the BLOB Transfer Client model. */
typedef struct esp_ble_mesh_blob_cli_cb esp_ble_mesh_blob_cli_cb_t;
/** BLOB transfer. */
typedef struct esp_ble_mesh_blob_xfer esp_ble_mesh_blob_xfer_t;
/** BLOB transfer data block. */
typedef struct esp_ble_mesh_blob_block esp_ble_mesh_blob_block_t;
/** BLOB data chunk. */
typedef struct esp_ble_mesh_blob_chunk esp_ble_mesh_blob_chunk_t;
/** Transfer phase. */
typedef enum esp_ble_mesh_blob_xfer_phase {
ESP_BLE_MESH_BLOB_XFER_PHASE_INACTIVE, /*!< The BLOB Transfer Server is awaiting configuration. */
ESP_BLE_MESH_BLOB_XFER_PHASE_WAITING_FOR_START, /*!< The BLOB Transfer Server is ready to receive a BLOB transfer. */
ESP_BLE_MESH_BLOB_XFER_PHASE_WAITING_FOR_BLOCK, /*!< The BLOB Transfer Server is waiting for the next block of data. */
ESP_BLE_MESH_BLOB_XFER_PHASE_WAITING_FOR_CHUNK, /*!< The BLOB Transfer Server is waiting for the next chunk of data. */
ESP_BLE_MESH_BLOB_XFER_PHASE_COMPLETE, /*!< The BLOB was transferred successfully. */
ESP_BLE_MESH_BLOB_XFER_PHASE_SUSPENDED, /*!< The BLOB transfer is paused. */
} esp_ble_mesh_blob_xfer_phase_t;
/** BLOB transfer mode. */
typedef enum esp_ble_mesh_blob_xfer_mode {
ESP_BLE_MESH_BLOB_XFER_MODE_NONE, /*!< No valid transfer mode. */
ESP_BLE_MESH_BLOB_XFER_MODE_PUSH, /*!< Push mode (Push BLOB Transfer Mode). */
ESP_BLE_MESH_BLOB_XFER_MODE_PULL, /*!< Pull mode (Pull BLOB Transfer Mode). */
ESP_BLE_MESH_BLOB_XFER_MODE_ALL, /*!< Both modes are valid. */
} esp_ble_mesh_blob_xfer_mode_t;
/** BLOB model status codes. */
typedef enum esp_ble_mesh_blob_status {
/** The message was processed successfully. */
ESP_BLE_MESH_BLOB_SUCCESS,
/** The Block Number field value is not within the range of blocks being
* transferred.
*/
ESP_BLE_MESH_BLOB_ERR_INVALID_BLOCK_NUM,
/** The block size is smaller than the size indicated by the Min Block
* Size Log state or is larger than the size indicated by the Max Block
* Size Log state.
*/
ESP_BLE_MESH_BLOB_ERR_INVALID_BLOCK_SIZE,
/** The chunk size exceeds the size indicated by the Max Chunk Size
* state, or the number of chunks exceeds the number specified by the
* Max Total Chunks state.
*/
ESP_BLE_MESH_BLOB_ERR_INVALID_CHUNK_SIZE,
/** The operation cannot be performed while the server is in the current
* phase.
*/
ESP_BLE_MESH_BLOB_ERR_WRONG_PHASE,
/** A parameter value in the message cannot be accepted. */
ESP_BLE_MESH_BLOB_ERR_INVALID_PARAM,
/** The message contains a BLOB ID value that is not expected. */
ESP_BLE_MESH_BLOB_ERR_WRONG_BLOB_ID,
/** There is not enough space available in memory to receive the BLOB.
*/
ESP_BLE_MESH_BLOB_ERR_BLOB_TOO_LARGE,
/** The transfer mode is not supported by the BLOB Transfer Server
* model.
*/
ESP_BLE_MESH_BLOB_ERR_UNSUPPORTED_MODE,
/** An internal error occurred on the node. */
ESP_BLE_MESH_BLOB_ERR_INTERNAL,
/** The requested information cannot be provided while the server is in
* the current phase.
*/
ESP_BLE_MESH_BLOB_ERR_INFO_UNAVAILABLE,
} esp_ble_mesh_blob_status_t;
/** BLOB Transfer Client state. */
typedef enum esp_ble_mesh_blob_cli_state {
ESP_BLE_MESH_BLOB_CLI_STATE_NONE, /*!< No transfer is active. */
ESP_BLE_MESH_BLOB_CLI_STATE_CAPS_GET, /*!< Retrieving transfer capabilities. */
ESP_BLE_MESH_BLOB_CLI_STATE_START, /*!< Sending transfer start. */
ESP_BLE_MESH_BLOB_CLI_STATE_BLOCK_START, /*!< Sending block start. */
ESP_BLE_MESH_BLOB_CLI_STATE_BLOCK_SEND, /*!< Sending block chunks. */
ESP_BLE_MESH_BLOB_CLI_STATE_BLOCK_CHECK, /*!< Checking block status. */
ESP_BLE_MESH_BLOB_CLI_STATE_XFER_CHECK, /*!< Checking transfer status. */
ESP_BLE_MESH_BLOB_CLI_STATE_CANCEL, /*!< Cancelling transfer. */
ESP_BLE_MESH_BLOB_CLI_STATE_SUSPENDED, /*!< Transfer is suspended. */
ESP_BLE_MESH_BLOB_CLI_STATE_XFER_PROGRESS_GET, /*!< Checking transfer progress. */
} esp_ble_mesh_blob_cli_state_t;
/** BLOB stream interaction mode. */
typedef enum esp_ble_mesh_blob_io_mode {
ESP_BLE_MESH_BLOB_READ, /*!< Read data from the stream. */
ESP_BLE_MESH_BLOB_WRITE, /*!< Write data to the stream. */
} esp_ble_mesh_blob_io_mode_t;
/** BLOB transfer. */
struct esp_ble_mesh_blob_xfer {
uint64_t id; /*!< BLOB ID. */
size_t size; /*!< Total BLOB size in bytes. */
esp_ble_mesh_blob_xfer_mode_t mode; /*!< BLOB transfer mode. */
uint8_t block_size_log; /*!< Logarithmic representation of the block size. */
uint16_t chunk_size; /*!< Base chunk size. May be smaller for the last chunk. */
};
/** BLOB transfer data block. */
struct esp_ble_mesh_blob_block {
size_t size; /*!< Block size in bytes */
off_t offset; /*!< Offset in bytes from the start of the BLOB. */
uint16_t number; /*!< Block number */
uint16_t chunk_count; /*!< Number of chunks in block. */
uint8_t missing[DIV_ROUND_UP(CONFIG_BLE_MESH_BLOB_CHUNK_COUNT_MAX,
8)]; /*!< Bitmap of missing chunks. */
};
/** BLOB data chunk. */
struct esp_ble_mesh_blob_chunk {
off_t offset; /*!< Offset of the chunk data from the start of the block. */
size_t size; /*!< Chunk data size. */
uint8_t *data; /*!< Chunk data. */
};
/** BLOB stream. */
struct esp_ble_mesh_blob_io {
/** @brief Open callback.
*
* Called when the reader is opened for reading.
*
* @param io BLOB stream.
* @param xfer BLOB transfer.
* @param mode Direction of the stream (read/write).
*
* @return 0 on success, or (negative) error code otherwise.
*/
int (*open)(const esp_ble_mesh_blob_io_t *io,
const esp_ble_mesh_blob_xfer_t *xfer,
esp_ble_mesh_blob_io_mode_t mode);
/** @brief Close callback.
*
* Called when the reader is closed.
*
* @param io BLOB stream.
* @param xfer BLOB transfer.
*/
void (*close)(const esp_ble_mesh_blob_io_t *io,
const esp_ble_mesh_blob_xfer_t *xfer);
/** @brief Block start callback.
*
* Called when a new block is opened for sending. Each block is only
* sent once, and are always sent in increasing order. The data chunks
* inside a single block may be requested out of order and multiple
* times.
*
* @param io BLOB stream.
* @param xfer BLOB transfer.
* @param block Block that was started.
*/
int (*block_start)(const esp_ble_mesh_blob_io_t *io,
const esp_ble_mesh_blob_xfer_t *xfer,
const esp_ble_mesh_blob_block_t *block);
/** @brief Block end callback.
*
* Called when the current block has been transmitted in full.
* No data from this block will be requested again, and the application
* data associated with this block may be discarded.
*
* @param io BLOB stream.
* @param xfer BLOB transfer.
* @param block Block that finished sending.
*/
void (*block_end)(const esp_ble_mesh_blob_io_t *io,
const esp_ble_mesh_blob_xfer_t *xfer,
const esp_ble_mesh_blob_block_t *block);
/** @brief Chunk data write callback.
*
* Used by the BLOB Transfer Server on incoming data.
*
* Each block is divided into chunks of data. This callback is called
* when a new chunk of data is received. Chunks may be received in
* any order within their block.
*
* If the callback returns successfully, this chunk will be marked as
* received, and will not be received again unless the block is
* restarted due to a transfer suspension. If the callback returns a
* non-zero value, the chunk remains unreceived, and the BLOB Transfer
* Client will attempt to resend it later.
*
* Note that the Client will only perform a limited number of attempts
* at delivering a chunk before dropping a Target node from the transfer.
* The number of retries performed by the Client is implementation
* specific.
*
* @param io BLOB stream.
* @param xfer BLOB transfer.
* @param block Block the chunk is part of.
* @param chunk Received chunk.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int (*write)(const esp_ble_mesh_blob_io_t *io,
const esp_ble_mesh_blob_xfer_t *xfer,
const esp_ble_mesh_blob_block_t *block,
const esp_ble_mesh_blob_chunk_t *chunk);
/** @brief Chunk data read callback.
*
* Used by the BLOB Transfer Client to fetch outgoing data.
*
* The Client calls the chunk data request callback to populate a chunk
* message going out to the Target nodes. The data request callback
* may be called out of order and multiple times for each offset, and
* cannot be used as an indication of progress.
*
* Returning a non-zero status code on the chunk data request callback
* results in termination of the transfer.
*
* @param io BLOB stream.
* @param xfer BLOB transfer.
* @param block Block the chunk is part of.
* @param chunk Chunk to get the data of. The buffer pointer to by the
* @c data member should be filled by the callback.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int (*read)(const esp_ble_mesh_blob_io_t *io,
const esp_ble_mesh_blob_xfer_t *xfer,
const esp_ble_mesh_blob_block_t *block,
const esp_ble_mesh_blob_chunk_t *chunk);
};
/** @brief BLOB Transfer Server model event handlers.
*
* All callbacks are optional.
*/
struct esp_ble_mesh_blob_srv_cb {
/** @brief Transfer start callback.
*
* Called when the transfer has started with the prepared BLOB ID.
*
* @param srv BLOB Transfer Server instance.
* @param ctx Message context for the incoming start message. The
* entire transfer will be sent from the same source
* address.
* @param xfer Transfer parameters.
*
* @return 0 on success, or (negative) error code to reject the
* transfer.
*/
int (*start)(esp_ble_mesh_blob_srv_t *srv, esp_ble_mesh_msg_ctx_t *ctx,
esp_ble_mesh_blob_xfer_t *xfer);
/** @brief Transfer end callback.
*
* Called when the transfer ends, either because it was cancelled, or
* because it finished successfully. A new transfer may be prepared.
*
* @note The transfer may end before it's started if the start
* parameters are invalid.
*
* @param srv BLOB Transfer Server instance.
* @param id BLOB ID of the cancelled transfer.
* @param success Whether the transfer was successful.
*/
void (*end)(esp_ble_mesh_blob_srv_t *srv, uint64_t id, bool success);
/** @brief Transfer suspended callback.
*
* Called if the Server timed out while waiting for a transfer packet.
* A suspended transfer may resume later from the start of the current
* block. Any received chunks in the current block should be discarded,
* they will be received again if the transfer resumes.
*
* The transfer will call @c resumed again when resuming.
*
* @note The BLOB Transfer Server does not run a timer in the suspended state,
* and it's up to the application to determine whether the
* transfer should be permanently cancelled. Without interaction,
* the transfer will be suspended indefinitely, and the BLOB Transfer
* Server will not accept any new transfers.
*
* @param srv BLOB Transfer Server instance.
*/
void (*suspend)(esp_ble_mesh_blob_srv_t *srv);
/** @brief Transfer resume callback.
*
* Called if the transfer is resumed after being suspended.
*
* @param srv BLOB Transfer Server instance.
*/
void (*resume)(esp_ble_mesh_blob_srv_t *srv);
/** @brief Transfer recovery callback.
*
* Called when the Bluetooth mesh subsystem is started if the device is rebooted
* in the middle of a transfer.
*
* Transfers will not be resumed after a reboot if this callback is not
* defined.
*
* @param srv BLOB Transfer Server instance.
* @param xfer Transfer to resume.
* @param io BLOB stream return parameter. Must be set to a valid
* BLOB stream by the callback.
*
* @return 0 on success, or (negative) error code to abandon the
* transfer.
*/
int (*recover)(esp_ble_mesh_blob_srv_t *srv,
esp_ble_mesh_blob_xfer_t *xfer,
esp_ble_mesh_blob_io_t **io);
};
#if defined(CONFIG_BLE_MESH_BLOB_SRV)
#define ESP_BLE_MESH_BLOB_BLOCKS_MAX \
(DIV_ROUND_UP(CONFIG_BLE_MESH_BLOB_SIZE_MAX, \
CONFIG_BLE_MESH_BLOB_BLOCK_SIZE_MIN))
#else
#define ESP_BLE_MESH_BLOB_BLOCKS_MAX 1
#endif
/** @brief BLOB Transfer Server instance. */
struct esp_ble_mesh_blob_srv {
/** Event handler callbacks. */
esp_ble_mesh_blob_srv_cb_t *cb;
/** Runtime state: */
esp_ble_mesh_blob_io_t *io;
struct k_delayed_work rx_timeout;
esp_ble_mesh_blob_block_t block;
esp_ble_mesh_model_t *mod;
esp_ble_mesh_blob_xfer_phase_t phase;
/** State of blob serber. */
struct esp_ble_mesh_blob_srv_state {
esp_ble_mesh_blob_xfer_t xfer;
uint16_t cli;
uint16_t app_idx;
uint16_t timeout_base;
uint16_t mtu_size;
uint8_t ttl;
/* Bitfield of pending blocks. */
BLE_MESH_ATOMIC_DEFINE(blocks, ESP_BLE_MESH_BLOB_BLOCKS_MAX);
} state;
/* Pull mode (Pull BLOB Transfer Mode) behavior. */
struct {
uint16_t chunk_idx;
struct k_delayed_work report;
} pull;
};
/** Target node's Pull mode (Pull BLOB Transfer Mode) context used
* while sending chunks to the Target node.
*/
struct esp_ble_mesh_blob_target_pull {
int64_t block_report_timestamp; /*!< Timestamp when the Block Report Timeout Timer expires for this Target node. */
uint8_t missing[DIV_ROUND_UP(CONFIG_BLE_MESH_BLOB_CHUNK_COUNT_MAX, 8)]; /*!< Missing chunks reported by this Target node. */
};
/** BLOB Transfer Client Target node. */
struct esp_ble_mesh_blob_target {
sys_snode_t n; /*!< Linked list node */
uint16_t addr; /*!< Target node address. */
/** Target node's Pull mode context.
* Needs to be initialized when sending a BLOB in Pull mode.
*/
esp_ble_mesh_blob_target_pull_t *pull;
uint8_t status; /*!< BLOB transfer status, see esp_ble_mesh_blob_status. */
uint8_t procedure_complete: 1, /*!< Procedure has been completed. */
acked: 1, /*!< Message has been acknowledged. Not used when sending. */
timedout: 1, /*!< Target node didn't respond after specified timeout. */
skip: 1; /*!< Skip Target node from broadcast. */
};
/** BLOB transfer information. */
struct esp_ble_mesh_blob_xfer_info {
esp_ble_mesh_blob_status_t status; /*!< BLOB transfer status. */
esp_ble_mesh_blob_xfer_mode_t mode; /*!< BLOB transfer mode. */
esp_ble_mesh_blob_xfer_phase_t phase; /*!< BLOB transfer phase. */
uint64_t id; /*!< BLOB ID. */
uint32_t size; /*!< BLOB size in octets. */
uint8_t block_size_log; /*!< Logarithmic representation of the block size. */
uint16_t mtu_size; /*!< MTU size in octets. */
const uint8_t *missing_blocks; /*!< Bit field indicating blocks that were not received. */
};
/** BLOB Transfer Client transfer inputs. */
struct esp_ble_mesh_blob_cli_inputs {
/** Linked list of Target nodes. Each node should point to
* esp_ble_mesh_blob_target_t::n.
*/
sys_slist_t targets;
/** AppKey index to send with. */
uint16_t app_idx;
/** Group address destination for the BLOB transfer, or
* ESP_BLE_MESH_ADDR_UNASSIGNED to send every message to each Target
* node individually.
*/
uint16_t group;
/** Time to live value of BLOB transfer messages. */
uint8_t ttl;
/** Additional response time for the Target nodes, in 10-second increments.
*
* The extra time can be used to give the Target nodes more time to respond
* to messages from the Client. The actual timeout will be calculated
* according to the following formula:
*
* @verbatim
* timeout = 20 seconds + (10 seconds * timeout_base) + (100 ms * TTL)
* @endverbatim
*
* If a Target node fails to respond to a message from the Client within the
* configured transfer timeout, the Target node is dropped.
*/
uint16_t timeout_base;
};
/** Transfer capabilities of a Target node. */
struct esp_ble_mesh_blob_cli_caps {
size_t max_size; /*!< Max BLOB size. */
uint8_t min_block_size_log; /*!< Logarithmic representation of the minimum block size. */
uint8_t max_block_size_log; /*!< Logarithmic representation of the maximum block size. */
uint16_t max_chunks; /*!< Max number of chunks per block. */
uint16_t max_chunk_size; /*!< Max chunk size. */
uint16_t mtu_size; /*!< Max MTU size. */
esp_ble_mesh_blob_xfer_mode_t modes; /*!< Supported transfer modes. */
};
/** Event handler callbacks for the BLOB Transfer Client model.
*
* All handlers are optional.
*/
struct esp_ble_mesh_blob_cli_cb {
/** @brief Capabilities retrieval completion callback.
*
* Called when the capabilities retrieval procedure completes, indicating that
* a common set of acceptable transfer parameters have been established
* for the given list of Target nodes. All compatible Target nodes have
* status code ESP_BLE_MESH_BLOB_SUCCESS.
*
* @param cli BLOB Transfer Client instance.
* @param caps Safe transfer capabilities if the transfer capabilities
* of at least one Target node has satisfied the Client, or NULL otherwise.
*/
void (*caps)(esp_ble_mesh_blob_cli_t *cli,
const esp_ble_mesh_blob_cli_caps_t *caps);
/** @brief Target node loss callback.
*
* Called whenever a Target node has been lost due to some error in the
* transfer. Losing a Target node is not considered a fatal error for
* the Client until all Target nodes have been lost.
*
* @param cli BLOB Transfer Client instance.
* @param target Target node that was lost.
* @param reason Reason for the Target node loss.
*/
void (*lost_target)(esp_ble_mesh_blob_cli_t *cli,
esp_ble_mesh_blob_target_t *target,
esp_ble_mesh_blob_status_t reason);
/** @brief Transfer is suspended.
*
* Called when the transfer is suspended due to response timeout from all Target nodes.
*
* @param cli BLOB Transfer Client instance.
*/
void (*suspend)(esp_ble_mesh_blob_cli_t *cli);
/** @brief Transfer end callback.
*
* Called when the transfer ends.
*
* @param cli BLOB Transfer Client instance.
* @param xfer Completed transfer.
* @param success Status of the transfer.
* Is @c true if at least one Target
* node received the whole transfer.
*/
void (*end)(esp_ble_mesh_blob_cli_t *cli,
const esp_ble_mesh_blob_xfer_t *xfer, bool success);
/** @brief Transfer progress callback
*
* The content of @c info is invalidated upon exit from the callback.
* Therefore it needs to be copied if it is planned to be used later.
*
* @param cli BLOB Transfer Client instance.
* @param target Target node that responded to the request.
* @param info BLOB transfer information.
*/
void (*xfer_progress)(esp_ble_mesh_blob_cli_t *cli,
esp_ble_mesh_blob_target_t *target,
const esp_ble_mesh_blob_xfer_info_t *info);
/** @brief End of Get Transfer Progress procedure.
*
* Called when all Target nodes have responded or the procedure timed-out.
*
* @param cli BLOB Transfer Client instance.
*/
void (*xfer_progress_complete)(esp_ble_mesh_blob_cli_t *cli);
};
/** @cond INTERNAL_HIDDEN */
typedef struct {
/** Called for every Target node in unicast mode, or once in case of multicast mode. */
void (*send)(esp_ble_mesh_blob_cli_t *cli, uint16_t dst);
/** Called after every @ref blob_cli_broadcast_ctx::send callback. */
void (*send_complete)(esp_ble_mesh_blob_cli_t *cli, uint16_t dst);
/** If @ref blob_cli_broadcast_ctx::acked is true, called after all Target nodes
* have confirmed reception by @ref blob_cli_broadcast_rsp. Otherwise, called
* after transmission has been completed.
*/
void (*next)(esp_ble_mesh_blob_cli_t *cli);
/** If true, every transmission needs to be confirmed by @ref blob_cli_broadcast_rsp before
* @ref blob_cli_broadcast_ctx::next is called.
*/
bool acked;
/** If true, the message is always sent in a unicast way. */
bool force_unicast;
/** If true, non-responsive Target nodes won't be dropped after transfer has timed out. */
bool optional;
/** Set to true by the BLOB Transfer Client between blob_cli_broadcast
* and broadcast_complete calls.
*/
bool is_inited;
/* Defines a time in ms by which the broadcast API postpones sending the message to a next
* target or completing the broadcast.
*/
uint32_t post_send_delay_ms;
} esp_blob_cli_broadcast_ctx_t;
/** INTERNAL_HIDDEN @endcond */
/**
* @brief BLOB Transfer Client model instance.
* @note Preview version, the contents of this struct may change in the future.
*/
struct esp_ble_mesh_blob_cli {
/** Event handler callbacks */
const esp_ble_mesh_blob_cli_cb_t *cb;
/** Runtime state */
const esp_ble_mesh_model_t *mod;
/** Firmware transfer information */
struct {
esp_ble_mesh_blob_target_t *target;
esp_blob_cli_broadcast_ctx_t ctx;
struct k_delayed_work retry;
/* Represents Client Timeout timer in a timestamp. Used in Pull mode only. */
int64_t cli_timestamp;
struct k_work complete;
uint16_t pending;
uint8_t retries;
uint8_t sending : 1,
cancelled : 1;
} tx;
/** Firmware IO operation callbacks */
const esp_ble_mesh_blob_io_t *io;
/** BLOB Transfer Client transfer inputs. */
const esp_ble_mesh_blob_cli_inputs_t *inputs;
/** BLOB transfer. */
const esp_ble_mesh_blob_xfer_t *xfer;
/** Interval between chunk transmissions, in milliseconds. */
uint32_t chunk_interval_ms;
/** BLOCK count */
uint16_t block_count;
/** CHUNK index */
uint16_t chunk_idx;
/** Max Transfer Unit Size of BLOB Transfer */
uint16_t mtu_size;
/** State of blob client mode transfer */
esp_ble_mesh_blob_cli_state_t state;
/** BLOB transfer data block. */
esp_ble_mesh_blob_block_t block;
/** Transfer capabilities of a Target node. */
esp_ble_mesh_blob_cli_caps_t caps;
};
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BLE_MESH_BLOB_MODEL_API_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,148 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP_BLE_MESH_DFU_SLOT_API_H_
#define _ESP_BLE_MESH_DFU_SLOT_API_H_
#include "esp_ble_mesh_dfu_model_api.h"
#if CONFIG_BLE_MESH_DFU_SLOTS
#ifndef _BLE_MESH_BLOB_DEPRECATE_WARN
#define _BLE_MESH_BLOB_DEPRECATE_WARN
#warning Please note: All APIs published in this document are in Preview version and may undergo significant changes in the future.
#endif
#endif /* CONFIG_BLE_MESH_DFU_SLOTS */
typedef struct esp_ble_mesh_dfu_slot esp_ble_mesh_dfu_slot_t;
typedef enum esp_ble_mesh_dfu_iter
(*esp_ble_mesh_dfu_slot_cb_t) (const esp_ble_mesh_dfu_slot_t *slot, void *user_data);
/** @brief Get the number of slots committed to the firmware list.
*
* @return Number of committed slots.
*/
int esp_ble_mesh_dfu_slot_count(void);
/** @brief Reserve a new DFU image slot for a distributable image.
*
* A DFU image slot represents a single distributable DFU image with all its
* metadata. The slot data must be set using esp_ble_mesh_dfu_slot_info_set and
* esp_ble_mesh_dfu_slot_fwid_set, and the slot committed using
* esp_ble_mesh_dfu_slot_commit for the slot to be considered part of the slot
* list.
*
* @return
* - slot : A pointer to the reserved slot
* - @c NULL : Slot allocation failed
*/
esp_ble_mesh_dfu_slot_t *esp_ble_mesh_dfu_slot_reserve(void);
/** @brief Set the size and metadata for a reserved slot.
*
* @param dfu_slot Pointer to the reserved slot for which to set the
* metadata.
* @param size The size of the image.
* @param metadata Metadata or NULL.
* @param metadata_len Length of the metadata, at most @c
* CONFIG_BLE_MESH_DFU_METADATA_MAXLEN.
*
* @return
* - 0 : success
* - @c ESP_ERR_INVALID_ARG : invalid slot parameter or invalid metadata parameter
* - @c ESP_ERR_INVALID_SIZE : metadata length is zero or exceeds @c CONFIG_BLE_MESH_DFU_METADATA_MAXLEN
*/
int esp_ble_mesh_dfu_slot_info_set(esp_ble_mesh_dfu_slot_t *dfu_slot, size_t size,
const uint8_t *metadata, size_t metadata_len);
/** @brief Set the new fwid for the incoming image for a reserved slot.
*
* @param dfu_slot Pointer to the reserved slot for which to set the fwid.
* @param fwid Fwid to set.
* @param fwid_len Length of the fwid, at most @c
* CONFIG_BLE_MESH_DFU_FWID_MAXLEN.
*
* @return
* - 0 : success
* - @c ESP_ERR_INVALID_ARG : invalid slot parameter or invalid fwid parameter
* - @c ESP_ERR_INVALID_SIZE : fwid length is zero or exceeds @c CONFIG_BLE_MESH_DFU_FWID_MAXLEN
*/
int esp_ble_mesh_dfu_slot_fwid_set(esp_ble_mesh_dfu_slot_t *dfu_slot,
const uint8_t *fwid, size_t fwid_len);
/** @brief Commit the reserved slot to the list of slots, and store it
* persistently.
*
* If the commit fails for any reason, the slot will still be in the reserved
* state after this call.
*
* @param dfu_slot Pointer to the reserved slot.
*
* @return
* - 0 : success
* - @c ESP_ERR_INVALID_ARG : invalid slot parameter or slot has been committed
* - @c ESP_ERR_INVALID_SIZE : slot size is zero
*/
int esp_ble_mesh_dfu_slot_commit(esp_ble_mesh_dfu_slot_t *dfu_slot);
/** @brief Release a reserved slot so that it can be reserved again.
*
* @param dfu_slot Pointer to the reserved slot.
*/
void esp_ble_mesh_dfu_slot_release(const esp_ble_mesh_dfu_slot_t *dfu_slot);
/** @brief Delete a committed DFU image slot.
*
* @param slot Slot to delete. Must be a valid pointer acquired from this
* module.
*
* @return
* - 0 : success
* - @c ESP_ERR_INVALID_ARG : invalid slot parameter
*/
int esp_ble_mesh_dfu_slot_del(const esp_ble_mesh_dfu_slot_t *slot);
/** @brief Delete all DFU image slots.
*/
void esp_ble_mesh_dfu_slot_del_all(void);
/** @brief Get the DFU image slot at the given firmware image list index.
*
* @param img_idx DFU image slot index.
*
* @return
* - slot : A pointer to the reserved slot
* - @c NULL : No slot exists with the given index
*/
const esp_ble_mesh_dfu_slot_t *esp_ble_mesh_dfu_slot_at(uint16_t img_idx);
/** @brief Get the committed DFU image slot for the image with the given
* firmware ID.
*
* @param fwid Firmware ID.
* @param fwid_len Firmware ID length.
* @param slot Slot pointer to fill.
*
* @return
* - index : Slot index
* - @c ESP_ERR_INVALID_ARG : invalid fwid parameter or invalid slot parameter
* - @c ESP_ERR_INVALID_SIZE : fwid length is zero
* - @c ESP_ERR_NOT_FOUND : no slot exists with the given firmware id
*/
int esp_ble_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, esp_ble_mesh_dfu_slot_t **slot);
/** @brief Get the index in the firmware image list for the given slot.
*
* @param slot Slot to find.
*
* @return
* - index : Slot index
* - @c ESP_ERR_INVALID_ARG : invalid slot parameter
* - @c ESP_ERR_NOT_FOUND : The slot does not exist
*/
int esp_ble_mesh_dfu_slot_img_idx_get(const esp_ble_mesh_dfu_slot_t *slot);
#endif /* _ESP_BLE_MESH_FW_SLOT_API_H_ */
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -9,51 +9,86 @@
#include "esp_ble_mesh_defs.h"
#if CONFIG_BLE_MESH_MBT_SRV || CONFIG_BLE_MESH_MBT_CLI
#ifndef _BLE_MESH_MBT_DEPRECATE_WARN
#define _BLE_MESH_MBT_DEPRECATE_WARN
#warning "warning: 'All content in this document, including data structures and APIs, will be deprecated."
#endif
#endif /* CONFIG_BLE_MESH_MBT_SRV || CONFIG_BLE_MESH_MBT_CLI */
#ifdef __cplusplus
extern "C" {
#endif
#if CONFIG_IDF_CI_BUILD
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
/** @cond */
#if (CONFIG_BLE_MESH_MBT_SRV && CONFIG_BLE_MESH_BLOB_SRV) || \
(CONFIG_BLE_MESH_MBT_CLI && CONFIG_BLE_MESH_BLOB_CLI)
#error "BLOB Transfer Model and BLOB Model cannot be enabled at the same time"
#endif
/** @endcond */
/** @deprecated This macro will be deprecated in future versions. */
#define ESP_BLE_MESH_MODEL_OP_BLOB_TRANSFER_GET ESP_BLE_MESH_MODEL_OP_2(0x83, 0x00)
/** @deprecated This macro will be deprecated in future versions. */
#define ESP_BLE_MESH_MODEL_OP_BLOB_TRANSFER_START ESP_BLE_MESH_MODEL_OP_2(0x83, 0x01)
/** @deprecated This macro will be deprecated in future versions. */
#define ESP_BLE_MESH_MODEL_OP_BLOB_TRANSFER_CANCEL ESP_BLE_MESH_MODEL_OP_2(0x83, 0x02)
/** @deprecated This macro will be deprecated in future versions. */
#define ESP_BLE_MESH_MODEL_OP_BLOB_TRANSFER_STATUS ESP_BLE_MESH_MODEL_OP_2(0x83, 0x03)
/** @deprecated This macro will be deprecated in future versions. */
#define ESP_BLE_MESH_MODEL_OP_BLOB_BLOCK_GET ESP_BLE_MESH_MODEL_OP_2(0x83, 0x05)
/** @deprecated This macro will be deprecated in future versions. */
#define ESP_BLE_MESH_MODEL_OP_BLOB_BLOCK_START ESP_BLE_MESH_MODEL_OP_2(0x83, 0x04)
/** @deprecated This macro will be deprecated in future versions. */
#define ESP_BLE_MESH_MODEL_OP_BLOB_PARTIAL_BLOCK_REPORT ESP_BLE_MESH_MODEL_OP_1(0x65)
/** @deprecated This macro will be deprecated in future versions. */
#define ESP_BLE_MESH_MODEL_OP_BLOB_BLOCK_STATUS ESP_BLE_MESH_MODEL_OP_1(0x67)
/** @deprecated This macro will be deprecated in future versions. */
#define ESP_BLE_MESH_MODEL_OP_BLOB_CHUNK_TRANSFER ESP_BLE_MESH_MODEL_OP_1(0x66)
/** @deprecated This macro will be deprecated in future versions. */
#define ESP_BLE_MESH_MODEL_OP_BLOB_INFORMATION_GET ESP_BLE_MESH_MODEL_OP_2(0x83, 0x06)
/** @deprecated This macro will be deprecated in future versions. */
#define ESP_BLE_MESH_MODEL_OP_BLOB_INFORMATION_STATUS ESP_BLE_MESH_MODEL_OP_2(0x83, 0x07)
/** @deprecated This macro will be deprecated in future versions. */
#define ESP_BLE_MESH_BLOB_ID_SIZE 8
/** @def ESP_BLE_MESH_MODEL_MBT_CLI
/** @def ESP_BLE_MESH_MODEL_MBT_CLI
*
* @brief Define a new BLOB Transfer Client model.
* @brief Define a new BLOB Transfer Client model.
*
* @note This API needs to be called for each element on which
* the application needs to have a BLOB Transfer Client model.
* @note This API needs to be called for each element on which
* the application needs to have a BLOB Transfer Client model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
* @deprecated This macro will be deprecated in future versions.
*
* @return New BLOB Transfer Client model instance.
* @param cli_pub Pointer to unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to unique struct esp_ble_mesh_client_t.
*
* @return New BLOB Transfer Client model instance.
*/
#define ESP_BLE_MESH_MODEL_MBT_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_MBT_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_MBT_SRV
/** @def ESP_BLE_MESH_MODEL_MBT_SRV
*
* @brief Define a new BLOB Transfer Server model.
* @brief Define a new BLOB Transfer Server model.
*
* @note This API needs to be called for each element on which
* the application needs to have a BLOB Transfer Server model.
* @note This API needs to be called for each element on which
* the application needs to have a BLOB Transfer Server model.
*
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_blob_trans_srv_t.
* @deprecated This macro will be deprecated in future versions.
*
* @return New BLOB Transfer Server model instance.
* @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param srv_data Pointer to the unique struct esp_ble_mesh_blob_trans_srv_t.
*
* @return New BLOB Transfer Server model instance.
*/
#define ESP_BLE_MESH_MODEL_MBT_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_MBT_SRV, \
@@ -61,125 +96,125 @@ extern "C" {
/** BLOB Transfer Server model context */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
} esp_ble_mesh_mbt_srv_t;
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
} esp_ble_mesh_mbt_srv_t __attribute__((deprecated));
/** Parameters of BLOB receiver */
typedef struct {
uint16_t unicast_addr; /*!< Unicast address of the server */
uint8_t retrieved_transfer_phase; /*!< Retrieved transfer phase of the server */
uint8_t status:4; /*!< Status of the last operation */
uint16_t blocks_not_received_len; /*!< Indicates the length which blocks were not received by the server. */
uint8_t *blocks_not_received; /*!< Indicates which blocks were not received by the server. */
uint16_t missing_chunks_len; /*!< Indicates which chunks were not received in the current block */
uint8_t *missing_chunks; /*!< Indicates which chunks were not received by the server in the current block */
/* The followings are the additional information contained in status messages. */
uint8_t transfer_mode:2; /*!< BLOB transfer mode */
uint8_t expected_blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< Expected BLOB identifier list */
uint32_t blob_size; /*!< BLOB size in octets */
uint8_t block_size_log; /*!< Indicates the block size */
uint16_t transfer_mtu_size; /*!< MTU size in octets */
bool block_status_recv; /*!< Indicate if Blob Block Status is received as a response. */
} esp_ble_mesh_blob_receiver_t; /*!< Structure of BLOB receiver */
uint16_t unicast_addr; /*!< Unicast address of the server */
uint8_t retrieved_transfer_phase; /*!< Retrieved transfer phase of the server */
uint8_t status: 4; /*!< Status of the last operation */
uint16_t blocks_not_received_len; /*!< Indicates the length which blocks were not received by the server. */
uint8_t *blocks_not_received; /*!< Indicates which blocks were not received by the server. */
uint16_t missing_chunks_len; /*!< Indicates which chunks were not received in the current block */
uint8_t *missing_chunks; /*!< Indicates which chunks were not received by the server in the current block */
/* The following are the additional information contained in status messages. */
uint8_t transfer_mode: 2; /*!< BLOB transfer mode */
uint8_t expected_blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< Expected BLOB identifier list */
uint32_t blob_size; /*!< BLOB size in octets */
uint8_t block_size_log; /*!< Indicates the block size */
uint16_t transfer_mtu_size; /*!< MTU size in octets */
bool block_status_recv; /*!< Indicate if Blob Block Status is received as a response. */
} esp_ble_mesh_blob_receiver_t __attribute__((deprecated)); /*!< Structure of BLOB receiver */
/** Parameters of BLOB Information Status */
typedef struct {
uint8_t min_block_size_log; /*!< Min Block Size Log */
uint8_t max_block_size_log; /*!< Max Block Size Log */
uint16_t max_total_chunks; /*!< Max Total Chunks */
uint16_t max_chunk_size; /*!< Max Chunk Size */
uint32_t max_blob_size; /*!< Max BLOB Size */
uint16_t server_mtu_size; /*!< Server MTU size */
uint8_t supported_transfer_mode; /*!< Supported Transfer Mode */
} esp_ble_mesh_blob_capabilities_t; /*!< Parameters of BLOB Information Status */
uint8_t min_block_size_log; /*!< Min Block Size Log */
uint8_t max_block_size_log; /*!< Max Block Size Log */
uint16_t max_total_chunks; /*!< Max Total Chunks */
uint16_t max_chunk_size; /*!< Max Chunk Size */
uint32_t max_blob_size; /*!< Max BLOB Size */
uint16_t server_mtu_size; /*!< Server MTU size */
uint8_t supported_transfer_mode; /*!< Supported Transfer Mode */
} esp_ble_mesh_blob_capabilities_t __attribute__((deprecated)); /*!< Parameters of BLOB Information Status */
/** Parameters of BLOB retrieve capabilities */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
uint16_t multicast_addr; /*!< Multicast Address state */
uint16_t app_idx; /*!< AppKey Index state */
uint8_t transfer_ttl; /*!< Transfer TTL state */
uint8_t unicast_addr_count; /*!< The count of unicast address */
uint16_t *unicast_addr; /*!< Unicast address list */
} esp_ble_mesh_retrieve_capabilities_t; /*!< Parameters of BLOB retrieve capabilities */
uint16_t multicast_addr; /*!< Multicast Address state */
uint16_t app_idx; /*!< AppKey Index state */
uint8_t transfer_ttl; /*!< Transfer TTL state */
uint8_t unicast_addr_count; /*!< The count of unicast address */
uint16_t *unicast_addr; /*!< Unicast address list */
} esp_ble_mesh_retrieve_capabilities_t __attribute__((deprecated)); /*!< Parameters of BLOB retrieve capabilities */
/** Parameters of BLOB transfer */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
uint8_t unicast_addr_count; /*!< The count of unicast address */
uint16_t *unicast_addr; /*!< Unicast address list */
uint16_t multicast_addr; /*!< Multicast Address state */
uint16_t app_idx; /*!< AppKey Index state */
uint8_t transfer_ttl; /*!< Transfer TTL state */
uint8_t blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< BLOB identifier list */
uint32_t blob_size; /*!< BLOB size in octets */
uint8_t *blob_data; /*!< BLOB data */
uint8_t transfer_mode; /*!< BLOB transfer mode */
uint16_t client_timeout_base; /*!< Time wait for messages from the serve */
} esp_ble_mesh_transfer_blob_t; /*!< Parameters of BLOB transfer */
uint8_t unicast_addr_count; /*!< The count of unicast address */
uint16_t *unicast_addr; /*!< Unicast address list */
uint16_t multicast_addr; /*!< Multicast Address state */
uint16_t app_idx; /*!< AppKey Index state */
uint8_t transfer_ttl; /*!< Transfer TTL state */
uint8_t blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< BLOB identifier list */
uint32_t blob_size; /*!< BLOB size in octets */
uint8_t *blob_data; /*!< BLOB data */
uint8_t transfer_mode; /*!< BLOB transfer mode */
uint16_t client_timeout_base; /*!< Time wait for messages from the serve */
} esp_ble_mesh_transfer_blob_t __attribute__((deprecated)); /*!< Parameters of BLOB transfer */
/** Parameters of BLOB Block Status message */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
uint16_t multicast_addr; /*!< Multicast Address state */
uint16_t app_idx; /*!< AppKey Index state */
uint8_t transfer_ttl; /*!< Transfer TTL state */
uint16_t multicast_addr; /*!< Multicast Address state */
uint16_t app_idx; /*!< AppKey Index state */
uint8_t transfer_ttl; /*!< Transfer TTL state */
uint16_t block_number; /*!< Block number of the current block */
uint16_t chunk_size; /*!< Chunk Size (in octets) for the current block */
} esp_ble_mesh_send_block_t; /*!< BLOB Block Status message structure */
uint16_t block_number; /*!< Block number of the current block */
uint16_t chunk_size; /*!< Chunk Size (in octets) for the current block */
} esp_ble_mesh_send_block_t __attribute__((deprecated)); /*!< BLOB Block Status message structure */
/** Parameters of BLOB send message */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
uint16_t multicast_addr; /*!< Multicast Address state */
uint16_t app_idx; /*!< AppKey Index state */
uint8_t transfer_ttl; /*!< Transfer TTL state */
} esp_ble_mesh_send_data_t; /*!< Parameters of BLOB send message */
uint16_t multicast_addr; /*!< Multicast Address state */
uint16_t app_idx; /*!< AppKey Index state */
uint8_t transfer_ttl; /*!< Transfer TTL state */
} esp_ble_mesh_send_data_t __attribute__((deprecated)); /*!< Parameters of BLOB send message */
/** Parameters of determine Block Status message */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
uint16_t multicast_addr; /*!< Multicast Address state */
uint16_t app_idx; /*!< AppKey Index state */
uint8_t transfer_ttl; /*!< Transfer TTL state */
} esp_ble_mesh_determine_block_status_t; /*!< Parameters of determine Block Status message */
uint16_t multicast_addr; /*!< Multicast Address state */
uint16_t app_idx; /*!< AppKey Index state */
uint8_t transfer_ttl; /*!< Transfer TTL state */
} esp_ble_mesh_determine_block_status_t __attribute__((deprecated)); /*!< Parameters of determine Block Status message */
/** Parameters of determine Block Status message */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
uint16_t multicast_addr; /*!< Multicast Address state */
uint16_t app_idx; /*!< AppKey Index state */
uint8_t transfer_ttl; /*!< Transfer TTL state */
uint8_t unicast_addr_count; /*!< The count of unicast address */
uint16_t *unicast_addr; /*!< Unicast address list */
} esp_ble_mesh_determine_transfer_status_t; /*!< Parameters of determine Block Status message */
uint16_t multicast_addr; /*!< Multicast Address state */
uint16_t app_idx; /*!< AppKey Index state */
uint8_t transfer_ttl; /*!< Transfer TTL state */
uint8_t unicast_addr_count; /*!< The count of unicast address */
uint16_t *unicast_addr; /*!< Unicast address list */
} esp_ble_mesh_determine_transfer_status_t __attribute__((deprecated)); /*!< Parameters of determine Block Status message */
/** Parameters of cancel transfer message */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
esp_ble_mesh_model_t *model; /*!< Pointer to BLOB Transfer Server model */
uint8_t msg_role; /*!< Role of the device - Node/Provisioner */
uint16_t multicast_addr; /*!< Multicast Address state */
uint16_t app_idx; /*!< AppKey Index state */
uint8_t transfer_ttl; /*!< Transfer TTL state */
uint8_t unicast_addr_count; /*!< The count of unicast address */
uint16_t *unicast_addr; /*!< Unicast address list */
uint16_t multicast_addr; /*!< Multicast Address state */
uint16_t app_idx; /*!< AppKey Index state */
uint8_t transfer_ttl; /*!< Transfer TTL state */
uint8_t unicast_addr_count; /*!< The count of unicast address */
uint16_t *unicast_addr; /*!< Unicast address list */
uint8_t blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< BLOB identifier list */
} esp_ble_mesh_cancel_transfer_t; /*!< Parameters of cancel transfer message */
uint8_t blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< BLOB identifier list */
} esp_ble_mesh_cancel_transfer_t __attribute__((deprecated)); /*!< Parameters of cancel transfer message */
/**
* @brief BLOB Transfer Client model procedure result
@@ -193,113 +228,113 @@ typedef struct {
typedef union {
/** Retrieve capabilities status */
struct {
int error_code; /*!< Result of starting Retrieve Capabilities procedure */
esp_ble_mesh_retrieve_capabilities_t input; /*!< Input of starting Retrieve Capabilities procedure */
} retrieve_capabilities_status; /*!< Retrieve capabilities status */
int error_code; /*!< Result of starting Retrieve Capabilities procedure */
esp_ble_mesh_retrieve_capabilities_t input; /*!< Input of starting Retrieve Capabilities procedure */
} retrieve_capabilities_status; /*!< Retrieve capabilities status */
/** Transfer BLOB status */
struct {
int error_code; /*!< Result of starting Transfer BLOB procedure */
esp_ble_mesh_transfer_blob_t input; /*!< Input of starting Transfer BLOB procedure */
} transfer_blob_status; /*!< Transfer BLOB status */
int error_code; /*!< Result of starting Transfer BLOB procedure */
esp_ble_mesh_transfer_blob_t input; /*!< Input of starting Transfer BLOB procedure */
} transfer_blob_status; /*!< Transfer BLOB status */
/** Send block status */
struct {
int error_code; /*!< Result of starting Send Block sub-procedure */
esp_ble_mesh_send_block_t input; /*!< Input of starting Send Block sub-procedure */
} send_block_status; /*!< Send block status */
int error_code; /*!< Result of starting Send Block sub-procedure */
esp_ble_mesh_send_block_t input; /*!< Input of starting Send Block sub-procedure */
} send_block_status; /*!< Send block status */
/** Send data status */
struct {
int error_code; /*!< Result of starting Send Data sub-procedure */
esp_ble_mesh_send_data_t input; /*!< Input of starting Send Data sub-procedure */
} send_data_status; /*!< Send data status */
int error_code; /*!< Result of starting Send Data sub-procedure */
esp_ble_mesh_send_data_t input; /*!< Input of starting Send Data sub-procedure */
} send_data_status; /*!< Send data status */
/** Determine block status */
struct {
int error_code; /*!< Result of starting Determine Block Status sub-procedure */
esp_ble_mesh_determine_block_status_t input; /*!< Input of starting Determine Block Status sub-procedure */
} determine_block_status_status; /*!< Determine block status */
int error_code; /*!< Result of starting Determine Block Status sub-procedure */
esp_ble_mesh_determine_block_status_t input; /*!< Input of starting Determine Block Status sub-procedure */
} determine_block_status_status; /*!< Determine block status */
/** Determine transfer status */
struct {
int error_code; /*!< Result of starting Determine Transfer Status procedure */
esp_ble_mesh_determine_transfer_status_t input; /*!< Input of starting Determine Transfer Status procedure */
} determine_transfer_status_status; /*!< Determine transfer status */
int error_code; /*!< Result of starting Determine Transfer Status procedure */
esp_ble_mesh_determine_transfer_status_t input; /*!< Input of starting Determine Transfer Status procedure */
} determine_transfer_status_status; /*!< Determine transfer status */
/** Cancel transfer status */
struct {
int error_code; /*!< Result of starting Cancel Transfer procedure */
esp_ble_mesh_cancel_transfer_t input; /*!< Input of starting Cancel Transfer procedure */
} cancel_transfer_status; /*!< Cancel transfer status */
int error_code; /*!< Result of starting Cancel Transfer procedure */
esp_ble_mesh_cancel_transfer_t input; /*!< Input of starting Cancel Transfer procedure */
} cancel_transfer_status; /*!< Cancel transfer status */
/** Retrieve capabilities complete */
struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t result; /*!< Result of Retrieve Capabilities procedure */
} retrieve_capabilities_comp; /*!< Retrieve capabilities complete */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t result; /*!< Result of Retrieve Capabilities procedure */
} retrieve_capabilities_comp; /*!< Retrieve capabilities complete */
/** Transfer BLOB complete */
struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t result; /*!< Result of Transfer BLOB procedure */
} transfer_blob_comp; /*!< Transfer BLOB complete */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t result; /*!< Result of Transfer BLOB procedure */
} transfer_blob_comp; /*!< Transfer BLOB complete */
/** Send block complete */
struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t result; /*!< Result of Send Block sub-procedure */
} send_block_comp; /*!< Send block complete */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t result; /*!< Result of Send Block sub-procedure */
} send_block_comp; /*!< Send block complete */
/** Send data complete */
struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t result; /*!< Result of Send Data sub-procedure */
} send_data_comp; /*!< Send data complete */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t result; /*!< Result of Send Data sub-procedure */
} send_data_comp; /*!< Send data complete */
/** Determine block status complete */
struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t result; /*!< Result of Determine Block Status sub-procedure */
} determine_block_status_comp; /*!< Determine block status complete */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t result; /*!< Result of Determine Block Status sub-procedure */
} determine_block_status_comp; /*!< Determine block status complete */
/** Determine transfer status complete */
struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t result; /*!< Result of Determine Transfer Status procedure */
} determine_transfer_status_comp; /*!< Determine transfer status complete */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t result; /*!< Result of Determine Transfer Status procedure */
} determine_transfer_status_comp; /*!< Determine transfer status complete */
/** Cancel transfer complete */
struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t result; /*!< Result of Cancel Transfer procedure */
} cancel_transfer_comp; /*!< Cancel transfer complete */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t result; /*!< Result of Cancel Transfer procedure */
} cancel_transfer_comp; /*!< Cancel transfer complete */
/** Set transfer TTL */
struct {
int error_code; /*!< Result of setting Transfer TTL state */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t transfer_ttl; /*!< Transfer TTL state */
} set_transfer_ttl; /*!< Set transfer TTL */
int error_code; /*!< Result of setting Transfer TTL state */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t transfer_ttl; /*!< Transfer TTL state */
} set_transfer_ttl; /*!< Set transfer TTL */
/** Clear transfer TTL */
struct {
int error_code; /*!< Result of clearing Transfer TTL state */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
} clear_transfer_ttl; /*!< Clear transfer TTL */
int error_code; /*!< Result of clearing Transfer TTL state */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
} clear_transfer_ttl; /*!< Clear transfer TTL */
/** Set application index */
struct {
int error_code; /*!< Result of setting AppKey Index state */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint16_t app_idx; /*!< AppKey Index state */
} set_app_idx; /*!< Set application index */
int error_code; /*!< Result of setting AppKey Index state */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint16_t app_idx; /*!< AppKey Index state */
} set_app_idx; /*!< Set application index */
/** Clear application index */
struct {
int error_code; /*!< Result of clearing AppKey Index state */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
} clear_app_idx; /*!< Clear application index */
int error_code; /*!< Result of clearing AppKey Index state */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
} clear_app_idx; /*!< Clear application index */
/** Set multicast address */
struct {
int error_code; /*!< Result of setting Multicast Address state */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint16_t multicast_addr; /*!< Multicast Address state */
} set_multicast_addr; /*!< Set multicast address */
int error_code; /*!< Result of setting Multicast Address state */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint16_t multicast_addr; /*!< Multicast Address state */
} set_multicast_addr; /*!< Set multicast address */
/** Clear multicast address */
struct {
int error_code; /*!< Result of clearing Multicast Address state */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
} clear_multicast_addr; /*!< Clear multicast address */
} esp_ble_mesh_mbt_client_cb_value_t; /*!< BLOB Transfer Client model callback values union */
int error_code; /*!< Result of clearing Multicast Address state */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
} clear_multicast_addr; /*!< Clear multicast address */
} esp_ble_mesh_mbt_client_cb_value_t; /*!< BLOB Transfer Client model callback values union */
/** BLOB Transfer Client model callback parameters */
typedef struct {
esp_ble_mesh_mbt_client_cb_value_t value; /*!< BLOB Transfer Client model callback values */
} esp_ble_mesh_mbt_client_cb_param_t; /*!< BLOB Transfer Client model callback parameters */
esp_ble_mesh_mbt_client_cb_value_t value; /*!< BLOB Transfer Client model callback values */
} esp_ble_mesh_mbt_client_cb_param_t __attribute__((deprecated)); /*!< BLOB Transfer Client model callback parameters */
/**
* This enum value is the event of BLOB Transfer Client model.
@@ -327,30 +362,30 @@ typedef enum {
ESP_BLE_MESH_MBT_CLIENT_SET_MULTICAST_ADDR_COMP_EVT,
ESP_BLE_MESH_MBT_CLIENT_CLEAR_MULTICAST_ADDR_COMP_EVT,
ESP_BLE_MESH_MBT_CLIENT_EVT_MAX,
} esp_ble_mesh_mbt_client_cb_event_t;
} esp_ble_mesh_mbt_client_cb_event_t __attribute__((deprecated));
/** Parameters of initialize BLOB receive */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< BLOB identifier list */
uint16_t timeout; /*!< Timeout */
uint8_t transfer_ttl; /*!< Transfer TTL state */
} esp_ble_mesh_initialize_blob_receive_t; /*!< Structure of initialize BLOB receive */
uint8_t blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< BLOB identifier list */
uint16_t timeout; /*!< Timeout */
uint8_t transfer_ttl; /*!< Transfer TTL state */
} esp_ble_mesh_initialize_blob_receive_t __attribute__((deprecated)); /*!< Structure of initialize BLOB receive */
/** Parameters of cancel BLOB receive */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
uint8_t blob_id[ESP_BLE_MESH_BLOB_ID_SIZE]; /*!< BLOB identifier list */
} esp_ble_mesh_cancel_blob_receive_t;/*!< */
} esp_ble_mesh_cancel_blob_receive_t __attribute__((deprecated));/*!< */
/** Parameters of cancel BLOB receive */
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the BLOB Transfer Client model */
esp_ble_mesh_blob_capabilities_t caps; /*!< Parameters of BLOB Information Status */
} esp_ble_mesh_set_blob_capabilities_t;/*!< */
} esp_ble_mesh_set_blob_capabilities_t __attribute__((deprecated));
/**
* @brief BLOB Transfer Server model callback value union
@@ -358,61 +393,61 @@ typedef struct {
typedef union {
/** Initialize BLOB receive complete */
struct {
int error_code; /*!< Result of initializing BLOB receive */
esp_ble_mesh_initialize_blob_receive_t input; /*!< Input of initializing BLOB receive */
} initialize_blob_receive_comp; /*!< Initialize BLOB receive complete */
int error_code; /*!< Result of initializing BLOB receive */
esp_ble_mesh_initialize_blob_receive_t input; /*!< Input of initializing BLOB receive */
} initialize_blob_receive_comp; /*!< Initialize BLOB receive complete */
/** Cancel BLOB receive complete */
struct {
int error_code; /*!< Result of canceling BLOB receive */
esp_ble_mesh_cancel_blob_receive_t input; /*!< Input of canceling BLOB receive */
} cancel_blob_receive_comp; /*!< Cancel BLOB receive complete */
int error_code; /*!< Result of canceling BLOB receive */
esp_ble_mesh_cancel_blob_receive_t input; /*!< Input of canceling BLOB receive */
} cancel_blob_receive_comp; /*!< Cancel BLOB receive complete */
/** Set BLOB capabilities complete */
struct {
int error_code; /*!< Result of setting BLOB capabilities */
esp_ble_mesh_set_blob_capabilities_t input; /*!< Input of setting BLOB capabilities */
} set_blob_capabilities_comp; /*!< Set BLOB capabilities complete */
int error_code; /*!< Result of setting BLOB capabilities */
esp_ble_mesh_set_blob_capabilities_t input; /*!< Input of setting BLOB capabilities */
} set_blob_capabilities_comp; /*!< Set BLOB capabilities complete */
/** BLOB transfer get */
struct {
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Transfer Get message context */
} blob_transfer_get; /*!< BLOB transfer get */
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Transfer Get message context */
} blob_transfer_get; /*!< BLOB transfer get */
/** BLOB transfer start */
struct {
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Transfer Start message context */
} blob_transfer_start; /*!< BLOB transfer start */
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Transfer Start message context */
} blob_transfer_start; /*!< BLOB transfer start */
/** BLOB transfer cancel */
struct {
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Transfer Cancel message context */
} blob_transfer_cancel; /*!< BLOB transfer cancel */
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Transfer Cancel message context */
} blob_transfer_cancel; /*!< BLOB transfer cancel */
/** BLOB block get */
struct {
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Block Get message context */
} blob_block_get; /*!< BLOB block get */
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Block Get message context */
} blob_block_get; /*!< BLOB block get */
/** BLOB block start */
struct {
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Block Start message context */
} blob_block_start; /*!< BLOB block start */
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Block Start message context */
} blob_block_start; /*!< BLOB block start */
/** BLOB chunk transfer */
struct {
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Chunk Transfer message context */
} blob_chunk_transfer; /*!< BLOB chunk transfer */
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Chunk Transfer message context */
} blob_chunk_transfer; /*!< BLOB chunk transfer */
/** BLOB information get */
struct {
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Information Get message context */
} blob_information_get; /*!< BLOB information get */
esp_ble_mesh_msg_ctx_t ctx; /*!< BLOB Information Get message context */
} blob_information_get; /*!< BLOB information get */
/** Block receive complete */
struct {
esp_ble_mesh_msg_ctx_t ctx; /*!< Information of receiving BLOB block completely */
} block_receive_comp; /*!< Block receive complete */
esp_ble_mesh_msg_ctx_t ctx; /*!< Information of receiving BLOB block completely */
} block_receive_comp; /*!< Block receive complete */
/** BLOB receive complete */
struct {
esp_ble_mesh_msg_ctx_t ctx; /*!< Information of receiving BLOB completely */
} blob_receive_comp; /*!< BLOB receive complete */
} esp_ble_mesh_mbt_server_cb_value_t; /*!< BLOB Transfer Server model callback value union */
esp_ble_mesh_msg_ctx_t ctx; /*!< Information of receiving BLOB completely */
} blob_receive_comp; /*!< BLOB receive complete */
} esp_ble_mesh_mbt_server_cb_value_t __attribute__((deprecated)); /*!< BLOB Transfer Server model callback value union */
/** BLOB Transfer Server model callback parameters */
typedef struct {
esp_ble_mesh_mbt_server_cb_value_t value; /*!< Value of the received blob transfer messages */
} esp_ble_mesh_mbt_server_cb_param_t; /*!< BLOB Transfer Server model callback parameters */
esp_ble_mesh_mbt_server_cb_value_t value; /*!< Value of the received blob transfer messages */
} esp_ble_mesh_mbt_server_cb_param_t __attribute__((deprecated)); /*!< BLOB Transfer Server model callback parameters */
/** This enum value is the event of BLOB Transfer Server model */
typedef enum {
@@ -430,7 +465,7 @@ typedef enum {
ESP_BLE_MESH_MBT_SERVER_BLOB_RECEIVE_COMP_EVT,
ESP_BLE_MESH_MBT_SERVER_BLOB_RECEIVE_TIMEOUT_EVT,
ESP_BLE_MESH_MBT_SERVER_EVT_MAX,
} esp_ble_mesh_mbt_server_cb_event_t;
} esp_ble_mesh_mbt_server_cb_event_t __attribute__((deprecated));
/**
* @brief BLOB Transfer Client model callback function type
@@ -453,96 +488,116 @@ typedef void (* esp_ble_mesh_mbt_server_cb_t)(esp_ble_mesh_mbt_server_cb_event_t
/**
* @brief Register BLE Mesh BLOB Transfer Client model callback.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_mbt_client_callback(esp_ble_mesh_mbt_client_cb_t callback);
esp_err_t esp_ble_mesh_register_mbt_client_callback(esp_ble_mesh_mbt_client_cb_t callback) __attribute__((deprecated));
/**
* @brief Register BLE Mesh BLOB Transfer Server model callback.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_mbt_server_callback(esp_ble_mesh_mbt_server_cb_t callback);
esp_err_t esp_ble_mesh_register_mbt_server_callback(esp_ble_mesh_mbt_server_cb_t callback) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client starts Retrieve Capabilities procedure.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] input: The input of Retrieve Capabilities procedure.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_mbt_client_retrieve_capabilities(esp_ble_mesh_retrieve_capabilities_t *input);
esp_err_t esp_ble_mesh_mbt_client_retrieve_capabilities(esp_ble_mesh_retrieve_capabilities_t *input) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client starts Transfer BLOB procedure.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] input: The input of Transfer BLOB procedure.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_mbt_client_transfer_blob(esp_ble_mesh_transfer_blob_t *input);
esp_err_t esp_ble_mesh_mbt_client_transfer_blob(esp_ble_mesh_transfer_blob_t *input) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client starts Send Block sub-procedure.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] input: The input of Send Block sub-procedure.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_mbt_client_send_block(esp_ble_mesh_send_block_t *input);
esp_err_t esp_ble_mesh_mbt_client_send_block(esp_ble_mesh_send_block_t *input) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client starts Send Data sub-procedure.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] input: The input of Send Data sub-procedure.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_mbt_client_send_data(esp_ble_mesh_send_data_t *input);
esp_err_t esp_ble_mesh_mbt_client_send_data(esp_ble_mesh_send_data_t *input) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client starts Determine Block Status sub-procedure.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] input: The input of Determine Block Status sub-procedure.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_mbt_client_determine_block_status(esp_ble_mesh_determine_block_status_t *input);
esp_err_t esp_ble_mesh_mbt_client_determine_block_status(esp_ble_mesh_determine_block_status_t *input) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client starts Determine Transfer Status procedure.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] input: The input of Determine Transfer Status procedure.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_mbt_client_determine_transfer_status(esp_ble_mesh_determine_transfer_status_t *input);
esp_err_t esp_ble_mesh_mbt_client_determine_transfer_status(esp_ble_mesh_determine_transfer_status_t *input) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client starts Cancel Transfer procedure.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] input: The input of Cancel Transfer procedure.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_mbt_client_cancel_transfer(esp_ble_mesh_cancel_transfer_t *input);
esp_err_t esp_ble_mesh_mbt_client_cancel_transfer(esp_ble_mesh_cancel_transfer_t *input) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client gets BLOB receiver.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] model: BLOB Transfer Client model.
* @param[in] unicast_addr: Unicast address of the BLOB receiver.
*
@@ -550,21 +605,25 @@ esp_err_t esp_ble_mesh_mbt_client_cancel_transfer(esp_ble_mesh_cancel_transfer_t
*
*/
const esp_ble_mesh_blob_receiver_t *esp_ble_mesh_mbt_client_get_blob_receiver(esp_ble_mesh_model_t *model,
uint16_t unicast_addr);
uint16_t unicast_addr) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client gets active BLOB receiver list.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] model: BLOB Transfer Client model.
*
* @return Active BLOB receiver list on success or NULL on failure.
*
*/
const esp_ble_mesh_blob_receiver_t **esp_ble_mesh_mbt_client_get_active_blob_receiver(esp_ble_mesh_model_t *model);
const esp_ble_mesh_blob_receiver_t **esp_ble_mesh_mbt_client_get_active_blob_receiver(esp_ble_mesh_model_t *model) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client gets BLOB transfer progress.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] model: BLOB Transfer Client model.
* @param[in] unicast_addr: Unicast address of the BLOB receiver.
* @param[in] block_percent: Block reception percent to be updated.
@@ -576,11 +635,13 @@ const esp_ble_mesh_blob_receiver_t **esp_ble_mesh_mbt_client_get_active_blob_rec
esp_err_t esp_ble_mesh_mbt_client_get_transfer_progress(esp_ble_mesh_model_t *model,
uint16_t unicast_addr,
uint8_t *block_percent,
uint8_t *chunk_percent);
uint8_t *chunk_percent) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client sets Transfer TTL state.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] model: BLOB Transfer Client model.
* @param[in] transfer_ttl: Transfer TTL state value.
*
@@ -588,21 +649,25 @@ esp_err_t esp_ble_mesh_mbt_client_get_transfer_progress(esp_ble_mesh_model_t *mo
*
*/
esp_err_t esp_ble_mesh_mbt_client_set_transfer_ttl(esp_ble_mesh_model_t *model,
uint8_t transfer_ttl);
uint8_t transfer_ttl) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client clear Transfer TTL state.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] model: BLOB Transfer Client model.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_mbt_client_clear_transfer_ttl(esp_ble_mesh_model_t *model);
esp_err_t esp_ble_mesh_mbt_client_clear_transfer_ttl(esp_ble_mesh_model_t *model) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client sets AppKey Index state.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] model: BLOB Transfer Client model.
* @param[in] app_idx: AppKey Index state value.
*
@@ -610,21 +675,25 @@ esp_err_t esp_ble_mesh_mbt_client_clear_transfer_ttl(esp_ble_mesh_model_t *model
*
*/
esp_err_t esp_ble_mesh_mbt_client_set_app_idx(esp_ble_mesh_model_t *model,
uint16_t app_idx);
uint16_t app_idx) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client clear AppKey Index state.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] model: BLOB Transfer Client model.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_mbt_client_clear_app_idx(esp_ble_mesh_model_t *model);
esp_err_t esp_ble_mesh_mbt_client_clear_app_idx(esp_ble_mesh_model_t *model) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client sets Multicast Address state.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] model: BLOB Transfer Client model.
* @param[in] multicast_addr: Multicast Address state value.
*
@@ -632,51 +701,61 @@ esp_err_t esp_ble_mesh_mbt_client_clear_app_idx(esp_ble_mesh_model_t *model);
*
*/
esp_err_t esp_ble_mesh_mbt_client_set_multicast_addr(esp_ble_mesh_model_t *model,
uint16_t multicast_addr);
uint16_t multicast_addr) __attribute__((deprecated));
/**
* @brief BLOB Transfer Client clear Multicast Address state.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] model: BLOB Transfer Client model.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_mbt_client_clear_multicast_addr(esp_ble_mesh_model_t *model);
esp_err_t esp_ble_mesh_mbt_client_clear_multicast_addr(esp_ble_mesh_model_t *model) __attribute__((deprecated));
/**
* @brief BLOB Transfer Server initializes BLOB receive.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] input: The input of initializing BLOB receive.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_mbt_server_initialize_blob_receive(esp_ble_mesh_initialize_blob_receive_t *input);
esp_err_t esp_ble_mesh_mbt_server_initialize_blob_receive(esp_ble_mesh_initialize_blob_receive_t *input) __attribute__((deprecated));
/**
* @brief BLOB Transfer Server cancels BLOB receive.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] input: The input of cancelling BLOB receive.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_mbt_server_cancel_blob_receive(esp_ble_mesh_cancel_blob_receive_t *input);
esp_err_t esp_ble_mesh_mbt_server_cancel_blob_receive(esp_ble_mesh_cancel_blob_receive_t *input) __attribute__((deprecated));
/**
* @brief BLOB Transfer Server sets BLOB capabilities.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] input: The input of setting BLOB capabilities.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_mbt_server_set_blob_capabilities(esp_ble_mesh_set_blob_capabilities_t *input);
esp_err_t esp_ble_mesh_mbt_server_set_blob_capabilities(esp_ble_mesh_set_blob_capabilities_t *input) __attribute__((deprecated));
/**
* @brief BLOB Transfer Server gets current BLOB reception progress.
*
* @deprecated This function will be deprecated in future versions.
*
* @param[in] model: BLOB Transfer Server model.
* @param[in] reception_progress: Reception progress to be updated.
*
@@ -684,7 +763,11 @@ esp_err_t esp_ble_mesh_mbt_server_set_blob_capabilities(esp_ble_mesh_set_blob_ca
*
*/
esp_err_t esp_ble_mesh_mbt_server_get_blob_reception_progress(esp_ble_mesh_model_t *model,
uint8_t *reception_progress);
uint8_t *reception_progress) __attribute__((deprecated));
#if CONFIG_IDF_CI_BUILD
#pragma GCC diagnostic pop
#endif
#ifdef __cplusplus
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,79 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <errno.h>
#include "dfu_slot.h"
#include "esp_ble_mesh_dfu_model_api.h"
#include "esp_ble_mesh_dfu_slot_api.h"
#include "btc_ble_mesh_dfu_slot.h"
#if CONFIG_BLE_MESH_DFU_SLOTS
int btc_ble_mesh_dfu_slot_count(void)
{
return bt_mesh_dfu_slot_count();
}
struct esp_ble_mesh_dfu_slot *btc_ble_mesh_dfu_slot_reserve(void)
{
return (struct esp_ble_mesh_dfu_slot *)bt_mesh_dfu_slot_reserve();
}
int btc_ble_mesh_dfu_slot_info_set(struct esp_ble_mesh_dfu_slot *dfu_slot, size_t size,
const uint8_t *metadata, size_t metadata_len)
{
return bt_mesh_dfu_slot_info_set((struct bt_mesh_dfu_slot *) dfu_slot, size,
metadata, metadata_len);
}
int btc_ble_mesh_dfu_slot_fwid_set(struct esp_ble_mesh_dfu_slot *dfu_slot,
const uint8_t *fwid, size_t fwid_len)
{
return bt_mesh_dfu_slot_fwid_set((struct bt_mesh_dfu_slot *) dfu_slot, fwid,
fwid_len);
}
int btc_ble_mesh_dfu_slot_commit(struct esp_ble_mesh_dfu_slot *dfu_slot)
{
return bt_mesh_dfu_slot_commit((struct bt_mesh_dfu_slot *) dfu_slot);
}
void btc_ble_mesh_dfu_slot_release(const struct esp_ble_mesh_dfu_slot *dfu_slot)
{
bt_mesh_dfu_slot_release((const struct bt_mesh_dfu_slot *)dfu_slot);
}
int btc_ble_mesh_dfu_slot_del(const struct esp_ble_mesh_dfu_slot *slot)
{
return bt_mesh_dfu_slot_del((const struct bt_mesh_dfu_slot *)slot);
}
void btc_ble_mesh_dfu_slot_del_all(void)
{
bt_mesh_dfu_slot_del_all();
}
const struct esp_ble_mesh_dfu_slot *btc_ble_mesh_dfu_slot_at(uint16_t img_idx)
{
return (const struct esp_ble_mesh_dfu_slot *)bt_mesh_dfu_slot_at(img_idx);
}
int btc_ble_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, struct esp_ble_mesh_dfu_slot **slot)
{
return bt_mesh_dfu_slot_get(fwid, fwid_len, (struct bt_mesh_dfu_slot **)slot);
}
int btc_ble_mesh_dfu_slot_img_idx_get(const struct esp_ble_mesh_dfu_slot *slot)
{
return bt_mesh_dfu_slot_img_idx_get((const struct bt_mesh_dfu_slot *)slot);
}
size_t btc_ble_mesh_dfu_slot_foreach(esp_ble_mesh_dfu_slot_cb_t cb, void *user_data)
{
return bt_mesh_dfu_slot_foreach((bt_mesh_dfu_slot_cb_t)cb, user_data);
}
#endif /* CONFIG_BLE_MESH_DFU_SLOTS */
@@ -0,0 +1,123 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BTC_BLE_MESH_DFU_MODEL_H_
#define _BTC_BLE_MESH_DFU_MODEL_H_
#include "btc/btc_manage.h"
#include "esp_ble_mesh_dfu_model_api.h"
#ifdef __cplusplus
extern "C" {
#endif
#if CONFIG_BLE_MESH_DFU_CLI
typedef enum {
BTC_BLE_MESH_ACT_DFU_CLIENT_GET_STATE,
BTC_BLE_MESH_ACT_DFU_CLIENT_IMG_SEND,
BTC_BLE_MESH_ACT_DFU_CLIENT_MAX,
} btc_ble_mesh_dfu_client_act_t;
typedef union {
struct {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_dfu_client_get_t *get;
} dfu_get;
struct {
struct esp_ble_mesh_dfu_cli *cli;
struct esp_ble_mesh_blob_cli_inputs *inputs;
struct esp_ble_mesh_blob_io *io;
struct esp_ble_mesh_dfu_cli_xfer *xfer;
} send_arg;
} btc_ble_mesh_dfu_client_args_t;
typedef enum {
BTC_BLE_MESH_EVT_DFU_CLIENT_TIMEOUT,
BTC_BLE_MESH_EVT_DFU_CLIENT_RECV_GET_RSP,
BTC_BLE_MESH_EVT_DFU_CLIENT_IMG_SEND_CMP,
BTC_BLE_MESH_EVT_DFU_CLIENT_MAX,
} btc_ble_mesh_dfu_client_cb_evt_t;
void btc_ble_mesh_dfu_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_dfu_client_arg_deep_free(btc_msg_t *msg);
void bt_mesh_dfu_client_cb_evt_to_btc(uint32_t opcode, uint8_t event,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const uint8_t *val, size_t len);
void btc_ble_mesh_dfu_client_call_handler(btc_msg_t *msg);
void btc_ble_mesh_dfu_client_cb_handler(btc_msg_t *msg);
uint8_t btc_ble_mesh_dfu_cli_progress(struct esp_ble_mesh_dfu_cli *cli);
#endif /* CONFIG_BLE_MESH_DFU_CLI */
#if CONFIG_BLE_MESH_DFU_SRV
void btc_ble_mesh_dfu_srv_verified(esp_ble_mesh_dfu_srv_t *srv);
void btc_ble_mesh_dfu_srv_rejected(esp_ble_mesh_dfu_srv_t *srv);
void btc_ble_mesh_dfu_srv_cancel(esp_ble_mesh_dfu_srv_t *srv);
void btc_ble_mesh_dfu_srv_applied(esp_ble_mesh_dfu_srv_t *srv);
bool btc_ble_mesh_dfu_srv_is_busy(const esp_ble_mesh_dfu_srv_t *srv);
uint8_t btc_ble_mesh_dfu_srv_progress(const esp_ble_mesh_dfu_srv_t *srv);
#endif /* CONFIG_BLE_MESH_DFU_SRV */
#if CONFIG_BLE_MESH_DFD_CLI
typedef enum {
BTC_BLE_MESH_ACT_DFD_CLIENT_GET,
BTC_BLE_MESH_ACT_DFD_CLIENT_SET,
BTC_BLE_MESH_ACT_DFD_CLIEND_SEND_COMP,
BTC_BLE_MESH_ACT_DFD_CLIENT_MAX,
} btc_ble_mesh_dfd_client_act_t;
typedef enum {
BTC_BLE_MESH_EVT_DFD_CLIENT_TIMEOUT,
BTC_BLE_MESH_EVT_DFD_CLIENT_RECV_RSP,
BTC_BLE_MESH_EVT_DFD_CLIENT_MAX,
} btc_ble_mesh_dfd_client_cb_evt_t;
typedef union {
struct {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_dfd_client_get_param_t *get;
} dfd_client_get;
struct {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_dfd_client_set_param_t *set;
} dfd_client_set;
} btc_ble_mesh_dfd_client_args_t;
void btc_ble_mesh_dfd_client_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_dfd_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_dfd_client_arg_deep_free(btc_msg_t *msg);
void btc_ble_mesh_dfd_client_rsp_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_dfd_client_rsp_deep_free(btc_msg_t *msg);
void bt_mesh_dfd_client_cb_evt_to_btc(btc_ble_mesh_dfd_client_cb_evt_t event,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const uint8_t *val, size_t len);
void btc_ble_mesh_dfd_client_call_handler(btc_msg_t *msg);
#endif /* CONFIG_BLE_MESH_DFD_CLI */
#if CONFIG_BLE_MESH_DFD_SRV
#if CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD
int btc_ble_mesh_dfd_srv_oob_check_complete(struct esp_ble_mesh_dfd_srv *srv,
const struct esp_ble_mesh_dfu_slot *slot, int status,
uint8_t *fwid, size_t fwid_len);
int btc_ble_mesh_dfd_srv_oob_store_complete(struct esp_ble_mesh_dfd_srv *srv,
const struct esp_ble_mesh_dfu_slot *slot, bool success,
size_t size, const uint8_t *metadata, size_t metadata_len);
#endif /* CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD */
#endif /* CONFIG_BLE_MESH_DFD_SRV */
#ifdef __cplusplus
}
#endif
#endif /* _BTC_BLE_MESH_DFU_MODEL_H_ */
@@ -0,0 +1,36 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BTC_BLE_MESH_DFU_SLOT_H_
#define _BTC_BLE_MESH_DFU_SLOT_H_
int btc_ble_mesh_dfu_slot_count(void);
struct esp_ble_mesh_dfu_slot *btc_ble_mesh_dfu_slot_reserve(void);
int btc_ble_mesh_dfu_slot_info_set(struct esp_ble_mesh_dfu_slot *dfu_slot, size_t size,
const uint8_t *metadata, size_t metadata_len);
int btc_ble_mesh_dfu_slot_fwid_set(struct esp_ble_mesh_dfu_slot *dfu_slot,
const uint8_t *fwid, size_t fwid_len);
int btc_ble_mesh_dfu_slot_commit(struct esp_ble_mesh_dfu_slot *dfu_slot);
void btc_ble_mesh_dfu_slot_release(const struct esp_ble_mesh_dfu_slot *dfu_slot);
int btc_ble_mesh_dfu_slot_del(const struct esp_ble_mesh_dfu_slot *slot);
void btc_ble_mesh_dfu_slot_del_all(void);
const struct esp_ble_mesh_dfu_slot *btc_ble_mesh_dfu_slot_at(uint16_t img_idx);
int btc_ble_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, struct esp_ble_mesh_dfu_slot **slot);
int btc_ble_mesh_dfu_slot_img_idx_get(const struct esp_ble_mesh_dfu_slot *slot);
size_t btc_ble_mesh_dfu_slot_foreach(esp_ble_mesh_dfu_slot_cb_t cb, void *user_data);
#endif /* _BTC_BLE_MESH_DFU_SLOT_H_ */
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -14,6 +14,11 @@
extern "C" {
#endif
#if CONFIG_IDF_CI_BUILD
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
typedef enum {
BTC_BLE_MESH_ACT_MBT_CLIENT_RETRIEVE_CAPABILITIES,
BTC_BLE_MESH_ACT_MBT_CLIENT_TRANSFER_BLOB,
@@ -136,6 +141,10 @@ void bt_mesh_mbt_server_cb_evt_to_btc(uint8_t event,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx);
#if CONFIG_IDF_CI_BUILD
#pragma GCC diagnostic pop
#endif
#ifdef __cplusplus
}
#endif

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