feat(ble_mesh): Adapt DFU/MBT to esp-idf

This commit is contained in:
luoxu
2024-11-19 17:57:17 +08:00
committed by Luo Xu
parent 8417c7006d
commit f19c2a36f2
52 changed files with 9633 additions and 5729 deletions
+13
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)
@@ -623,9 +626,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,6 +640,12 @@ 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/lib/ext.c")
if(CONFIG_BLE_MESH_SAR_ENHANCEMENT)
list(APPEND srcs "esp_ble_mesh/core/transport.enh.c")
+4
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,9 @@ 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_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,10 @@ 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_BLE_MESH_BLE_COEX,
#endif /* CONFIG_BLE_MESH */
#if (BLE_FEAT_ISO_EN == TRUE)
+205 -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,212 @@ 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
endmenu # Device Firmware Update model
endmenu #Support for BLE Mesh Client/Server models
@@ -1982,8 +1982,12 @@ 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
/**
* esp_ble_mesh_opcode_config_client_get_t belongs to esp_ble_mesh_opcode_t, this typedef is only
@@ -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,23 @@ 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 */
static void btc_ble_mesh_model_op_set(esp_ble_mesh_model_t *model)
{
@@ -2205,9 +2222,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 +2237,43 @@ 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 */
default:
goto set_vnd_op;
}
@@ -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,
+26 -7
View File
@@ -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);
@@ -300,7 +300,7 @@ 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)
{
return &comp_0->elem[mod->elem_idx];
}
@@ -548,12 +548,31 @@ 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)
{
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;
@@ -635,7 +654,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);
@@ -793,7 +812,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);
@@ -951,7 +970,7 @@ void bt_mesh_choose_better_security_cred(struct bt_mesh_net_tx *tx)
}
#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)
@@ -1041,7 +1060,7 @@ 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)
+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,
@@ -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.
*
@@ -1,6 +1,6 @@
/*
* SPDX-FileCopyrightText: 2018 Intel Corporation
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -45,10 +45,12 @@
* key: "mesh/s/xxxx/b" -> write/read to set/get SIG MODEL Bind AppKey List
* key: "mesh/s/xxxx/s" -> write/read to set/get SIG MODEL Subscription List
* key: "mesh/s/xxxx/p" -> write/read to set/get SIG MODEL Publication
* key: "mesh/s/xxxx/d" -> write/read to set/get SIG MODEL Data
* key: "mesh/vnd" -> write/read to set/get all VENDOR MODEL model_keys.
* key: "mesh/v/xxxx/b" -> write/read to set/get VENDOR MODEL Bind AppKey List
* key: "mesh/v/xxxx/s" -> write/read to set/get VENDOR MODEL Subscription List
* key: "mesh/v/xxxx/p" -> write/read to set/get VENDOR MODEL Publication
* key: "mesh/v/xxxx/d" -> write/read to set/get VENDOR MODEL Data
* key: "mesh/vaddr" -> write/read to set/get all virtual addresses
* key: "mesh/va/xxxx" -> write/read to set/get the "xxxx" virtual address
* key: "mesh/dkca" -> write/read to set/get Device Key Candidate
@@ -2731,3 +2733,40 @@ void bt_mesh_settings_reset(bool erase)
}
#endif /* CONFIG_BLE_MESH_SETTINGS */
#define SETTINGS_MAX_DIR_DEPTH 8
int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd,
const char *name, const void *data,
size_t data_len)
{
int err = 0;
char path[30] = {'\0'};
uint16_t model_key = 0U;
model_key = BLE_MESH_GET_MODEL_KEY(mod->elem_idx, mod->model_idx);
sprintf(path, "mesh/%s/%04x/d", vnd ? "v" : "s", model_key);
if (name) {
strcat(path, "/");
strncat(path, name, SETTINGS_MAX_DIR_DEPTH);
}
if (data_len) {
err = bt_mesh_save_core_settings(path, data, data_len);
if (err) {
BT_ERR("Failed to store %s", path);
return err;
}
err = bt_mesh_add_core_settings_item(vnd ? "mesh/vnd" : "mesh/sig", model_key);
if (err) {
BT_ERR("Failed to add model data to %s, model_key 0x%04x",
vnd ? "mesh/vnd" : "mesh/sig", model_key);
}
} else {
bt_mesh_erase_core_settings(path);
bt_mesh_remove_core_settings_item(vnd ? "mesh/vnd" : "mesh/sig", model_key);
}
return err;
}
@@ -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);
@@ -11,6 +11,7 @@
#define _TRANSPORT_H_
#include "net.h"
#include "access.h"
#ifdef __cplusplus
extern "C" {
@@ -0,0 +1,148 @@
/*
* 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 */
@@ -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_ */
@@ -0,0 +1,999 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP_BLE_MESH_DFU_MODEL_API_H_
#define _ESP_BLE_MESH_DFU_MODEL_API_H_
#include "esp_ble_mesh_defs.h"
#include "esp_ble_mesh_blob_model_api.h"
#include "esp_ble_mesh_dfu_slot_api.h"
#if CONFIG_BLE_MESH_DFU_CLI || CONFIG_BLE_MESH_DFU_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_DFU_CLI || CONFIG_BLE_MESH_DFU_SRV */
#ifdef __cplusplus
extern "C" {
#endif
#define ESP_BLE_MESH_DFU_OP_UPDATE_INFO_GET ESP_BLE_MESH_MODEL_OP_2(0x83, 0x08)
#define ESP_BLE_MESH_DFU_OP_UPDATE_INFO_STATUS ESP_BLE_MESH_MODEL_OP_2(0x83, 0x09)
#define ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK ESP_BLE_MESH_MODEL_OP_2(0x83, 0x0a)
#define ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_STATUS ESP_BLE_MESH_MODEL_OP_2(0x83, 0x0b)
#define ESP_BLE_MESH_DFU_OP_UPDATE_GET ESP_BLE_MESH_MODEL_OP_2(0x83, 0x0c)
#define ESP_BLE_MESH_DFU_OP_UPDATE_START ESP_BLE_MESH_MODEL_OP_2(0x83, 0x0d)
#define ESP_BLE_MESH_DFU_OP_UPDATE_CANCEL ESP_BLE_MESH_MODEL_OP_2(0x83, 0x0e)
#define ESP_BLE_MESH_DFU_OP_UPDATE_APPLY ESP_BLE_MESH_MODEL_OP_2(0x83, 0x0f)
#define ESP_BLE_MESH_DFU_OP_UPDATE_STATUS ESP_BLE_MESH_MODEL_OP_2(0x83, 0x10)
#if CONFIG_BLE_MESH_DFU_CLI
/** @def ESP_BLE_MESH_MODEL_DFU_CLI
*
* @brief Define a new DFU Client model.
*
* @note This API needs to be called for each element on which
* the application needs to have a DFU 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 DFU Client model instance.
*/
#define ESP_BLE_MESH_MODEL_DFU_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_MODEL_BLOB_CLI(NULL, &(cli_data)->blob), \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_DFU_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_DFU_CLI_INIT
*
* @brief Initialize a DFU Client model instance.
*
* @note This macro is used to initialize the DFU Client model.
* It sets the callback handlers for the DFU Client.
*
* @param _handlers Pointer to the callback handler structure (esp_ble_mesh_dfu_cli_cb_t).
*
* @return An initialized DFU Client model instance.
*/
#define ESP_BLE_MESH_DFU_CLI_INIT(_handlers) \
{ \
.cb = _handlers, \
}
#endif /* CONFIG_BLE_MESH_DFU_CLI */
#if CONFIG_BLE_MESH_DFU_SRV
/** @def ESP_BLE_MESH_MODEL_DFU_SRV
*
* @brief Define a new DFU Server model.
*
* @note This API needs to be called for each element on which
* the application needs to have a DFU 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_dfu_trans_srv_t.
*
* @return New DFU Server model instance.
*/
#define ESP_BLE_MESH_MODEL_DFU_SRV(srv_pub, srv_data) \
ESP_BLE_MESH_MODEL_BLOB_SRV(NULL, &(srv_data)->blob), \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_DFU_SRV, \
NULL, srv_pub, srv_data)
/** @def ESP_BLE_MESH_DFU_SRV_INIT
*
* @brief Initialize a DFU Server model instance.
*
* @note This macro is used to initialize the DFU Server model.
* It sets the callback handlers and image information for the DFU Server.
*
* @param _handlers Pointer to the callback handler structure (esp_ble_mesh_dfu_srv_cb_t).
* @param _imgs Pointer to the array of DFU images (esp_ble_mesh_dfu_img_t).
* @param _img_count Number of DFU images in the array.
*
* @return An initialized DFU Server model instance.
*/
#define ESP_BLE_MESH_DFU_SRV_INIT(_handlers, _imgs, _img_count) \
{ \
.cb = _handlers, \
.imgs = _imgs, .img_count = _img_count, \
}
#endif /* CONFIG_BLE_MESH_DFU_SRV */
/** @brief DFU image structure. **/
typedef struct esp_ble_mesh_dfu_img esp_ble_mesh_dfu_img_t;
#if CONFIG_BLE_MESH_DFU_CLI
/** @brief DFU Client model instance structure.
*
* This structure represents a DFU (Device Firmware Update) Client model instance.
* It contains the necessary fields for managing DFU operations as a client.
* Should be initialized with ESP_BLE_MESH_DFU_CLI_INIT.
*
* @note Preview version, the contents of this struct may change in the future.
*/
typedef struct esp_ble_mesh_dfu_cli esp_ble_mesh_dfu_cli_t;
/** @brief DFU iteration action enumeration.
*
* This enumeration defines the possible actions that can be taken
* during DFU iteration callbacks. It controls whether to continue
* or stop iterating through DFU images.
*/
typedef enum esp_ble_mesh_dfu_iter esp_ble_mesh_dfu_iter_t;
/** @brief DFU image callback.
*
* The image callback is called for every DFU image on the Target node when
* calling bt_mesh_dfu_cli_imgs_get.
*
* @param cli Firmware Update Client model instance.
* @param ctx Message context of the received message.
* @param idx Image index.
* @param total Total number of images on the Target node.
* @param img Image information for the given image index.
* @param cb_data Callback data.
*
* @retval ESP_BLE_MESH_DFU_ITER_STOP Stop iterating through the image list and
* return from bt_mesh_dfu_cli_imgs_get.
* @retval ESP_BLE_MESH_DFU_ITER_CONTINUE Continue iterating through the image list
* if any images remain.
*/
typedef esp_ble_mesh_dfu_iter_t (*esp_ble_mesh_dfu_img_cb_t)(esp_ble_mesh_dfu_cli_t *cli,
esp_ble_mesh_msg_ctx_t *ctx, uint8_t idx,
uint8_t total, const esp_ble_mesh_dfu_img_t *img,
void *cb_data);
/** @brief DFU image slot structure.
*
* This structure represents a DFU image slot used for DFU distribution.
* It contains information about the firmware image including size,
* firmware ID, metadata, and their respective lengths.
*/
typedef struct esp_ble_mesh_dfu_slot esp_ble_mesh_dfu_slot_t;
/** @brief DFU Target node structure.
*
* This structure represents a DFU Target node in the mesh network.
* It contains information about the target's BLOB transfer status,
* image index, expected DFU effect, current status, and phase.
*/
typedef struct esp_ble_mesh_dfu_target esp_ble_mesh_dfu_target_t;
/** @brief DFU Client callback structure.
*
* This structure contains callback function pointers for DFU Client events
* such as transfer suspension, completion, application, confirmation,
* and target node loss.
*/
typedef struct esp_ble_mesh_dfu_cli_cb esp_ble_mesh_dfu_cli_cb_t;
/** @brief DFU Client model instance structure.
*
* This structure represents a DFU (Device Firmware Update) Client model instance.
* It contains the necessary fields for managing DFU operations as a client.
* Should be initialized with ESP_BLE_MESH_DFU_CLI_INIT.
*
* @note Preview version, the contents of this struct may change in the future.
*/
typedef struct esp_ble_mesh_dfu_cli esp_ble_mesh_dfu_cli_t;
/** @brief DFU Client BLOB transfer parameters structure.
*
* This structure contains parameters for BLOB transfer during DFU operations,
* including block size logarithmic representation and base chunk size.
*/
typedef struct esp_ble_mesh_dfu_cli_xfer_blob_params esp_ble_mesh_dfu_cli_xfer_blob_params_t;
/** @brief DFU Client transfer parameters structure.
*
* This structure contains parameters for DFU transfer operations,
* including BLOB ID, image slot, transfer mode, and BLOB parameters.
*/
typedef struct esp_ble_mesh_dfu_cli_xfer esp_ble_mesh_dfu_cli_xfer_t;
/** @brief Device Firmware Update Info Get parameters structure.
*
* This structure contains parameters for the Firmware Update Information Get message,
* including the first index and entries limit for requesting firmware information.
*/
typedef struct esp_ble_mesh_device_firmware_update_info_get esp_ble_mesh_device_firmware_update_info_get_t;
/** @brief Device Firmware Update Metadata Check parameters structure.
*
* This structure contains parameters for the Firmware Update Metadata Check message,
* including the update firmware index and vendor-specific metadata.
*/
typedef struct esp_ble_mesh_device_firmware_update_metadata_check esp_ble_mesh_device_firmware_update_metadata_check_t;
/** @brief DFU Client get message union.
*
* This union contains different parameter structures for various DFU Client
* get messages, allowing type-safe access to message-specific parameters.
*/
typedef union esp_ble_mesh_dfu_client_get esp_ble_mesh_dfu_client_get_t;
/** @brief DFU Client send arguments structure.
*
* This structure contains arguments for sending firmware via DFU Client,
* including the client instance, transfer inputs, BLOB stream, and transfer parameters.
*/
typedef struct esp_ble_mesh_dfu_cli_send_arg esp_ble_mesh_dfu_cli_send_arg_t;
/** @brief Firmware information structure.
*
* This structure contains information about firmware including firmware ID
* and update URI for retrieving new firmware.
*/
typedef struct esp_ble_mesh_firmware_info esp_ble_mesh_firmware_info_t;
/** @brief Device Firmware Update Info Status response structure.
*
* This structure contains the response parameters for Firmware Update Information
* Status message, including firmware information list count and details.
*/
typedef struct esp_ble_mesh_device_firmware_update_info_status esp_ble_mesh_device_firmware_update_info_status_t;
/** @brief Device Firmware Update Metadata Check Status response structure.
*
* This structure contains the response parameters for Firmware Update Metadata
* Check Status message, including status code and additional information.
*/
typedef struct esp_ble_mesh_device_firmware_metadata_check_status esp_ble_mesh_device_firmware_metadata_check_status_t;
/** @brief Device Firmware Update Status response structure.
*
* This structure contains the response parameters for various Firmware Update
* Status messages (Get, Start, Cancel, Apply), including status, phase,
* TTL, timeout base, BLOB ID, and firmware image index.
*/
typedef struct esp_ble_mesh_device_firmware_update_status esp_ble_mesh_device_firmware_update_status_t;
/** @brief DFU Client send callback structure.
*
* This structure contains the result of sending DFU Client messages,
* including error code indicating success or failure.
*/
typedef struct esp_ble_mesh_dfu_client_send_cb esp_ble_mesh_dfu_client_send_cb_t;
/** @brief DFU Client receive callback union.
*
* This union contains different response structures for various DFU Client
* received status messages, allowing type-safe access to message-specific responses.
*/
typedef union esp_ble_mesh_dfu_client_recv_cb esp_ble_mesh_dfu_client_recv_cb_t;
/** @brief DFU Client callback parameters structure.
*
* This structure contains parameters for DFU Client callbacks, including
* common client parameters and a union of send/receive callback data.
*/
typedef struct esp_ble_mesh_dfu_client_cb_param esp_ble_mesh_dfu_client_cb_param_t;
#endif /* CONFIG_BLE_MESH_DFU_CLI */
#if CONFIG_BLE_MESH_DFU_SRV
/** @brief Firmware Update Server instance structure.
*
* This structure represents a DFU (Device Firmware Update) Server model instance.
* It contains the necessary fields for managing DFU operations as a server.
* Should be initialized with ESP_BLE_MESH_DFU_SRV_INIT.
*
* @note Preview version, the contents of this struct may change in the future.
*/
typedef struct esp_ble_mesh_dfu_srv esp_ble_mesh_dfu_srv_t;
/** @brief Firmware Update Server callback structure.
*
* This structure contains callback function pointers for DFU Server events
* such as transfer check, start, end, recovery, and apply.
*/
typedef struct esp_ble_mesh_dfu_srv_cb esp_ble_mesh_dfu_srv_cb_t;
#endif /* CONFIG_BLE_MESH_DFU_SRV */
/** DFU transfer phase. */
typedef enum esp_ble_mesh_dfu_phase {
/** Ready to start a Receive Firmware procedure. */
ESP_BLE_MESH_DFU_PHASE_IDLE,
/** The Transfer BLOB procedure failed. */
ESP_BLE_MESH_DFU_PHASE_TRANSFER_ERR,
/** The Receive Firmware procedure is being executed. */
ESP_BLE_MESH_DFU_PHASE_TRANSFER_ACTIVE,
/** The Verify Firmware procedure is being executed. */
ESP_BLE_MESH_DFU_PHASE_VERIFY,
/** The Verify Firmware procedure completed successfully. */
ESP_BLE_MESH_DFU_PHASE_VERIFY_OK,
/** The Verify Firmware procedure failed. */
ESP_BLE_MESH_DFU_PHASE_VERIFY_FAIL,
/** The Apply New Firmware procedure is being executed. */
ESP_BLE_MESH_DFU_PHASE_APPLYING,
/** Firmware transfer has been canceled. */
ESP_BLE_MESH_DFU_PHASE_TRANSFER_CANCELED,
/** Firmware applying succeeded. */
ESP_BLE_MESH_DFU_PHASE_APPLY_SUCCESS,
/** Firmware applying failed. */
ESP_BLE_MESH_DFU_PHASE_APPLY_FAIL,
/** Phase of a node was not yet retrieved. */
ESP_BLE_MESH_DFU_PHASE_UNKNOWN,
} esp_ble_mesh_dfu_phase_t;
/** Expected effect of a DFU transfer. */
typedef enum esp_ble_mesh_dfu_effect {
/** No changes to node Composition Data. */
ESP_BLE_MESH_DFU_EFFECT_NONE,
/** Node Composition Data changed and the node does not support remote
* provisioning.
*/
ESP_BLE_MESH_DFU_EFFECT_COMP_CHANGE_NO_RPR,
/** Node Composition Data changed, and remote provisioning is supported.
* The node supports remote provisioning and Composition Data Page
* 0x80. Page 0x80 contains different Composition Data than Page 0x0.
*/
ESP_BLE_MESH_DFU_EFFECT_COMP_CHANGE,
/** Node will be unprovisioned after the update. */
ESP_BLE_MESH_DFU_EFFECT_UNPROV,
} esp_ble_mesh_dfu_effect_t;
/** DFU status. */
typedef enum esp_ble_mesh_dfu_status {
/** The message was processed successfully. */
ESP_BLE_MESH_DFU_SUCCESS,
/** Insufficient resources on the node */
ESP_BLE_MESH_DFU_ERR_RESOURCES,
/** The operation cannot be performed while the Server is in the current
* phase.
*/
ESP_BLE_MESH_DFU_ERR_WRONG_PHASE,
/** An internal error occurred on the node. */
ESP_BLE_MESH_DFU_ERR_INTERNAL,
/** The message contains a firmware index value that is not expected. */
ESP_BLE_MESH_DFU_ERR_FW_IDX,
/** The metadata check failed. */
ESP_BLE_MESH_DFU_ERR_METADATA,
/** The Server cannot start a firmware update. */
ESP_BLE_MESH_DFU_ERR_TEMPORARILY_UNAVAILABLE,
/** Another BLOB transfer is in progress. */
ESP_BLE_MESH_DFU_ERR_BLOB_XFER_BUSY,
} esp_ble_mesh_dfu_status_t;
#if CONFIG_BLE_MESH_DFU_CLI
/** Action for DFU iteration callbacks. */
enum esp_ble_mesh_dfu_iter {
/** Stop iterating. */
ESP_BLE_MESH_DFU_ITER_STOP,
/** Continue iterating. */
ESP_BLE_MESH_DFU_ITER_CONTINUE,
};
/** @brief DFU transfer states
*
* This enumeration defines the various states of a DFU (Device Firmware Update) transfer.
* These states track the progress of firmware distribution from idle state through
* transfer, verification, application, and confirmation phases.
*/
typedef enum esp_ble_mesh_dfu_xfer_state {
/** Idle state - No DFU transfer is in progress. */
ESP_BLE_MESH_DFU_XFER_IDLE,
/** Transfer state - Firmware data is being transferred to target nodes. */
ESP_BLE_MESH_DFU_XFER_TRANSFER,
/** Refresh state - Transfer is paused or being refreshed. */
ESP_BLE_MESH_DFU_XFER_REFRESH,
/** Verified state - Firmware has been successfully verified on target nodes. */
ESP_BLE_MESH_DFU_XFER_VERIFIED,
/** Apply state - Firmware is being applied on target nodes. */
ESP_BLE_MESH_DFU_XFER_APPLY,
/** Applied state - Firmware has been successfully applied on target nodes. */
ESP_BLE_MESH_DFU_XFER_APPLIED,
/** Confirm state - Waiting for confirmation from target nodes. */
ESP_BLE_MESH_DFU_XFER_CONFIRM,
/** Cancel state - DFU transfer has been cancelled. */
ESP_BLE_MESH_DFU_XFER_CANCEL,
/** Suspended state - DFU transfer has been suspended. */
ESP_BLE_MESH_DFU_XFER_SUSPENDED,
} esp_ble_mesh_dfu_xfer_state_t;
/** @brief Callback events of Device Firmware Update Client Model
*
* This enumeration defines the various callback events that can be generated
* by the DFU (Device Firmware Update) Client model. These events are used
* to notify the application about different stages and states of the DFU process,
* including message sending, timeouts, response reception, and image transfer completion.
*/
typedef enum {
/** DFU Client message sending completed event.
* This event is triggered when a DFU Client message has been successfully sent.
*/
ESP_BLE_MESH_DFU_CLIENT_SEND_COMP_EVT,
/** DFU Client timeout event.
* This event is triggered when a DFU Client operation times out waiting for a response.
*/
ESP_BLE_MESH_DFU_CLIENT_TIMEOUT_EVT,
/** DFU Client received Get response event.
* This event is triggered when the DFU Client receives a response to a Get message.
*/
ESP_BLE_MESH_DFU_CLIENT_RECV_GET_RSP_EVT,
/** DFU Client image send completed event.
* This event is triggered when the DFU Client has completed sending a firmware image.
*/
ESP_BLE_MESH_DFU_CLIENT_IMG_SEND_CMP_EVT,
/** Maximum DFU Client event value (used for bounds checking). */
ESP_BLE_MESH_DFU_CLIENT_EVT_MAX,
} esp_ble_mesh_dfu_client_cb_event_t;
#endif /* CONFIG_BLE_MESH_DFU_CLI */
/** DFU image instance.
*
* Each DFU image represents a single updatable firmware image.
*/
struct esp_ble_mesh_dfu_img {
/** Firmware ID. */
const void *fwid;
/** Length of the firmware ID. */
size_t fwid_len;
/** Update URI, or NULL. */
const char *uri;
};
#if CONFIG_BLE_MESH_DFU_CLI
/** DFU image slot for DFU distribution. */
struct esp_ble_mesh_dfu_slot {
/** Size of the firmware in bytes. */
size_t size;
/** Length of the firmware ID. */
size_t fwid_len;
/** Length of the metadata. */
size_t metadata_len;
/** Firmware ID. */
uint8_t fwid[CONFIG_BLE_MESH_DFU_FWID_MAXLEN];
/** Metadata. */
uint8_t metadata[CONFIG_BLE_MESH_DFU_METADATA_MAXLEN];
};
/** DFU Target node. */
struct esp_ble_mesh_dfu_target {
/** BLOB Target node */
esp_ble_mesh_blob_target_t blob;
/** Image index on the Target node */
uint8_t img_idx;
/** Expected DFU effect, see bt_mesh_dfu_effect. */
uint8_t effect;
/** Current DFU status, see bt_mesh_dfu_status. */
uint8_t status;
/** Current DFU phase, see bt_mesh_dfu_phase. */
uint8_t phase;
};
/** Firmware Update Client event callbacks. */
struct esp_ble_mesh_dfu_cli_cb {
/** @brief BLOB transfer is suspended.
*
* Called when the BLOB transfer is suspended due to response timeout from all Target nodes.
*
* @param cli Firmware Update Client model instance.
*/
void (*suspended)(esp_ble_mesh_dfu_cli_t *cli);
/** @brief DFU ended.
*
* Called when the DFU transfer ends, either because all Target nodes were
* lost or because the transfer was completed successfully.
*
* @param cli Firmware Update Client model instance.
* @param reason Reason for ending.
*/
void (*ended)(esp_ble_mesh_dfu_cli_t *cli,
esp_ble_mesh_dfu_status_t reason);
/** @brief DFU transfer applied on all active Target nodes.
*
* Called at the end of the apply procedure.
*
* @param cli Firmware Update Client model instance.
*/
void (*applied)(esp_ble_mesh_dfu_cli_t *cli);
/** @brief DFU transfer confirmed on all active Target nodes.
*
* Called at the end of the apply procedure.
*
* @param cli Firmware Update Client model instance.
*/
void (*confirmed)(esp_ble_mesh_dfu_cli_t *cli);
/** @brief DFU Target node was lost.
*
* A DFU Target node was dropped from the receivers list. The Target node's
* @c status is set to reflect the reason for the failure.
*
* @param cli Firmware Update Client model instance.
* @param target DFU Target node that was lost.
*/
void (*lost_target)(esp_ble_mesh_dfu_cli_t *cli,
esp_ble_mesh_dfu_target_t *target);
};
/** Firmware Update Client model instance.
* Should be initialized with ESP_BLE_MESH_DFU_CLI_INIT.
*
* @note Preview version, the contents of this struct may change in the future.
*/
struct esp_ble_mesh_dfu_cli {
/** Callback structure. */
const esp_ble_mesh_dfu_cli_cb_t *cb;
/** Underlying BLOB Transfer Client. */
esp_ble_mesh_blob_cli_t blob;
/** runtime state */
uint32_t op;
/** ble mesh model instance. */
esp_ble_mesh_model_t *mod;
/** BLOB Transfer information */
struct {
const esp_ble_mesh_dfu_slot_t *slot;
const esp_ble_mesh_blob_io_t *io;
esp_ble_mesh_blob_xfer_t blob;
uint8_t state;
uint8_t flags;
} xfer;
/** Current request */
void *req;
};
/** BLOB parameters for Firmware Update Client transfer */
struct esp_ble_mesh_dfu_cli_xfer_blob_params {
/** Logarithmic representation of the block size. */
uint8_t block_size_log;
/** Base chunk size. May be smaller for the last chunk. */
uint16_t chunk_size;
};
/** Firmware Update Client transfer parameters */
struct esp_ble_mesh_dfu_cli_xfer {
/** BLOB ID to use for this transfer, or 0 to set it randomly. */
uint64_t blob_id;
/** DFU image slot to transfer. */
const esp_ble_mesh_dfu_slot_t *slot;
/** Transfer mode (Push (Push BLOB Transfer Mode) or Pull (Pull BLOB Transfer Mode)) */
enum esp_ble_mesh_blob_xfer_mode mode;
/** BLOB parameters to be used for the transfer, or NULL to retrieve Target nodes'
* capabilities before sending a firmware.
*/
const esp_ble_mesh_dfu_cli_xfer_blob_params_t *blob_params;
};
/**
* @brief Parameters of Device Firmware Update Info Get.
*/
struct esp_ble_mesh_device_firmware_update_info_get {
uint8_t first_index; /*!< Index of the first requested entry from the Firmware Information List state */
uint8_t entries_limit; /*!< Maximum number of entries that the server includes in a Firmware Update Information Status message */
esp_ble_mesh_dfu_img_cb_t img_cb; /*!< Added by Espressif, callback function used to walkthrough recceived images */
};
/**
* @brief Parameters of Device Firmware Update Firmware Metadata Check.
*/
struct esp_ble_mesh_device_firmware_update_metadata_check {
uint8_t update_firmware_index; /*!< Index of the firmware image in the Firmware Information List state to check */
struct net_buf_simple *metadata; /*!< Vendor-specific metadata */
};
/**
* @brief Device Firmware Update Client model get message union.
* For ESP_BLE_MESH_DFU_OP_UPDATE_INFO_GET
* ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK
* ESP_BLE_MESH_DFU_OP_UPDATE_START
* the get_state parameter in the `esp_ble_mesh_dfu_client_get_state` function should not be set to NULL.
*/
union esp_ble_mesh_dfu_client_get {
esp_ble_mesh_device_firmware_update_info_get_t dfu_update_info_get; /*!< For ESP_BLE_MESH_DFU_OP_UPDATE_INFO_GET */
esp_ble_mesh_device_firmware_update_metadata_check_t dfu_metadata_check; /*!< For ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK */
};
/**
* @brief Parameters of Device Firmware Update Client
* model to send Firmware.
*/
struct esp_ble_mesh_dfu_cli_send_arg {
esp_ble_mesh_dfu_cli_t *cli; /*!< Device Firmware Update Client model instance */
esp_ble_mesh_blob_cli_inputs_t *inputs; /*!< BLOB Transfer Client transfer inputs. */
esp_ble_mesh_blob_io_t *io; /*!< BLOB stream. */
esp_ble_mesh_dfu_cli_xfer_t *xfer; /*!< Firmware Update Client transfer parameters */
};
/**
* @brief Struct of firmware information.
*/
struct esp_ble_mesh_firmware_info {
struct net_buf_simple *fw_id; /*!< Firmware ID */
struct net_buf_simple *update_uri; /*!< URI used to retrieve a new firmware */
};
/**
* @brief Response of Firmware Update Information Get Message
*/
struct esp_ble_mesh_device_firmware_update_info_status {
uint8_t fw_info_list_cnt; /*!< The number of entries in the Firmware Information List */
uint8_t first_index; /*!< Index of the first requested entry from the Firmware Information List */
esp_ble_mesh_firmware_info_t *fw_info_list; /*!< List of firmware information entries */
};
/**
* @brief Response of Firmware Update Firmware Metadata Check Message
*/
struct esp_ble_mesh_device_firmware_metadata_check_status {
uint8_t status : 3; /*!< Status Code from the firmware metadata check */
uint8_t additional_info : 5; /*!< The Firmware Update Additional Information state from the Firmware Update Server (see Section 4.1.3)*/
uint8_t update_firmware_image_index; /*!< Index of the firmware image in the Firmware Information List state that was checked*/
};
/**
* @brief Response of Firmware Update Get Message,
* Firmware Update Start Message,
* Firmware Update Cancel Message,
* Firmware Update Apply Message.
*/
struct esp_ble_mesh_device_firmware_update_status {
uint8_t status : 3; /*!< Status Code for the requesting message */
uint8_t update_phase : 3; /*!< The Update Phase state of the Firmware Update Server */
uint8_t update_ttl; /*!< TTL value to use during firmware image transfer */
uint8_t additional_info : 5; /*!< The Firmware Update Additional Information state from the Firmware Update Server (see Section 4.1.3)*/
uint16_t update_timeout_base; /*!< Used to compute the timeout of the firmware image transfer */
uint64_t update_blob_id; /*!< BLOB identifier for the firmware image */
uint8_t update_fw_img_idx; /*!< The index of the firmware image in the Firmware Information List state being updated*/
};
/** Result of sending Device Firmware Update Client messages */
struct esp_ble_mesh_dfu_client_send_cb {
int err_code; /*!< Result of sending a message */
};
/**
* @brief Device Firmware Update Client model received message union
*/
union esp_ble_mesh_dfu_client_recv_cb {
esp_ble_mesh_device_firmware_update_info_status_t dfu_update_info_status; /*!< ESP_BLE_MESH_MODEL_OP_DIRECTED_CONTROL_STATUS */
esp_ble_mesh_device_firmware_metadata_check_status_t dfu_metadata_check_status; /*!< ESP_BLE_MESH_MODEL_OP_PATH_METRIC_STATUS */
esp_ble_mesh_device_firmware_update_status_t dfu_firmware_update_status; /*!< ESP_BLE_MESH_MODEL_OP_DISCOVERY_TABLE_CAPS_STATUS */
};
/** Device Firmware Update Client model callback parameters */
struct esp_ble_mesh_dfu_client_cb_param {
esp_ble_mesh_client_common_param_t *params; /*!< Client common parameters, used by all events. */
/** Union of DF Client callback */
union {
esp_ble_mesh_dfu_client_send_cb_t send; /*!< Result of sending a message */
esp_ble_mesh_dfu_client_recv_cb_t recv; /*!< Parameters of received status message */
};
};
/**
* @brief Bluetooth Mesh Device Firmware Update client and server model functions.
*/
/**
* @brief Device Firmware Update Client model callback function type
* @param event: Event type
* @param param: Pointer to callback parameter
*/
typedef void (* esp_ble_mesh_dfu_client_cb_t)(esp_ble_mesh_dfu_client_cb_event_t event,
esp_ble_mesh_dfu_client_cb_param_t *param);
/**
* @brief Device Firmware Update Server model callback function type
* @param event: Event type
* @param param: Pointer to callback parameter
*/
typedef void (* esp_ble_mesh_dfu_server_cb_t)(esp_ble_mesh_dfu_client_cb_event_t event,
esp_ble_mesh_dfu_client_cb_param_t *param);
/**
* @brief Register BLE Mesh Device Firmware Update Client model callback.
*
* @param callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_dfu_client_callback(esp_ble_mesh_dfu_client_cb_t callback);
/**
* @brief Get the value of Device Firmware Server model state with the corresponding get message.
*
* @param params: Pointer to BLE Mesh common client parameters.
* @param get: Pointer to a union, each kind of opcode corresponds to one structure inside.
*
* @return ESP_OK on success or error code otherwise.
*
*/
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);
/** @brief Start distributing a DFU.
*
* Starts distribution of the firmware in the given slot to the list of DFU
* Target nodes in @c ctx. The transfer runs in the background, and its end is
* signalled through the bt_mesh_dfu_cli_cb::ended callback.
*
* @note The BLOB Transfer Client transfer inputs @c targets list must point to a list of
* bt_mesh_dfu_target nodes. The contents of `inputs`, `io`, `xfer` must not be changed or
* released from the beginning to the end of the transmission.
*
* @param cli Firmware Update Client model instance.
* @param inputs BLOB Transfer Client transfer inputs.
* @param io BLOB stream to read BLOB from.
* @param xfer Firmware Update Client transfer parameters.
*
* @return 0 on success, or (negative) error code otherwise.
*/
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);
/** @brief Get progress as a percentage of completion.
*
* @param cli Firmware Update Client model instance.
*
* @return The progress of the current transfer in percent, or 0 if no
* transfer is active.
*/
uint8_t esp_ble_mesh_dfu_cli_progress(esp_ble_mesh_dfu_cli_t *cli);
#endif /* CONFIG_BLE_MESH_DFU_CLI */
#if CONFIG_BLE_MESH_DFU_SRV
/** @brief Firmware Update Server event callbacks. */
struct esp_ble_mesh_dfu_srv_cb {
/** @brief Transfer check callback.
*
* The transfer check can be used to validate the incoming transfer
* before it starts. The contents of the metadata is implementation
* specific, and should contain all the information the application
* needs to determine whether this image should be accepted, and what
* the effect of the transfer would be.
*
* If applying the image will have an effect on the provisioning state
* of the mesh stack, this can be communicated through the @c effect
* return parameter.
*
* The metadata check can be performed both as part of starting a new
* transfer and as a separate procedure.
*
* This handler is optional.
*
* @param srv Firmware Update Server instance.
* @param img DFU image the metadata check is performed on.
* @param metadata Image metadata.
* @param effect Return parameter for the image effect on the
* provisioning state of the mesh stack.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int (*check)(esp_ble_mesh_dfu_srv_t *srv,
const esp_ble_mesh_dfu_img_t *img,
struct net_buf_simple *metadata,
esp_ble_mesh_dfu_effect_t *effect);
/** @brief Transfer start callback.
*
* Called when the Firmware Update Server is ready to start a new DFU transfer.
* The application must provide an initialized BLOB stream to be used
* during the DFU transfer.
*
* The following error codes are treated specially, and should be used
* to communicate these issues:
* - @c -ENOMEM: The device cannot fit this image.
* - @c -EBUSY: The application is temporarily unable to accept the
* transfer.
* - @c -EALREADY: The device has already received and verified this
* image, and there's no need to transfer it again. The Firmware Update model
* will skip the transfer phase, and mark the image as verified.
*
* This handler is mandatory.
*
* @param srv Firmware Update Server instance.
* @param img DFU image being updated.
* @param metadata Image metadata.
* @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 otherwise. Return
* codes @c -ENOMEM, @c -EBUSY @c -EALREADY will be passed to
* the updater, other error codes are reported as internal
* errors.
*/
int (*start)(esp_ble_mesh_dfu_srv_t *srv,
const esp_ble_mesh_dfu_img_t *img,
struct net_buf_simple *metadata,
const esp_ble_mesh_blob_io_t **io);
/** @brief Transfer end callback.
*
* This handler is optional.
*
* If the transfer is successful, the application should verify the
* firmware image, and call either bt_mesh_dfu_srv_verified or
* bt_mesh_dfu_srv_rejected depending on the outcome.
*
* If the transfer fails, the Firmware Update Server will be available for new
* transfers immediately after this function returns.
*
* @param srv Firmware Update Server instance.
* @param img DFU image that failed the update.
* @param success Whether the DFU transfer was successful.
*/
void (*end)(esp_ble_mesh_dfu_srv_t *srv,
const esp_ble_mesh_dfu_img_t *img, bool success);
/** @brief Transfer recovery callback.
*
* If the device reboots in the middle of a transfer, the Firmware Update Server
* calls this function when the Bluetooth mesh subsystem is started.
*
* This callback is optional, but transfers will not be recovered after
* a reboot without it.
*
* @param srv Firmware Update Server instance.
* @param img DFU image being updated.
* @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_dfu_srv_t *srv,
const esp_ble_mesh_dfu_img_t *img,
const esp_ble_mesh_blob_io_t **io);
/** @brief Transfer apply callback.
*
* Called after a transfer has been validated, and the updater sends an
* apply message to the Target nodes.
*
* This handler is optional.
*
* @param srv Firmware Update Server instance.
* @param img DFU image that should be applied.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int (*apply)(esp_ble_mesh_dfu_srv_t *srv,
const esp_ble_mesh_dfu_img_t *img);
};
/** @brief Firmware Update Server instance.
*
* Should be initialized with ESP_BLE_MESH_DFU_SRV_INIT.
* @note Preview version, the contents of this struct may change in the future.
*/
struct esp_ble_mesh_dfu_srv {
/** Underlying BLOB Transfer Server. */
esp_ble_mesh_blob_srv_t blob;
/** Callback structure. */
const esp_ble_mesh_dfu_srv_cb_t *cb;
/** List of updatable images. */
const esp_ble_mesh_dfu_img_t *imgs;
/** Number of updatable images. */
size_t img_count;
/** Runtime state */
esp_ble_mesh_model_t *mod;
/** Update information */
struct {
/* Effect of transfer, @see bt_mesh_dfu_effect. */
uint8_t effect;
/* Current phase, @see bt_mesh_dfu_phase. */
uint8_t phase;
uint8_t ttl;
uint8_t idx;
uint16_t timeout_base;
uint16_t meta;
} update;
};
/** @brief Accept the received DFU transfer.
*
* Should be called at the end of a successful DFU transfer.
*
* If the DFU transfer completes successfully, the application should verify
* the image validity (including any image authentication or integrity checks),
* and call this function if the image is ready to be applied.
*
* @param srv Firmware Update Server instance.
*/
void esp_ble_mesh_dfu_srv_verified(esp_ble_mesh_dfu_srv_t *srv);
/** @brief Reject the received DFU transfer.
*
* Should be called at the end of a successful DFU transfer.
*
* If the DFU transfer completes successfully, the application should verify
* the image validity (including any image authentication or integrity checks),
* and call this function if one of the checks fail.
*
* @param srv Firmware Update Server instance.
*/
void esp_ble_mesh_dfu_srv_rejected(esp_ble_mesh_dfu_srv_t *srv);
/** @brief Cancel the ongoing DFU transfer.
*
* @param srv Firmware Update Server instance.
*/
void esp_ble_mesh_dfu_srv_cancel(esp_ble_mesh_dfu_srv_t *srv);
/** @brief Confirm that the received DFU transfer was applied.
*
* Should be called as a result of the `bt_mesh_dfu_srv_cb.apply` callback.
*
* @param srv Firmware Update Server instance.
*/
void esp_ble_mesh_dfu_srv_applied(esp_ble_mesh_dfu_srv_t *srv);
/** @brief Check if the Firmware Update Server is busy processing a transfer.
*
* @param srv Firmware Update Server instance.
*
* @return true if a DFU procedure is in progress, false otherwise.
*/
bool esp_ble_mesh_dfu_srv_is_busy(const esp_ble_mesh_dfu_srv_t *srv);
/** @brief Get the progress of the current DFU procedure, in percent.
*
* @param srv Firmware Update Server instance.
*
* @return The current transfer progress in percent.
*/
uint8_t esp_ble_mesh_dfu_srv_progress(const esp_ble_mesh_dfu_srv_t *srv);
#endif /* CONFIG_BLE_MESH_DFU_SRV */
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BLE_MESH_DFU_MODEL_API_H_ */
@@ -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
}
@@ -0,0 +1,414 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <errno.h>
#include "btc_ble_mesh_model_common.h"
#include "btc_ble_mesh_dfu_model.h"
#include "esp_ble_mesh_dfu_model_api.h"
#include "mesh_v1.1/dfu/dfu_cli.h"
#include "mesh_v1.1/dfu/dfu_srv.h"
#if CONFIG_BLE_MESH_DFU_CLI
/* Device Firmware Update Client model related functions */
static inline void btc_ble_mesh_dfu_client_cb_to_app(btc_ble_mesh_dfu_client_cb_evt_t event,
esp_ble_mesh_dfu_client_cb_param_t *param)
{
esp_ble_mesh_dfu_client_cb_t btc_ble_mesh_cb =
btc_profile_cb_get(BTC_PID_DFU_CLIENT);
if (btc_ble_mesh_cb) {
btc_ble_mesh_cb(event, param);
}
}
void btc_ble_mesh_dfu_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
btc_ble_mesh_dfu_client_args_t *dst = p_dest;
btc_ble_mesh_dfu_client_args_t *src = p_src;
if (!msg || !dst || !src) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
switch (msg->act) {
case BTC_BLE_MESH_ACT_DFU_CLIENT_GET_STATE: {
dst->dfu_get.params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t));
if (dst->dfu_get.params) {
memcpy(dst->dfu_get.params, src->dfu_get.params,
sizeof(esp_ble_mesh_client_common_param_t));
} else {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
break;
}
if (src->dfu_get.get) {
dst->dfu_get.get = bt_mesh_calloc(sizeof(esp_ble_mesh_dfu_client_get_t));
if (dst->dfu_get.get) {
memcpy(dst->dfu_get.get, src->dfu_get.get,
sizeof(esp_ble_mesh_dfu_client_get_t));
if (src->dfu_get.params->opcode == ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK) {
if (src->dfu_get.get->dfu_metadata_check.metadata) {
dst->dfu_get.get->dfu_metadata_check.metadata = bt_mesh_alloc_buf(src->dfu_get.get->dfu_metadata_check.metadata->len);
if (dst->dfu_get.get->dfu_metadata_check.metadata) {
net_buf_simple_add_mem(dst->dfu_get.get->dfu_metadata_check.metadata,
src->dfu_get.get->dfu_metadata_check.metadata->data,
src->dfu_get.get->dfu_metadata_check.metadata->len);
} else {
BT_ERR("Out of memory for metadata");
return;
}
} else {
BT_ERR("Metadata should be exists");
return;
}
}
} else {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
}
}
break;
}
default:
BT_DBG("%s, Unknown act %d", __func__, msg->act);
break;
}
}
void btc_ble_mesh_dfu_client_arg_deep_free(btc_msg_t *msg)
{
btc_ble_mesh_dfu_client_args_t *arg = NULL;
if (!msg) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
arg = (btc_ble_mesh_dfu_client_args_t *)msg->arg;
switch (msg->act) {
case BTC_BLE_MESH_ACT_DFU_CLIENT_GET_STATE:
if (arg->dfu_get.params) {
bt_mesh_free(arg->dfu_get.params);
}
if (arg->dfu_get.get) {
bt_mesh_free(arg->dfu_get.get);
}
break;
default:
break;
}
}
static void btc_ble_mesh_dfu_client_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
{
esp_ble_mesh_dfu_client_cb_param_t *p_dest_data = p_dest;
esp_ble_mesh_dfu_client_cb_param_t *p_src_data = p_src;
uint16_t length = 0;
if (!msg || !p_src_data || !p_dest_data) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
if (p_src_data->params) {
p_dest_data->params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t));
if (!p_dest_data->params) {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
return;
}
memcpy(p_dest_data->params, p_src_data->params, sizeof(esp_ble_mesh_client_common_param_t));
}
switch (msg->act) {
case ESP_BLE_MESH_DFU_CLIENT_RECV_GET_RSP_EVT:
if (p_src_data->params) {
switch (p_src_data->params->opcode) {
case ESP_BLE_MESH_DFU_OP_UPDATE_INFO_GET:
if (p_src_data->recv.dfu_update_info_status.fw_info_list_cnt) {
length = p_src_data->recv.dfu_update_info_status.fw_info_list_cnt * sizeof(esp_ble_mesh_firmware_info_t);
p_dest_data->recv.dfu_update_info_status.fw_info_list = bt_mesh_calloc(length);
if (!p_dest_data->recv.dfu_update_info_status.fw_info_list) {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
return;
}
memcpy(p_dest_data->recv.dfu_update_info_status.fw_info_list,
p_src_data->recv.dfu_update_info_status.fw_info_list,
length);
}
break;
default:
break;
}
}
case ESP_BLE_MESH_DFU_CLIENT_SEND_COMP_EVT:
case ESP_BLE_MESH_DFU_CLIENT_TIMEOUT_EVT:
case ESP_BLE_MESH_DFU_CLIENT_IMG_SEND_CMP_EVT:
break;
default:
break;
}
}
static void btc_ble_mesh_dfu_client_free_req_data(btc_msg_t *msg)
{
esp_ble_mesh_dfu_client_cb_param_t *arg = NULL;
if (!msg) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
if (msg->act >= ESP_BLE_MESH_DFU_CLIENT_EVT_MAX) {
BT_ERR("%s, Invalid event %d", msg->act);
return;
}
arg = (esp_ble_mesh_dfu_client_cb_param_t *)msg->arg;
switch (msg->act) {
case ESP_BLE_MESH_DFU_CLIENT_RECV_GET_RSP_EVT:
if (arg->params) {
switch (arg->params->opcode) {
case ESP_BLE_MESH_DFU_OP_UPDATE_INFO_GET:
bt_mesh_free(arg->recv.dfu_update_info_status.fw_info_list);
break;
default:
break;
}
}
case ESP_BLE_MESH_DFU_CLIENT_SEND_COMP_EVT:
case ESP_BLE_MESH_DFU_CLIENT_TIMEOUT_EVT:
case ESP_BLE_MESH_DFU_CLIENT_IMG_SEND_CMP_EVT:
break;
default:
BT_WARN("Unprocessed event %d", msg->act);
break;
}
if (arg->params) {
bt_mesh_free(arg->params);
}
return;
}
static void btc_ble_mesh_dfu_client_cb(esp_ble_mesh_dfu_client_cb_param_t *cb_params, uint8_t act)
{
btc_msg_t msg = {0};
/* If corresponding callback is not registered, event will not be posted. */
if (!btc_profile_cb_get(BTC_PID_DFU_CLIENT)) {
return;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_DFU_CLIENT;
msg.act = act;
btc_transfer_context(&msg, cb_params, sizeof(esp_ble_mesh_dfu_client_cb_param_t),
btc_ble_mesh_dfu_client_copy_req_data,
btc_ble_mesh_dfu_client_free_req_data);
}
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)
{
esp_ble_mesh_dfu_client_cb_param_t cb_params = {0};
esp_ble_mesh_client_common_param_t params = {0};
uint8_t act = 0;
if (!model || !ctx || len > sizeof(cb_params.recv)) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
switch (event) {
case BTC_BLE_MESH_EVT_DFU_CLIENT_TIMEOUT:
act = ESP_BLE_MESH_DFU_CLIENT_TIMEOUT_EVT;
break;
case BTC_BLE_MESH_EVT_DFU_CLIENT_RECV_GET_RSP:
act = ESP_BLE_MESH_DFU_CLIENT_RECV_GET_RSP_EVT;
break;
case BTC_BLE_MESH_EVT_DFU_CLIENT_IMG_SEND_CMP:
act = ESP_BLE_MESH_DFU_CLIENT_IMG_SEND_CMP_EVT;
break;
default:
BT_ERR("Unknown Device Firmware Update client event type %d", event);
return;
}
params.opcode = opcode;
params.model = (esp_ble_mesh_model_t *)model;
params.ctx.net_idx = ctx->net_idx;
params.ctx.app_idx = ctx->app_idx;
params.ctx.addr = ctx->addr;
params.ctx.recv_ttl = ctx->recv_ttl;
params.ctx.recv_op = ctx->recv_op;
params.ctx.recv_dst = ctx->recv_dst;
params.ctx.recv_rssi = ctx->recv_rssi;
params.ctx.send_ttl = ctx->send_ttl;
cb_params.params = &params;
if (val && len) {
memcpy(&cb_params.recv, val, len);
}
btc_ble_mesh_dfu_client_cb(&cb_params, act);
}
static int btc_ble_mesh_dfu_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_dfu_client_get_t *get)
{
bt_mesh_client_common_param_t param = {0};
struct bt_mesh_dfu_cli *dfu_cli = NULL;
if (params == NULL ||
params->model == NULL ||
params->model->user_data == NULL) {
BT_ERR("%s, Invalid parameter %d %p %p", __func__, params == NULL, params->model, params->model->user_data);
return -EINVAL;
}
dfu_cli = (struct bt_mesh_dfu_cli *)params->model->user_data;
switch (params->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:
if (get == NULL) {
BT_ERR("Invalid Device Firmware Update Get");
return -EINVAL;
}
break;
default:
break;
}
btc_ble_mesh_set_client_common_param(params, &param, false);
switch (param.opcode) {
case ESP_BLE_MESH_DFU_OP_UPDATE_INFO_GET:
return bt_mesh_dfu_cli_imgs_get(dfu_cli, &param.ctx, (bt_mesh_dfu_img_cb_t) get->dfu_update_info_get.img_cb,
NULL, get->dfu_update_info_get.first_index,
get->dfu_update_info_get.entries_limit);
case ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK:
return bt_mesh_dfu_cli_metadata_check(dfu_cli, &param.ctx, get->dfu_metadata_check.update_firmware_index,
get->dfu_metadata_check.metadata);
case ESP_BLE_MESH_DFU_OP_UPDATE_GET:
return bt_mesh_dfu_cli_status_get(dfu_cli, &param.ctx);
case ESP_BLE_MESH_DFU_OP_UPDATE_START:
// automatic start
return 0;
case ESP_BLE_MESH_DFU_OP_UPDATE_CANCEL:
return bt_mesh_dfu_cli_cancel(dfu_cli, &param.ctx);
case ESP_BLE_MESH_DFU_OP_UPDATE_APPLY:
return bt_mesh_dfu_cli_apply(dfu_cli);
default:
BT_ERR("Invalid Device firmware Get opcode 0x%04x", param.opcode);
return -EINVAL;
}
}
void btc_ble_mesh_dfu_client_call_handler(btc_msg_t *msg)
{
esp_ble_mesh_dfu_client_cb_param_t cb = {0};
btc_ble_mesh_dfu_client_args_t *arg = NULL;
if (!msg) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
arg = (btc_ble_mesh_dfu_client_args_t *)msg->arg;
switch (msg->act) {
case BTC_BLE_MESH_ACT_DFU_CLIENT_GET_STATE:
cb.params = arg->dfu_get.params;
cb.send.err_code = btc_ble_mesh_dfu_client_get_state(arg->dfu_get.params,
arg->dfu_get.get);
btc_ble_mesh_dfu_client_cb(&cb,
ESP_BLE_MESH_DFU_CLIENT_SEND_COMP_EVT);
break;
case BTC_BLE_MESH_ACT_DFU_CLIENT_IMG_SEND:
cb.send.err_code = bt_mesh_dfu_cli_send((struct bt_mesh_dfu_cli *)arg->send_arg.cli,
(struct bt_mesh_blob_cli_inputs *)arg->send_arg.inputs,
(struct bt_mesh_blob_io *)arg->send_arg.io,
(struct bt_mesh_dfu_cli_xfer *)arg->send_arg.xfer);
btc_ble_mesh_dfu_client_cb(&cb,
ESP_BLE_MESH_DFU_CLIENT_IMG_SEND_CMP_EVT);
break;
default:
break;
}
btc_ble_mesh_dfu_client_arg_deep_free(msg);
}
void btc_ble_mesh_dfu_client_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_dfu_client_cb_param_t *arg = NULL;
if (!msg) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
arg = (esp_ble_mesh_dfu_client_cb_param_t *)msg->arg;
if (msg->act < ESP_BLE_MESH_DFU_CLIENT_EVT_MAX) {
btc_ble_mesh_dfu_client_cb_to_app(msg->act, arg);
} else {
BT_ERR("%s, Unknown act %d", __func__, msg->act);
}
btc_ble_mesh_dfu_client_free_req_data(msg);
}
uint8_t btc_ble_mesh_dfu_cli_progress(struct esp_ble_mesh_dfu_cli *cli)
{
return bt_mesh_dfu_cli_progress((struct bt_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)
{
bt_mesh_dfu_srv_verified((struct bt_mesh_dfu_srv *)srv);
}
void btc_ble_mesh_dfu_srv_rejected(esp_ble_mesh_dfu_srv_t *srv)
{
bt_mesh_dfu_srv_rejected((struct bt_mesh_dfu_srv *)srv);
}
void btc_ble_mesh_dfu_srv_cancel(esp_ble_mesh_dfu_srv_t *srv)
{
bt_mesh_dfu_srv_cancel((struct bt_mesh_dfu_srv *)srv);
}
void btc_ble_mesh_dfu_srv_applied(esp_ble_mesh_dfu_srv_t *srv)
{
bt_mesh_dfu_srv_applied((struct bt_mesh_dfu_srv *)srv);
}
bool btc_ble_mesh_dfu_srv_is_busy(const esp_ble_mesh_dfu_srv_t *srv)
{
return bt_mesh_dfu_srv_is_busy((struct bt_mesh_dfu_srv *)srv);
}
uint8_t btc_ble_mesh_dfu_srv_progress(const esp_ble_mesh_dfu_srv_t *srv)
{
return bt_mesh_dfu_srv_progress((struct bt_mesh_dfu_srv *)srv);
}
#endif /* CONFIG_BLE_MESH_DFU_SRV */
@@ -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,74 @@
/*
* 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 */
#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
+30 -24
View File
@@ -1,29 +1,35 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#define BT_MESH_DFD_OP_RECEIVERS_ADD BT_MESH_MODEL_OP_2(0x83, 0x11)
#define BT_MESH_DFD_OP_RECEIVERS_DELETE_ALL BT_MESH_MODEL_OP_2(0x83, 0x12)
#define BT_MESH_DFD_OP_RECEIVERS_STATUS BT_MESH_MODEL_OP_2(0x83, 0x13)
#define BT_MESH_DFD_OP_RECEIVERS_GET BT_MESH_MODEL_OP_2(0x83, 0x14)
#define BT_MESH_DFD_OP_RECEIVERS_LIST BT_MESH_MODEL_OP_2(0x83, 0x15)
#define BT_MESH_DFD_OP_CAPABILITIES_GET BT_MESH_MODEL_OP_2(0x83, 0x16)
#define BT_MESH_DFD_OP_CAPABILITIES_STATUS BT_MESH_MODEL_OP_2(0x83, 0x17)
#define BT_MESH_DFD_OP_GET BT_MESH_MODEL_OP_2(0x83, 0x18)
#define BT_MESH_DFD_OP_START BT_MESH_MODEL_OP_2(0x83, 0x19)
#define BT_MESH_DFD_OP_SUSPEND BT_MESH_MODEL_OP_2(0x83, 0x1a)
#define BT_MESH_DFD_OP_CANCEL BT_MESH_MODEL_OP_2(0x83, 0x1b)
#define BT_MESH_DFD_OP_APPLY BT_MESH_MODEL_OP_2(0x83, 0x1c)
#define BT_MESH_DFD_OP_STATUS BT_MESH_MODEL_OP_2(0x83, 0x1d)
#define BT_MESH_DFD_OP_UPLOAD_GET BT_MESH_MODEL_OP_2(0x83, 0x1e)
#define BT_MESH_DFD_OP_UPLOAD_START BT_MESH_MODEL_OP_2(0x83, 0x1f)
#define BT_MESH_DFD_OP_UPLOAD_START_OOB BT_MESH_MODEL_OP_2(0x83, 0x20)
#define BT_MESH_DFD_OP_UPLOAD_CANCEL BT_MESH_MODEL_OP_2(0x83, 0x21)
#define BT_MESH_DFD_OP_UPLOAD_STATUS BT_MESH_MODEL_OP_2(0x83, 0x22)
#define BT_MESH_DFD_OP_FW_GET BT_MESH_MODEL_OP_2(0x83, 0x23)
#define BT_MESH_DFD_OP_FW_GET_BY_INDEX BT_MESH_MODEL_OP_2(0x83, 0x24)
#define BT_MESH_DFD_OP_FW_DELETE BT_MESH_MODEL_OP_2(0x83, 0x25)
#define BT_MESH_DFD_OP_FW_DELETE_ALL BT_MESH_MODEL_OP_2(0x83, 0x26)
#define BT_MESH_DFD_OP_FW_STATUS BT_MESH_MODEL_OP_2(0x83, 0x27)
#include "access.h"
/* @todo: adapt to dfd client */
#if CONFIG_BLE_MESH_DFD_SRV
#define BT_MESH_DFD_OP_RECEIVERS_ADD BLE_MESH_MODEL_OP_2(0x83, 0x11)
#define BT_MESH_DFD_OP_RECEIVERS_DELETE_ALL BLE_MESH_MODEL_OP_2(0x83, 0x12)
#define BT_MESH_DFD_OP_RECEIVERS_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x13)
#define BT_MESH_DFD_OP_RECEIVERS_GET BLE_MESH_MODEL_OP_2(0x83, 0x14)
#define BT_MESH_DFD_OP_RECEIVERS_LIST BLE_MESH_MODEL_OP_2(0x83, 0x15)
#define BT_MESH_DFD_OP_CAPABILITIES_GET BLE_MESH_MODEL_OP_2(0x83, 0x16)
#define BT_MESH_DFD_OP_CAPABILITIES_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x17)
#define BT_MESH_DFD_OP_GET BLE_MESH_MODEL_OP_2(0x83, 0x18)
#define BT_MESH_DFD_OP_START BLE_MESH_MODEL_OP_2(0x83, 0x19)
#define BT_MESH_DFD_OP_SUSPEND BLE_MESH_MODEL_OP_2(0x83, 0x1a)
#define BT_MESH_DFD_OP_CANCEL BLE_MESH_MODEL_OP_2(0x83, 0x1b)
#define BT_MESH_DFD_OP_APPLY BLE_MESH_MODEL_OP_2(0x83, 0x1c)
#define BT_MESH_DFD_OP_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x1d)
#define BT_MESH_DFD_OP_UPLOAD_GET BLE_MESH_MODEL_OP_2(0x83, 0x1e)
#define BT_MESH_DFD_OP_UPLOAD_START BLE_MESH_MODEL_OP_2(0x83, 0x1f)
#define BT_MESH_DFD_OP_UPLOAD_START_OOB BLE_MESH_MODEL_OP_2(0x83, 0x20)
#define BT_MESH_DFD_OP_UPLOAD_CANCEL BLE_MESH_MODEL_OP_2(0x83, 0x21)
#define BT_MESH_DFD_OP_UPLOAD_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x22)
#define BT_MESH_DFD_OP_FW_GET BLE_MESH_MODEL_OP_2(0x83, 0x23)
#define BT_MESH_DFD_OP_FW_GET_BY_INDEX BLE_MESH_MODEL_OP_2(0x83, 0x24)
#define BT_MESH_DFD_OP_FW_DELETE BLE_MESH_MODEL_OP_2(0x83, 0x25)
#define BT_MESH_DFD_OP_FW_DELETE_ALL BLE_MESH_MODEL_OP_2(0x83, 0x26)
#define BT_MESH_DFD_OP_FW_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x27)
#endif
File diff suppressed because it is too large Load Diff
@@ -1,47 +1,49 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFD_SRV_INTERNAL_H__
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFD_SRV_INTERNAL_H__
#ifndef _BLE_MESH_v11_DFD_SRV_INTERNAL_H__
#define _BLE_MESH_v11_DFD_SRV_INTERNAL_H__
#include <zephyr/bluetooth/mesh.h>
#include "mesh_v1.1/dfu/dfd_srv.h"
#if CONFIG_BLE_MESH_DFD_SRV
#ifdef __cplusplus
extern "C" {
#endif
struct bt_mesh_dfd_start_params {
uint16_t app_idx, timeout_base, slot_idx, group;
enum bt_mesh_blob_xfer_mode xfer_mode;
uint8_t ttl;
bool apply;
uint16_t app_idx, timeout_base, slot_idx, group;
enum bt_mesh_blob_xfer_mode xfer_mode;
uint8_t ttl;
bool apply;
};
enum bt_mesh_dfd_status bt_mesh_dfd_srv_receiver_add(struct bt_mesh_dfd_srv *srv, uint16_t addr,
uint8_t img_idx);
uint8_t img_idx);
enum bt_mesh_dfd_status bt_mesh_dfd_srv_receivers_delete_all(struct bt_mesh_dfd_srv *srv);
enum bt_mesh_dfd_status bt_mesh_dfd_srv_start(struct bt_mesh_dfd_srv *srv,
struct bt_mesh_dfd_start_params *params);
struct bt_mesh_dfd_start_params *params);
enum bt_mesh_dfd_status bt_mesh_dfd_srv_suspend(struct bt_mesh_dfd_srv *srv);
enum bt_mesh_dfd_status bt_mesh_dfd_srv_cancel(struct bt_mesh_dfd_srv *srv,
struct bt_mesh_msg_ctx *ctx);
struct bt_mesh_msg_ctx *ctx);
enum bt_mesh_dfd_status bt_mesh_dfd_srv_apply(struct bt_mesh_dfd_srv *srv);
enum bt_mesh_dfd_status bt_mesh_dfd_srv_fw_delete(struct bt_mesh_dfd_srv *srv, size_t *fwid_len,
const uint8_t **fwid);
const uint8_t **fwid);
enum bt_mesh_dfd_status bt_mesh_dfd_srv_fw_delete_all(struct bt_mesh_dfd_srv *srv);
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFD_SRV_INTERNAL_H__ */
#endif
#endif /* _BLE_MESH_v11_DFD_SRV_INTERNAL_H__ */
+30 -27
View File
@@ -1,44 +1,47 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "mesh/buf.h"
#define BT_MESH_DFU_OP_UPDATE_INFO_GET BT_MESH_MODEL_OP_2(0x83, 0x08)
#define BT_MESH_DFU_OP_UPDATE_INFO_STATUS BT_MESH_MODEL_OP_2(0x83, 0x09)
#if CONFIG_BLE_MESH_DFU_SRV || CONFIG_BLE_MESH_DFU_CLI
#define BLE_MESH_DFU_OP_UPDATE_INFO_GET BLE_MESH_MODEL_OP_2(0x83, 0x08)
#define BLE_MESH_DFU_OP_UPDATE_INFO_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x09)
#define BT_MESH_DFU_OP_UPDATE_METADATA_CHECK BT_MESH_MODEL_OP_2(0x83, 0x0a)
#define BT_MESH_DFU_OP_UPDATE_METADATA_STATUS BT_MESH_MODEL_OP_2(0x83, 0x0b)
#define BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK BLE_MESH_MODEL_OP_2(0x83, 0x0a)
#define BLE_MESH_DFU_OP_UPDATE_METADATA_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x0b)
#define BT_MESH_DFU_OP_UPDATE_GET BT_MESH_MODEL_OP_2(0x83, 0x0c)
#define BT_MESH_DFU_OP_UPDATE_START BT_MESH_MODEL_OP_2(0x83, 0x0d)
#define BT_MESH_DFU_OP_UPDATE_CANCEL BT_MESH_MODEL_OP_2(0x83, 0x0e)
#define BT_MESH_DFU_OP_UPDATE_APPLY BT_MESH_MODEL_OP_2(0x83, 0x0f)
#define BT_MESH_DFU_OP_UPDATE_STATUS BT_MESH_MODEL_OP_2(0x83, 0x10)
#define BLE_MESH_DFU_OP_UPDATE_GET BLE_MESH_MODEL_OP_2(0x83, 0x0c)
#define BLE_MESH_DFU_OP_UPDATE_START BLE_MESH_MODEL_OP_2(0x83, 0x0d)
#define BLE_MESH_DFU_OP_UPDATE_CANCEL BLE_MESH_MODEL_OP_2(0x83, 0x0e)
#define BLE_MESH_DFU_OP_UPDATE_APPLY BLE_MESH_MODEL_OP_2(0x83, 0x0f)
#define BLE_MESH_DFU_OP_UPDATE_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x10)
#define DFU_UPDATE_INFO_STATUS_MSG_MINLEN (4 + CONFIG_BT_MESH_DFU_FWID_MAXLEN + \
CONFIG_BT_MESH_DFU_URI_MAXLEN)
#define DFU_UPDATE_START_MSG_MAXLEN (12 + CONFIG_BT_MESH_DFU_METADATA_MAXLEN)
#define DFU_UPDATE_INFO_STATUS_MSG_MINLEN (4 + CONFIG_BLE_MESH_DFU_FWID_MAXLEN + \
CONFIG_BLE_MESH_DFU_URI_MAXLEN)
#define DFU_UPDATE_START_MSG_MAXLEN (12 + CONFIG_BLE_MESH_DFU_METADATA_MAXLEN)
static inline uint16_t dfu_metadata_checksum(struct net_buf_simple *buf)
{
/* Simple Fletcher-16 checksum to ensure duplicate start messages don't
* have different metadata.
*/
struct net_buf_simple_state state;
uint8_t sum[2] = {0, 0};
/* Simple Fletcher-16 checksum to ensure duplicate start messages don't
* have different metadata.
*/
struct net_buf_simple_state state;
uint8_t sum[2] = {0, 0};
net_buf_simple_save(buf, &state);
net_buf_simple_save(buf, &state);
while (buf->len) {
uint8_t byte = net_buf_simple_pull_u8(buf);
while (buf->len) {
uint8_t byte = net_buf_simple_pull_u8(buf);
sum[0] += byte;
sum[1] += sum[0];
}
sum[0] += byte;
sum[1] += sum[0];
}
net_buf_simple_restore(buf, &state);
net_buf_simple_restore(buf, &state);
return (sum[0] << 8U) | sum[1];
return (sum[0] << 8U) | sum[1];
}
#endif /* CONFIG_BLE_MESH_DFU_SRV || CONFIG_BLE_MESH_DFU_CLI */
File diff suppressed because it is too large Load Diff
@@ -1,102 +1,105 @@
/*
* Copyright (c) 2021 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/net_buf.h>
#include <zephyr/sys/byteorder.h>
#include <string.h>
#include <zephyr/bluetooth/mesh.h>
#include "crypto.h"
#include "access.h"
#include "mesh/byteorder.h"
#include "mesh/buf.h"
#include "mesh_v1.1/dfu/dfu_metadata.h"
#if CONFIG_BLE_MESH_DFU_METADATA
int bt_mesh_dfu_metadata_decode(struct net_buf_simple *buf,
struct bt_mesh_dfu_metadata *metadata)
struct bt_mesh_dfu_metadata *metadata)
{
if (buf->len < 12) {
return -EMSGSIZE;
}
if (buf->len < 12) {
return -EMSGSIZE;
}
metadata->fw_ver.major = net_buf_simple_pull_u8(buf);
metadata->fw_ver.minor = net_buf_simple_pull_u8(buf);
metadata->fw_ver.revision = net_buf_simple_pull_le16(buf);
metadata->fw_ver.build_num = net_buf_simple_pull_le32(buf);
metadata->fw_size = net_buf_simple_pull_le24(buf);
metadata->fw_core_type = net_buf_simple_pull_u8(buf);
metadata->fw_ver.major = net_buf_simple_pull_u8(buf);
metadata->fw_ver.minor = net_buf_simple_pull_u8(buf);
metadata->fw_ver.revision = net_buf_simple_pull_le16(buf);
metadata->fw_ver.build_num = net_buf_simple_pull_le32(buf);
metadata->fw_size = net_buf_simple_pull_le24(buf);
metadata->fw_core_type = net_buf_simple_pull_u8(buf);
if (metadata->fw_core_type & BT_MESH_DFU_FW_CORE_TYPE_APP) {
if (buf->len < 6) {
return -EMSGSIZE;
}
if (metadata->fw_core_type & BLE_MESH_DFU_FW_CORE_TYPE_APP) {
if (buf->len < 6) {
return -EMSGSIZE;
}
metadata->comp_hash = net_buf_simple_pull_le32(buf);
metadata->elems = net_buf_simple_pull_le16(buf);
}
metadata->comp_hash = net_buf_simple_pull_le32(buf);
metadata->elems = net_buf_simple_pull_le16(buf);
}
metadata->user_data = buf->len > 0 ? buf->data : NULL;
metadata->user_data_len = buf->len;
metadata->user_data = buf->len > 0 ? buf->data : NULL;
metadata->user_data_len = buf->len;
return 0;
return 0;
}
int bt_mesh_dfu_metadata_encode(const struct bt_mesh_dfu_metadata *metadata,
struct net_buf_simple *buf)
struct net_buf_simple *buf)
{
size_t md_len_min = 12 + metadata->user_data_len;
size_t md_len_min = 12 + metadata->user_data_len;
if (metadata->fw_core_type & BT_MESH_DFU_FW_CORE_TYPE_APP) {
md_len_min += 6;
}
if (metadata->fw_core_type & BLE_MESH_DFU_FW_CORE_TYPE_APP) {
md_len_min += 6;
}
if (net_buf_simple_tailroom(buf) < md_len_min) {
return -EMSGSIZE;
}
if (net_buf_simple_tailroom(buf) < md_len_min) {
return -EMSGSIZE;
}
net_buf_simple_add_u8(buf, metadata->fw_ver.major);
net_buf_simple_add_u8(buf, metadata->fw_ver.minor);
net_buf_simple_add_le16(buf, metadata->fw_ver.revision);
net_buf_simple_add_le32(buf, metadata->fw_ver.build_num);
net_buf_simple_add_le24(buf, metadata->fw_size);
net_buf_simple_add_u8(buf, metadata->fw_core_type);
net_buf_simple_add_le32(buf, metadata->comp_hash);
net_buf_simple_add_le16(buf, metadata->elems);
net_buf_simple_add_u8(buf, metadata->fw_ver.major);
net_buf_simple_add_u8(buf, metadata->fw_ver.minor);
net_buf_simple_add_le16(buf, metadata->fw_ver.revision);
net_buf_simple_add_le32(buf, metadata->fw_ver.build_num);
net_buf_simple_add_le24(buf, metadata->fw_size);
net_buf_simple_add_u8(buf, metadata->fw_core_type);
net_buf_simple_add_le32(buf, metadata->comp_hash);
net_buf_simple_add_le16(buf, metadata->elems);
if (metadata->user_data_len > 0) {
net_buf_simple_add_mem(buf, metadata->user_data, metadata->user_data_len);
}
if (metadata->user_data_len > 0) {
net_buf_simple_add_mem(buf, metadata->user_data, metadata->user_data_len);
}
return 0;
return 0;
}
int bt_mesh_dfu_metadata_comp_hash_get(struct net_buf_simple *buf, uint8_t *key, uint32_t *hash)
{
uint8_t mac[16];
int err;
struct bt_mesh_sg sg = {.data = buf->data, .len = buf->len};
uint8_t mac[16];
int err;
struct bt_mesh_sg sg = {.data = buf->data, .len = buf->len};
err = bt_mesh_aes_cmac_raw_key(key, &sg, 1, mac);
if (err) {
return err;
}
/* The implementation of this function is the same as function `bt_mesh_aes_cmac_raw_key` in Zephyr. */
err = bt_mesh_aes_cmac(key, &sg, 1, mac);
if (err) {
return err;
}
*hash = sys_get_le32(mac);
*hash = sys_get_le32(mac);
return 0;
return 0;
}
int bt_mesh_dfu_metadata_comp_hash_local_get(uint8_t *key, uint32_t *hash)
{
NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_TX_SDU_MAX);
int err;
NET_BUF_SIMPLE_DEFINE(buf, BLE_MESH_TX_SDU_MAX);
int err;
err = bt_mesh_comp_data_get_page_0(&buf, 0);
if (err) {
return err;
}
err = bt_mesh_get_comp_data(&buf, 0, 0, true);
if (err) {
return err;
}
err = bt_mesh_dfu_metadata_comp_hash_get(&buf, key, hash);
return err;
err = bt_mesh_dfu_metadata_comp_hash_get(&buf, key, hash);
return err;
}
#endif /* CONFIG_BLE_MESH_DFU_METADATA */
+286 -244
View File
@@ -1,402 +1,444 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/settings/settings.h>
#include "dfu_slot.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <zephyr/sys/util.h>
#include <common/bt_str.h>
#define LOG_LEVEL CONFIG_BT_MESH_DFU_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_mesh_dfu_slot);
#include "mesh/common.h"
#include "mesh/utils.h"
#include "settings_nvs.h"
#include "settings.h"
#if CONFIG_BLE_MESH_DFU_SLOTS
#define SLOT_ENTRY_BUFLEN 25
#define DFU_SLOT_SETTINGS_PATH "bt/mesh-dfu/slot"
#define DFU_SLOT_SETTINGS_PATH "mesh/dfu/s"
#define HEADER_SIZE offsetof(struct slot, slot.fwid)
#define PROP_HEADER "h"
#define PROP_FWID "id"
#define PROP_METADATA "m"
#define SETTINGS_NAME_END '='
#define SETTINGS_NAME_SEPARATOR '/'
static sys_slist_t list;
static struct slot {
uint32_t idx;
struct bt_mesh_dfu_slot slot;
sys_snode_t n;
} slots[CONFIG_BT_MESH_DFU_SLOT_CNT];
uint32_t idx;
struct bt_mesh_dfu_slot slot;
sys_snode_t n;
} slots[CONFIG_BLE_MESH_DFU_SLOT_CNT];
static uint32_t slot_index;
static char *slot_entry_encode(uint16_t idx, char buf[SLOT_ENTRY_BUFLEN],
const char *property)
inline int settings_name_next(const char *name, const char **next)
{
snprintf(buf, SLOT_ENTRY_BUFLEN, DFU_SLOT_SETTINGS_PATH "/%x/%s", idx,
property);
int rc = 0;
return buf;
if (next) {
*next = NULL;
}
if (!name) {
return 0;
}
/* name might come from flash directly, in flash the name would end
* with '=' or '\0' depending how storage is done. Flash reading is
* limited to what can be read
*/
while ((*name != '\0') && (*name != SETTINGS_NAME_END) &&
(*name != SETTINGS_NAME_SEPARATOR)) {
rc++;
name++;
}
if (*name == SETTINGS_NAME_SEPARATOR) {
if (next) {
*next = name + 1;
}
return rc;
}
return rc;
}
static bool slot_eq(const struct bt_mesh_dfu_slot *slot,
const uint8_t *fwid, size_t fwid_len)
#if CONFIG_BLE_MESH_SETTINGS
static char *slot_entry_encode(uint16_t idx, char buf[SLOT_ENTRY_BUFLEN],
const char *property)
{
return (slot->fwid_len == fwid_len) &&
!memcmp(fwid, slot->fwid, fwid_len);
snprintf(buf, SLOT_ENTRY_BUFLEN, DFU_SLOT_SETTINGS_PATH "/%x/%s", idx,
property);
return buf;
}
#endif
static bool slot_eq(const struct bt_mesh_dfu_slot *slot,
const uint8_t *fwid, size_t fwid_len)
{
return (slot->fwid_len == fwid_len) &&
!memcmp(fwid, slot->fwid, fwid_len);
}
static bool is_slot_committed(struct slot *slot_to_check)
{
struct slot *s;
struct slot *s;
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
if (s == slot_to_check) {
return true;
}
}
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
if (s == slot_to_check) {
return true;
}
}
return false;
return false;
}
static int slot_store(const struct slot *slot_to_store)
{
uint16_t idx = ARRAY_INDEX(slots, slot_to_store);
char buf[SLOT_ENTRY_BUFLEN];
int err;
int err = 0;
#if CONFIG_BLE_MESH_SETTINGS
uint16_t idx = ARRAY_INDEX(slots, slot_to_store);
char buf[SLOT_ENTRY_BUFLEN];
err = settings_save_one(slot_entry_encode(idx, buf, PROP_HEADER),
slot_to_store, HEADER_SIZE);
if (err) {
return err;
}
err = bt_mesh_save_core_settings(slot_entry_encode(idx, buf, PROP_HEADER),
(uint8_t *)slot_to_store, HEADER_SIZE);
if (err) {
return err;
}
err = settings_save_one(slot_entry_encode(idx, buf, PROP_FWID),
slot_to_store->slot.fwid, slot_to_store->slot.fwid_len);
if (err) {
return err;
}
err = bt_mesh_save_core_settings(slot_entry_encode(idx, buf, PROP_FWID),
slot_to_store->slot.fwid, slot_to_store->slot.fwid_len);
if (err) {
return err;
}
err = settings_save_one(slot_entry_encode(idx, buf,
PROP_METADATA),
slot_to_store->slot.metadata, slot_to_store->slot.metadata_len);
err = bt_mesh_save_core_settings(slot_entry_encode(idx, buf, PROP_METADATA),
slot_to_store->slot.metadata, slot_to_store->slot.metadata_len);
return err;
#endif
return err;
}
static void slot_erase(struct slot *slot_to_erase)
{
uint16_t idx = ARRAY_INDEX(slots, slot_to_erase);
char buf[SLOT_ENTRY_BUFLEN];
#if CONFIG_BLE_MESH_SETTINGS
uint16_t idx = ARRAY_INDEX(slots, slot_to_erase);
char buf[SLOT_ENTRY_BUFLEN];
(void)settings_delete(slot_entry_encode(idx, buf, PROP_HEADER));
(void)settings_delete(slot_entry_encode(idx, buf, PROP_FWID));
(void)settings_delete(slot_entry_encode(idx, buf, PROP_METADATA));
bt_mesh_erase_core_settings(slot_entry_encode(idx, buf, PROP_HEADER));
bt_mesh_erase_core_settings(slot_entry_encode(idx, buf, PROP_FWID));
bt_mesh_erase_core_settings(slot_entry_encode(idx, buf, PROP_METADATA));
#endif
}
static void slot_index_defrag(void)
{
slot_index = 0;
struct slot *s;
slot_index = 0;
struct slot *s;
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
s->idx = ++slot_index;
slot_store(s);
}
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
s->idx = ++slot_index;
slot_store(s);
}
}
int bt_mesh_dfu_slot_count(void)
{
int cnt = 0;
sys_snode_t *n;
int cnt = 0;
sys_snode_t *n;
SYS_SLIST_FOR_EACH_NODE(&list, n) {
cnt++;
}
SYS_SLIST_FOR_EACH_NODE(&list, n) {
cnt++;
}
return cnt;
return cnt;
}
struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_reserve(void)
{
struct slot *slot = NULL;
struct slot *slot = NULL;
for (int i = 0; i < ARRAY_SIZE(slots); ++i) {
if (slots[i].idx == 0) {
slot = &slots[i];
break;
}
}
for (int i = 0; i < ARRAY_SIZE(slots); ++i) {
if (slots[i].idx == 0) {
slot = &slots[i];
break;
}
}
if (!slot) {
LOG_WRN("No space");
return NULL;
}
if (!slot) {
BT_WARN("No space");
return NULL;
}
if (slot_index == UINT32_MAX) {
slot_index_defrag();
}
if (slot_index == UINT32_MAX) {
slot_index_defrag();
}
slot->slot.fwid_len = 0;
slot->slot.metadata_len = 0;
slot->slot.size = 0;
slot->idx = ++slot_index;
slot->slot.fwid_len = 0;
slot->slot.metadata_len = 0;
slot->slot.size = 0;
slot->idx = ++slot_index;
LOG_DBG("Reserved slot #%u", slot - &slots[0]);
BT_DBG("Reserved slot #%u", slot - &slots[0]);
return &slot->slot;
return &slot->slot;
}
int bt_mesh_dfu_slot_info_set(struct bt_mesh_dfu_slot *dfu_slot, size_t size,
const uint8_t *metadata, size_t metadata_len)
const uint8_t *metadata, size_t metadata_len)
{
struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot);
struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot);
if (metadata_len > CONFIG_BT_MESH_DFU_METADATA_MAXLEN) {
return -EFBIG;
}
if (metadata_len > CONFIG_BLE_MESH_DFU_METADATA_MAXLEN) {
return -EFBIG;
}
if (slot->idx == 0 || is_slot_committed(slot)) {
return -EINVAL;
}
if (slot->idx == 0 || is_slot_committed(slot)) {
return -EINVAL;
}
slot->slot.size = size;
slot->slot.metadata_len = metadata_len;
memcpy(slot->slot.metadata, metadata, metadata_len);
return 0;
slot->slot.size = size;
slot->slot.metadata_len = metadata_len;
memcpy(slot->slot.metadata, metadata, metadata_len);
return 0;
}
int bt_mesh_dfu_slot_fwid_set(struct bt_mesh_dfu_slot *dfu_slot,
const uint8_t *fwid, size_t fwid_len)
const uint8_t *fwid, size_t fwid_len)
{
struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot);
struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot);
if (fwid_len > CONFIG_BT_MESH_DFU_FWID_MAXLEN) {
return -EFBIG;
}
if (fwid_len > CONFIG_BLE_MESH_DFU_FWID_MAXLEN) {
return -EFBIG;
}
if (slot->idx == 0 || is_slot_committed(slot)) {
return -EINVAL;
}
if (slot->idx == 0) {
return -EINVAL;
}
for (int i = 0; i < ARRAY_SIZE(slots); i++) {
if (slots[i].idx != 0 &&
slot_eq(&slots[i].slot, fwid, fwid_len)) {
return is_slot_committed(&slots[i]) ?
-EEXIST : -EALREADY;
}
}
if (is_slot_committed(slot)) {
return -EEXIST;
}
slot->slot.fwid_len = fwid_len;
memcpy(slot->slot.fwid, fwid, fwid_len);
return 0;
for (int i = 0; i < ARRAY_SIZE(slots); i++) {
if (slots[i].idx != 0 &&
slot_eq(&slots[i].slot, fwid, fwid_len)) {
return -EALREADY;
}
}
slot->slot.fwid_len = fwid_len;
memcpy(slot->slot.fwid, fwid, fwid_len);
return 0;
}
int bt_mesh_dfu_slot_commit(struct bt_mesh_dfu_slot *dfu_slot)
{
int err;
struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot);
int err;
struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot);
if (slot->idx == 0 ||
slot->slot.fwid_len == 0 ||
slot->slot.size == 0 ||
is_slot_committed(slot)) {
return -EINVAL;
}
if (slot->idx == 0 ||
slot->slot.fwid_len == 0 ||
slot->slot.size == 0 ||
is_slot_committed(slot)) {
return -EINVAL;
}
err = slot_store(slot);
if (err) {
LOG_WRN("Store failed (err: %d)", err);
return err;
}
err = slot_store(slot);
if (err) {
BT_WARN("Store failed (err: %d)", err);
return err;
}
sys_slist_append(&list, &slot->n);
sys_slist_append(&list, &slot->n);
LOG_DBG("Stored slot #%u: %s", ARRAY_INDEX(slots, slot),
bt_hex(slot->slot.fwid, slot->slot.fwid_len));
return 0;
BT_DBG("Stored slot #%u: %s", ARRAY_INDEX(slots, slot),
bt_hex(slot->slot.fwid, slot->slot.fwid_len));
return 0;
}
void bt_mesh_dfu_slot_release(const struct bt_mesh_dfu_slot *dfu_slot)
{
struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot);
struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot);
if (is_slot_committed(slot)) {
return;
}
if (is_slot_committed(slot)) {
return;
}
slot->idx = 0;
slot->idx = 0;
}
int bt_mesh_dfu_slot_del(const struct bt_mesh_dfu_slot *dfu_slot)
{
struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot);
struct slot *slot = CONTAINER_OF(dfu_slot, struct slot, slot);
if (!sys_slist_find_and_remove(&list, &slot->n)) {
return -EINVAL;
}
if (!sys_slist_find_and_remove(&list, &slot->n)) {
return -EINVAL;
}
int idx = ARRAY_INDEX(slots, slot);
int idx = ARRAY_INDEX(slots, slot);
LOG_DBG("%u", idx);
BT_DBG("%u", idx);
slot_erase(slot);
slot->idx = 0;
slot_erase(slot);
slot->idx = 0;
return 0;
return 0;
}
void bt_mesh_dfu_slot_del_all(void)
{
struct slot *s;
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
slot_erase(s);
s->idx = 0;
}
struct slot *s;
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
slot_erase(s);
s->idx = 0;
}
sys_slist_init(&list);
sys_slist_init(&list);
}
const struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_at(uint16_t img_idx)
{
struct slot *s;
struct slot *s;
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
if (!img_idx--) {
return &s->slot;
}
}
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
if (!img_idx--) {
return &s->slot;
}
}
return NULL;
return NULL;
}
int bt_mesh_dfu_slot_get(const uint8_t *fwid, size_t fwid_len, struct bt_mesh_dfu_slot **slot)
{
struct slot *s;
int idx = 0;
struct slot *s;
int idx = 0;
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
if (slot_eq(&s->slot, fwid, fwid_len)) {
if (slot) {
*slot = &s->slot;
}
return idx;
}
idx++;
}
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
if (slot_eq(&s->slot, fwid, fwid_len)) {
if (slot) {
*slot = &s->slot;
}
return idx;
}
idx++;
}
return -ENOENT;
return -ENOENT;
}
int bt_mesh_dfu_slot_img_idx_get(const struct bt_mesh_dfu_slot *dfu_slot)
{
struct slot *s;
int idx = 0;
struct slot *s;
int idx = 0;
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
if (&s->slot == dfu_slot) {
return idx;
}
idx++;
}
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
if (&s->slot == dfu_slot) {
return idx;
}
idx++;
}
return -ENOENT;
return -ENOENT;
}
size_t bt_mesh_dfu_slot_foreach(bt_mesh_dfu_slot_cb_t cb, void *user_data)
{
enum bt_mesh_dfu_iter iter;
size_t cnt = 0;
struct slot *s;
enum bt_mesh_dfu_iter iter;
size_t cnt = 0;
struct slot *s;
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
cnt++;
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
cnt++;
if (!cb) {
continue;
}
if (!cb) {
continue;
}
iter = cb(&s->slot, user_data);
if (iter != BT_MESH_DFU_ITER_CONTINUE) {
break;
}
}
iter = cb(&s->slot, user_data);
if (iter != BLE_MESH_DFU_ITER_CONTINUE) {
break;
}
}
return cnt;
return cnt;
}
#if 0
static int slot_data_load(const char *key, size_t len_rd,
settings_read_cb read_cb, void *cb_arg)
settings_read_cb read_cb, void *cb_arg)
{
const char *prop;
size_t len;
uint16_t idx;
const char *prop;
size_t len;
uint16_t idx;
idx = strtol(key, NULL, 16);
idx = strtol(key, NULL, 16);
if (idx >= ARRAY_SIZE(slots)) {
return 0;
}
if (idx >= ARRAY_SIZE(slots)) {
return 0;
}
len = settings_name_next(key, &prop);
len = settings_name_next(key, &prop);
if (!strncmp(prop, PROP_HEADER, len)) {
if (read_cb(cb_arg, &slots[idx], HEADER_SIZE) > 0) {
struct slot *s, *prev = NULL;
if (!strncmp(prop, PROP_HEADER, len)) {
if (read_cb(cb_arg, &slots[idx], HEADER_SIZE) > 0) {
struct slot *s, *prev = NULL;
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
if (s->idx > slots[idx].idx) {
break;
}
SYS_SLIST_FOR_EACH_CONTAINER(&list, s, n) {
if (s->idx > slots[idx].idx) {
break;
}
prev = s;
}
prev = s;
}
if (prev == NULL) {
sys_slist_prepend(&list, &slots[idx].n);
} else {
sys_slist_insert(&list, &prev->n, &slots[idx].n);
}
if (prev == NULL) {
sys_slist_prepend(&list, &slots[idx].n);
} else {
sys_slist_insert(&list, &prev->n, &slots[idx].n);
}
if (slots[idx].idx >= slot_index) {
slot_index = slots[idx].idx + 1;
}
}
return 0;
}
if (slots[idx].idx >= slot_index) {
slot_index = slots[idx].idx + 1;
}
}
return 0;
}
if (!strncmp(prop, PROP_FWID, len)) {
if (read_cb(cb_arg, &slots[idx].slot.fwid,
sizeof(slots[idx].slot.fwid)) < 0) {
slots[idx].idx = 0;
sys_slist_find_and_remove(&list, &slots[idx].n);
return 0;
}
if (!strncmp(prop, PROP_FWID, len)) {
if (read_cb(cb_arg, &slots[idx].slot.fwid,
sizeof(slots[idx].slot.fwid)) < 0) {
slots[idx].idx = 0;
sys_slist_find_and_remove(&list, &slots[idx].n);
return 0;
}
slots[idx].slot.fwid_len = len_rd;
return 0;
}
slots[idx].slot.fwid_len = len_rd;
return 0;
}
if (!strncmp(prop, PROP_METADATA, len)) {
if (read_cb(cb_arg, &slots[idx].slot.metadata,
sizeof(slots[idx].slot.metadata)) < 0) {
slots[idx].idx = 0;
sys_slist_find_and_remove(&list, &slots[idx].n);
return 0;
}
if (!strncmp(prop, PROP_METADATA, len)) {
if (read_cb(cb_arg, &slots[idx].slot.metadata,
sizeof(slots[idx].slot.metadata)) < 0) {
slots[idx].idx = 0;
sys_slist_find_and_remove(&list, &slots[idx].n);
return 0;
}
slots[idx].slot.metadata_len = len_rd;
return 0;
}
slots[idx].slot.metadata_len = len_rd;
return 0;
}
return 0;
return 0;
}
SETTINGS_STATIC_HANDLER_DEFINE(bt_mesh_dfu_slots, DFU_SLOT_SETTINGS_PATH, NULL,
slot_data_load, NULL, NULL);
#endif
#endif /* CONFIG_BLE_MESH_DFU_SLOTS */
+12 -10
View File
@@ -1,11 +1,12 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/bluetooth/mesh.h>
#include "mesh_v1.1/dfu/dfu.h"
#if CONFIG_BLE_MESH_DFU_SLOTS
/** @brief Slot iteration callback.
*
* @param slot A valid DFU image slot.
@@ -13,8 +14,8 @@
*
* @return Iteration action determining next step.
*/
typedef enum bt_mesh_dfu_iter (*bt_mesh_dfu_slot_cb_t)(
const struct bt_mesh_dfu_slot *slot, void *user_data);
typedef enum bt_mesh_dfu_iter(*bt_mesh_dfu_slot_cb_t)
(const struct bt_mesh_dfu_slot *slot, void *user_data);
/** @brief Get the number of slots committed to the firmware list.
*
@@ -41,24 +42,24 @@ struct bt_mesh_dfu_slot *bt_mesh_dfu_slot_reserve(void);
* @param size The size of the image.
* @param metadata Metadata or NULL.
* @param metadata_len Length of the metadata, at most @c
* CONFIG_BT_MESH_DFU_METADATA_MAXLEN.
* CONFIG_BLE_MESH_DFU_METADATA_MAXLEN.
*
* @return 0 on success, (negative) error code otherwise.
*/
int bt_mesh_dfu_slot_info_set(struct bt_mesh_dfu_slot *dfu_slot, size_t size,
const uint8_t *metadata, size_t metadata_len);
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_BT_MESH_DFU_FWID_MAXLEN.
* CONFIG_BLE_MESH_DFU_FWID_MAXLEN.
*
* @return 0 on success, (negative) error code otherwise.
*/
int bt_mesh_dfu_slot_fwid_set(struct bt_mesh_dfu_slot *dfu_slot,
const uint8_t *fwid, size_t fwid_len);
const uint8_t *fwid, size_t fwid_len);
/** @brief Commit the reserved slot to the list of slots, and store it
* persistently.
@@ -124,7 +125,7 @@ int bt_mesh_dfu_slot_img_idx_get(const struct bt_mesh_dfu_slot *slot);
/** @brief Iterate through all DFU image slots.
*
* Calls the callback for every DFU image slot or until the callback returns
* something other than @ref BT_MESH_DFU_ITER_CONTINUE.
* something other than @ref BLE_MESH_DFU_ITER_CONTINUE.
*
* @param cb Callback to call for each slot, or NULL to just count the
* number of slots.
@@ -133,3 +134,4 @@ int bt_mesh_dfu_slot_img_idx_get(const struct bt_mesh_dfu_slot *slot);
* @return The number of slots iterated over.
*/
size_t bt_mesh_dfu_slot_foreach(bt_mesh_dfu_slot_cb_t cb, void *user_data);
#endif /* CONFIG_BLE_MESH_DFU_SLOTS */
File diff suppressed because it is too large Load Diff
@@ -1,13 +1,12 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFD_H__
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFD_H__
#include <zephyr/bluetooth/mesh.h>
#ifndef _BLE_MESH_v11_DFD_H__
#define _BLE_MESH_v11_DFD_H__
#ifdef __cplusplus
extern "C" {
@@ -21,97 +20,97 @@ extern "C" {
/** Firmware distribution status. */
enum bt_mesh_dfd_status {
/** The message was processed successfully. */
BT_MESH_DFD_SUCCESS,
/** The message was processed successfully. */
BT_MESH_DFD_SUCCESS,
/** Insufficient resources on the node. */
BT_MESH_DFD_ERR_INSUFFICIENT_RESOURCES,
/** Insufficient resources on the node. */
BT_MESH_DFD_ERR_INSUFFICIENT_RESOURCES,
/** The operation cannot be performed while the Server is in the current
* phase.
*/
BT_MESH_DFD_ERR_WRONG_PHASE,
/** The operation cannot be performed while the Server is in the current
* phase.
*/
BT_MESH_DFD_ERR_WRONG_PHASE,
/** An internal error occurred on the node. */
BT_MESH_DFD_ERR_INTERNAL,
/** An internal error occurred on the node. */
BT_MESH_DFD_ERR_INTERNAL,
/** The requested firmware image is not stored on the Distributor. */
BT_MESH_DFD_ERR_FW_NOT_FOUND,
/** The requested firmware image is not stored on the Distributor. */
BT_MESH_DFD_ERR_FW_NOT_FOUND,
/** The AppKey identified by the AppKey Index is not known to the node.
*/
BT_MESH_DFD_ERR_INVALID_APPKEY_INDEX,
/** The AppKey identified by the AppKey Index is not known to the node.
*/
BT_MESH_DFD_ERR_INVALID_APPKEY_INDEX,
/** There are no Target nodes in the Distribution Receivers List
* state.
*/
BT_MESH_DFD_ERR_RECEIVERS_LIST_EMPTY,
/** There are no Target nodes in the Distribution Receivers List
* state.
*/
BT_MESH_DFD_ERR_RECEIVERS_LIST_EMPTY,
/** Another firmware image distribution is in progress. */
BT_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION,
/** Another firmware image distribution is in progress. */
BT_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION,
/** Another upload is in progress. */
BT_MESH_DFD_ERR_BUSY_WITH_UPLOAD,
/** Another upload is in progress. */
BT_MESH_DFD_ERR_BUSY_WITH_UPLOAD,
/** The URI scheme name indicated by the Update URI is not supported. */
BT_MESH_DFD_ERR_URI_NOT_SUPPORTED,
/** The URI scheme name indicated by the Update URI is not supported. */
BT_MESH_DFD_ERR_URI_NOT_SUPPORTED,
/** The format of the Update URI is invalid. */
BT_MESH_DFD_ERR_URI_MALFORMED,
/** The format of the Update URI is invalid. */
BT_MESH_DFD_ERR_URI_MALFORMED,
/** The URI is currently unreachable. */
BT_MESH_DFD_ERR_URI_UNREACHABLE,
/** The URI is currently unreachable. */
BT_MESH_DFD_ERR_URI_UNREACHABLE,
/** The Check Firmware OOB procedure did not find any new firmware. */
BT_MESH_DFD_ERR_NEW_FW_NOT_AVAILABLE,
/** The Check Firmware OOB procedure did not find any new firmware. */
BT_MESH_DFD_ERR_NEW_FW_NOT_AVAILABLE,
/** The suspension of the Distribute Firmware procedure failed. */
BT_MESH_DFD_ERR_SUSPEND_FAILED,
/** The suspension of the Distribute Firmware procedure failed. */
BT_MESH_DFD_ERR_SUSPEND_FAILED,
};
/** Firmware distribution phases. */
enum bt_mesh_dfd_phase {
/** No firmware distribution is in progress. */
BT_MESH_DFD_PHASE_IDLE,
/** No firmware distribution is in progress. */
BT_MESH_DFD_PHASE_IDLE,
/** Firmware distribution is in progress. */
BT_MESH_DFD_PHASE_TRANSFER_ACTIVE,
/** Firmware distribution is in progress. */
BT_MESH_DFD_PHASE_TRANSFER_ACTIVE,
/** The Transfer BLOB procedure has completed successfully. */
BT_MESH_DFD_PHASE_TRANSFER_SUCCESS,
/** The Transfer BLOB procedure has completed successfully. */
BT_MESH_DFD_PHASE_TRANSFER_SUCCESS,
/** The Apply Firmware on Target Nodes procedure is being executed. */
BT_MESH_DFD_PHASE_APPLYING_UPDATE,
/** The Apply Firmware on Target Nodes procedure is being executed. */
BT_MESH_DFD_PHASE_APPLYING_UPDATE,
/** The Distribute Firmware procedure has completed successfully. */
BT_MESH_DFD_PHASE_COMPLETED,
/** The Distribute Firmware procedure has completed successfully. */
BT_MESH_DFD_PHASE_COMPLETED,
/** The Distribute Firmware procedure has failed. */
BT_MESH_DFD_PHASE_FAILED,
/** The Distribute Firmware procedure has failed. */
BT_MESH_DFD_PHASE_FAILED,
/** The Cancel Firmware Update procedure is being executed. */
BT_MESH_DFD_PHASE_CANCELING_UPDATE,
/** The Cancel Firmware Update procedure is being executed. */
BT_MESH_DFD_PHASE_CANCELING_UPDATE,
/** The Transfer BLOB procedure is suspended. */
BT_MESH_DFD_PHASE_TRANSFER_SUSPENDED,
/** The Transfer BLOB procedure is suspended. */
BT_MESH_DFD_PHASE_TRANSFER_SUSPENDED,
};
/** Firmware upload phases. */
enum bt_mesh_dfd_upload_phase {
/** No firmware upload is in progress. */
BT_MESH_DFD_UPLOAD_PHASE_IDLE,
/** No firmware upload is in progress. */
BT_MESH_DFD_UPLOAD_PHASE_IDLE,
/** The Store Firmware procedure is being executed. */
BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE,
/** The Store Firmware procedure is being executed. */
BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE,
/** The Store Firmware procedure or Store Firmware OOB procedure failed.
*/
BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ERROR,
/** The Store Firmware procedure or Store Firmware OOB procedure failed.
*/
BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ERROR,
/** The Store Firmware procedure or the Store Firmware OOB procedure
* completed successfully.
*/
BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS,
/** The Store Firmware procedure or the Store Firmware OOB procedure
* completed successfully.
*/
BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS,
};
/** @} */
@@ -120,4 +119,4 @@ enum bt_mesh_dfd_upload_phase {
}
#endif
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFD_H__ */
#endif /* _BLE_MESH_v11_DFD_H__ */
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -12,34 +13,34 @@
* @brief API for the Firmware Distribution Server model
*/
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFD_SRV_H__
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFD_SRV_H__
#ifndef _BLE_MESH_v11_DFD_SRV_H__
#define _BLE_MESH_v11_DFD_SRV_H__
#include <zephyr/bluetooth/mesh/access.h>
#include <zephyr/bluetooth/mesh/dfd.h>
#include <zephyr/bluetooth/mesh/blob_srv.h>
#include <zephyr/bluetooth/mesh/blob_cli.h>
#include <zephyr/bluetooth/mesh/dfu_cli.h>
#include "mesh/access.h"
#include "mesh_v1.1/dfu/dfd.h"
#include "mesh_v1.1/dfu/dfu_cli.h"
#include "mesh_v1.1/mbt/blob_cli.h"
#include "mesh_v1.1/mbt/blob_srv.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX
#define CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX 0
#ifndef CONFIG_BLE_MESH_DFD_SRV_TARGETS_MAX
#define CONFIG_BLE_MESH_DFD_SRV_TARGETS_MAX 0
#endif
#ifndef CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE
#define CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE 0
#ifndef CONFIG_BLE_MESH_DFD_SRV_SLOT_MAX_SIZE
#define CONFIG_BLE_MESH_DFD_SRV_SLOT_MAX_SIZE 0
#endif
#ifndef CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE
#define CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE 0
#ifndef CONFIG_BLE_MESH_DFD_SRV_SLOT_SPACE
#define CONFIG_BLE_MESH_DFD_SRV_SLOT_SPACE 0
#endif
struct bt_mesh_dfd_srv;
#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
#ifdef CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD
/**
*
* @brief Initialization parameters for the @ref bt_mesh_dfd_srv with OOB
@@ -51,19 +52,19 @@ struct bt_mesh_dfd_srv;
* Bluetooth SIG Assigned Numbers document.
* @param[in] _oob_schemes_count Number of schemes in @c _oob_schemes.
*/
#define BT_MESH_DFD_SRV_OOB_INIT(_cb, _oob_schemes, _oob_schemes_count) \
{ \
.cb = _cb, \
.dfu = BT_MESH_DFU_CLI_INIT(&_bt_mesh_dfd_srv_dfu_cb), \
.upload = { \
.blob = { .cb = &_bt_mesh_dfd_srv_blob_cb }, \
}, \
.oob_schemes = { \
.schemes = _oob_schemes, \
.count = _oob_schemes_count, \
}, \
}
#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */
#define BT_MESH_DFD_SRV_OOB_INIT(_cb, _oob_schemes, _oob_schemes_count) \
{ \
.cb = _cb, \
.dfu = BLE_MESH_DFU_CLI_INIT(&_bt_mesh_dfd_srv_dfu_cb), \
.upload = { \
.blob = { .cb = &_bt_mesh_dfd_srv_blob_cb }, \
}, \
.oob_schemes = { \
.schemes = _oob_schemes, \
.count = _oob_schemes_count, \
}, \
}
#endif /* CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD */
/**
*
@@ -71,14 +72,14 @@ struct bt_mesh_dfd_srv;
*
* @param[in] _cb Pointer to a @ref bt_mesh_dfd_srv_cb instance.
*/
#define BT_MESH_DFD_SRV_INIT(_cb) \
{ \
.cb = _cb, \
.dfu = BT_MESH_DFU_CLI_INIT(&_bt_mesh_dfd_srv_dfu_cb), \
.upload = { \
.blob = { .cb = &_bt_mesh_dfd_srv_blob_cb }, \
}, \
}
#define BT_MESH_DFD_SRV_INIT(_cb) \
{ \
.cb = _cb, \
.dfu = BLE_MESH_DFU_CLI_INIT(&_bt_mesh_dfd_srv_dfu_cb), \
.upload = { \
.blob = { .cb = &_bt_mesh_dfd_srv_blob_cb }, \
}, \
}
/**
*
@@ -86,168 +87,168 @@ struct bt_mesh_dfd_srv;
*
* @param _srv Pointer to a @ref bt_mesh_dfd_srv instance.
*/
#define BT_MESH_MODEL_DFD_SRV(_srv) \
BT_MESH_MODEL_DFU_CLI(&(_srv)->dfu), \
BT_MESH_MODEL_BLOB_SRV(&(_srv)->upload.blob), \
BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_DFD_SRV, _bt_mesh_dfd_srv_op, NULL, \
_srv, &_bt_mesh_dfd_srv_cb)
#define BT_MESH_MODEL_DFD_SRV(_srv) \
BT_MESH_MODEL_DFU_CLI(&(_srv)->dfu), \
BT_MESH_MODEL_BLOB_SRV(&(_srv)->upload.blob), \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_DFD_SRV, _bt_mesh_dfd_srv_op, NULL, \
_srv, &_bt_mesh_dfd_srv_cb)
/** Firmware Distribution Server callbacks: */
struct bt_mesh_dfd_srv_cb {
/** @brief Slot receive callback.
*
* Called at the start of an upload procedure. The callback must fill
* @c io with a pointer to a writable BLOB stream for the Firmware Distribution
* Server to write the firmware image to.
*
* @param srv Firmware Distribution Server model instance.
* @param slot DFU image slot being received.
* @param io BLOB stream response pointer.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int (*recv)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot,
const struct bt_mesh_blob_io **io);
/** @brief Slot receive callback.
*
* Called at the start of an upload procedure. The callback must fill
* @c io with a pointer to a writable BLOB stream for the Firmware Distribution
* Server to write the firmware image to.
*
* @param srv Firmware Distribution Server model instance.
* @param slot DFU image slot being received.
* @param io BLOB stream response pointer.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int (*recv)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot,
const struct bt_mesh_blob_io **io);
#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
/** @brief Firmware upload OOB start callback.
*
* Called at the start of an OOB firmware upload. The application must
* start a firmware check using an OOB mechanism, and then call
* @ref bt_mesh_dfd_srv_oob_check_complete. Depending on the return
* value of this function, the application must then start storing the
* firmware image using an OOB mechanism, and call
* @ref bt_mesh_dfd_srv_oob_store_complete. This callback is mandatory
* to support OOB uploads.
*
* @param srv Firmware Distribution Server model instance.
* @param slot Slot to be used for the upload.
* @param uri Pointer to buffer containing the URI used to
* check for new firmware.
* @param uri_len Length of the URI buffer.
* @param fwid Pointer to buffer containing the current
* firmware ID to be used when checking for
* availability of new firmware.
* @param fwid_len Length of the current firmware ID. Must be set
* to the length of the new firmware ID if it is
* available, or to 0 if new firmware is not
* available.
*
* @return BT_MESH_DFD_SUCCESS on success, or error code otherwise.
*/
int (*start_oob_upload)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot,
const char *uri, uint8_t uri_len,
const uint8_t *fwid, uint16_t fwid_len);
#ifdef CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD
/** @brief Firmware upload OOB start callback.
*
* Called at the start of an OOB firmware upload. The application must
* start a firmware check using an OOB mechanism, and then call
* @ref bt_mesh_dfd_srv_oob_check_complete. Depending on the return
* value of this function, the application must then start storing the
* firmware image using an OOB mechanism, and call
* @ref bt_mesh_dfd_srv_oob_store_complete. This callback is mandatory
* to support OOB uploads.
*
* @param srv Firmware Distribution Server model instance.
* @param slot Slot to be used for the upload.
* @param uri Pointer to buffer containing the URI used to
* check for new firmware.
* @param uri_len Length of the URI buffer.
* @param fwid Pointer to buffer containing the current
* firmware ID to be used when checking for
* availability of new firmware.
* @param fwid_len Length of the current firmware ID. Must be set
* to the length of the new firmware ID if it is
* available, or to 0 if new firmware is not
* available.
*
* @return BT_MESH_DFD_SUCCESS on success, or error code otherwise.
*/
int (*start_oob_upload)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot,
const char *uri, uint8_t uri_len,
const uint8_t *fwid, uint16_t fwid_len);
/** @brief Cancel store OOB callback
*
* Called when an OOB store is cancelled. The application must stop
* any ongoing OOB image transfer. This callback is mandatory to
* support OOB uploads.
*
* @param srv Firmware Distribution Server model instance.
* @param slot DFU image slot to cancel
*/
void (*cancel_oob_upload)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot);
/** @brief Cancel store OOB callback
*
* Called when an OOB store is cancelled. The application must stop
* any ongoing OOB image transfer. This callback is mandatory to
* support OOB uploads.
*
* @param srv Firmware Distribution Server model instance.
* @param slot DFU image slot to cancel
*/
void (*cancel_oob_upload)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot);
/** @brief Get the progress of an ongoing OOB store
*
* Called by the Firmware Distribution Server model when it needs to
* get the current progress of an ongoing OOB store from the
* application. This callback is mandatory to support OOB uploads.
*
* @param srv Firmware Distribution Server model instance.
* @param slot DFU image slot to get progress for.
*
* @return The current progress of the ongoing OOB store, in percent.
*/
uint8_t (*oob_progress_get)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot);
#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */
/** @brief Get the progress of an ongoing OOB store
*
* Called by the Firmware Distribution Server model when it needs to
* get the current progress of an ongoing OOB store from the
* application. This callback is mandatory to support OOB uploads.
*
* @param srv Firmware Distribution Server model instance.
* @param slot DFU image slot to get progress for.
*
* @return The current progress of the ongoing OOB store, in percent.
*/
uint8_t (*oob_progress_get)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot);
#endif /* CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD */
/** @brief Slot delete callback.
*
* Called when the Firmware Distribution Server is about to delete a DFU image slot.
* All allocated data associated with the firmware slot should be
* deleted.
*
* @param srv Firmware Update Server instance.
* @param slot DFU image slot being deleted.
*/
void (*del)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot);
/** @brief Slot delete callback.
*
* Called when the Firmware Distribution Server is about to delete a DFU image slot.
* All allocated data associated with the firmware slot should be
* deleted.
*
* @param srv Firmware Update Server instance.
* @param slot DFU image slot being deleted.
*/
void (*del)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot);
/** @brief Slot send callback.
*
* Called at the start of a distribution procedure. The callback must
* fill @c io with a pointer to a readable BLOB stream for the Firmware
* Distribution Server to read the firmware image from.
*
* @param srv Firmware Distribution Server model instance.
* @param slot DFU image slot being sent.
* @param io BLOB stream response pointer.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int (*send)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot,
const struct bt_mesh_blob_io **io);
/** @brief Slot send callback.
*
* Called at the start of a distribution procedure. The callback must
* fill @c io with a pointer to a readable BLOB stream for the Firmware
* Distribution Server to read the firmware image from.
*
* @param srv Firmware Distribution Server model instance.
* @param slot DFU image slot being sent.
* @param io BLOB stream response pointer.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int (*send)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot,
const struct bt_mesh_blob_io **io);
/** @brief Phase change callback (Optional).
*
* Called whenever the phase of the Firmware Distribution Server changes.
*
* @param srv Firmware Distribution Server model instance.
* @param phase New Firmware Distribution phase.
*/
void (*phase)(struct bt_mesh_dfd_srv *srv, enum bt_mesh_dfd_phase phase);
/** @brief Phase change callback (Optional).
*
* Called whenever the phase of the Firmware Distribution Server changes.
*
* @param srv Firmware Distribution Server model instance.
* @param phase New Firmware Distribution phase.
*/
void (*phase)(struct bt_mesh_dfd_srv *srv, enum bt_mesh_dfd_phase phase);
};
/** Firmware Distribution Server instance. */
struct bt_mesh_dfd_srv {
const struct bt_mesh_dfd_srv_cb *cb;
const struct bt_mesh_model *mod;
struct bt_mesh_dfu_cli dfu;
struct bt_mesh_dfu_target targets[CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX];
struct bt_mesh_blob_target_pull pull_ctxs[CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX];
const struct bt_mesh_blob_io *io;
uint16_t target_cnt;
uint16_t slot_idx;
bool apply;
enum bt_mesh_dfd_phase phase;
struct bt_mesh_blob_cli_inputs inputs;
const struct bt_mesh_dfd_srv_cb *cb;
const struct bt_mesh_model *mod;
struct bt_mesh_dfu_cli dfu;
struct bt_mesh_dfu_target targets[CONFIG_BLE_MESH_DFD_SRV_TARGETS_MAX];
struct bt_mesh_blob_target_pull pull_ctxs[CONFIG_BLE_MESH_DFD_SRV_TARGETS_MAX];
const struct bt_mesh_blob_io *io;
uint16_t target_cnt;
uint16_t slot_idx;
bool apply;
enum bt_mesh_dfd_phase phase;
struct bt_mesh_blob_cli_inputs inputs;
struct {
enum bt_mesh_dfd_upload_phase phase;
struct bt_mesh_dfu_slot *slot;
const struct flash_area *area;
struct bt_mesh_blob_srv blob;
#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
bool is_oob;
bool is_pending_oob_check;
struct {
uint8_t uri_len;
uint8_t uri[CONFIG_BT_MESH_DFU_URI_MAXLEN];
uint16_t current_fwid_len;
uint8_t current_fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN];
struct bt_mesh_msg_ctx ctx;
} oob;
#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */
} upload;
struct {
enum bt_mesh_dfd_upload_phase phase;
struct bt_mesh_dfu_slot *slot;
const struct flash_area *area;
struct bt_mesh_blob_srv blob;
#ifdef CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD
bool is_oob;
bool is_pending_oob_check;
struct {
uint8_t uri_len;
char uri[CONFIG_BLE_MESH_DFU_URI_MAXLEN];
uint16_t current_fwid_len;
uint8_t current_fwid[CONFIG_BLE_MESH_DFU_FWID_MAXLEN];
struct bt_mesh_msg_ctx ctx;
} oob;
#endif /* CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD */
} upload;
#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
struct {
const uint8_t *schemes;
const uint8_t count;
} oob_schemes;
#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */
#ifdef CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD
struct {
const uint8_t *schemes;
const uint8_t count;
} oob_schemes;
#endif /* CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD */
};
#ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
#ifdef CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD
/** @brief Call when an OOB check has completed or failed
*
* This should be called by the application after an OOB check started by the @c start_oob_upload
@@ -274,8 +275,8 @@ struct bt_mesh_dfd_srv {
* @return 0 on success, (negative) error code otherwise.
*/
int bt_mesh_dfd_srv_oob_check_complete(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot, int status,
uint8_t *fwid, size_t fwid_len);
const struct bt_mesh_dfu_slot *slot, int status,
uint8_t *fwid, size_t fwid_len);
/** @brief Call when an OOB store has completed or failed
*
@@ -293,9 +294,9 @@ int bt_mesh_dfd_srv_oob_check_complete(struct bt_mesh_dfd_srv *srv,
* @return 0 on success, (negative) error code otherwise.
*/
int bt_mesh_dfd_srv_oob_store_complete(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot, bool success,
size_t size, const uint8_t *metadata, size_t metadata_len);
#endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */
const struct bt_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 */
/** @cond INTERNAL_HIDDEN */
extern const struct bt_mesh_model_op _bt_mesh_dfd_srv_op[];
@@ -308,6 +309,6 @@ extern const struct bt_mesh_blob_srv_cb _bt_mesh_dfd_srv_blob_cb;
}
#endif
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFD_SRV_H__ */
#endif /* _BLE_MESH_v11_DFD_SRV_H__ */
/** @} */
@@ -1,16 +1,19 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_H__
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_H__
#ifndef _BLE_MESH_v11_DFU_H__
#define _BLE_MESH_v11_DFU_H__
#include <sys/types.h>
#include <zephyr/kernel.h>
#include <zephyr/bluetooth/mesh/blob.h>
#include "mesh/types.h"
#include "mesh/utils.h"
#include "mesh_v1.1/mbt/blob.h"
#ifdef __cplusplus
extern "C" {
@@ -22,115 +25,114 @@ extern "C" {
* @{
*/
#ifndef CONFIG_BT_MESH_DFU_FWID_MAXLEN
#define CONFIG_BT_MESH_DFU_FWID_MAXLEN 0
#ifndef CONFIG_BLE_MESH_DFU_FWID_MAXLEN
#define CONFIG_BLE_MESH_DFU_FWID_MAXLEN 0
#endif
#ifndef CONFIG_BT_MESH_DFU_METADATA_MAXLEN
#define CONFIG_BT_MESH_DFU_METADATA_MAXLEN 0
#ifndef CONFIG_BLE_MESH_DFU_METADATA_MAXLEN
#define CONFIG_BLE_MESH_DFU_METADATA_MAXLEN 0
#endif
#ifndef CONFIG_BT_MESH_DFU_URI_MAXLEN
#define CONFIG_BT_MESH_DFU_URI_MAXLEN 0
#ifndef CONFIG_BLE_MESH_DFU_URI_MAXLEN
#define CONFIG_BLE_MESH_DFU_URI_MAXLEN 0
#endif
#ifndef CONFIG_BT_MESH_DFU_SLOT_CNT
#define CONFIG_BT_MESH_DFU_SLOT_CNT 0
#ifndef CONFIG_BLE_MESH_DFU_SLOT_CNT
#define CONFIG_BLE_MESH_DFU_SLOT_CNT 0
#endif
/** DFU transfer phase. */
enum bt_mesh_dfu_phase {
/** Ready to start a Receive Firmware procedure. */
BT_MESH_DFU_PHASE_IDLE,
/** Ready to start a Receive Firmware procedure. */
BLE_MESH_DFU_PHASE_IDLE,
/** The Transfer BLOB procedure failed. */
BT_MESH_DFU_PHASE_TRANSFER_ERR,
/** The Transfer BLOB procedure failed. */
BLE_MESH_DFU_PHASE_TRANSFER_ERR,
/** The Receive Firmware procedure is being executed. */
BT_MESH_DFU_PHASE_TRANSFER_ACTIVE,
/** The Receive Firmware procedure is being executed. */
BLE_MESH_DFU_PHASE_TRANSFER_ACTIVE,
/** The Verify Firmware procedure is being executed. */
BT_MESH_DFU_PHASE_VERIFY,
/** The Verify Firmware procedure is being executed. */
BLE_MESH_DFU_PHASE_VERIFY,
/** The Verify Firmware procedure completed successfully. */
BT_MESH_DFU_PHASE_VERIFY_OK,
/** The Verify Firmware procedure completed successfully. */
BLE_MESH_DFU_PHASE_VERIFY_OK,
/** The Verify Firmware procedure failed. */
BT_MESH_DFU_PHASE_VERIFY_FAIL,
/** The Verify Firmware procedure failed. */
BLE_MESH_DFU_PHASE_VERIFY_FAIL,
/** The Apply New Firmware procedure is being executed. */
BT_MESH_DFU_PHASE_APPLYING,
/** The Apply New Firmware procedure is being executed. */
BLE_MESH_DFU_PHASE_APPLYING,
/** Firmware transfer has been canceled. */
BT_MESH_DFU_PHASE_TRANSFER_CANCELED,
/** Firmware transfer has been canceled. */
BLE_MESH_DFU_PHASE_TRANSFER_CANCELED,
/** Firmware applying succeeded. */
BT_MESH_DFU_PHASE_APPLY_SUCCESS,
/** Firmware applying succeeded. */
BLE_MESH_DFU_PHASE_APPLY_SUCCESS,
/** Firmware applying failed. */
BT_MESH_DFU_PHASE_APPLY_FAIL,
/** Firmware applying failed. */
BLE_MESH_DFU_PHASE_APPLY_FAIL,
/** Phase of a node was not yet retrieved. */
BT_MESH_DFU_PHASE_UNKNOWN,
/** Phase of a node was not yet retrieved. */
BLE_MESH_DFU_PHASE_UNKNOWN,
};
/** DFU status. */
enum bt_mesh_dfu_status {
/** The message was processed successfully. */
BT_MESH_DFU_SUCCESS,
/** The message was processed successfully. */
BLE_MESH_DFU_SUCCESS,
/** Insufficient resources on the node */
BT_MESH_DFU_ERR_RESOURCES,
/** Insufficient resources on the node */
BLE_MESH_DFU_ERR_RESOURCES,
/** The operation cannot be performed while the Server is in the current
* phase.
*/
BT_MESH_DFU_ERR_WRONG_PHASE,
/** The operation cannot be performed while the Server is in the current
* phase.
*/
BLE_MESH_DFU_ERR_WRONG_PHASE,
/** An internal error occurred on the node. */
BT_MESH_DFU_ERR_INTERNAL,
/** An internal error occurred on the node. */
BLE_MESH_DFU_ERR_INTERNAL,
/** The message contains a firmware index value that is not expected. */
BT_MESH_DFU_ERR_FW_IDX,
/** The message contains a firmware index value that is not expected. */
BLE_MESH_DFU_ERR_FW_IDX,
/** The metadata check failed. */
BT_MESH_DFU_ERR_METADATA,
/** The metadata check failed. */
BLE_MESH_DFU_ERR_METADATA,
/** The Server cannot start a firmware update. */
BT_MESH_DFU_ERR_TEMPORARILY_UNAVAILABLE,
/** The Server cannot start a firmware update. */
BLE_MESH_DFU_ERR_TEMPORARILY_UNAVAILABLE,
/** Another BLOB transfer is in progress. */
BT_MESH_DFU_ERR_BLOB_XFER_BUSY,
/** Another BLOB transfer is in progress. */
BLE_MESH_DFU_ERR_BLOB_XFER_BUSY,
};
/** Expected effect of a DFU transfer. */
enum bt_mesh_dfu_effect {
/** No changes to node Composition Data. */
BT_MESH_DFU_EFFECT_NONE,
/** No changes to node Composition Data. */
BLE_MESH_DFU_EFFECT_NONE,
/** Node Composition Data changed and the node does not support remote
* provisioning.
*/
BT_MESH_DFU_EFFECT_COMP_CHANGE_NO_RPR,
/** Node Composition Data changed and the node does not support remote
* provisioning.
*/
BLE_MESH_DFU_EFFECT_COMP_CHANGE_NO_RPR,
/** Node Composition Data changed, and remote provisioning is supported.
* The node supports remote provisioning and Composition Data Page
* 0x80. Page 0x80 contains different Composition Data than Page 0x0.
*/
BT_MESH_DFU_EFFECT_COMP_CHANGE,
/** Node Composition Data changed, and remote provisioning is supported.
* The node supports remote provisioning and Composition Data Page
* 0x80. Page 0x80 contains different Composition Data than Page 0x0.
*/
BLE_MESH_DFU_EFFECT_COMP_CHANGE,
/** Node will be unprovisioned after the update. */
BT_MESH_DFU_EFFECT_UNPROV,
/** Node will be unprovisioned after the update. */
BLE_MESH_DFU_EFFECT_UNPROV,
};
/** Action for DFU iteration callbacks. */
enum bt_mesh_dfu_iter {
/** Stop iterating. */
BT_MESH_DFU_ITER_STOP,
/** Stop iterating. */
BLE_MESH_DFU_ITER_STOP,
/** Continue iterating. */
BT_MESH_DFU_ITER_CONTINUE,
/** Continue iterating. */
BLE_MESH_DFU_ITER_CONTINUE,
};
/** DFU image instance.
@@ -138,28 +140,28 @@ enum bt_mesh_dfu_iter {
* Each DFU image represents a single updatable firmware image.
*/
struct bt_mesh_dfu_img {
/** Firmware ID. */
const void *fwid;
/** Firmware ID. */
const void *fwid;
/** Length of the firmware ID. */
size_t fwid_len;
/** Length of the firmware ID. */
size_t fwid_len;
/** Update URI, or NULL. */
const char *uri;
/** Update URI, or NULL. */
const char *uri;
};
/** DFU image slot for DFU distribution. */
struct bt_mesh_dfu_slot {
/** Size of the firmware in bytes. */
size_t size;
/** Length of the firmware ID. */
size_t fwid_len;
/** Length of the metadata. */
size_t metadata_len;
/** Firmware ID. */
uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN];
/** Metadata. */
uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN];
/** Size of the firmware in bytes. */
size_t size;
/** Length of the firmware ID. */
size_t fwid_len;
/** Length of the metadata. */
size_t metadata_len;
/** Firmware ID. */
uint8_t fwid[CONFIG_BLE_MESH_DFU_FWID_MAXLEN];
/** Metadata. */
uint8_t metadata[CONFIG_BLE_MESH_DFU_METADATA_MAXLEN];
};
/** @} */
@@ -168,4 +170,4 @@ struct bt_mesh_dfu_slot {
}
#endif
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_H__ */
#endif /* _BLE_MESH_v11_DFU_H__ */
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -12,12 +13,14 @@
* @brief API for the Bluetooth Mesh Firmware Update Client model
*/
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_CLI_H__
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_CLI_H__
#ifndef _BLE_MESH_v11_DFU_CLI_H__
#define _BLE_MESH_v11_DFU_CLI_H__
#include <zephyr/bluetooth/mesh/access.h>
#include <zephyr/bluetooth/mesh/blob_cli.h>
#include <zephyr/bluetooth/mesh/dfu.h>
#include "freertos/semphr.h"
#include "mesh/access.h"
#include "mesh_v1.1/mbt/blob_cli.h"
#include "mesh_v1.1/dfu/dfu.h"
#ifdef __cplusplus
extern "C" {
@@ -33,11 +36,11 @@ struct bt_mesh_dfu_cli;
*
* @param _handlers Handler callback structure.
*/
#define BT_MESH_DFU_CLI_INIT(_handlers) \
{ \
.cb = _handlers, \
.blob = { .cb = &_bt_mesh_dfu_cli_blob_handlers }, \
}
#define BLE_MESH_DFU_CLI_INIT(_handlers) \
{ \
.cb = _handlers, \
.blob = { .cb = &_bt_mesh_dfu_cli_blob_handlers }, \
}
/**
*
@@ -45,64 +48,67 @@ struct bt_mesh_dfu_cli;
*
* @param _cli Pointer to a @ref bt_mesh_dfu_cli instance.
*/
#define BT_MESH_MODEL_DFU_CLI(_cli) \
BT_MESH_MODEL_BLOB_CLI(&(_cli)->blob), \
BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_DFU_CLI, _bt_mesh_dfu_cli_op, NULL, \
_cli, &_bt_mesh_dfu_cli_cb)
#define BT_MESH_MODEL_DFU_CLI(_cli) \
BT_MESH_MODEL_BLOB_CLI(&(_cli)->blob), \
BT_MESH_MODEL_CB(BLE_MESH_MODEL_ID_DFU_CLI, _bt_mesh_dfu_cli_op, NULL, \
_cli, &_bt_mesh_dfu_cli_cb)
/** DFU Target node. */
struct bt_mesh_dfu_target {
/** BLOB Target node */
struct bt_mesh_blob_target blob;
/** Image index on the Target node */
uint8_t img_idx;
/** Expected DFU effect, see @ref bt_mesh_dfu_effect. */
uint8_t effect;
/** Current DFU status, see @ref bt_mesh_dfu_status. */
uint8_t status;
/** Current DFU phase, see @ref bt_mesh_dfu_phase. */
uint8_t phase;
/** BLOB Target node */
struct bt_mesh_blob_target blob;
/** Image index on the Target node */
uint8_t img_idx;
/** Expected DFU effect, see @ref bt_mesh_dfu_effect. */
uint8_t effect;
/** Current DFU status, see @ref bt_mesh_dfu_status. */
uint8_t status;
/** Current DFU phase, see @ref bt_mesh_dfu_phase. */
uint8_t phase;
};
/** Metadata status response. */
struct bt_mesh_dfu_metadata_status {
/** Image index. */
uint8_t idx;
/** Status code. */
enum bt_mesh_dfu_status status;
/** Effect of transfer. */
enum bt_mesh_dfu_effect effect;
/** Image index. */
uint8_t idx;
/** Status code. */
enum bt_mesh_dfu_status status;
/** Effect of transfer. */
enum bt_mesh_dfu_effect effect;
};
/** DFU Target node status parameters. */
/** DFU Target node status parameters.
* The structure should be same as
* @ref esp_ble_mesh_device_firmware_update_status_t
*/
struct bt_mesh_dfu_target_status {
/** Status of the previous operation. */
enum bt_mesh_dfu_status status;
/** Phase of the current DFU transfer. */
enum bt_mesh_dfu_phase phase;
/** The effect the update will have on the Target device's state. */
enum bt_mesh_dfu_effect effect;
/** BLOB ID used in the transfer. */
uint64_t blob_id;
/** Image index to transfer. */
uint8_t img_idx;
/** TTL used in the transfer. */
uint8_t ttl;
/** Status of the previous operation. */
enum bt_mesh_dfu_status status;
/** Phase of the current DFU transfer. */
enum bt_mesh_dfu_phase phase;
/** The effect the update will have on the Target device's state. */
enum bt_mesh_dfu_effect effect;
/** BLOB ID used in the transfer. */
uint64_t blob_id;
/** Image index to transfer. */
uint8_t img_idx;
/** TTL used in the transfer. */
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;
/** 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;
};
/** @brief DFU image callback.
@@ -117,120 +123,140 @@ struct bt_mesh_dfu_target_status {
* @param img Image information for the given image index.
* @param cb_data Callback data.
*
* @retval BT_MESH_DFU_ITER_STOP Stop iterating through the image list and
* @retval BLE_MESH_DFU_ITER_STOP Stop iterating through the image list and
* return from @ref bt_mesh_dfu_cli_imgs_get.
* @retval BT_MESH_DFU_ITER_CONTINUE Continue iterating through the image list
* @retval BLE_MESH_DFU_ITER_CONTINUE Continue iterating through the image list
* if any images remain.
*/
typedef enum bt_mesh_dfu_iter (*bt_mesh_dfu_img_cb_t)(
struct bt_mesh_dfu_cli *cli, struct bt_mesh_msg_ctx *ctx, uint8_t idx,
uint8_t total, const struct bt_mesh_dfu_img *img, void *cb_data);
typedef enum bt_mesh_dfu_iter(*bt_mesh_dfu_img_cb_t)(struct bt_mesh_dfu_cli *cli,
struct bt_mesh_msg_ctx *ctx,
uint8_t idx, uint8_t total,
const struct bt_mesh_dfu_img *img,
void *cb_data);
/** Firmware Update Client event callbacks. */
struct bt_mesh_dfu_cli_cb {
/** @brief BLOB transfer is suspended.
*
* Called when the BLOB transfer is suspended due to response timeout from all Target nodes.
*
* @param cli Firmware Update Client model instance.
*/
void (*suspended)(struct bt_mesh_dfu_cli *cli);
/** @brief BLOB transfer is suspended.
*
* Called when the BLOB transfer is suspended due to response timeout from all Target nodes.
*
* @param cli Firmware Update Client model instance.
*/
void (*suspended)(struct bt_mesh_dfu_cli *cli);
/** @brief DFU ended.
*
* Called when the DFU transfer ends, either because all Target nodes were
* lost or because the transfer was completed successfully.
*
* @param cli Firmware Update Client model instance.
* @param reason Reason for ending.
*/
void (*ended)(struct bt_mesh_dfu_cli *cli,
enum bt_mesh_dfu_status reason);
/** @brief DFU ended.
*
* Called when the DFU transfer ends, either because all Target nodes were
* lost or because the transfer was completed successfully.
*
* @param cli Firmware Update Client model instance.
* @param reason Reason for ending.
*/
void (*ended)(struct bt_mesh_dfu_cli *cli,
enum bt_mesh_dfu_status reason);
/** @brief DFU transfer applied on all active Target nodes.
*
* Called at the end of the apply procedure started by @ref
* bt_mesh_dfu_cli_apply.
*
* @param cli Firmware Update Client model instance.
*/
void (*applied)(struct bt_mesh_dfu_cli *cli);
/** @brief DFU transfer applied on all active Target nodes.
*
* Called at the end of the apply procedure started by @ref
* bt_mesh_dfu_cli_apply.
*
* @param cli Firmware Update Client model instance.
*/
void (*applied)(struct bt_mesh_dfu_cli *cli);
/** @brief DFU transfer confirmed on all active Target nodes.
*
* Called at the end of the apply procedure started by @ref
* bt_mesh_dfu_cli_confirm.
*
* @param cli Firmware Update Client model instance.
*/
void (*confirmed)(struct bt_mesh_dfu_cli *cli);
/** @brief DFU transfer confirmed on all active Target nodes.
*
* Called at the end of the apply procedure started by @ref
* bt_mesh_dfu_cli_confirm.
*
* @param cli Firmware Update Client model instance.
*/
void (*confirmed)(struct bt_mesh_dfu_cli *cli);
/** @brief DFU Target node was lost.
*
* A DFU Target node was dropped from the receivers list. The Target node's
* @c status is set to reflect the reason for the failure.
*
* @param cli Firmware Update Client model instance.
* @param target DFU Target node that was lost.
*/
void (*lost_target)(struct bt_mesh_dfu_cli *cli,
struct bt_mesh_dfu_target *target);
/** @brief DFU Target node was lost.
*
* A DFU Target node was dropped from the receivers list. The Target node's
* @c status is set to reflect the reason for the failure.
*
* @param cli Firmware Update Client model instance.
* @param target DFU Target node that was lost.
*/
void (*lost_target)(struct bt_mesh_dfu_cli *cli,
struct bt_mesh_dfu_target *target);
};
enum {
STATE_IDLE,
STATE_TRANSFER,
STATE_REFRESH,
STATE_VERIFIED,
STATE_APPLY,
STATE_APPLIED,
STATE_CONFIRM,
STATE_CANCEL,
STATE_SUSPENDED,
};
typedef struct {
sys_snode_t node;
uint8_t ttl;
uint8_t type;
uint8_t img_cnt;
uint32_t opcode;
void *params;
bt_mesh_dfu_img_cb_t img_cb;
struct bt_mesh_dfu_cli *dfu_cli;
struct bt_mesh_msg_ctx ctx;
int32_t timeout;
struct k_delayed_work timer; /* Time used to get response. Only for internal use. */
} bt_mesh_dfu_cli_req_t;
/** Firmware Update Client model instance.
*
* Should be initialized with @ref BT_MESH_DFU_CLI_INIT.
* Should be initialized with @ref BLE_MESH_DFU_CLI_INIT.
*/
struct bt_mesh_dfu_cli {
/** Callback structure. */
const struct bt_mesh_dfu_cli_cb *cb;
/** Underlying BLOB Transfer Client. */
struct bt_mesh_blob_cli blob;
/** Callback structure. */
const struct bt_mesh_dfu_cli_cb *cb;
/** Underlying BLOB Transfer Client. */
struct bt_mesh_blob_cli blob;
/* runtime state */
/* runtime state */
uint32_t op;
const struct bt_mesh_model *mod;
uint32_t op;
struct bt_mesh_model *mod;
struct {
const struct bt_mesh_dfu_slot *slot;
const struct bt_mesh_blob_io *io;
struct bt_mesh_blob_xfer blob;
uint8_t state;
uint8_t flags;
} xfer;
struct {
const struct bt_mesh_dfu_slot *slot;
const struct bt_mesh_blob_io *io;
struct bt_mesh_blob_xfer blob;
uint8_t state;
uint8_t flags;
} xfer;
struct {
uint8_t ttl;
uint8_t type;
uint8_t img_cnt;
uint16_t addr;
struct k_sem sem;
void *params;
bt_mesh_dfu_img_cb_t img_cb;
} req;
bt_mesh_dfu_cli_req_t *req;
};
/** BLOB parameters for Firmware Update Client transfer: */
struct bt_mesh_dfu_cli_xfer_blob_params {
/* Logarithmic representation of the block size. */
uint8_t block_size_log;
/** Base chunk size. May be smaller for the last chunk. */
uint16_t chunk_size;
/* Logarithmic representation of the block size. */
uint8_t block_size_log;
/** Base chunk size. May be smaller for the last chunk. */
uint16_t chunk_size;
};
/** Firmware Update Client transfer parameters: */
struct bt_mesh_dfu_cli_xfer {
/** BLOB ID to use for this transfer, or 0 to set it randomly. */
uint64_t blob_id;
/** DFU image slot to transfer. */
const struct bt_mesh_dfu_slot *slot;
/** Transfer mode (Push (Push BLOB Transfer Mode) or Pull (Pull BLOB Transfer Mode)) */
enum bt_mesh_blob_xfer_mode mode;
/** BLOB parameters to be used for the transfer, or NULL to retrieve Target nodes'
* capabilities before sending a firmware.
*/
const struct bt_mesh_dfu_cli_xfer_blob_params *blob_params;
/** BLOB ID to use for this transfer, or 0 to set it randomly. */
uint64_t blob_id;
/** DFU image slot to transfer. */
const struct bt_mesh_dfu_slot *slot;
/** Transfer mode (Push (Push BLOB Transfer Mode) or Pull (Pull BLOB Transfer Mode)) */
enum bt_mesh_blob_xfer_mode mode;
/** BLOB parameters to be used for the transfer, or NULL to retrieve Target nodes'
* capabilities before sending a firmware.
*/
const struct bt_mesh_dfu_cli_xfer_blob_params *blob_params;
};
/** @brief Start distributing a DFU.
@@ -250,9 +276,9 @@ struct bt_mesh_dfu_cli_xfer {
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_cli_send(struct bt_mesh_dfu_cli *cli,
const struct bt_mesh_blob_cli_inputs *inputs,
const struct bt_mesh_blob_io *io,
const struct bt_mesh_dfu_cli_xfer *xfer);
const struct bt_mesh_blob_cli_inputs *inputs,
const struct bt_mesh_blob_io *io,
const struct bt_mesh_dfu_cli_xfer *xfer);
/** @brief Suspend a DFU transfer.
*
@@ -281,7 +307,7 @@ int bt_mesh_dfu_cli_resume(struct bt_mesh_dfu_cli *cli);
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_cli_cancel(struct bt_mesh_dfu_cli *cli,
struct bt_mesh_msg_ctx *ctx);
struct bt_mesh_msg_ctx *ctx);
/** @brief Apply the completed DFU transfer.
*
@@ -300,7 +326,7 @@ int bt_mesh_dfu_cli_apply(struct bt_mesh_dfu_cli *cli);
* Client's @c confirmed callback is called at the end of the confirm
* procedure.
*
* Target nodes that have reported the effect as @ref BT_MESH_DFU_EFFECT_UNPROV
* Target nodes that have reported the effect as @ref BLE_MESH_DFU_EFFECT_UNPROV
* are expected to not respond to the query, and will fail if they do.
*
* @param cli Firmware Update Client model instance.
@@ -341,14 +367,15 @@ bool bt_mesh_dfu_cli_is_busy(struct bt_mesh_dfu_cli *cli);
* @param ctx Message context.
* @param cb Callback to call for each image index.
* @param cb_data Callback data to pass to @c cb.
* @param first_idx Index of the first requested imgs entry.
* @param max_count Max number of images to return.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_cli_imgs_get(struct bt_mesh_dfu_cli *cli,
struct bt_mesh_msg_ctx *ctx,
bt_mesh_dfu_img_cb_t cb, void *cb_data,
uint8_t max_count);
struct bt_mesh_msg_ctx *ctx,
bt_mesh_dfu_img_cb_t cb, void *cb_data,
uint8_t first_idx, uint8_t max_count);
/** @brief Perform a metadata check for the given DFU image slot.
*
@@ -357,30 +384,26 @@ int bt_mesh_dfu_cli_imgs_get(struct bt_mesh_dfu_cli *cli,
*
* Waits for a response until the procedure timeout expires.
*
* @param cli Firmware Update Client model instance.
* @param ctx Message context.
* @param img_idx Target node's image index to check.
* @param slot DFU image slot to check for.
* @param rsp Metadata status response buffer.
* @param cli Firmware Update Client model instance.
* @param ctx Message context.
* @param img_idx Target node's image index to check.
* @param metadata DFU image metadata to check for.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_cli_metadata_check(struct bt_mesh_dfu_cli *cli,
struct bt_mesh_msg_ctx *ctx, uint8_t img_idx,
const struct bt_mesh_dfu_slot *slot,
struct bt_mesh_dfu_metadata_status *rsp);
struct bt_mesh_msg_ctx *ctx, uint8_t img_idx,
struct net_buf_simple *metadata);
/** @brief Get the status of a Target node.
*
* @param cli Firmware Update Client model instance.
* @param ctx Message context.
* @param rsp Response data buffer.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_cli_status_get(struct bt_mesh_dfu_cli *cli,
struct bt_mesh_msg_ctx *ctx,
struct bt_mesh_dfu_target_status *rsp);
struct bt_mesh_msg_ctx *ctx);
/** @brief Get the current procedure timeout value.
*
@@ -404,6 +427,4 @@ extern const struct bt_mesh_model_op _bt_mesh_dfu_cli_op[];
}
#endif
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_CLI_H__ */
/** @} */
#endif /* _BLE_MESH_v11_DFU_CLI_H__ */
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2021 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -12,14 +13,15 @@
* @brief Common types and functions for the Bluetooth Mesh DFU metadata.
*/
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_METADATA_H__
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_METADATA_H__
#ifndef _BLE_MESH_v11_DFU_METADATA_H__
#define _BLE_MESH_v11_DFU_METADATA_H__
#include <stdint.h>
#include <sys/types.h>
#include <zephyr/kernel.h>
#include "mesh/types.h"
#include "mesh/utils.h"
#ifdef __cplusplus
extern "C" {
@@ -27,42 +29,40 @@ extern "C" {
/** Firmware version. */
struct bt_mesh_dfu_metadata_fw_ver {
/** Firmware major version. */
uint8_t major;
/** Firmware minor version. */
uint8_t minor;
/** Firmware revision. */
uint16_t revision;
/** Firmware build number. */
uint32_t build_num;
/** Firmware major version. */
uint8_t major;
/** Firmware minor version. */
uint8_t minor;
/** Firmware revision. */
uint16_t revision;
/** Firmware build number. */
uint32_t build_num;
};
/** Firmware core type. */
enum bt_mesh_dfu_metadata_fw_core_type {
/** Application core. */
BT_MESH_DFU_FW_CORE_TYPE_APP = BIT(0),
/** Network core. */
BT_MESH_DFU_FW_CORE_TYPE_NETWORK = BIT(1),
/** Application-specific BLOB. */
BT_MESH_DFU_FW_CORE_TYPE_APP_SPECIFIC_BLOB = BIT(2),
/** Application core. */
BLE_MESH_DFU_FW_CORE_TYPE_APP = BIT(0),
/** Application-specific BLOB. */
BLE_MESH_DFU_FW_CORE_TYPE_APP_SPECIFIC_BLOB = BIT(2),
};
/** Firmware metadata. */
struct bt_mesh_dfu_metadata {
/** New firmware version. */
struct bt_mesh_dfu_metadata_fw_ver fw_ver;
/** New firmware size. */
uint32_t fw_size;
/** New firmware core type. */
enum bt_mesh_dfu_metadata_fw_core_type fw_core_type;
/** Hash of incoming Composition Data. */
uint32_t comp_hash;
/** New number of node elements. */
uint16_t elems;
/** Application-specific data for new firmware. This field is optional. */
uint8_t *user_data;
/** Length of the application-specific field. */
uint32_t user_data_len;
/** New firmware version. */
struct bt_mesh_dfu_metadata_fw_ver fw_ver;
/** New firmware size. */
uint32_t fw_size;
/** New firmware core type. */
enum bt_mesh_dfu_metadata_fw_core_type fw_core_type;
/** Hash of incoming Composition Data. */
uint32_t comp_hash;
/** New number of node elements. */
uint16_t elems;
/** Application-specific data for new firmware. This field is optional. */
uint8_t *user_data;
/** Length of the application-specific field. */
uint32_t user_data_len;
};
/** @brief Decode a firmware metadata from a network buffer.
@@ -73,7 +73,7 @@ struct bt_mesh_dfu_metadata {
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_metadata_decode(struct net_buf_simple *buf,
struct bt_mesh_dfu_metadata *metadata);
struct bt_mesh_dfu_metadata *metadata);
/** @brief Encode a firmware metadata into a network buffer.
*
@@ -83,7 +83,7 @@ int bt_mesh_dfu_metadata_decode(struct net_buf_simple *buf,
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_dfu_metadata_encode(const struct bt_mesh_dfu_metadata *metadata,
struct net_buf_simple *buf);
struct net_buf_simple *buf);
/** @brief Compute hash of the Composition Data state.
*
@@ -110,6 +110,4 @@ int bt_mesh_dfu_metadata_comp_hash_local_get(uint8_t *key, uint32_t *hash);
}
#endif
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_METADATA_H__ */
/** @} */
#endif /* _BLE_MESH_v11_DFU_METADATA_H__ */
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -12,12 +13,11 @@
* @brief API for the Bluetooth Mesh Firmware Update Server model
*/
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_SRV_H__
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_SRV_H__
#ifndef _BLE_MESH_v11_DFU_SRV_H__
#define _BLE_MESH_v11_DFU_SRV_H__
#include <zephyr/bluetooth/mesh/dfu.h>
#include <zephyr/bluetooth/mesh/blob_srv.h>
#include <zephyr/bluetooth/mesh/access.h>
#include "mesh/access.h"
#include "mesh_v1.1/mbt/blob_srv.h"
#ifdef __cplusplus
extern "C" {
@@ -33,11 +33,11 @@ struct bt_mesh_dfu_srv;
* @param _imgs List of @ref bt_mesh_dfu_img managed by this Server.
* @param _img_count Number of DFU images managed by this Server.
*/
#define BT_MESH_DFU_SRV_INIT(_handlers, _imgs, _img_count) \
{ \
.blob = { .cb = &_bt_mesh_dfu_srv_blob_cb }, .cb = _handlers, \
.imgs = _imgs, .img_count = _img_count, \
}
#define BLE_MESH_DFU_SRV_INIT(_handlers, _imgs, _img_count) \
{ \
.blob = { .cb = &_bt_mesh_dfu_srv_blob_cb }, .cb = _handlers, \
.imgs = _imgs, .img_count = _img_count, \
}
/**
*
@@ -45,156 +45,156 @@ struct bt_mesh_dfu_srv;
*
* @param _srv Pointer to a @ref bt_mesh_dfu_srv instance.
*/
#define BT_MESH_MODEL_DFU_SRV(_srv) \
BT_MESH_MODEL_BLOB_SRV(&(_srv)->blob), \
BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_DFU_SRV, _bt_mesh_dfu_srv_op, NULL, \
_srv, &_bt_mesh_dfu_srv_cb)
#define BT_MESH_MODEL_DFU_SRV(_srv) \
BT_MESH_MODEL_BLOB_SRV(&(_srv)->blob), \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_DFU_SRV, _bt_mesh_dfu_srv_op, NULL, \
_srv, &_bt_mesh_dfu_srv_cb)
/** @brief Firmware Update Server event callbacks. */
struct bt_mesh_dfu_srv_cb {
/** @brief Transfer check callback.
*
* The transfer check can be used to validate the incoming transfer
* before it starts. The contents of the metadata is implementation
* specific, and should contain all the information the application
* needs to determine whether this image should be accepted, and what
* the effect of the transfer would be.
*
* If applying the image will have an effect on the provisioning state
* of the mesh stack, this can be communicated through the @c effect
* return parameter.
*
* The metadata check can be performed both as part of starting a new
* transfer and as a separate procedure.
*
* This handler is optional.
*
* @param srv Firmware Update Server instance.
* @param img DFU image the metadata check is performed on.
* @param metadata Image metadata.
* @param effect Return parameter for the image effect on the
* provisioning state of the mesh stack.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int (*check)(struct bt_mesh_dfu_srv *srv,
const struct bt_mesh_dfu_img *img,
struct net_buf_simple *metadata,
enum bt_mesh_dfu_effect *effect);
/** @brief Transfer check callback.
*
* The transfer check can be used to validate the incoming transfer
* before it starts. The contents of the metadata is implementation
* specific, and should contain all the information the application
* needs to determine whether this image should be accepted, and what
* the effect of the transfer would be.
*
* If applying the image will have an effect on the provisioning state
* of the mesh stack, this can be communicated through the @c effect
* return parameter.
*
* The metadata check can be performed both as part of starting a new
* transfer and as a separate procedure.
*
* This handler is optional.
*
* @param srv Firmware Update Server instance.
* @param img DFU image the metadata check is performed on.
* @param metadata Image metadata.
* @param effect Return parameter for the image effect on the
* provisioning state of the mesh stack.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int (*check)(struct bt_mesh_dfu_srv *srv,
const struct bt_mesh_dfu_img *img,
struct net_buf_simple *metadata,
enum bt_mesh_dfu_effect *effect);
/** @brief Transfer start callback.
*
* Called when the Firmware Update Server is ready to start a new DFU transfer.
* The application must provide an initialized BLOB stream to be used
* during the DFU transfer.
*
* The following error codes are treated specially, and should be used
* to communicate these issues:
* - @c -ENOMEM: The device cannot fit this image.
* - @c -EBUSY: The application is temporarily unable to accept the
* transfer.
* - @c -EALREADY: The device has already received and verified this
* image, and there's no need to transfer it again. The Firmware Update model
* will skip the transfer phase, and mark the image as verified.
*
* This handler is mandatory.
*
* @param srv Firmware Update Server instance.
* @param img DFU image being updated.
* @param metadata Image metadata.
* @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 otherwise. Return
* codes @c -ENOMEM, @c -EBUSY @c -EALREADY will be passed to
* the updater, other error codes are reported as internal
* errors.
*/
int (*start)(struct bt_mesh_dfu_srv *srv,
const struct bt_mesh_dfu_img *img,
struct net_buf_simple *metadata,
const struct bt_mesh_blob_io **io);
/** @brief Transfer start callback.
*
* Called when the Firmware Update Server is ready to start a new DFU transfer.
* The application must provide an initialized BLOB stream to be used
* during the DFU transfer.
*
* The following error codes are treated specially, and should be used
* to communicate these issues:
* - @c -ENOMEM: The device cannot fit this image.
* - @c -EBUSY: The application is temporarily unable to accept the
* transfer.
* - @c -EALREADY: The device has already received and verified this
* image, and there's no need to transfer it again. The Firmware Update model
* will skip the transfer phase, and mark the image as verified.
*
* This handler is mandatory.
*
* @param srv Firmware Update Server instance.
* @param img DFU image being updated.
* @param metadata Image metadata.
* @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 otherwise. Return
* codes @c -ENOMEM, @c -EBUSY @c -EALREADY will be passed to
* the updater, other error codes are reported as internal
* errors.
*/
int (*start)(struct bt_mesh_dfu_srv *srv,
const struct bt_mesh_dfu_img *img,
struct net_buf_simple *metadata,
const struct bt_mesh_blob_io **io);
/** @brief Transfer end callback.
*
* This handler is optional.
*
* If the transfer is successful, the application should verify the
* firmware image, and call either @ref bt_mesh_dfu_srv_verified or
* @ref bt_mesh_dfu_srv_rejected depending on the outcome.
*
* If the transfer fails, the Firmware Update Server will be available for new
* transfers immediately after this function returns.
*
* @param srv Firmware Update Server instance.
* @param img DFU image that failed the update.
* @param success Whether the DFU transfer was successful.
*/
void (*end)(struct bt_mesh_dfu_srv *srv,
const struct bt_mesh_dfu_img *img, bool success);
/** @brief Transfer end callback.
*
* This handler is optional.
*
* If the transfer is successful, the application should verify the
* firmware image, and call either @ref bt_mesh_dfu_srv_verified or
* @ref bt_mesh_dfu_srv_rejected depending on the outcome.
*
* If the transfer fails, the Firmware Update Server will be available for new
* transfers immediately after this function returns.
*
* @param srv Firmware Update Server instance.
* @param img DFU image that failed the update.
* @param success Whether the DFU transfer was successful.
*/
void (*end)(struct bt_mesh_dfu_srv *srv,
const struct bt_mesh_dfu_img *img, bool success);
/** @brief Transfer recovery callback.
*
* If the device reboots in the middle of a transfer, the Firmware Update Server
* calls this function when the Bluetooth Mesh subsystem is started.
*
* This callback is optional, but transfers will not be recovered after
* a reboot without it.
*
* @param srv Firmware Update Server instance.
* @param img DFU image being updated.
* @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)(struct bt_mesh_dfu_srv *srv,
const struct bt_mesh_dfu_img *img,
const struct bt_mesh_blob_io **io);
/** @brief Transfer recovery callback.
*
* If the device reboots in the middle of a transfer, the Firmware Update Server
* calls this function when the Bluetooth Mesh subsystem is started.
*
* This callback is optional, but transfers will not be recovered after
* a reboot without it.
*
* @param srv Firmware Update Server instance.
* @param img DFU image being updated.
* @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)(struct bt_mesh_dfu_srv *srv,
const struct bt_mesh_dfu_img *img,
const struct bt_mesh_blob_io **io);
/** @brief Transfer apply callback.
*
* Called after a transfer has been validated, and the updater sends an
* apply message to the Target nodes.
*
* This handler is optional.
*
* @param srv Firmware Update Server instance.
* @param img DFU image that should be applied.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int (*apply)(struct bt_mesh_dfu_srv *srv,
const struct bt_mesh_dfu_img *img);
/** @brief Transfer apply callback.
*
* Called after a transfer has been validated, and the updater sends an
* apply message to the Target nodes.
*
* This handler is optional.
*
* @param srv Firmware Update Server instance.
* @param img DFU image that should be applied.
*
* @return 0 on success, or (negative) error code otherwise.
*/
int (*apply)(struct bt_mesh_dfu_srv *srv,
const struct bt_mesh_dfu_img *img);
};
/** @brief Firmware Update Server instance.
*
* Should be initialized with @ref BT_MESH_DFU_SRV_INIT.
* Should be initialized with @ref BLE_MESH_DFU_SRV_INIT.
*/
struct bt_mesh_dfu_srv {
/** Underlying BLOB Transfer Server. */
struct bt_mesh_blob_srv blob;
/** Callback structure. */
const struct bt_mesh_dfu_srv_cb *cb;
/** List of updatable images. */
const struct bt_mesh_dfu_img *imgs;
/** Number of updatable images. */
size_t img_count;
/** Underlying BLOB Transfer Server. */
struct bt_mesh_blob_srv blob;
/** Callback structure. */
const struct bt_mesh_dfu_srv_cb *cb;
/** List of updatable images. */
const struct bt_mesh_dfu_img *imgs;
/** Number of updatable images. */
size_t img_count;
/* Runtime state */
const struct bt_mesh_model *mod;
struct {
/* Effect of transfer, @see bt_mesh_dfu_effect. */
uint8_t effect;
/* Current phase, @see bt_mesh_dfu_phase. */
uint8_t phase;
uint8_t ttl;
uint8_t idx;
uint16_t timeout_base;
uint16_t meta;
} update;
/* Runtime state */
const struct bt_mesh_model *mod;
struct {
/* Effect of transfer, @see bt_mesh_dfu_effect. */
uint8_t effect;
/* Current phase, @see bt_mesh_dfu_phase. */
uint8_t phase;
uint8_t ttl;
uint8_t idx;
uint16_t timeout_base;
uint16_t meta;
} update;
};
/** @brief Accept the received DFU transfer.
@@ -235,7 +235,7 @@ void bt_mesh_dfu_srv_cancel(struct bt_mesh_dfu_srv *srv);
*/
void bt_mesh_dfu_srv_applied(struct bt_mesh_dfu_srv *srv);
/** @brief Check if the Firmware Update Server is busy processing a transfer.
/** @brief Check if the Firmware Update Server is busy processing a transfer.
*
* @param srv Firmware Update Server instance.
*
@@ -261,6 +261,4 @@ extern const struct bt_mesh_blob_srv_cb _bt_mesh_dfu_srv_blob_cb;
}
#endif
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_SRV_H__ */
/** @} */
#endif /* _BLE_MESH_v11_DFU_SRV_H__ */
@@ -1,15 +1,25 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_H__
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_H__
#ifndef _BLE_MESH_v11_BLOB_H__
#define _BLE_MESH_v11_BLOB_H__
#include <sys/types.h>
#include <zephyr/kernel.h>
#include "mesh/types.h"
#include "mesh/utils.h"
#include "mesh.h"
#include "mesh/utils.h"
#include "mesh/access.h"
#include "mesh/atomic.h"
#include "mesh/timer.h"
#include "mesh/compiler.h"
#include "mesh/trace.h"
#include "transport.h"
#include "mesh_v1.1/mbt/blob.h"
#ifdef __cplusplus
extern "C" {
@@ -21,236 +31,236 @@ extern "C" {
* @{
*/
#ifndef CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX
#define CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX 0
#ifndef CONFIG_BLE_MESH_BLOB_CHUNK_COUNT_MAX
#define CONFIG_BLE_MESH_BLOB_CHUNK_COUNT_MAX 0
#endif
/** BLOB transfer mode. */
enum bt_mesh_blob_xfer_mode {
/** No valid transfer mode. */
BT_MESH_BLOB_XFER_MODE_NONE,
/** Push mode (Push BLOB Transfer Mode). */
BT_MESH_BLOB_XFER_MODE_PUSH,
/** Pull mode (Pull BLOB Transfer Mode). */
BT_MESH_BLOB_XFER_MODE_PULL,
/** Both modes are valid. */
BT_MESH_BLOB_XFER_MODE_ALL,
/** No valid transfer mode. */
BT_MESH_BLOB_XFER_MODE_NONE,
/** Push mode (Push BLOB Transfer Mode). */
BT_MESH_BLOB_XFER_MODE_PUSH,
/** Pull mode (Pull BLOB Transfer Mode). */
BT_MESH_BLOB_XFER_MODE_PULL,
/** Both modes are valid. */
BT_MESH_BLOB_XFER_MODE_ALL,
};
/** Transfer phase. */
enum bt_mesh_blob_xfer_phase {
/** The BLOB Transfer Server is awaiting configuration. */
BT_MESH_BLOB_XFER_PHASE_INACTIVE,
/** The BLOB Transfer Server is ready to receive a BLOB transfer. */
BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_START,
/** The BLOB Transfer Server is waiting for the next block of data. */
BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_BLOCK,
/** The BLOB Transfer Server is waiting for the next chunk of data. */
BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_CHUNK,
/** The BLOB was transferred successfully. */
BT_MESH_BLOB_XFER_PHASE_COMPLETE,
/** The BLOB transfer is paused. */
BT_MESH_BLOB_XFER_PHASE_SUSPENDED,
/** The BLOB Transfer Server is awaiting configuration. */
BT_MESH_BLOB_XFER_PHASE_INACTIVE,
/** The BLOB Transfer Server is ready to receive a BLOB transfer. */
BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_START,
/** The BLOB Transfer Server is waiting for the next block of data. */
BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_BLOCK,
/** The BLOB Transfer Server is waiting for the next chunk of data. */
BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_CHUNK,
/** The BLOB was transferred successfully. */
BT_MESH_BLOB_XFER_PHASE_COMPLETE,
/** The BLOB transfer is paused. */
BT_MESH_BLOB_XFER_PHASE_SUSPENDED,
};
/** BLOB model status codes. */
enum bt_mesh_blob_status {
/** The message was processed successfully. */
BT_MESH_BLOB_SUCCESS,
/** The Block Number field value is not within the range of blocks being
* transferred.
*/
BT_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.
*/
BT_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.
*/
BT_MESH_BLOB_ERR_INVALID_CHUNK_SIZE,
/** The operation cannot be performed while the server is in the current
* phase.
*/
BT_MESH_BLOB_ERR_WRONG_PHASE,
/** A parameter value in the message cannot be accepted. */
BT_MESH_BLOB_ERR_INVALID_PARAM,
/** The message contains a BLOB ID value that is not expected. */
BT_MESH_BLOB_ERR_WRONG_BLOB_ID,
/** There is not enough space available in memory to receive the BLOB.
*/
BT_MESH_BLOB_ERR_BLOB_TOO_LARGE,
/** The transfer mode is not supported by the BLOB Transfer Server
* model.
*/
BT_MESH_BLOB_ERR_UNSUPPORTED_MODE,
/** An internal error occurred on the node. */
BT_MESH_BLOB_ERR_INTERNAL,
/** The requested information cannot be provided while the server is in
* the current phase.
*/
BT_MESH_BLOB_ERR_INFO_UNAVAILABLE,
/** The message was processed successfully. */
BT_MESH_BLOB_SUCCESS,
/** The Block Number field value is not within the range of blocks being
* transferred.
*/
BT_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.
*/
BT_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.
*/
BT_MESH_BLOB_ERR_INVALID_CHUNK_SIZE,
/** The operation cannot be performed while the server is in the current
* phase.
*/
BT_MESH_BLOB_ERR_WRONG_PHASE,
/** A parameter value in the message cannot be accepted. */
BT_MESH_BLOB_ERR_INVALID_PARAM,
/** The message contains a BLOB ID value that is not expected. */
BT_MESH_BLOB_ERR_WRONG_BLOB_ID,
/** There is not enough space available in memory to receive the BLOB.
*/
BT_MESH_BLOB_ERR_BLOB_TOO_LARGE,
/** The transfer mode is not supported by the BLOB Transfer Server
* model.
*/
BT_MESH_BLOB_ERR_UNSUPPORTED_MODE,
/** An internal error occurred on the node. */
BT_MESH_BLOB_ERR_INTERNAL,
/** The requested information cannot be provided while the server is in
* the current phase.
*/
BT_MESH_BLOB_ERR_INFO_UNAVAILABLE,
};
/** BLOB transfer data block. */
struct bt_mesh_blob_block {
/** Block size in bytes */
size_t size;
/** Offset in bytes from the start of the BLOB. */
off_t offset;
/** Block number */
uint16_t number;
/** Number of chunks in block. */
uint16_t chunk_count;
/** Bitmap of missing chunks. */
uint8_t missing[DIV_ROUND_UP(CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX,
8)];
/** Block size in bytes */
size_t size;
/** Offset in bytes from the start of the BLOB. */
off_t offset;
/** Block number */
uint16_t number;
/** Number of chunks in block. */
uint16_t chunk_count;
/** Bitmap of missing chunks. */
uint8_t missing[DIV_ROUND_UP(CONFIG_BLE_MESH_BLOB_CHUNK_COUNT_MAX,
8)];
};
/** BLOB data chunk. */
struct bt_mesh_blob_chunk {
/** Offset of the chunk data from the start of the block. */
off_t offset;
/** Chunk data size. */
size_t size;
/** Chunk data. */
uint8_t *data;
/** Offset of the chunk data from the start of the block. */
off_t offset;
/** Chunk data size. */
size_t size;
/** Chunk data. */
uint8_t *data;
};
/** BLOB transfer. */
struct bt_mesh_blob_xfer {
/** BLOB ID. */
uint64_t id;
/** Total BLOB size in bytes. */
size_t size;
/** BLOB transfer mode. */
enum bt_mesh_blob_xfer_mode mode;
/* Logarithmic representation of the block size. */
uint8_t block_size_log;
/** Base chunk size. May be smaller for the last chunk. */
uint16_t chunk_size;
/** BLOB ID. */
uint64_t id;
/** Total BLOB size in bytes. */
size_t size;
/** BLOB transfer mode. */
enum bt_mesh_blob_xfer_mode mode;
/* Logarithmic representation of the block size. */
uint8_t block_size_log;
/** Base chunk size. May be smaller for the last chunk. */
uint16_t chunk_size;
};
/** BLOB stream interaction mode. */
enum bt_mesh_blob_io_mode {
/** Read data from the stream. */
BT_MESH_BLOB_READ,
/** Write data to the stream. */
BT_MESH_BLOB_WRITE,
/** Read data from the stream. */
BT_MESH_BLOB_READ,
/** Write data to the stream. */
BT_MESH_BLOB_WRITE,
};
/** BLOB stream. */
struct bt_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 struct bt_mesh_blob_io *io,
const struct bt_mesh_blob_xfer *xfer,
enum bt_mesh_blob_io_mode mode);
/** @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 struct bt_mesh_blob_io *io,
const struct bt_mesh_blob_xfer *xfer,
enum bt_mesh_blob_io_mode mode);
/** @brief Close callback.
*
* Called when the reader is closed.
*
* @param io BLOB stream.
* @param xfer BLOB transfer.
*/
void (*close)(const struct bt_mesh_blob_io *io,
const struct bt_mesh_blob_xfer *xfer);
/** @brief Close callback.
*
* Called when the reader is closed.
*
* @param io BLOB stream.
* @param xfer BLOB transfer.
*/
void (*close)(const struct bt_mesh_blob_io *io,
const struct bt_mesh_blob_xfer *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 struct bt_mesh_blob_io *io,
const struct bt_mesh_blob_xfer *xfer,
const struct bt_mesh_blob_block *block);
/** @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 struct bt_mesh_blob_io *io,
const struct bt_mesh_blob_xfer *xfer,
const struct bt_mesh_blob_block *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 struct bt_mesh_blob_io *io,
const struct bt_mesh_blob_xfer *xfer,
const struct bt_mesh_blob_block *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 struct bt_mesh_blob_io *io,
const struct bt_mesh_blob_xfer *xfer,
const struct bt_mesh_blob_block *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 (*wr)(const struct bt_mesh_blob_io *io,
const struct bt_mesh_blob_xfer *xfer,
const struct bt_mesh_blob_block *block,
const struct bt_mesh_blob_chunk *chunk);
/** @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 (*wr)(const struct bt_mesh_blob_io *io,
const struct bt_mesh_blob_xfer *xfer,
const struct bt_mesh_blob_block *block,
const struct bt_mesh_blob_chunk *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 (*rd)(const struct bt_mesh_blob_io *io,
const struct bt_mesh_blob_xfer *xfer,
const struct bt_mesh_blob_block *block,
const struct bt_mesh_blob_chunk *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 (*rd)(const struct bt_mesh_blob_io *io,
const struct bt_mesh_blob_xfer *xfer,
const struct bt_mesh_blob_block *block,
const struct bt_mesh_blob_chunk *chunk);
};
/** @} */
@@ -259,4 +269,4 @@ struct bt_mesh_blob_io {
}
#endif
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_H__ */
#endif /* _BLE_MESH_v11_BLOB_H__ */
@@ -1,16 +1,26 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_CLI_H_
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_CLI_H_
#ifndef _BLE_MESH_v11_BLOB_CLI_H_
#define _BLE_MESH_v11_BLOB_CLI_H_
#include <sys/types.h>
#include <zephyr/bluetooth/mesh/access.h>
#include <zephyr/bluetooth/mesh/blob.h>
#include "mesh/access.h"
#include "mesh/utils.h"
#include "mesh.h"
#include "mesh/utils.h"
#include "mesh/access.h"
#include "mesh/atomic.h"
#include "mesh/timer.h"
#include "mesh/compiler.h"
#include "mesh/trace.h"
#include "transport.h"
#include "mesh_v1.1/mbt/blob.h"
#ifdef __cplusplus
extern "C" {
@@ -30,41 +40,41 @@ struct bt_mesh_blob_cli;
*
* @param _cli Pointer to a @ref bt_mesh_blob_cli instance.
*/
#define BT_MESH_MODEL_BLOB_CLI(_cli) \
BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_BLOB_CLI, _bt_mesh_blob_cli_op, \
NULL, _cli, &_bt_mesh_blob_cli_cb)
#define BT_MESH_MODEL_BLOB_CLI(_cli) \
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_BLOB_CLI, _bt_mesh_blob_cli_op, \
NULL, _cli, &_bt_mesh_blob_cli_cb)
/** Target node's Pull mode (Pull BLOB Transfer Mode) context used
* while sending chunks to the Target node.
*/
struct bt_mesh_blob_target_pull {
/** Timestamp when the Block Report Timeout Timer expires for this Target node. */
int64_t block_report_timestamp;
/** Timestamp when the Block Report Timeout Timer expires for this Target node. */
int64_t block_report_timestamp;
/** Missing chunks reported by this Target node. */
uint8_t missing[DIV_ROUND_UP(CONFIG_BT_MESH_BLOB_CHUNK_COUNT_MAX, 8)];
/** Missing chunks reported by this Target node. */
uint8_t missing[DIV_ROUND_UP(CONFIG_BLE_MESH_BLOB_CHUNK_COUNT_MAX, 8)];
};
/** BLOB Transfer Client Target node. */
struct bt_mesh_blob_target {
/** Linked list node */
sys_snode_t n;
/** Linked list node */
sys_snode_t n;
/** Target node address. */
uint16_t addr;
/** Target node address. */
uint16_t addr;
/** Target node's Pull mode context.
* Needs to be initialized when sending a BLOB in Pull mode.
*/
struct bt_mesh_blob_target_pull *pull;
struct bt_mesh_blob_target_pull *pull;
/** BLOB transfer status, see @ref bt_mesh_blob_status. */
uint8_t status;
/** BLOB transfer status, see @ref bt_mesh_blob_status. */
uint8_t 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. */
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.
@@ -75,112 +85,112 @@ struct bt_mesh_blob_target {
* the fields below @c id are not initialized.
*/
struct bt_mesh_blob_xfer_info {
/** BLOB transfer status. */
enum bt_mesh_blob_status status;
/** BLOB transfer status. */
enum bt_mesh_blob_status status;
/** BLOB transfer mode. */
enum bt_mesh_blob_xfer_mode mode;
/** BLOB transfer mode. */
enum bt_mesh_blob_xfer_mode mode;
/** BLOB transfer phase. */
enum bt_mesh_blob_xfer_phase phase;
/** BLOB transfer phase. */
enum bt_mesh_blob_xfer_phase phase;
/** BLOB ID. */
uint64_t id;
/** BLOB ID. */
uint64_t id;
/** BLOB size in octets. */
uint32_t size;
/** BLOB size in octets. */
uint32_t size;
/** Logarithmic representation of the block size. */
uint8_t block_size_log;
/** Logarithmic representation of the block size. */
uint8_t block_size_log;
/** MTU size in octets. */
uint16_t mtu_size;
/** MTU size in octets. */
uint16_t mtu_size;
/** Bit field indicating blocks that were not received. */
const uint8_t *missing_blocks;
/** Bit field indicating blocks that were not received. */
const uint8_t *missing_blocks;
};
/** BLOB Transfer Client transfer inputs. */
struct bt_mesh_blob_cli_inputs {
/** Linked list of Target nodes. Each node should point to @ref
* bt_mesh_blob_target::n.
*/
sys_slist_t targets;
/** Linked list of Target nodes. Each node should point to @ref
* bt_mesh_blob_target::n.
*/
sys_slist_t targets;
/** AppKey index to send with. */
uint16_t app_idx;
/** AppKey index to send with. */
uint16_t app_idx;
/** Group address destination for the BLOB transfer, or @ref
* BT_MESH_ADDR_UNASSIGNED to send every message to each Target
* node individually.
*/
uint16_t group;
/** Group address destination for the BLOB transfer, or @ref
* 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;
/** 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;
/** 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 bt_mesh_blob_cli_caps {
/** Max BLOB size. */
size_t max_size;
/** Max BLOB size. */
size_t max_size;
/** Logarithmic representation of the minimum block size. */
uint8_t min_block_size_log;
/** Logarithmic representation of the minimum block size. */
uint8_t min_block_size_log;
/** Logarithmic representation of the maximum block size. */
uint8_t max_block_size_log;
/** Logarithmic representation of the maximum block size. */
uint8_t max_block_size_log;
/** Max number of chunks per block. */
uint16_t max_chunks;
/** Max number of chunks per block. */
uint16_t max_chunks;
/** Max chunk size. */
uint16_t max_chunk_size;
/** Max chunk size. */
uint16_t max_chunk_size;
/** Max MTU size. */
uint16_t mtu_size;
/** Max MTU size. */
uint16_t mtu_size;
/** Supported transfer modes. */
enum bt_mesh_blob_xfer_mode modes;
/** Supported transfer modes. */
enum bt_mesh_blob_xfer_mode modes;
};
/** BLOB Transfer Client state. */
enum bt_mesh_blob_cli_state {
/** No transfer is active. */
BT_MESH_BLOB_CLI_STATE_NONE,
/** Retrieving transfer capabilities. */
BT_MESH_BLOB_CLI_STATE_CAPS_GET,
/** Sending transfer start. */
BT_MESH_BLOB_CLI_STATE_START,
/** Sending block start. */
BT_MESH_BLOB_CLI_STATE_BLOCK_START,
/** Sending block chunks. */
BT_MESH_BLOB_CLI_STATE_BLOCK_SEND,
/** Checking block status. */
BT_MESH_BLOB_CLI_STATE_BLOCK_CHECK,
/** Checking transfer status. */
BT_MESH_BLOB_CLI_STATE_XFER_CHECK,
/** Cancelling transfer. */
BT_MESH_BLOB_CLI_STATE_CANCEL,
/** Transfer is suspended. */
BT_MESH_BLOB_CLI_STATE_SUSPENDED,
/** Checking transfer progress. */
BT_MESH_BLOB_CLI_STATE_XFER_PROGRESS_GET,
/** No transfer is active. */
BT_MESH_BLOB_CLI_STATE_NONE,
/** Retrieving transfer capabilities. */
BT_MESH_BLOB_CLI_STATE_CAPS_GET,
/** Sending transfer start. */
BT_MESH_BLOB_CLI_STATE_START,
/** Sending block start. */
BT_MESH_BLOB_CLI_STATE_BLOCK_START,
/** Sending block chunks. */
BT_MESH_BLOB_CLI_STATE_BLOCK_SEND,
/** Checking block status. */
BT_MESH_BLOB_CLI_STATE_BLOCK_CHECK,
/** Checking transfer status. */
BT_MESH_BLOB_CLI_STATE_XFER_CHECK,
/** Cancelling transfer. */
BT_MESH_BLOB_CLI_STATE_CANCEL,
/** Transfer is suspended. */
BT_MESH_BLOB_CLI_STATE_SUSPENDED,
/** Checking transfer progress. */
BT_MESH_BLOB_CLI_STATE_XFER_PROGRESS_GET,
};
/** Event handler callbacks for the BLOB Transfer Client model.
@@ -188,138 +198,138 @@ enum bt_mesh_blob_cli_state {
* All handlers are optional.
*/
struct bt_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 @ref BT_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)(struct bt_mesh_blob_cli *cli,
const struct bt_mesh_blob_cli_caps *caps);
/** @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 @ref BT_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)(struct bt_mesh_blob_cli *cli,
const struct bt_mesh_blob_cli_caps *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)(struct bt_mesh_blob_cli *cli,
struct bt_mesh_blob_target *target,
enum bt_mesh_blob_status reason);
/** @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)(struct bt_mesh_blob_cli *cli,
struct bt_mesh_blob_target *target,
enum bt_mesh_blob_status 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 (*suspended)(struct bt_mesh_blob_cli *cli);
/** @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 (*suspended)(struct bt_mesh_blob_cli *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)(struct bt_mesh_blob_cli *cli,
const struct bt_mesh_blob_xfer *xfer, bool success);
/** @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)(struct bt_mesh_blob_cli *cli,
const struct bt_mesh_blob_xfer *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)(struct bt_mesh_blob_cli *cli,
struct bt_mesh_blob_target *target,
const struct bt_mesh_blob_xfer_info *info);
/** @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)(struct bt_mesh_blob_cli *cli,
struct bt_mesh_blob_target *target,
const struct bt_mesh_blob_xfer_info *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)(struct bt_mesh_blob_cli *cli);
/** @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)(struct bt_mesh_blob_cli *cli);
};
/** @cond INTERNAL_HIDDEN */
struct blob_cli_broadcast_ctx {
/** Called for every Target node in unicast mode, or once in case of multicast mode. */
void (*send)(struct bt_mesh_blob_cli *cli, uint16_t dst);
/** Called after every @ref blob_cli_broadcast_ctx::send callback. */
void (*send_complete)(struct bt_mesh_blob_cli *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)(struct bt_mesh_blob_cli *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;
/** Called for every Target node in unicast mode, or once in case of multicast mode. */
void (*send)(struct bt_mesh_blob_cli *cli, uint16_t dst);
/** Called after every @ref blob_cli_broadcast_ctx::send callback. */
void (*send_complete)(struct bt_mesh_blob_cli *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)(struct bt_mesh_blob_cli *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;
};
/** INTERNAL_HIDDEN @endcond */
/** BLOB Transfer Client model instance. */
struct bt_mesh_blob_cli {
/** Event handler callbacks */
const struct bt_mesh_blob_cli_cb *cb;
/** Event handler callbacks */
const struct bt_mesh_blob_cli_cb *cb;
/* Runtime state */
const struct bt_mesh_model *mod;
/* Runtime state */
const struct bt_mesh_model *mod;
struct {
struct bt_mesh_blob_target *target;
struct blob_cli_broadcast_ctx ctx;
struct k_work_delayable retry;
/* Represents Client Timeout timer in a timestamp. Used in Pull mode only. */
int64_t cli_timestamp;
struct k_work_delayable complete;
uint16_t pending;
uint8_t retries;
uint8_t sending : 1,
cancelled : 1;
} tx;
struct {
struct bt_mesh_blob_target *target;
struct blob_cli_broadcast_ctx ctx;
struct k_work_delayable retry;
/* Represents Client Timeout timer in a timestamp. Used in Pull mode only. */
int64_t cli_timestamp;
struct k_work_delayable complete;
uint16_t pending;
uint8_t retries;
uint8_t sending : 1,
cancelled : 1;
} tx;
const struct bt_mesh_blob_io *io;
const struct bt_mesh_blob_cli_inputs *inputs;
const struct bt_mesh_blob_xfer *xfer;
uint32_t chunk_interval_ms;
uint16_t block_count;
uint16_t chunk_idx;
uint16_t mtu_size;
enum bt_mesh_blob_cli_state state;
struct bt_mesh_blob_block block;
struct bt_mesh_blob_cli_caps caps;
const struct bt_mesh_blob_io *io;
const struct bt_mesh_blob_cli_inputs *inputs;
const struct bt_mesh_blob_xfer *xfer;
uint32_t chunk_interval_ms;
uint16_t block_count;
uint16_t chunk_idx;
uint16_t mtu_size;
enum bt_mesh_blob_cli_state state;
struct bt_mesh_blob_block block;
struct bt_mesh_blob_cli_caps caps;
};
/** @brief Retrieve transfer capabilities for a list of Target nodes.
@@ -342,7 +352,7 @@ struct bt_mesh_blob_cli {
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_blob_cli_caps_get(struct bt_mesh_blob_cli *cli,
const struct bt_mesh_blob_cli_inputs *inputs);
const struct bt_mesh_blob_cli_inputs *inputs);
/** @brief Perform a BLOB transfer.
*
@@ -366,9 +376,9 @@ int bt_mesh_blob_cli_caps_get(struct bt_mesh_blob_cli *cli,
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_blob_cli_send(struct bt_mesh_blob_cli *cli,
const struct bt_mesh_blob_cli_inputs *inputs,
const struct bt_mesh_blob_xfer *xfer,
const struct bt_mesh_blob_io *io);
const struct bt_mesh_blob_cli_inputs *inputs,
const struct bt_mesh_blob_xfer *xfer,
const struct bt_mesh_blob_io *io);
/** @brief Suspend the active transfer.
*
@@ -392,6 +402,9 @@ int bt_mesh_blob_cli_resume(struct bt_mesh_blob_cli *cli);
*/
void bt_mesh_blob_cli_cancel(struct bt_mesh_blob_cli *cli);
void bt_mesh_blob_cli_send_cancel(struct bt_mesh_blob_cli *cli,
const struct bt_mesh_blob_xfer *xfer);
/** @brief Get the progress of BLOB transfer.
*
* This function can only be used if the BLOB Transfer Client is currently
@@ -405,7 +418,7 @@ void bt_mesh_blob_cli_cancel(struct bt_mesh_blob_cli *cli);
* @return 0 on success, or (negative) error code otherwise.
*/
int bt_mesh_blob_cli_xfer_progress_get(struct bt_mesh_blob_cli *cli,
const struct bt_mesh_blob_cli_inputs *inputs);
const struct bt_mesh_blob_cli_inputs *inputs);
/** @brief Get the current progress of the active transfer in percent.
*
@@ -451,4 +464,4 @@ extern const struct bt_mesh_model_cb _bt_mesh_blob_cli_cb;
}
#endif
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_CLI_H_ */
#endif /* _BLE_MESH_v11_BLOB_CLI_H_ */
@@ -1,14 +1,24 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_SRV_H_
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_SRV_H_
#ifndef _BLE_MESH_v11_BLOB_SRV_H_
#define _BLE_MESH_v11_BLOB_SRV_H_
#include <zephyr/bluetooth/mesh/access.h>
#include <zephyr/bluetooth/mesh/blob.h>
#include "mesh/access.h"
#include "mesh/utils.h"
#include "mesh_v1.1/mbt/blob.h"
#include "mesh.h"
#include "mesh/utils.h"
#include "mesh/access.h"
#include "mesh/atomic.h"
#include "mesh/timer.h"
#include "mesh/compiler.h"
#include "mesh/trace.h"
#include "transport.h"
#ifdef __cplusplus
extern "C" {
@@ -26,10 +36,9 @@ struct bt_mesh_blob_srv;
*
* @brief Max number of blocks in a single transfer.
*/
#if defined(CONFIG_BT_MESH_BLOB_SRV)
#define BT_MESH_BLOB_BLOCKS_MAX \
(DIV_ROUND_UP(CONFIG_BT_MESH_BLOB_SIZE_MAX, \
CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MIN))
#if defined(CONFIG_BLE_MESH_BLOB_SRV)
#define BT_MESH_BLOB_BLOCKS_MAX \
(DIV_ROUND_UP(CONFIG_BLE_MESH_BLOB_SIZE_MAX, CONFIG_BLE_MESH_BLOB_BLOCK_SIZE_MIN))
#else
#define BT_MESH_BLOB_BLOCKS_MAX 1
#endif
@@ -41,121 +50,121 @@ struct bt_mesh_blob_srv;
* @param _srv Pointer to a @ref bt_mesh_blob_srv instance.
*/
#define BT_MESH_MODEL_BLOB_SRV(_srv) \
BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_BLOB_SRV, _bt_mesh_blob_srv_op, \
NULL, _srv, &_bt_mesh_blob_srv_cb)
BLE_MESH_MODEL_CB(BLE_MESH_MODEL_ID_BLOB_SRV, _bt_mesh_blob_srv_op, \
NULL, _srv, &_bt_mesh_blob_srv_cb)
/** @brief BLOB Transfer Server model event handlers.
*
* All callbacks are optional.
*/
struct bt_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)(struct bt_mesh_blob_srv *srv, struct bt_mesh_msg_ctx *ctx,
struct bt_mesh_blob_xfer *xfer);
/** @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)(struct bt_mesh_blob_srv *srv, struct bt_mesh_msg_ctx *ctx,
struct bt_mesh_blob_xfer *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)(struct bt_mesh_blob_srv *srv, uint64_t id, bool success);
/** @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)(struct bt_mesh_blob_srv *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 (*suspended)(struct bt_mesh_blob_srv *srv);
/** @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 (*suspended)(struct bt_mesh_blob_srv *srv);
/** @brief Transfer resume callback.
*
* Called if the transfer is resumed after being suspended.
*
* @param srv BLOB Transfer Server instance.
*/
void (*resume)(struct bt_mesh_blob_srv *srv);
/** @brief Transfer resume callback.
*
* Called if the transfer is resumed after being suspended.
*
* @param srv BLOB Transfer Server instance.
*/
void (*resume)(struct bt_mesh_blob_srv *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)(struct bt_mesh_blob_srv *srv,
struct bt_mesh_blob_xfer *xfer,
const struct bt_mesh_blob_io **io);
/** @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)(struct bt_mesh_blob_srv *srv,
struct bt_mesh_blob_xfer *xfer,
const struct bt_mesh_blob_io **io);
};
/** @brief BLOB Transfer Server model instance. */
struct bt_mesh_blob_srv {
/** Event handler callbacks. */
const struct bt_mesh_blob_srv_cb *cb;
/** Event handler callbacks. */
const struct bt_mesh_blob_srv_cb *cb;
/* Runtime state: */
const struct bt_mesh_blob_io *io;
struct k_work_delayable rx_timeout;
struct bt_mesh_blob_block block;
const struct bt_mesh_model *mod;
enum bt_mesh_blob_xfer_phase phase;
/* Runtime state: */
const struct bt_mesh_blob_io *io;
struct k_work_delayable rx_timeout;
struct bt_mesh_blob_block block;
const struct bt_mesh_model *mod;
enum bt_mesh_blob_xfer_phase phase;
struct bt_mesh_blob_srv_state {
struct bt_mesh_blob_xfer xfer;
uint16_t cli;
uint16_t app_idx;
uint16_t timeout_base;
uint16_t mtu_size;
uint8_t ttl;
struct bt_mesh_blob_srv_state {
struct bt_mesh_blob_xfer xfer;
uint16_t cli;
uint16_t app_idx;
uint16_t timeout_base;
uint16_t mtu_size;
uint8_t ttl;
/* Bitfield of pending blocks. */
ATOMIC_DEFINE(blocks, BT_MESH_BLOB_BLOCKS_MAX);
} state;
/* Bitfield of pending blocks. */
BLE_MESH_ATOMIC_DEFINE(blocks, BT_MESH_BLOB_BLOCKS_MAX);
} state;
/* Pull mode (Pull BLOB Transfer Mode) behavior. */
struct {
uint16_t chunk_idx;
struct k_work_delayable report;
} pull;
/* Pull mode (Pull BLOB Transfer Mode) behavior. */
struct {
uint16_t chunk_idx;
struct k_work_delayable report;
} pull;
};
/** @brief Prepare BLOB Transfer Server for an incoming transfer.
@@ -174,8 +183,8 @@ struct bt_mesh_blob_srv {
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_blob_srv_recv(struct bt_mesh_blob_srv *srv, uint64_t id,
const struct bt_mesh_blob_io *io, uint8_t ttl,
uint16_t timeout_base);
const struct bt_mesh_blob_io *io, uint8_t ttl,
uint16_t timeout_base);
/** @brief Cancel the current BLOB transfer.
*
@@ -217,4 +226,4 @@ extern const struct bt_mesh_model_cb _bt_mesh_blob_srv_cb;
}
#endif
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_BLOB_SRV_H_ */
#endif /* _BLE_MESH_v11_BLOB_SRV_H_ */
+62 -52
View File
@@ -1,44 +1,51 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <zephyr/sys/util.h>
#define BT_MESH_BLOB_OP_XFER_GET BT_MESH_MODEL_OP_2(0x83, 0x00)
#define BT_MESH_BLOB_OP_XFER_START BT_MESH_MODEL_OP_2(0x83, 0x01)
#define BT_MESH_BLOB_OP_XFER_CANCEL BT_MESH_MODEL_OP_2(0x83, 0x02)
#define BT_MESH_BLOB_OP_XFER_STATUS BT_MESH_MODEL_OP_2(0x83, 0x03)
#define BT_MESH_BLOB_OP_BLOCK_GET BT_MESH_MODEL_OP_2(0x83, 0x05)
#define BT_MESH_BLOB_OP_BLOCK_START BT_MESH_MODEL_OP_2(0x83, 0x04)
#define BT_MESH_BLOB_OP_CHUNK BT_MESH_MODEL_OP_1(0x66)
#define BT_MESH_BLOB_OP_BLOCK_STATUS BT_MESH_MODEL_OP_1(0x67)
#define BT_MESH_BLOB_OP_BLOCK_REPORT BT_MESH_MODEL_OP_1(0x68)
#define BT_MESH_BLOB_OP_INFO_GET BT_MESH_MODEL_OP_2(0x83, 0x06)
#define BT_MESH_BLOB_OP_INFO_STATUS BT_MESH_MODEL_OP_2(0x83, 0x07)
#if CONFIG_BLE_MESH_BLOB_CLI || CONFIG_BLE_MESH_BLOB_SRV
#include "mesh/utils.h"
#include "mesh_v1.1/mbt/blob.h"
#include "mesh_v1.1/mbt/blob_cli.h"
#include "mesh_v1.1/mbt/blob_srv.h"
#define BT_MESH_BLOB_OP_XFER_GET BLE_MESH_MODEL_OP_2(0x83, 0x00)
#define BT_MESH_BLOB_OP_XFER_START BLE_MESH_MODEL_OP_2(0x83, 0x01)
#define BT_MESH_BLOB_OP_XFER_CANCEL BLE_MESH_MODEL_OP_2(0x83, 0x02)
#define BT_MESH_BLOB_OP_XFER_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x03)
#define BT_MESH_BLOB_OP_BLOCK_GET BLE_MESH_MODEL_OP_2(0x83, 0x05)
#define BT_MESH_BLOB_OP_BLOCK_START BLE_MESH_MODEL_OP_2(0x83, 0x04)
#define BT_MESH_BLOB_OP_CHUNK BLE_MESH_MODEL_OP_1(0x66)
#define BT_MESH_BLOB_OP_BLOCK_STATUS BLE_MESH_MODEL_OP_1(0x67)
#define BT_MESH_BLOB_OP_BLOCK_REPORT BLE_MESH_MODEL_OP_1(0x68)
#define BT_MESH_BLOB_OP_INFO_GET BLE_MESH_MODEL_OP_2(0x83, 0x06)
#define BT_MESH_BLOB_OP_INFO_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x07)
#define BLOB_BLOCK_NOT_SET 0xffff
#define BLOB_CHUNK_SDU_OVERHEAD \
(BT_MESH_MODEL_OP_LEN(BT_MESH_BLOB_OP_CHUNK) + 2 + BT_MESH_MIC_SHORT)
#define BLOB_CHUNK_SDU_OVERHEAD \
(BLE_MESH_MODEL_OP_LEN(BT_MESH_BLOB_OP_CHUNK) + 2 + BLE_MESH_MIC_SHORT)
#define BLOB_CHUNK_SIZE_MAX(sdu_max) ((sdu_max) - BLOB_CHUNK_SDU_OVERHEAD)
#define BLOB_CHUNK_SDU_LEN(chunk_size) (BLOB_CHUNK_SDU_OVERHEAD + (chunk_size))
#if CONFIG_BT_MESH_ALIGN_CHUNK_SIZE_TO_MAX_SEGMENT || \
CONFIG_BT_MESH_RX_BLOB_CHUNK_SIZE > BLOB_CHUNK_SIZE_MAX(BT_MESH_RX_SDU_MAX)
#define BLOB_RX_CHUNK_SIZE BLOB_CHUNK_SIZE_MAX(BT_MESH_RX_SDU_MAX)
#if CONFIG_BLE_MESH_ALIGN_CHUNK_SIZE_TO_MAX_SEGMENT || \
CONFIG_BLE_MESH_RX_BLOB_CHUNK_SIZE > BLOB_CHUNK_SIZE_MAX(BLE_MESH_RX_SDU_MAX)
#define BLOB_RX_CHUNK_SIZE BLOB_CHUNK_SIZE_MAX(BLE_MESH_RX_SDU_MAX)
#else
#define BLOB_RX_CHUNK_SIZE CONFIG_BT_MESH_RX_BLOB_CHUNK_SIZE
#define BLOB_RX_CHUNK_SIZE CONFIG_BLE_MESH_RX_BLOB_CHUNK_SIZE
#endif
#if CONFIG_BT_MESH_ALIGN_CHUNK_SIZE_TO_MAX_SEGMENT || \
CONFIG_BT_MESH_TX_BLOB_CHUNK_SIZE > BLOB_CHUNK_SIZE_MAX(BT_MESH_TX_SDU_MAX)
#define BLOB_TX_CHUNK_SIZE BLOB_CHUNK_SIZE_MAX(BT_MESH_TX_SDU_MAX)
#if CONFIG_BLE_MESH_ALIGN_CHUNK_SIZE_TO_MAX_SEGMENT || \
CONFIG_BLE_MESH_TX_BLOB_CHUNK_SIZE > BLOB_CHUNK_SIZE_MAX(BLE_MESH_TX_SDU_MAX)
#define BLOB_TX_CHUNK_SIZE BLOB_CHUNK_SIZE_MAX(BLE_MESH_TX_SDU_MAX)
#else
#define BLOB_TX_CHUNK_SIZE CONFIG_BT_MESH_TX_BLOB_CHUNK_SIZE
#define BLOB_TX_CHUNK_SIZE CONFIG_BLE_MESH_TX_BLOB_CHUNK_SIZE
#endif
/* Utility macros for calculating log2 of a number at compile time.
@@ -57,17 +64,17 @@
#define BLOB_BLOCK_SIZE_LOG_FLOOR(x) (LISTIFY(20, _BLOB_LOG_2_FLOOR, (), x) 20)
/* Log2 representation of the minimum block size */
#define BLOB_BLOCK_SIZE_LOG_MIN BLOB_BLOCK_SIZE_LOG_CEIL(CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MIN)
#define BLOB_BLOCK_SIZE_LOG_MIN BLOB_BLOCK_SIZE_LOG_CEIL(CONFIG_BLE_MESH_BLOB_BLOCK_SIZE_MIN)
/* Log2 representation of the maximum block size */
#define BLOB_BLOCK_SIZE_LOG_MAX BLOB_BLOCK_SIZE_LOG_FLOOR(CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MAX)
#define BLOB_BLOCK_SIZE_LOG_MAX BLOB_BLOCK_SIZE_LOG_FLOOR(CONFIG_BLE_MESH_BLOB_BLOCK_SIZE_MAX)
#if defined(CONFIG_BT_MESH_BLOB_SRV)
#define BLOB_BLOCK_REPORT_STATUS_MSG_MAXLEN ( \
MAX(sizeof(((struct bt_mesh_blob_block *)0)->missing), \
CONFIG_BT_MESH_BLOB_SRV_PULL_REQ_COUNT * 3))
#define BLOB_BLOCK_STATUS_MSG_MAXLEN (5 + \
MAX(sizeof(((struct bt_mesh_blob_block *)0)->missing), \
CONFIG_BT_MESH_BLOB_SRV_PULL_REQ_COUNT * 3))
#if defined(CONFIG_BLE_MESH_BLOB_SRV)
#define BLOB_BLOCK_REPORT_STATUS_MSG_MAXLEN ( \
MAX(sizeof(((struct bt_mesh_blob_block *)0)->missing), \
CONFIG_BLE_MESH_BLOB_SRV_PULL_REQ_COUNT * 3))
#define BLOB_BLOCK_STATUS_MSG_MAXLEN (5 + \
MAX(sizeof(((struct bt_mesh_blob_block *)0)->missing), \
CONFIG_BLE_MESH_BLOB_SRV_PULL_REQ_COUNT * 3))
#else
#define BLOB_BLOCK_REPORT_STATUS_MSG_MAXLEN sizeof(((struct bt_mesh_blob_srv *)0)->block.missing)
#define BLOB_BLOCK_STATUS_MSG_MAXLEN (5 + sizeof(((struct bt_mesh_blob_srv *)0)->block.missing))
@@ -76,49 +83,50 @@
#define BLOB_XFER_STATUS_MSG_MAXLEN (17 + sizeof(((struct bt_mesh_blob_srv *)0)->state.blocks))
enum bt_mesh_blob_chunks_missing {
BT_MESH_BLOB_CHUNKS_MISSING_ALL,
BT_MESH_BLOB_CHUNKS_MISSING_NONE,
BT_MESH_BLOB_CHUNKS_MISSING_SOME,
BT_MESH_BLOB_CHUNKS_MISSING_ENCODED,
BT_MESH_BLOB_CHUNKS_MISSING_ALL,
BT_MESH_BLOB_CHUNKS_MISSING_NONE,
BT_MESH_BLOB_CHUNKS_MISSING_SOME,
BT_MESH_BLOB_CHUNKS_MISSING_ENCODED,
};
static inline size_t blob_block_size(size_t xfer_size, uint8_t block_size_log,
uint32_t idx)
uint32_t idx)
{
if (((idx + 1U) << block_size_log) <= xfer_size) {
return (1U << block_size_log);
}
if (((idx + 1U) << block_size_log) <= xfer_size) {
return (1U << block_size_log);
}
return xfer_size & BIT_MASK(block_size_log);
return xfer_size & BIT_MASK(block_size_log);
}
static inline void blob_chunk_missing_set(uint8_t *missing_chunks,
int idx, bool missing)
int idx, bool missing)
{
WRITE_BIT(missing_chunks[idx / 8], idx % 8, missing);
WRITE_BIT(missing_chunks[idx / 8], idx % 8, missing);
}
static inline bool
blob_chunk_missing_get(const uint8_t *missing_chunks, int idx)
{
return !!(missing_chunks[idx / 8] & BIT(idx % 8));
return !!(missing_chunks[idx / 8] & BIT(idx % 8));
}
static inline void blob_chunk_missing_set_all(struct bt_mesh_blob_block *block)
{
size_t bytes = block->chunk_count / 8;
size_t bytes = block->chunk_count / 8;
memset(block->missing, 0xff, bytes);
if (block->chunk_count % 8) {
block->missing[bytes] = BIT_MASK(block->chunk_count % 8);
}
memset(block->missing, 0xff, bytes);
if (block->chunk_count % 8) {
block->missing[bytes] = BIT_MASK(block->chunk_count % 8);
}
}
static inline void blob_chunk_missing_set_none(struct bt_mesh_blob_block *block)
{
memset(block->missing, 0, sizeof(block->missing));
memset(block->missing, 0, sizeof(block->missing));
}
#if CONFIG_BLE_MESH_BLOB_CLI
/** @brief Perform a message broadcast to all BLOB Transfer Client Target nodes.
*
* Will send to a group or each Target node individually, repeating until
@@ -128,7 +136,7 @@ static inline void blob_chunk_missing_set_none(struct bt_mesh_blob_block *block)
* @param ctx Broadcast context
*/
void blob_cli_broadcast(struct bt_mesh_blob_cli *cli,
const struct blob_cli_broadcast_ctx *ctx);
const struct blob_cli_broadcast_ctx *ctx);
/** @brief Register that a Target node responded to a broadcast.
*
@@ -136,7 +144,7 @@ void blob_cli_broadcast(struct bt_mesh_blob_cli *cli,
* @param target Target node that responded.
*/
void blob_cli_broadcast_rsp(struct bt_mesh_blob_cli *cli,
struct bt_mesh_blob_target *target);
struct bt_mesh_blob_target *target);
/** @brief Notify the BLOB Transfer Client that the requested transmission is complete.
*
@@ -152,3 +160,5 @@ void blob_cli_broadcast_tx_complete(struct bt_mesh_blob_cli *cli);
* @param cli BLOB Transfer Client instance.
*/
void blob_cli_broadcast_abort(struct bt_mesh_blob_cli *cli);
#endif /* CONFIG_BLE_MESH_BLOB_CLI */
#endif /* CONFIG_BLE_MESH_BLOB_CLI || CONFIG_BLE_MESH_BLOB_SRV */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2
View File
@@ -46,6 +46,8 @@ INPUT = \
$(PROJECT_PATH)/components/bt/esp_ble_mesh/v1.1/api/core/include/esp_ble_mesh_rpr_model_api.h \
$(PROJECT_PATH)/components/bt/esp_ble_mesh/v1.1/api/core/include/esp_ble_mesh_sar_model_api.h \
$(PROJECT_PATH)/components/bt/esp_ble_mesh/v1.1/api/core/include/esp_ble_mesh_srpl_model_api.h \
$(PROJECT_PATH)/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_dfu_model_api.h \
$(PROJECT_PATH)/components/bt/esp_ble_mesh/v1.1/api/models/include/esp_ble_mesh_dfu_slot_api.h \
$(PROJECT_PATH)/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h \
$(PROJECT_PATH)/components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_config_model_api.h \
$(PROJECT_PATH)/components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_generic_model_api.h \
@@ -29,6 +29,7 @@ Mesh Core
* Private Beacon
* Subnet Bridge
* Minor Enhancements
* Device Firmware Update (Preview)
* Multiple Client Models Run Simultaneously
* Support multiple client models send packets to different nodes simultaneously
@@ -132,6 +133,14 @@ Mesh Models
* Light LC Server
* Light LC Setup Server
* Device Firmware Update Client models
* Firmware Update Client model (Preview)
* Firmware Distribution Client model (coming soon)
* Device Firmware Update Server models
* Firmware Update Server model (Preview)
* Firmware Distribution Server model (coming soon)
Mesh Examples
"""""""""""""
@@ -228,3 +228,12 @@ Composition and Metadata
^^^^^^^^^^^^^^^^^^^^^^^^
.. include-build-file:: inc/esp_ble_mesh_cm_data_api.inc
Device Firmware Update
.. include-build-file:: inc/esp_ble_mesh_dfu_model_api.inc
Device Firmware Slots
.. include-build-file:: inc/esp_ble_mesh_dfu_slot_api.inc