Merge branch 'feat/ble_mesh_dfd_cli_support' into 'master'

feat(ble_mesh): dfd client/server supported

Closes BLERP-2435 and BLERP-2461

See merge request espressif/esp-idf!43924
This commit is contained in:
Island
2025-12-19 14:39:09 +08:00
20 changed files with 3518 additions and 326 deletions
+2
View File
@@ -654,6 +654,8 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/v1.1/dfu/dfu_srv.c"
"esp_ble_mesh/v1.1/dfu/dfu_slot.c"
"esp_ble_mesh/v1.1/dfu/dfu_metadata.c"
"esp_ble_mesh/v1.1/dfu/dfd_srv.c"
"esp_ble_mesh/v1.1/dfu/dfd_cli.c"
"esp_ble_mesh/lib/ext.c")
if(CONFIG_BLE_MESH_SAR_ENHANCEMENT)
+3
View File
@@ -266,6 +266,9 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = {
#if CONFIG_BLE_MESH_DFU_CLI
[BTC_PID_DFU_CLIENT] = {btc_ble_mesh_dfu_client_call_handler, btc_ble_mesh_dfu_client_cb_handler},
#endif /* CONFIG_BLE_MESH_DFU_CLI */
#if CONFIG_BLE_MESH_DFD_CLI
[BTC_PID_DFD_CLIENT] = {btc_ble_mesh_dfd_client_call_handler, btc_ble_mesh_dfd_client_cb_handler},
#endif /* CONFIG_BLE_MESH_DFD_CLI */
#if CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50
[BTC_PID_BLE_MESH_BLE_COEX] = {btc_ble_mesh_ble_call_handler, btc_ble_mesh_ble_cb_handler },
#endif /* CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50 */
@@ -110,6 +110,8 @@ typedef enum {
BTC_PID_BLOB_SERVER,
BTC_PID_DFU_CLIENT,
BTC_PID_DFU_SERVER,
BTC_PID_DFD_CLIENT,
BTC_PID_DFD_SERVER,
BTC_PID_BLE_MESH_BLE_COEX,
#endif /* CONFIG_BLE_MESH */
#if (BLE_FEAT_ISO_EN == TRUE)
+47
View File
@@ -1870,6 +1870,53 @@ if BLE_MESH
endif #BLE_MESH_DFU_SLOTS
config BLE_MESH_DFD_CLI
bool "Support for Device Distribution Client model"
help
Enable the Device Distribution Client model
config BLE_MESH_DFD_SRV
bool "Support for Firmware Distribution Server model"
depends on BLE_MESH_BLOB_SRV
depends on BLE_MESH_DFU_CLI
help
Enable the Firmware Distribution Server model.
if BLE_MESH_DFD_SRV
config BLE_MESH_DFD_SRV_SLOT_MAX_SIZE
int "Largest DFU image that can be stored"
default BLE_MESH_BLOB_SIZE_MAX
range 0 BLE_MESH_BLOB_SIZE_MAX
help
This value defines the largest DFU image a single slot can store.
config BLE_MESH_DFD_SRV_SLOT_SPACE
int "Total DFU image storage space"
default BLE_MESH_DFD_SRV_SLOT_MAX_SIZE
range 0 4294967295
help
This value defines the total storage space dedicated to storing DFU
images on the Firmware Distribution Server.
config BLE_MESH_DFD_SRV_TARGETS_MAX
int "Maximum Target node count"
default 8
range 1 65535
help
This value defines the maximum number of Target nodes the Firmware
Distribution Server can target simultaneously.
config BLE_MESH_DFD_SRV_OOB_UPLOAD
bool "Support for DFU image OOB upload"
help
This enables support for OOB upload of firmware images for
distribution. This makes several callbacks and use of the init
macro BLE_MESH_DFD_SRV_INIT_OOB mandatory. See the API documentation
for bt_mesh_dfd_srv_cb for details about the mandatory callbacks.
endif #BLE_MESH_DFD_SRV
endmenu # Device Firmware Update model
endmenu #Support for BLE Mesh Client/Server models
@@ -1988,7 +1988,8 @@ typedef union {
#define ESP_BLE_MESH_MODEL_ID_BLOB_CLI 0x1401
#define ESP_BLE_MESH_MODEL_ID_DFU_SRV 0x1402
#define ESP_BLE_MESH_MODEL_ID_DFU_CLI 0x1403
#define ESP_BLE_MESH_MODEL_ID_DFD_SRV 0x1404
#define ESP_BLE_MESH_MODEL_ID_DFD_CLI 0x1405
/**
* esp_ble_mesh_opcode_config_client_get_t belongs to esp_ble_mesh_opcode_t, this typedef is only
* used to locate the opcodes used by esp_ble_mesh_config_client_get_state.
@@ -1427,6 +1427,14 @@ extern const struct bt_mesh_model_cb _bt_mesh_dfu_srv_cb;
extern const struct bt_mesh_model_op _bt_mesh_dfu_cli_op[];
extern const struct bt_mesh_model_cb _bt_mesh_dfu_cli_cb;
#endif /* CONFIG_BLE_MESH_DFU_CLI */
#if CONFIG_BLE_MESH_DFD_SRV
extern const struct bt_mesh_model_op _bt_mesh_dfd_srv_op[];
extern const struct bt_mesh_model_cb _bt_mesh_dfd_srv_cb;
#endif /* CONFIG_BLE_MESH_DFD_SRV */
#if CONFIG_BLE_MESH_DFD_CLI
extern const struct bt_mesh_model_op _bt_mesh_dfd_cli_op[];
extern const struct bt_mesh_model_cb _bt_mesh_dfd_cli_cb;
#endif /* CONFIG_BLE_MESH_DFD_CLI */
static void btc_ble_mesh_model_op_set(esp_ble_mesh_model_t *model)
{
@@ -2274,6 +2282,24 @@ static void btc_ble_mesh_model_op_set(esp_ble_mesh_model_t *model)
}
break;
#endif /* CONFIG_BLE_MESH_DFU_SRV */
#if CONFIG_BLE_MESH_DFD_SRV
case BLE_MESH_MODEL_ID_DFD_SRV:
model->op = (esp_ble_mesh_model_op_t *)_bt_mesh_dfd_srv_op;
model->cb = (esp_ble_mesh_model_cbs_t *)&_bt_mesh_dfd_srv_cb;
if (model->pub) {
model->pub->update = (esp_ble_mesh_cb_t)btc_ble_mesh_model_publish_update;
}
break;
#endif /* CONFIG_BLE_MESH_DFD_SRV */
#if CONFIG_BLE_MESH_DFD_CLI
case BLE_MESH_MODEL_ID_DFD_CLI:
model->op = (esp_ble_mesh_model_op_t *)_bt_mesh_dfd_cli_op;
model->cb = (esp_ble_mesh_model_cbs_t *)&_bt_mesh_dfd_cli_cb;
if (model->pub) {
model->pub->update = (esp_ble_mesh_cb_t)btc_ble_mesh_model_publish_update;
}
break;
#endif /* CONFIG_BLE_MESH_DFD_SRV */
default:
goto set_vnd_op;
}
@@ -17,6 +17,45 @@
extern "C" {
#endif
static inline void btc_ble_mesh_msg_ctx_copy(struct bt_mesh_msg_ctx *dst,
const struct bt_mesh_msg_ctx *src,
bool use_dev_key)
{
if (dst == NULL ||
src == NULL) {
return;
}
dst->net_idx = src->net_idx;
dst->app_idx = use_dev_key ? BLE_MESH_KEY_DEV : src->app_idx;
dst->addr = src->addr;
dst->send_szmic = src->send_szmic;
dst->send_ttl = src->send_ttl;
dst->send_cred = src->send_cred;
dst->send_tag = src->send_tag;
if (src->enh.adv_cfg_used) {
dst->enh.adv_cfg_used = src->enh.adv_cfg_used;
dst->enh.adv_cfg.adv_cnt = src->enh.adv_cfg.adv_cnt;
dst->enh.adv_cfg.adv_itvl = src->enh.adv_cfg.adv_itvl;
dst->enh.adv_cfg.channel_map = src->enh.adv_cfg.channel_map;
}
#if CONFIG_BLE_MESH_EXT_ADV
if (src->enh.ext_adv_cfg_used) {
dst->enh.ext_adv_cfg_used = src->enh.ext_adv_cfg_used;
dst->enh.ext_adv_cfg.primary_phy = src->enh.ext_adv_cfg.primary_phy;
dst->enh.ext_adv_cfg.secondary_phy = src->enh.ext_adv_cfg.secondary_phy;
dst->enh.ext_adv_cfg.include_tx_power = src->enh.ext_adv_cfg.include_tx_power;
dst->enh.ext_adv_cfg.tx_power = src->enh.ext_adv_cfg.tx_power;
}
#if CONFIG_BLE_MESH_LONG_PACKET
if (src->enh.long_pkt_cfg_used) {
dst->enh.long_pkt_cfg_used = src->enh.long_pkt_cfg_used;
dst->enh.long_pkt_cfg = src->enh.long_pkt_cfg;
}
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
#endif /* CONFIG_BLE_MESH_EXT_ADV */
}
static inline void btc_ble_mesh_set_client_common_param(esp_ble_mesh_client_common_param_t *input,
bt_mesh_client_common_param_t *output,
bool use_dev_key)
@@ -24,35 +63,8 @@ static inline void btc_ble_mesh_set_client_common_param(esp_ble_mesh_client_comm
if (input && output) {
output->opcode = input->opcode;
output->model = (struct bt_mesh_model *)input->model;
output->ctx.net_idx = input->ctx.net_idx;
output->ctx.app_idx = use_dev_key ? BLE_MESH_KEY_DEV : input->ctx.app_idx;
output->ctx.addr = input->ctx.addr;
output->ctx.send_szmic = input->ctx.send_szmic;
output->ctx.send_ttl = input->ctx.send_ttl;
output->ctx.send_cred = input->ctx.send_cred;
output->ctx.send_tag = input->ctx.send_tag;
output->msg_timeout = input->msg_timeout;
if (input->ctx.enh.adv_cfg_used) {
output->ctx.enh.adv_cfg_used = input->ctx.enh.adv_cfg_used;
output->ctx.enh.adv_cfg.adv_cnt = input->ctx.enh.adv_cfg.adv_cnt;
output->ctx.enh.adv_cfg.adv_itvl = input->ctx.enh.adv_cfg.adv_itvl;
output->ctx.enh.adv_cfg.channel_map = input->ctx.enh.adv_cfg.channel_map;
}
#if CONFIG_BLE_MESH_EXT_ADV
if (input->ctx.enh.ext_adv_cfg_used) {
output->ctx.enh.ext_adv_cfg_used = input->ctx.enh.ext_adv_cfg_used;
output->ctx.enh.ext_adv_cfg.primary_phy = input->ctx.enh.ext_adv_cfg.primary_phy;
output->ctx.enh.ext_adv_cfg.secondary_phy = input->ctx.enh.ext_adv_cfg.secondary_phy;
output->ctx.enh.ext_adv_cfg.include_tx_power = input->ctx.enh.ext_adv_cfg.include_tx_power;
output->ctx.enh.ext_adv_cfg.tx_power = input->ctx.enh.ext_adv_cfg.tx_power;
}
#if CONFIG_BLE_MESH_LONG_PACKET
if (input->ctx.enh.long_pkt_cfg_used) {
output->ctx.enh.long_pkt_cfg_used = input->ctx.enh.long_pkt_cfg_used;
output->ctx.enh.long_pkt_cfg = input->ctx.enh.long_pkt_cfg;
}
#endif
#endif
btc_ble_mesh_msg_ctx_copy(&output->ctx, (const struct bt_mesh_msg_ctx *)&input->ctx, use_dev_key);
}
}
@@ -146,3 +146,104 @@ uint8_t esp_ble_mesh_dfu_srv_progress(const esp_ble_mesh_dfu_srv_t *srv)
return btc_ble_mesh_dfu_srv_progress(srv);
}
#endif /* CONFIG_BLE_MESH_DFU_SRV */
#if CONFIG_BLE_MESH_DFD_CLI
esp_err_t esp_ble_mesh_register_dfd_cli_callback(esp_ble_mesh_dfd_client_cb_t callback)
{
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_DFD_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
}
static bool dfd_client_opcode_need_param(esp_ble_mesh_opcode_t opcode)
{
switch (opcode)
{
/* Get opcode */
case ESP_BLE_MESH_DFD_OP_RECEIVERS_GET:
case ESP_BLE_MESH_DFD_OP_FW_GET:
case ESP_BLE_MESH_DFD_OP_FW_GET_BY_INDEX:
/* Set opcode */
case ESP_BLE_MESH_DFD_OP_RECEIVERS_ADD:
case ESP_BLE_MESH_DFD_OP_START:
case ESP_BLE_MESH_DFD_OP_UPLOAD_START:
case ESP_BLE_MESH_DFD_OP_UPLOAD_START_OOB:
case ESP_BLE_MESH_DFD_OP_FW_DELETE:
return true;
default:
return false;
}
}
esp_err_t esp_ble_mesh_dfd_cli_get(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_dfd_client_get_param_t *get_param)
{
btc_ble_mesh_dfd_client_args_t arg = {0};
btc_msg_t msg = {0};
if (params == NULL || params->model == NULL ||
params->ctx.net_idx == ESP_BLE_MESH_KEY_UNUSED ||
!ESP_BLE_MESH_ADDR_IS_UNICAST(params->ctx.addr) ||
(dfd_client_opcode_need_param(params->opcode) && get_param == NULL)) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_DFD_CLIENT;
msg.act = ESP_BLE_MESH_ACT_DFD_CLIENT_GET;
arg.dfd_client_get.params = params;
arg.dfd_client_get.get = get_param;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_dfd_client_args_t), btc_ble_mesh_dfd_client_arg_deep_copy,
btc_ble_mesh_dfd_client_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_dfd_cli_set(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_dfd_client_set_param_t *set_param)
{
btc_ble_mesh_dfd_client_args_t arg = {0};
btc_msg_t msg = {0};
if (params == NULL || params->model == NULL ||
params->ctx.net_idx == ESP_BLE_MESH_KEY_UNUSED ||
!ESP_BLE_MESH_ADDR_IS_UNICAST(params->ctx.addr) ||
(dfd_client_opcode_need_param(params->opcode) && set_param == NULL)) {
return ESP_ERR_INVALID_ARG;
}
switch (params->opcode) {
case ESP_BLE_MESH_DFD_OP_RECEIVERS_ADD:
if (set_param->receivers_add.receivers_cnt == 0) {
return ESP_ERR_INVALID_ARG;
}
break;
case ESP_BLE_MESH_DFD_OP_UPLOAD_START:
if (set_param->dist_upload_start.fw_size == 0) {
return ESP_ERR_INVALID_ARG;
}
if (set_param->dist_upload_start.fwid == NULL) {
return ESP_ERR_INVALID_ARG;
}
break;
case ESP_BLE_MESH_DFD_OP_UPLOAD_START_OOB:
if (set_param->dist_upload_oob_start.url == NULL) {
return ESP_ERR_INVALID_ARG;
}
break;
}
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_DFD_CLIENT;
msg.act = ESP_BLE_MESH_ACT_DFD_CLIENT_SET;
arg.dfd_client_set.params = params;
arg.dfd_client_set.set = set_param;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_dfd_client_args_t), btc_ble_mesh_dfd_client_arg_deep_copy,
btc_ble_mesh_dfd_client_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#endif /* CONFIG_BLE_MESH_DFD_CLI */
File diff suppressed because it is too large Load Diff
@@ -12,6 +12,9 @@
#include "esp_ble_mesh_dfu_model_api.h"
#include "mesh_v1.1/dfu/dfu_cli.h"
#include "mesh_v1.1/dfu/dfu_srv.h"
#include "mesh_v1.1/dfu/dfd.h"
#include "mesh_v1.1/dfu/dfd_cli.h"
#include "mesh_v1.1/dfu/dfd_srv.h"
#if CONFIG_BLE_MESH_DFU_CLI
/* Device Firmware Update Client model related functions */
@@ -59,15 +62,20 @@ void btc_ble_mesh_dfu_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p
src->dfu_get.get->dfu_metadata_check.metadata->data,
src->dfu_get.get->dfu_metadata_check.metadata->len);
} else {
bt_mesh_free(dst->dfu_get.get);
bt_mesh_free(dst->dfu_get.params);
BT_ERR("Out of memory for metadata");
return;
}
} else {
bt_mesh_free(dst->dfu_get.get);
bt_mesh_free(dst->dfu_get.params);
BT_ERR("Metadata should be exists");
return;
}
}
} else {
bt_mesh_free(dst->dfu_get.params);
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
}
}
@@ -92,12 +100,21 @@ void btc_ble_mesh_dfu_client_arg_deep_free(btc_msg_t *msg)
switch (msg->act) {
case BTC_BLE_MESH_ACT_DFU_CLIENT_GET_STATE:
if (arg->dfu_get.get) {
switch (arg->dfu_get.params->opcode) {
case ESP_BLE_MESH_DFU_OP_UPDATE_METADATA_CHECK:
if (arg->dfu_get.get->dfu_metadata_check.metadata) {
bt_mesh_free_buf(arg->dfu_get.get->dfu_metadata_check.metadata);
}
break;
default:
break;
}
bt_mesh_free(arg->dfu_get.get);
}
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;
@@ -134,12 +151,15 @@ static void btc_ble_mesh_dfu_client_copy_req_data(btc_msg_t *msg, void *p_dest,
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_mesh_free(p_dest_data->params);
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);
} else {
p_dest_data->recv.dfu_update_info_status.fw_info_list = NULL;
}
break;
default:
@@ -412,3 +432,785 @@ 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 */
#if CONFIG_BLE_MESH_DFD_CLI
static inline void btc_ble_mesh_dfd_client_cb_to_app(btc_ble_mesh_dfd_client_cb_evt_t event,
esp_ble_mesh_dfd_client_cb_param_t *param)
{
esp_ble_mesh_dfd_client_cb_t btc_ble_mesh_cb =
(esp_ble_mesh_dfd_client_cb_t)btc_profile_cb_get(BTC_PID_DFD_CLIENT);
if (btc_ble_mesh_cb) {
btc_ble_mesh_cb(event, param);
}
}
static inline bool dfd_client_param_need(uint32_t opcode)
{
switch (opcode) {
case ESP_BLE_MESH_DFD_OP_RECEIVERS_GET:
case ESP_BLE_MESH_DFD_OP_FW_GET:
case ESP_BLE_MESH_DFD_OP_FW_GET_BY_INDEX:
case ESP_BLE_MESH_DFD_OP_RECEIVERS_ADD:
case ESP_BLE_MESH_DFD_OP_START:
case ESP_BLE_MESH_DFD_OP_UPLOAD_START:
case ESP_BLE_MESH_DFD_OP_UPLOAD_START_OOB:
case ESP_BLE_MESH_DFD_OP_FW_DELETE:
return true;
default:
break;
}
return false;
}
static int btc_ble_mesh_dfd_client_get(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_dfd_client_get_param_t *get)
{
bt_mesh_client_common_param_t param = {0};
if (params == NULL) {
BT_ERR("%s:InvParam", __func__);
return -EINVAL;
}
if (dfd_client_param_need(params->opcode) != (!!get)) {
BT_ERR("%s:InvParam", __func__);
return -EINVAL;
}
switch(params->opcode) {
case ESP_BLE_MESH_DFD_OP_RECEIVERS_GET:
case ESP_BLE_MESH_DFD_OP_FW_GET:
case ESP_BLE_MESH_DFD_OP_FW_GET_BY_INDEX:
if (get == NULL) {
BT_ERR("%s:InvParam", __func__);
return -EINVAL;
}
break;
default:
break;
}
btc_ble_mesh_set_client_common_param(params, &param, false);
switch (params->opcode) {
case ESP_BLE_MESH_DFD_OP_RECEIVERS_GET:
return bt_mesh_dfd_cli_receivers_get(&param, get->receivers_get.first_index,
get->receivers_get.entries_limit);
case ESP_BLE_MESH_DFD_OP_CAPABILITIES_GET:
return bt_mesh_dfd_cli_distribution_capabilities_get(&param);
case ESP_BLE_MESH_DFD_OP_GET:
return bt_mesh_dfd_cli_distribution_get(&param);
case ESP_BLE_MESH_DFD_OP_UPLOAD_GET:
return bt_mesh_dfd_cli_distribution_upload_get(&param);
case ESP_BLE_MESH_DFD_OP_FW_GET:
return bt_mesh_dfd_cli_firmware_get(&param, get->dist_fw_get.fwid);
case ESP_BLE_MESH_DFD_OP_FW_GET_BY_INDEX:
return bt_mesh_dfd_cli_firmware_get_by_index(&param, get->dist_fw_get_by_idx.dist_fw_idx);
default:
BT_ERR("UknOpc:%04x", params->opcode);
return -EINVAL;
}
}
static int btc_ble_mesh_dfd_client_set(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_dfd_client_set_param_t *set)
{
bt_mesh_client_common_param_t param = {0};
if (params == NULL) {
BT_ERR("%s:InvParam", __func__);
return -EINVAL;
}
if (dfd_client_param_need(params->opcode) != (!!set)) {
BT_ERR("%s:InvParam", __func__);
return -EINVAL;
}
btc_ble_mesh_set_client_common_param(params, &param, false);
switch (params->opcode) {
case ESP_BLE_MESH_DFD_OP_RECEIVERS_ADD:
return bt_mesh_dfd_cli_receivers_add(&param, (dfd_cli_receiver_entry_t *)set->receivers_add.receivers, set->receivers_add.receivers_cnt);
case ESP_BLE_MESH_DFD_OP_RECEIVERS_DELETE_ALL:
return bt_mesh_dfd_cli_receivers_delete_all(&param);
case ESP_BLE_MESH_DFD_OP_START:
return bt_mesh_dfd_cli_distribution_start(&param, (dfd_cli_dist_start_t *)&set->dist_start);
case ESP_BLE_MESH_DFD_OP_SUSPEND:
return bt_mesh_dfd_cli_distribution_suspend(&param);
case ESP_BLE_MESH_DFD_OP_CANCEL:
return bt_mesh_dfd_cli_distribution_cancel(&param);
case ESP_BLE_MESH_DFD_OP_APPLY:
return bt_mesh_dfd_cli_distribution_apply(&param);
case ESP_BLE_MESH_DFD_OP_UPLOAD_START:
return bt_mesh_dfd_cli_distribution_upload_start(&param, (dfd_cli_dist_upload_start_t *)&set->dist_upload_start);
case ESP_BLE_MESH_DFD_OP_UPLOAD_START_OOB:
return bt_mesh_dfd_cli_distribution_upload_oob_start(&param, (dfd_cli_dist_upload_oob_start_t *)&set->dist_upload_oob_start);
case ESP_BLE_MESH_DFD_OP_UPLOAD_CANCEL:
return bt_mesh_dfd_cli_distribution_upload_oob_cancel(&param);
case ESP_BLE_MESH_DFD_OP_FW_DELETE:
return bt_mesh_dfd_cli_firmware_get_delete(&param, set->dist_fw_del.fwid);
case ESP_BLE_MESH_DFD_OP_FW_DELETE_ALL:
return bt_mesh_dfd_cli_firmware_delete_all(&param);
default:
BT_ERR("UknOpc:%04x", params->opcode);
return -EINVAL;
}
}
void btc_ble_mesh_dfd_client_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_dfd_client_cb_param_t *arg = NULL;
if (!msg) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
arg = (esp_ble_mesh_dfd_client_cb_param_t *)msg->arg;
if (msg->act < ESP_BLE_MESH_EVT_DFD_CLIENT_MAX) {
btc_ble_mesh_dfd_client_cb_to_app(msg->act, arg);
} else {
BT_ERR("%s, Unknown act %d", __func__, msg->act);
}
btc_ble_mesh_dfd_client_rsp_deep_free(msg);
}
void btc_ble_mesh_dfd_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
btc_ble_mesh_dfd_client_args_t *dst = (btc_ble_mesh_dfd_client_args_t *)p_dest;
btc_ble_mesh_dfd_client_args_t *src = (btc_ble_mesh_dfd_client_args_t *)p_src;
if (!msg || !dst || !src) {
BT_ERR("%s,InvParam", __func__);
return;
}
switch (msg->act) {
case BTC_BLE_MESH_ACT_DFD_CLIENT_GET:
dst->dfd_client_get.params =
(esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t));
if (dst->dfd_client_get.params == NULL) {
BT_ERR("%s:%d,OutMem", __func__, __LINE__);
break;
}
memcpy(dst->dfd_client_get.params, src->dfd_client_get.params, sizeof(esp_ble_mesh_client_common_param_t));
if (src->dfd_client_get.get) {
dst->dfd_client_get.get = (esp_ble_mesh_dfd_client_get_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_dfd_client_get_param_t));
if (dst->dfd_client_get.get == NULL) {
bt_mesh_free(dst->dfd_client_get.params);
dst->dfd_client_get.params = NULL;
BT_ERR("%s:%d,OutMem", __func__, __LINE__);
break;
}
memcpy(dst->dfd_client_get.get, src->dfd_client_get.get, sizeof(esp_ble_mesh_dfd_client_get_param_t));
}
switch (dst->dfd_client_get.params->opcode) {
case ESP_BLE_MESH_DFD_OP_FW_GET:
if (src->dfd_client_get.get->dist_fw_get.fwid == NULL) {
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
bt_mesh_free(dst->dfd_client_get.params);
dst->dfd_client_get.params = NULL;
bt_mesh_free(dst->dfd_client_get.get);
dst->dfd_client_get.get = NULL;
break;
}
dst->dfd_client_get.get->dist_fw_get.fwid =
bt_mesh_alloc_buf(src->dfd_client_get.get->dist_fw_get.fwid->len);
if (dst->dfd_client_get.get->dist_fw_get.fwid == NULL) {
bt_mesh_free(dst->dfd_client_get.params);
dst->dfd_client_get.params = NULL;
bt_mesh_free(dst->dfd_client_get.get);
dst->dfd_client_get.get = NULL;
BT_ERR("%s:%d,OutMem", __func__, __LINE__);
break;
}
net_buf_simple_add_mem(
dst->dfd_client_get.get->dist_fw_get.fwid,
src->dfd_client_get.get->dist_fw_get.fwid->data,
src->dfd_client_get.get->dist_fw_get.fwid->len);
break;
default:
break;
}
break;
case BTC_BLE_MESH_ACT_DFD_CLIENT_SET:
dst->dfd_client_set.params =
(esp_ble_mesh_client_common_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t));
if (dst->dfd_client_set.params == NULL) {
BT_ERR("%s:%d,OutMem", __func__, __LINE__);
break;
}
memcpy(dst->dfd_client_set.params, src->dfd_client_set.params, sizeof(esp_ble_mesh_client_common_param_t));
if (src->dfd_client_set.set) {
dst->dfd_client_set.set = (esp_ble_mesh_dfd_client_set_param_t *)bt_mesh_calloc(sizeof(esp_ble_mesh_dfd_client_set_param_t));
if (dst->dfd_client_set.set == NULL) {
bt_mesh_free(dst->dfd_client_set.params);
dst->dfd_client_set.params = NULL;
BT_ERR("%s:%d,OutMem", __func__, __LINE__);
break;
}
memcpy(dst->dfd_client_set.set, src->dfd_client_set.set, sizeof(esp_ble_mesh_dfd_client_set_param_t));
}
switch (dst->dfd_client_set.params->opcode) {
case ESP_BLE_MESH_DFD_OP_RECEIVERS_ADD:
if (src->dfd_client_set.set->receivers_add.receivers_cnt == 0) {
dst->dfd_client_set.set->receivers_add.receivers = NULL;
bt_mesh_free(dst->dfd_client_set.params);
dst->dfd_client_set.params = NULL;
bt_mesh_free(dst->dfd_client_set.set);
dst->dfd_client_set.set = NULL;
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
break;
}
dst->dfd_client_set.set->receivers_add.receivers =
(esp_ble_mesh_dfd_cli_receiver_entry_t *)bt_mesh_calloc(dst->dfd_client_set.set->receivers_add.receivers_cnt *
sizeof(esp_ble_mesh_dfd_cli_receiver_entry_t));
if (dst->dfd_client_set.set->receivers_add.receivers == NULL) {
bt_mesh_free(dst->dfd_client_set.params);
dst->dfd_client_set.params = NULL;
bt_mesh_free(dst->dfd_client_set.set);
dst->dfd_client_set.set = NULL;
BT_ERR("%s:%d,OutMem", __func__, __LINE__);
break;
}
memcpy(dst->dfd_client_set.set->receivers_add.receivers, src->dfd_client_set.set->receivers_add.receivers,
dst->dfd_client_set.set->receivers_add.receivers_cnt * sizeof(esp_ble_mesh_dfd_cli_receiver_entry_t));
break;
case ESP_BLE_MESH_DFD_OP_UPLOAD_START:
if (src->dfd_client_set.set->dist_upload_start.fwid == NULL) {
dst->dfd_client_set.set->dist_upload_start.fwid = NULL;
bt_mesh_free(dst->dfd_client_set.params);
dst->dfd_client_set.params = NULL;
bt_mesh_free(dst->dfd_client_set.set);
dst->dfd_client_set.set = NULL;
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
break;
}
dst->dfd_client_set.set->dist_upload_start.fwid =
bt_mesh_alloc_buf(src->dfd_client_set.set->dist_upload_start.fwid->len);
if (dst->dfd_client_set.set->dist_upload_start.fwid == NULL) {
bt_mesh_free(dst->dfd_client_set.params);
dst->dfd_client_set.params = NULL;
bt_mesh_free(dst->dfd_client_set.set);
dst->dfd_client_set.set = NULL;
BT_ERR("%s:%d,OutMem", __func__, __LINE__);
break;
}
net_buf_simple_add_mem(
dst->dfd_client_set.set->dist_upload_start.fwid,
src->dfd_client_set.set->dist_upload_start.fwid->data,
src->dfd_client_set.set->dist_upload_start.fwid->len);
if (src->dfd_client_set.set->dist_upload_start.fw_metadata->len == 0) {
dst->dfd_client_set.set->dist_upload_start.fw_metadata = NULL;
break;
} else {
dst->dfd_client_set.set->dist_upload_start.fw_metadata =
bt_mesh_alloc_buf(src->dfd_client_set.set->dist_upload_start.fw_metadata->len);
if (dst->dfd_client_set.set->dist_upload_start.fw_metadata == NULL) {
bt_mesh_free(dst->dfd_client_set.params);
dst->dfd_client_set.params = NULL;
bt_mesh_free(dst->dfd_client_set.set);
dst->dfd_client_set.set = NULL;
bt_mesh_free_buf(dst->dfd_client_set.set->dist_upload_start.fwid);
dst->dfd_client_set.set->dist_upload_start.fwid = NULL;
BT_ERR("%s:%d,OutMem", __func__, __LINE__);
break;
}
net_buf_simple_add_mem(
dst->dfd_client_set.set->dist_upload_start.fw_metadata,
src->dfd_client_set.set->dist_upload_start.fw_metadata->data,
src->dfd_client_set.set->dist_upload_start.fw_metadata->len);
}
break;
case ESP_BLE_MESH_DFD_OP_UPLOAD_START_OOB:
if (src->dfd_client_set.set->dist_upload_oob_start.url == NULL ||
src->dfd_client_set.set->dist_upload_oob_start.fwid == NULL) {
bt_mesh_free(dst->dfd_client_set.params);
dst->dfd_client_set.params = NULL;
bt_mesh_free(dst->dfd_client_set.set);
dst->dfd_client_set.set = NULL;
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
break;
}
dst->dfd_client_set.set->dist_upload_oob_start.url =
bt_mesh_alloc_buf(src->dfd_client_set.set->dist_upload_oob_start.url->len);
if (dst->dfd_client_set.set->dist_upload_oob_start.url == NULL) {
bt_mesh_free(dst->dfd_client_set.params);
dst->dfd_client_set.params = NULL;
bt_mesh_free(dst->dfd_client_set.set);
dst->dfd_client_set.set = NULL;
BT_ERR("%s:%d,OutMem", __func__, __LINE__);
break;
}
dst->dfd_client_set.set->dist_upload_oob_start.fwid =
bt_mesh_alloc_buf(src->dfd_client_set.set->dist_upload_oob_start.fwid->len);
if (dst->dfd_client_set.set->dist_upload_oob_start.fwid == NULL) {
bt_mesh_free(dst->dfd_client_set.params);
dst->dfd_client_set.params = NULL;
bt_mesh_free(dst->dfd_client_set.set);
dst->dfd_client_set.set = NULL;
bt_mesh_free_buf(dst->dfd_client_set.set->dist_upload_oob_start.url);
dst->dfd_client_set.set->dist_upload_oob_start.url = NULL;
BT_ERR("%s:%d,OutMem", __func__, __LINE__);
break;
}
net_buf_simple_add_mem(
dst->dfd_client_set.set->dist_upload_oob_start.url,
src->dfd_client_set.set->dist_upload_oob_start.url->data,
src->dfd_client_set.set->dist_upload_oob_start.url->len);
net_buf_simple_add_mem(
dst->dfd_client_set.set->dist_upload_oob_start.fwid,
src->dfd_client_set.set->dist_upload_oob_start.fwid->data,
src->dfd_client_set.set->dist_upload_oob_start.fwid->len);
break;
case ESP_BLE_MESH_DFD_OP_FW_DELETE:
if (src->dfd_client_set.set->dist_fw_del.fwid == NULL) {
bt_mesh_free(dst->dfd_client_set.params);
dst->dfd_client_set.params = NULL;
bt_mesh_free(dst->dfd_client_set.set);
dst->dfd_client_set.set = NULL;
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
break;
}
dst->dfd_client_set.set->dist_fw_del.fwid =
bt_mesh_alloc_buf(src->dfd_client_set.set->dist_fw_del.fwid->len);
if (dst->dfd_client_set.set->dist_fw_del.fwid == NULL) {
bt_mesh_free(dst->dfd_client_set.params);
dst->dfd_client_set.params = NULL;
bt_mesh_free(dst->dfd_client_set.set);
dst->dfd_client_set.set = NULL;
BT_ERR("%s:%d,OutMem", __func__, __LINE__);
break;
}
net_buf_simple_add_mem(
dst->dfd_client_set.set->dist_fw_del.fwid,
src->dfd_client_set.set->dist_fw_del.fwid->data,
src->dfd_client_set.set->dist_fw_del.fwid->len);
break;
default:
break;
}
default:
BT_DBG("%s, Unknown act %d", __func__, msg->act);
break;
}
}
void btc_ble_mesh_dfd_client_arg_deep_free(btc_msg_t *msg)
{
btc_ble_mesh_dfd_client_args_t *arg = NULL;
if (!msg) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
if (msg->act >= ESP_BLE_MESH_ACT_DFD_CLIENT_MAX) {
BT_ERR("%s, Invalid event %d", __func__, msg->act);
return;
}
arg = (btc_ble_mesh_dfd_client_args_t *)msg->arg;
switch (msg->act) {
case ESP_BLE_MESH_ACT_DFD_CLIENT_GET:
if (arg->dfd_client_get.params == NULL) {
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
break;
}
switch (arg->dfd_client_get.params->opcode) {
case ESP_BLE_MESH_DFD_OP_FW_GET:
if (arg->dfd_client_get.get->dist_fw_get.fwid == NULL) {
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
break;
}
bt_mesh_free_buf(arg->dfd_client_get.get->dist_fw_get.fwid);
break;
default:
break;
}
if (arg->dfd_client_get.get) {
bt_mesh_free(arg->dfd_client_get.get);
}
bt_mesh_free(arg->dfd_client_get.params);
break;
case ESP_BLE_MESH_ACT_DFD_CLIENT_SET:
if (arg->dfd_client_set.params == NULL) {
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
break;
}
switch (arg->dfd_client_set.params->opcode) {
case ESP_BLE_MESH_DFD_OP_RECEIVERS_ADD:
if (arg->dfd_client_set.set->receivers_add.receivers == NULL) {
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
break;
}
bt_mesh_free(arg->dfd_client_set.set->receivers_add.receivers);
break;
case ESP_BLE_MESH_DFD_OP_UPLOAD_START:
if (arg->dfd_client_set.set->dist_upload_start.fwid == NULL) {
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
break;
}
bt_mesh_free_buf(arg->dfd_client_set.set->dist_upload_start.fwid);
if (arg->dfd_client_set.set->dist_upload_start.fw_metadata) {
bt_mesh_free_buf(arg->dfd_client_set.set->dist_upload_start.fw_metadata);
}
break;
case ESP_BLE_MESH_DFD_OP_UPLOAD_START_OOB:
if (arg->dfd_client_set.set->dist_upload_oob_start.url == NULL ||
arg->dfd_client_set.set->dist_upload_oob_start.fwid == NULL) {
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
break;
}
bt_mesh_free_buf(arg->dfd_client_set.set->dist_upload_oob_start.url);
bt_mesh_free_buf(arg->dfd_client_set.set->dist_upload_oob_start.fwid);
break;
case ESP_BLE_MESH_DFD_OP_FW_DELETE:
if (arg->dfd_client_set.set->dist_fw_del.fwid == NULL) {
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
break;
}
bt_mesh_free_buf(arg->dfd_client_set.set->dist_fw_del.fwid);
break;
}
if (arg->dfd_client_set.set) {
bt_mesh_free(arg->dfd_client_set.set);
}
bt_mesh_free(arg->dfd_client_set.params);
break;
default:
BT_WARN("Unprocessed event %d", msg->act);
break;
}
return;
}
void btc_ble_mesh_dfd_client_rsp_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
esp_ble_mesh_dfd_client_cb_param_t *dst =(esp_ble_mesh_dfd_client_cb_param_t *) p_dest;
esp_ble_mesh_dfd_client_cb_param_t *src =(esp_ble_mesh_dfd_client_cb_param_t *) p_src;
if (!msg || !dst || !src) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
dst->err_code = src->err_code;
if (src->params) {
dst->params = bt_mesh_calloc(sizeof(esp_ble_mesh_client_common_param_t));
if (dst->params == NULL) {
BT_ERR("%s:%d,OutOfMem", __func__, __LINE__);
return;
}
memcpy(dst->params, src->params, sizeof(esp_ble_mesh_client_common_param_t));
}
switch (msg->act) {
case ESP_BLE_MESH_EVT_DFD_CLIENT_RECV_RSP:
switch(dst->params->opcode) {
case BLE_MESH_DFD_OP_RECEIVERS_LIST:
dst->status_cb.receiver_list.first_index = src->status_cb.receiver_list.first_index;
dst->status_cb.receiver_list.entries_cnt = src->status_cb.receiver_list.entries_cnt;
if (dst->status_cb.receiver_list.entries_cnt) {
dst->status_cb.receiver_list.entries = bt_mesh_calloc(sizeof(esp_ble_mesh_dfd_target_node_entry_t) * dst->status_cb.receiver_list.entries_cnt);
if (dst->status_cb.receiver_list.entries == NULL) {
BT_ERR("%s:%d,OutOfMem", __func__, __LINE__);
return;
}
memcpy(dst->status_cb.receiver_list.entries, src->status_cb.receiver_list.entries,
sizeof(esp_ble_mesh_dfd_target_node_entry_t) * dst->status_cb.receiver_list.entries_cnt);
} else {
dst->status_cb.receiver_list.entries = NULL;
}
break;
case BLE_MESH_DFD_OP_CAPABILITIES_STATUS:
dst->status_cb.dist_caps.max_receiver_list_sz = src->status_cb.dist_caps.max_receiver_list_sz;
dst->status_cb.dist_caps.max_fw_list_sz = src->status_cb.dist_caps.max_fw_list_sz;
dst->status_cb.dist_caps.max_fw_sz = src->status_cb.dist_caps.max_fw_sz;
dst->status_cb.dist_caps.max_upload_space = src->status_cb.dist_caps.max_upload_space;
dst->status_cb.dist_caps.remaining_upload_space = src->status_cb.dist_caps.remaining_upload_space;
dst->status_cb.dist_caps.oob_retrieval_supported = src->status_cb.dist_caps.oob_retrieval_supported;
if (src->status_cb.dist_caps.supported_url_scheme_names) {
dst->status_cb.dist_caps.supported_url_scheme_names =
bt_mesh_alloc_buf(src->status_cb.dist_caps.supported_url_scheme_names->len);
if (dst->status_cb.dist_caps.supported_url_scheme_names == NULL) {
BT_ERR("%s:%d,OutOfMem", __func__, __LINE__);
return;
}
net_buf_simple_add_mem(
dst->status_cb.dist_caps.supported_url_scheme_names,
src->status_cb.dist_caps.supported_url_scheme_names->data,
src->status_cb.dist_caps.supported_url_scheme_names->len);
} else {
dst->status_cb.dist_caps.supported_url_scheme_names = NULL;
}
break;
case BLE_MESH_DFD_OP_UPLOAD_STATUS:
dst->status_cb.upload_status.status = src->status_cb.upload_status.status;
dst->status_cb.upload_status.upload_phase = src->status_cb.upload_status.upload_phase;
dst->status_cb.upload_status.upload_progress = src->status_cb.upload_status.upload_progress;
dst->status_cb.upload_status.upload_type = src->status_cb.upload_status.upload_type;
if (dst->status_cb.upload_status.upload_progress == ESP_BLE_MESH_DFD_UPLOAD_PROGRESS_UNSET) {
dst->status_cb.upload_status.fwid = NULL;
return;
}
if (dst->status_cb.upload_status.upload_type == ESP_BLE_MESH_DFD_UPLOAD_TYPE_INBAND) {
if (src->status_cb.upload_status.fwid) {
dst->status_cb.upload_status.fwid = bt_mesh_alloc_buf(src->status_cb.upload_status.fwid->len);
if (dst->status_cb.upload_status.fwid == NULL) {
BT_ERR("%s:%d,OutOfMem", __func__, __LINE__);
return;
}
net_buf_simple_add_mem(
dst->status_cb.upload_status.fwid,
src->status_cb.upload_status.fwid->data,
src->status_cb.upload_status.fwid->len);
} else {
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
}
} else {
if(src->status_cb.upload_status.oob_fwid) {
dst->status_cb.upload_status.oob_fwid = bt_mesh_alloc_buf(src->status_cb.upload_status.oob_fwid->len);
if (dst->status_cb.upload_status.oob_fwid == NULL) {
BT_ERR("%s:%d,OutOfMem", __func__, __LINE__);
return;
}
net_buf_simple_add_mem(
dst->status_cb.upload_status.oob_fwid,
src->status_cb.upload_status.oob_fwid->data,
src->status_cb.upload_status.oob_fwid->len);
} else {
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
}
}
break;
case BLE_MESH_DFD_OP_FW_STATUS:
dst->status_cb.firmware_status.status = src->status_cb.firmware_status.status;
dst->status_cb.firmware_status.entry_cnt = src->status_cb.firmware_status.entry_cnt;
dst->status_cb.firmware_status.fw_idx = src->status_cb.firmware_status.fw_idx;
if (src->status_cb.firmware_status.fwid) {
dst->status_cb.firmware_status.fwid = bt_mesh_alloc_buf(src->status_cb.firmware_status.fwid->len);
if (dst->status_cb.firmware_status.fwid == NULL) {
BT_ERR("%s:%d,OutOfMem", __func__, __LINE__);
return;
}
net_buf_simple_add_mem(
dst->status_cb.firmware_status.fwid,
src->status_cb.firmware_status.fwid->data,
src->status_cb.firmware_status.fwid->len);
} else {
dst->status_cb.firmware_status.fwid = NULL;
}
break;
case BLE_MESH_DFD_OP_RECEIVERS_STATUS:
dst->status_cb.receiver_status.status = src->status_cb.receiver_status.status;
dst->status_cb.receiver_status.receiver_list_cnt = src->status_cb.receiver_status.receiver_list_cnt;
break;
case BLE_MESH_DFD_OP_STATUS:
dst->status_cb.dist_status.status = src->status_cb.dist_status.status;
dst->status_cb.dist_status.dist_phase = src->status_cb.dist_status.dist_phase;
dst->status_cb.dist_status.multicast_address = src->status_cb.dist_status.multicast_address;
dst->status_cb.dist_status.appkey_idx = src->status_cb.dist_status.appkey_idx;
dst->status_cb.dist_status.ttl = src->status_cb.dist_status.ttl;
dst->status_cb.dist_status.timeout_base = src->status_cb.dist_status.timeout_base;
dst->status_cb.dist_status.trans_mode = src->status_cb.dist_status.trans_mode;
dst->status_cb.dist_status.update_policy = src->status_cb.dist_status.update_policy;
dst->status_cb.dist_status.firmware_image_index = src->status_cb.dist_status.firmware_image_index;
break;
default:
BT_ERR("Unknown opcode %04x", dst->params->opcode);
break;
}
break;
case ESP_BLE_MESH_EVT_DFD_CLIENT_TIMEOUT:
break;
case ESP_BLE_MESH_ACT_DFD_CLIEND_SEND_COMP:
break;
default:
BT_ERR("Unknown event %d", msg->act);
}
}
void btc_ble_mesh_dfd_client_rsp_deep_free(btc_msg_t *msg)
{
esp_ble_mesh_dfd_client_cb_param_t *arg = NULL;
if (!msg) {
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
return;
}
arg = (esp_ble_mesh_dfd_client_cb_param_t *)(msg->arg);
if (arg->params == NULL &&
msg->act != ESP_BLE_MESH_ACT_DFD_CLIEND_SEND_COMP) {
BT_ERR("%s:%d,InvParam", __func__, __LINE__);
return;
}
switch (msg->act) {
case ESP_BLE_MESH_EVT_DFD_CLIENT_RECV_RSP:
switch (arg->params->opcode) {
case BLE_MESH_DFD_OP_RECEIVERS_LIST:
if (arg->status_cb.receiver_list.entries) {
bt_mesh_free(arg->status_cb.receiver_list.entries);
arg->status_cb.receiver_list.entries = NULL;
}
break;
case BLE_MESH_DFD_OP_CAPABILITIES_STATUS:
if (arg->status_cb.dist_caps.supported_url_scheme_names) {
bt_mesh_free_buf(arg->status_cb.dist_caps.supported_url_scheme_names);
arg->status_cb.dist_caps.supported_url_scheme_names = NULL;
}
break;
case BLE_MESH_DFD_OP_UPLOAD_STATUS:
/**
* firmware_id and upload_oob_firmware_id are a union
* structure, so only one pointer needs to be released
*/
if (arg->status_cb.upload_status.fwid) {
bt_mesh_free_buf(arg->status_cb.upload_status.fwid);
arg->status_cb.upload_status.fwid = NULL;
}
break;
case BLE_MESH_DFD_OP_FW_STATUS:
if (arg->status_cb.firmware_status.fwid) {
bt_mesh_free_buf(arg->status_cb.firmware_status.fwid);
arg->status_cb.firmware_status.fwid = NULL;
}
break;
}
break;
default:
break;
}
if (arg->params) {
bt_mesh_free(arg->params);
}
}
static void btc_ble_mesh_dfd_client_callback(esp_ble_mesh_dfd_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_DFD_CLIENT)) {
return;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_DFD_CLIENT;
msg.act = act;
btc_transfer_context(&msg, cb_params, cb_params == NULL ? 0 : sizeof(esp_ble_mesh_dfd_client_cb_param_t),
btc_ble_mesh_dfd_client_rsp_deep_copy, btc_ble_mesh_dfd_client_rsp_deep_free);
}
void bt_mesh_dfd_client_cb_evt_to_btc(btc_ble_mesh_dfd_client_cb_evt_t event,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const uint8_t *val, size_t len)
{
esp_ble_mesh_dfd_client_cb_param_t cb_params = {0};
esp_ble_mesh_client_common_param_t params = {0};
uint8_t act = 0U;
if (!model || !ctx || len > sizeof(cb_params.status_cb)) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
switch (event) {
case BTC_BLE_MESH_EVT_DFD_CLIENT_RECV_RSP:
act = ESP_BLE_MESH_EVT_DFD_CLIENT_RECV_RSP;
break;
case BTC_BLE_MESH_EVT_DFD_CLIENT_TIMEOUT:
act = ESP_BLE_MESH_EVT_DFD_CLIENT_TIMEOUT;
break;
default:
BT_ERR("Unknown event %d", event);
break;
}
params.opcode = ctx->recv_op;
params.model = (esp_ble_mesh_model_t *)model;
btc_ble_mesh_msg_ctx_copy((struct bt_mesh_msg_ctx *)&params.ctx, ctx, false);
cb_params.params = &params;
cb_params.err_code = 0;
if (val && len) {
memcpy(&cb_params.status_cb, val, len);
}
btc_ble_mesh_dfd_client_callback(&cb_params, act);
return;
}
void btc_ble_mesh_dfd_client_call_handler(btc_msg_t *msg)
{
esp_ble_mesh_dfd_client_cb_param_t cb = {0};
btc_ble_mesh_dfd_client_args_t *arg = NULL;
if (!msg) {
BT_ERR("%s,InvParam", __func__);
return;
}
arg = (btc_ble_mesh_dfd_client_args_t *)msg->arg;
switch (msg->act) {
case BTC_BLE_MESH_ACT_DFD_CLIENT_GET:
cb.params = arg->dfd_client_get.params;
cb.err_code = btc_ble_mesh_dfd_client_get(arg->dfd_client_get.params, arg->dfd_client_get.get);
btc_ble_mesh_dfd_client_callback(&cb, ESP_BLE_MESH_ACT_DFD_CLIEND_SEND_COMP);
break;
case BTC_BLE_MESH_ACT_DFD_CLIENT_SET:
cb.params = arg->dfd_client_set.params;
cb.err_code = btc_ble_mesh_dfd_client_set(arg->dfd_client_set.params, arg->dfd_client_set.set);
btc_ble_mesh_dfd_client_callback(&cb, ESP_BLE_MESH_ACT_DFD_CLIEND_SEND_COMP);
break;
default:
break;
}
btc_ble_mesh_dfd_client_arg_deep_free(msg);
}
#endif /* CONFIG_BLE_MESH_DFD_CLI */
#if CONFIG_BLE_MESH_DFD_SRV
#if CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD
int btc_ble_mesh_dfd_srv_oob_check_complete(struct esp_ble_mesh_dfd_srv *srv,
const struct esp_ble_mesh_dfu_slot *slot, int status,
uint8_t *fwid, size_t fwid_len)
{
bt_mesh_dfd_srv_oob_check_complete((struct bt_mesh_dfd_srv *)srv, (struct bt_mesh_dfu_slot *)slot, status, fwid, fwid_len);
return 0;
}
int btc_ble_mesh_dfd_srv_oob_store_complete(struct esp_ble_mesh_dfd_srv *srv,
const struct esp_ble_mesh_dfu_slot *slot, bool success,
size_t size, const uint8_t *metadata, size_t metadata_len)
{
bt_mesh_dfd_srv_oob_store_complete((struct bt_mesh_dfd_srv *)srv, (struct bt_mesh_dfu_slot *)slot, success, size, metadata, metadata_len);
return 0;
}
#endif /* CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD */
#endif /* CONFIG_BLE_MESH_DFD_SRV */
@@ -67,6 +67,55 @@ bool btc_ble_mesh_dfu_srv_is_busy(const esp_ble_mesh_dfu_srv_t *srv);
uint8_t btc_ble_mesh_dfu_srv_progress(const esp_ble_mesh_dfu_srv_t *srv);
#endif /* CONFIG_BLE_MESH_DFU_SRV */
#if CONFIG_BLE_MESH_DFD_CLI
typedef enum {
BTC_BLE_MESH_ACT_DFD_CLIENT_GET,
BTC_BLE_MESH_ACT_DFD_CLIENT_SET,
BTC_BLE_MESH_ACT_DFD_CLIEND_SEND_COMP,
BTC_BLE_MESH_ACT_DFD_CLIENT_MAX,
} btc_ble_mesh_dfd_client_act_t;
typedef enum {
BTC_BLE_MESH_EVT_DFD_CLIENT_TIMEOUT,
BTC_BLE_MESH_EVT_DFD_CLIENT_RECV_RSP,
BTC_BLE_MESH_EVT_DFD_CLIENT_MAX,
} btc_ble_mesh_dfd_client_cb_evt_t;
typedef union {
struct {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_dfd_client_get_param_t *get;
} dfd_client_get;
struct {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_dfd_client_set_param_t *set;
} dfd_client_set;
} btc_ble_mesh_dfd_client_args_t;
void btc_ble_mesh_dfd_client_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_dfd_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_dfd_client_arg_deep_free(btc_msg_t *msg);
void btc_ble_mesh_dfd_client_rsp_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_dfd_client_rsp_deep_free(btc_msg_t *msg);
void bt_mesh_dfd_client_cb_evt_to_btc(btc_ble_mesh_dfd_client_cb_evt_t event,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const uint8_t *val, size_t len);
void btc_ble_mesh_dfd_client_call_handler(btc_msg_t *msg);
#endif /* CONFIG_BLE_MESH_DFD_CLI */
#if CONFIG_BLE_MESH_DFD_SRV
#if CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD
int btc_ble_mesh_dfd_srv_oob_check_complete(struct esp_ble_mesh_dfd_srv *srv,
const struct esp_ble_mesh_dfu_slot *slot, int status,
uint8_t *fwid, size_t fwid_len);
int btc_ble_mesh_dfd_srv_oob_store_complete(struct esp_ble_mesh_dfd_srv *srv,
const struct esp_ble_mesh_dfu_slot *slot, bool success,
size_t size, const uint8_t *metadata, size_t metadata_len);
#endif /* CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD */
#endif /* CONFIG_BLE_MESH_DFD_SRV */
#ifdef __cplusplus
}
#endif
-35
View File
@@ -1,35 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020 Nordic Semiconductor ASA
* SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#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
@@ -0,0 +1,699 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "dfu_slot.h"
#include "dfu.h"
#include "net.h"
#include "transport.h"
#include "mesh_v1.1/dfu/dfd.h"
#include "mesh_v1.1/dfu/dfu_cli.h"
#include "mesh_v1.1/mbt/blob_srv.h"
#include "btc_ble_mesh_dfu_model.h"
#include "mesh_v1.1/dfu/dfd_cli.h"
#if CONFIG_BLE_MESH_DFD_CLI
static const bt_mesh_client_op_pair_t dfd_cli_pair[] = {
{BLE_MESH_DFD_OP_RECEIVERS_ADD, BLE_MESH_DFD_OP_RECEIVERS_STATUS},
{BLE_MESH_DFD_OP_RECEIVERS_DELETE_ALL, BLE_MESH_DFD_OP_RECEIVERS_STATUS},
{BLE_MESH_DFD_OP_RECEIVERS_GET, BLE_MESH_DFD_OP_RECEIVERS_LIST},
{BLE_MESH_DFD_OP_CAPABILITIES_GET, BLE_MESH_DFD_OP_CAPABILITIES_STATUS},
{BLE_MESH_DFD_OP_GET, BLE_MESH_DFD_OP_STATUS},
{BLE_MESH_DFD_OP_START, BLE_MESH_DFD_OP_STATUS},
{BLE_MESH_DFD_OP_SUSPEND, BLE_MESH_DFD_OP_STATUS},
{BLE_MESH_DFD_OP_CANCEL, BLE_MESH_DFD_OP_STATUS},
{BLE_MESH_DFD_OP_APPLY, BLE_MESH_DFD_OP_STATUS},
{BLE_MESH_DFD_OP_UPLOAD_GET, BLE_MESH_DFD_OP_UPLOAD_STATUS},
{BLE_MESH_DFD_OP_UPLOAD_START, BLE_MESH_DFD_OP_UPLOAD_STATUS},
{BLE_MESH_DFD_OP_UPLOAD_START_OOB, BLE_MESH_DFD_OP_UPLOAD_STATUS},
{BLE_MESH_DFD_OP_UPLOAD_CANCEL, BLE_MESH_DFD_OP_UPLOAD_STATUS},
{BLE_MESH_DFD_OP_FW_GET, BLE_MESH_DFD_OP_FW_STATUS},
{BLE_MESH_DFD_OP_FW_GET_BY_INDEX, BLE_MESH_DFD_OP_FW_STATUS},
{BLE_MESH_DFD_OP_FW_DELETE, BLE_MESH_DFD_OP_FW_STATUS},
{BLE_MESH_DFD_OP_FW_DELETE_ALL, BLE_MESH_DFD_OP_FW_STATUS},
};
static bt_mesh_mutex_t dfd_client_lock;
static void timeout_handler(struct k_work *work)
{
struct k_delayed_work *timer = NULL;
bt_mesh_client_node_t *node = NULL;
BT_WARN("DFDRspTmo");
bt_mesh_mutex_lock(&dfd_client_lock);
timer = CONTAINER_OF(work, struct k_delayed_work, work);
if (timer && !k_delayed_work_free(timer)) {
node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work);
if (node) {
bt_mesh_dfd_client_cb_evt_to_btc(BTC_BLE_MESH_EVT_DFD_CLIENT_TIMEOUT, node->model, &node->ctx, NULL, 0);
bt_mesh_client_free_node(node);
}
}
bt_mesh_mutex_unlock(&dfd_client_lock);
return;
}
static void dfd_client_recv_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
void *status, size_t len)
{
bt_mesh_client_node_t *node = NULL;
struct net_buf_simple buf = {0};
btc_ble_mesh_dfd_client_cb_evt_t evt = 0;
if (!model || !ctx) {
BT_ERR("%s,InvParam", __func__);
return;
}
buf.data = (uint8_t *)status;
buf.len = (uint16_t)len;
bt_mesh_mutex_lock(&dfd_client_lock);
node = bt_mesh_is_client_recv_publish_msg(model, ctx, &buf, true);
if (!node) {
BT_DBG("UnexpDfdStus:0x%04x", ctx->recv_op);
} else {
switch (ctx->recv_op) {
case BLE_MESH_DFD_OP_RECEIVERS_STATUS:
case BLE_MESH_DFD_OP_CAPABILITIES_GET:
case BLE_MESH_DFD_OP_RECEIVERS_LIST:
case BLE_MESH_DFD_OP_CAPABILITIES_STATUS:
case BLE_MESH_DFD_OP_STATUS:
case BLE_MESH_DFD_OP_UPLOAD_STATUS:
case BLE_MESH_DFD_OP_FW_STATUS:
evt = BTC_BLE_MESH_EVT_DFD_CLIENT_RECV_RSP;
break;
default:
BT_ERR("UnkwnOpc:%04x", node->opcode);
break;
}
if (!k_delayed_work_free(&node->timer)) {
bt_mesh_dfd_client_cb_evt_to_btc(evt, model, ctx, (const uint8_t *)status, len);
bt_mesh_client_free_node(node);
}
}
bt_mesh_mutex_unlock(&dfd_client_lock);
}
static void handle_receiver_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
dfd_status_t status = {0};
status.receiver_status.status = net_buf_simple_pull_u8(buf);
if (status.receiver_status.status > BLE_MESH_DFD_ERR_SUSPEND_FAILED) {
BT_ERR("InvSrvStu:%d", status.receiver_status.status);
return;
}
if (status.receiver_status.status != BLE_MESH_DFD_SUCCESS) {
BT_ERR("StusErr:%d", status);
return;
}
status.receiver_status.receiver_list_cnt = net_buf_simple_pull_le16(buf);
BT_DBG("RecvLstCnt:%d", status.receiver_status.receiver_list_cnt);
dfd_client_recv_status(model, ctx, &status, sizeof(status.receiver_status));
}
static void handle_receiver_list(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
int i = 0;
uint32_t target_info = 0;
dfd_status_t status = {0};
status.receiver_list.entries_cnt = net_buf_simple_pull_le16(buf);
status.receiver_list.first_index = net_buf_simple_pull_le16(buf);
status.receiver_list.entries = bt_mesh_calloc(status.receiver_list.entries_cnt * sizeof(target_node_entry_t));
for (i = 0; i < status.receiver_list.entries_cnt; i++) {
target_info = net_buf_simple_pull_le32(buf);
status.receiver_list.entries[i].addr = TARGET_ADDR(target_info);
status.receiver_list.entries[i].retrieved_update_phase = TARGET_UPDATE_PHASE(target_info);
status.receiver_list.entries[i].update_status = TARGET_UPDATE_STATUS(target_info);
status.receiver_list.entries[i].transfer_status = TARGET_TRANSFER_STATUS(target_info);
status.receiver_list.entries[i].transfer_progress = TARGET_TRANSFER_PROGRESS(target_info);
status.receiver_list.entries[i].update_fw_idx = net_buf_simple_pull_u8(buf);
}
dfd_client_recv_status(model, ctx, &status, sizeof(status.receiver_list));
bt_mesh_free(status.receiver_list.entries);
return;
}
static void handle_capabilities(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
dfd_status_t status = {0};
struct net_buf_simple url_scheme_names = {0};
status.dist_caps.max_receiver_list_sz = net_buf_simple_pull_le16(buf);
status.dist_caps.max_fw_list_sz = net_buf_simple_pull_le16(buf);
status.dist_caps.max_fw_sz = net_buf_simple_pull_le32(buf);
status.dist_caps.max_upload_space = net_buf_simple_pull_le32(buf);
status.dist_caps.remaining_upload_space = net_buf_simple_pull_le32(buf);
status.dist_caps.oob_retrieval_supported = net_buf_simple_pull_le32(buf);
if (buf->len) {
status.dist_caps.supported_url_scheme_names = &url_scheme_names;
net_buf_simple_init_with_data(status.dist_caps.supported_url_scheme_names, buf->data, buf->len);
net_buf_simple_pull_mem(buf, buf->len);
}
dfd_client_recv_status(model, ctx, &status, sizeof(status.dist_caps));
return;
}
static void handle_dfd_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
dfd_status_t status = {0};
uint8_t trans_mode_policy = 0;
status.dist_status.status = net_buf_simple_pull_u8(buf);
status.dist_status.dist_phase = net_buf_simple_pull_u8(buf);
if (buf->len != 0 && buf->len != 10) {
BT_ERR("Invalid data");
return;
}
status.dist_status.multicast_address = net_buf_simple_pull_le16(buf);
status.dist_status.appkey_idx = net_buf_simple_pull_le16(buf);
status.dist_status.ttl = net_buf_simple_pull_u8(buf);
status.dist_status.timeout_base = net_buf_simple_pull_le16(buf);
trans_mode_policy = net_buf_simple_pull_u8(buf);
if ((trans_mode_policy & ~(BIT6 - 1)) != 0) {
BT_ERR("RFU should be zero");
return;
}
status.dist_status.trans_mode = trans_mode_policy >> 6;
status.dist_status.update_policy = (trans_mode_policy >> 5) & 0x01;
status.dist_status.RFU = trans_mode_policy & 0x1f;
status.dist_status.fw_idx = net_buf_simple_pull_le16(buf);
dfd_client_recv_status(model, ctx, &status, sizeof(status.dist_status));
return;
}
static void handle_upload_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
dfd_status_t status = {0};
uint8_t progress_type = 0;
struct net_buf_simple buf_cache = {0};
status.upload_status.status = net_buf_simple_pull_u8(buf);
status.upload_status.upload_phase = net_buf_simple_pull_u8(buf);
if (buf->len == 0) {
status.upload_status.upload_progress = UPLOAD_PROGRESS_UNSET;
dfd_client_recv_status(model, ctx, &status, sizeof(status.upload_status));
return;
}
progress_type = net_buf_simple_pull_u8(buf);
status.upload_status.upload_progress = progress_type>>1;
if (status.upload_status.upload_progress >= UPLOAD_PROGRESS_UNSET) {
BT_ERR("Invalid upload progress");
return;
}
if (buf->len == 0) {
BT_ERR("InvFwID");
return;
}
status.upload_status.upload_type = progress_type & 0x01;
if (status.upload_status.upload_type == UPLOAD_IN_BAND) {
status.upload_status.fwid = &buf_cache;
net_buf_simple_init_with_data(status.upload_status.fwid, buf->data, buf->len);
net_buf_simple_pull_mem(buf, buf->len);
} else if (status.upload_status.upload_type == UPLOAD_OOB){
status.upload_status.oob_fwid = &buf_cache;
net_buf_simple_init_with_data(status.upload_status.oob_fwid, buf->data, buf->len);
net_buf_simple_pull_mem(buf, buf->len);
} else {
BT_ERR("Invalid upload type:%d", status.upload_status.upload_type);
return;
}
dfd_client_recv_status(model, ctx, &status, sizeof(status.upload_status));
return;
}
static void handle_fw_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
dfd_status_t status = {0};
struct net_buf_simple buf_cache = {0};
status.firmware_status.status = net_buf_simple_pull_u8(buf);
status.firmware_status.entry_cnt = net_buf_simple_pull_le16(buf);
status.firmware_status.firmware_image_index = net_buf_simple_pull_le16(buf);
if (buf->len) {
status.firmware_status.fwid = &buf_cache;
net_buf_simple_init_with_data(status.firmware_status.fwid, buf->data, buf->len);
net_buf_simple_pull_mem(buf, buf->len);
}
dfd_client_recv_status(model, ctx, &status, sizeof(status.firmware_status));
return;
}
const struct bt_mesh_model_op _bt_mesh_dfd_cli_op[] = {
{ BLE_MESH_DFD_OP_RECEIVERS_STATUS, 3, handle_receiver_status },
{ BLE_MESH_DFD_OP_RECEIVERS_LIST, 4 , handle_receiver_list },
{ BLE_MESH_DFD_OP_CAPABILITIES_STATUS, 17, handle_capabilities },
{ BLE_MESH_DFD_OP_STATUS, 2, handle_dfd_status },
{ BLE_MESH_DFD_OP_UPLOAD_STATUS, 2, handle_upload_status },
{ BLE_MESH_DFD_OP_FW_STATUS, 5, handle_fw_status },
};
int bt_mesh_dfd_cli_receivers_add(bt_mesh_client_common_param_t *param, dfd_cli_receiver_entry_t *receivers, uint16_t receivers_cnt)
{
uint16_t msg_length = 2;
struct net_buf_simple *msg = NULL;
dfd_cli_receiver_entry_t *entry = NULL;
int err = 0;
if (param == NULL) {
BT_ERR("Invalid param");
return -EINVAL;
}
BT_INFO("AddedValidCnt:%d", receivers_cnt);
msg_length += (receivers_cnt * 3);
/* needs to confirm long or short mic */
if (msg_length > BLE_MESH_MAX_PDU_LEN_WITH_SMIC) {
BT_ERR("Too much receivers added once time");
return -EINVAL;
}
msg = bt_mesh_alloc_buf(msg_length + BLE_MESH_MIC_SHORT);
if (!msg) {
BT_ERR("Failed to alloc buffer to send message");
return -EINVAL;
}
bt_mesh_model_msg_init(msg, BLE_MESH_DFD_OP_RECEIVERS_ADD);
for (int i = 0; i < receivers_cnt; i++) {
entry = &receivers[i];
if (BLE_MESH_ADDR_IS_UNICAST(entry->addr)) {
net_buf_simple_add_le16(msg, entry->addr);
net_buf_simple_add_u8(msg, entry->fw_idx);
BT_INFO("AddedUnicastAddr:0x%04x,FwIdx:%d", entry->addr, entry->fw_idx);
}
}
err = bt_mesh_client_send_msg(param, msg, true, timeout_handler);
bt_mesh_free_buf(msg);
return err;
}
int bt_mesh_dfd_cli_receivers_delete_all(bt_mesh_client_common_param_t *param)
{
BLE_MESH_MODEL_BUF_DEFINE(msg, BLE_MESH_DFD_OP_RECEIVERS_DELETE_ALL, 0);
if (!param) {
BT_ERR("Invalid param");
return -EINVAL;
}
bt_mesh_model_msg_init(&msg, BLE_MESH_DFD_OP_RECEIVERS_DELETE_ALL);
return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
}
int bt_mesh_dfd_cli_receivers_get(bt_mesh_client_common_param_t *param, uint16_t first_index, uint16_t entries_limit)
{
BLE_MESH_MODEL_BUF_DEFINE(msg, BLE_MESH_DFD_OP_RECEIVERS_GET, 4);
if (!param) {
BT_ERR("Invalid param");
return -EINVAL;
}
bt_mesh_model_msg_init(&msg, BLE_MESH_DFD_OP_RECEIVERS_GET);
net_buf_simple_add_le16(&msg, first_index);
net_buf_simple_add_le16(&msg, entries_limit);
return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
}
int bt_mesh_dfd_cli_distribution_capabilities_get(bt_mesh_client_common_param_t *param)
{
BLE_MESH_MODEL_BUF_DEFINE(msg, BLE_MESH_DFD_OP_CAPABILITIES_GET, 0);
if (!param) {
BT_ERR("Invalid param");
return -EINVAL;
}
bt_mesh_model_msg_init(&msg, BLE_MESH_DFD_OP_CAPABILITIES_GET);
return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
}
int bt_mesh_dfd_cli_distribution_get(bt_mesh_client_common_param_t *param)
{
BLE_MESH_MODEL_BUF_DEFINE(msg, BLE_MESH_DFD_OP_GET, 0);
if (!param) {
BT_ERR("Invalid param");
return -EINVAL;
}
bt_mesh_model_msg_init(&msg, BLE_MESH_DFD_OP_GET);
return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
}
int bt_mesh_dfd_cli_distribution_start(bt_mesh_client_common_param_t *param,
dfd_cli_dist_start_t *start)
{
BLE_MESH_MODEL_BUF_DEFINE(msg, BLE_MESH_DFD_OP_START, 2 + 1 + 2 + 1 + 2 + 16);
if (!param || !start) {
BT_ERR("Invalid param");
return -EINVAL;
}
bt_mesh_model_msg_init(&msg, BLE_MESH_DFD_OP_START);
net_buf_simple_add_le16(&msg, start->app_idx);
net_buf_simple_add_u8(&msg, start->ttl);
net_buf_simple_add_le16(&msg, start->timeout_base);
net_buf_simple_add_u8(&msg, ((start->trans_mode) << 6) | ((start->update_policy) << 5));
net_buf_simple_add_le16(&msg, start->fw_idx);
if (start->is_va) {
net_buf_simple_add_mem(&msg, &(start->label_uuid), 16);
} else {
net_buf_simple_add_le16(&msg, start->group_addr);
}
return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
}
int bt_mesh_dfd_cli_distribution_suspend(bt_mesh_client_common_param_t *param)
{
BLE_MESH_MODEL_BUF_DEFINE(msg, BLE_MESH_DFD_OP_SUSPEND, 0);
if (!param) {
BT_ERR("Invalid param");
return -EINVAL;
}
bt_mesh_model_msg_init(&msg, BLE_MESH_DFD_OP_SUSPEND);
return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
}
int bt_mesh_dfd_cli_distribution_cancel(bt_mesh_client_common_param_t *param)
{
BLE_MESH_MODEL_BUF_DEFINE(msg, BLE_MESH_DFD_OP_CANCEL, 0);
if (!param) {
BT_ERR("Invalid param");
return -EINVAL;
}
bt_mesh_model_msg_init(&msg, BLE_MESH_DFD_OP_CANCEL);
return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
}
int bt_mesh_dfd_cli_distribution_apply(bt_mesh_client_common_param_t *param)
{
BLE_MESH_MODEL_BUF_DEFINE(msg, BLE_MESH_DFD_OP_APPLY, 0);
if (!param) {
BT_ERR("Invalid param");
return -EINVAL;
}
bt_mesh_model_msg_init(&msg, BLE_MESH_DFD_OP_APPLY);
return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
}
int bt_mesh_dfd_cli_distribution_upload_get(bt_mesh_client_common_param_t *param)
{
BLE_MESH_MODEL_BUF_DEFINE(msg, BLE_MESH_DFD_OP_UPLOAD_GET, 0);
if (!param) {
BT_ERR("Invalid param");
return -EINVAL;
}
bt_mesh_model_msg_init(&msg, BLE_MESH_DFD_OP_UPLOAD_GET);
return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
}
int bt_mesh_dfd_cli_distribution_upload_start(bt_mesh_client_common_param_t *param,
dfd_cli_dist_upload_start_t *start)
{
struct net_buf_simple *msg = NULL;
uint16_t msg_length = 2;
int err = 0;
if (!param || !start) {
BT_ERR("Invalid param");
return -EINVAL;
}
msg_length += (1 + 2 + 8 + 4 + 1 + start->fwid->len);
if (start->fw_metadata) {
msg_length += start->fw_metadata->len;
}
msg = bt_mesh_alloc_buf(msg_length + BLE_MESH_MIC_SHORT);
if (!msg) {
BT_ERR("Failed to alloc buffer to send message");
return -EINVAL;
}
bt_mesh_model_msg_init(msg, BLE_MESH_DFD_OP_UPLOAD_START);
net_buf_simple_add_u8(msg, start->ttl);
net_buf_simple_add_le16(msg, start->timeout_base);
net_buf_simple_add_le64(msg, start->blob_id);
net_buf_simple_add_le32(msg, start->fw_size);
if (start->fw_metadata) {
net_buf_simple_add_u8(msg, start->fw_metadata->len);
net_buf_simple_add_mem(msg, start->fw_metadata->data, start->fw_metadata->len);
} else {
net_buf_simple_add_u8(msg, 0);
}
net_buf_simple_add_mem(msg, start->fwid->data, start->fwid->len);
err = bt_mesh_client_send_msg(param, msg, true, timeout_handler);
bt_mesh_free_buf(msg);
return err;
}
int bt_mesh_dfd_cli_distribution_upload_oob_start(bt_mesh_client_common_param_t *param,
dfd_cli_dist_upload_oob_start_t *start)
{
int err = 0;
struct net_buf_simple *msg = NULL;
uint16_t msg_length = 2;
if (!param || !start) {
BT_ERR("Invalid param");
return -1;
}
if (!start->url) {
BT_ERR("Null url info");
return -1;
}
if (!start->fwid) {
BT_ERR("Invalid firmware id");
return -1;
}
msg_length += (1 + start->url->len + start->fwid->len);
msg = bt_mesh_alloc_buf(msg_length + BLE_MESH_MIC_SHORT);
if (!msg) {
BT_ERR("Failed to alloc buffer to send message");
return -EINVAL;
}
bt_mesh_model_msg_init(msg, BLE_MESH_DFD_OP_UPLOAD_START_OOB);
net_buf_simple_add_u8(msg, start->url->len);
net_buf_simple_add_mem(msg, start->url->data, start->url->len);
net_buf_simple_add_mem(msg, start->fwid->data, start->fwid->len);
err = bt_mesh_client_send_msg(param, msg, true, timeout_handler);
bt_mesh_free_buf(msg);
return err;
}
int bt_mesh_dfd_cli_distribution_upload_oob_cancel(bt_mesh_client_common_param_t *param)
{
BLE_MESH_MODEL_BUF_DEFINE(msg, BLE_MESH_DFD_OP_UPLOAD_CANCEL, 0);
bt_mesh_model_msg_init(&msg, BLE_MESH_DFD_OP_UPLOAD_CANCEL);
return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
}
int bt_mesh_dfd_cli_firmware_get(bt_mesh_client_common_param_t *param, struct net_buf_simple *fwid)
{
struct net_buf_simple *msg = NULL;
uint16_t msg_length = 2;
int err;
if (!fwid) {
BT_ERR("NULL Firmware id");
return -EINVAL;
}
msg_length += fwid->len;
msg = bt_mesh_alloc_buf(msg_length + BLE_MESH_MIC_SHORT);
if (!msg) {
BT_ERR("Failed to alloc buffer to send message");
return -EINVAL;
}
bt_mesh_model_msg_init(msg, BLE_MESH_DFD_OP_FW_GET);
net_buf_simple_add_mem(msg, fwid->data, fwid->len);
err = bt_mesh_client_send_msg(param, msg, true, timeout_handler);
bt_mesh_free_buf(msg);
return err;
}
int bt_mesh_dfd_cli_firmware_get_by_index(bt_mesh_client_common_param_t *param, uint16_t fw_id_index)
{
BLE_MESH_MODEL_BUF_DEFINE(msg, BLE_MESH_DFD_OP_FW_GET_BY_INDEX, 2);
bt_mesh_model_msg_init(&msg, BLE_MESH_DFD_OP_FW_GET_BY_INDEX);
net_buf_simple_add_le16(&msg, fw_id_index);
return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
}
int bt_mesh_dfd_cli_firmware_get_delete(bt_mesh_client_common_param_t *param, struct net_buf_simple *fwid)
{
struct net_buf_simple *msg = NULL;
uint16_t msg_length = 2;
int err;
if (!fwid) {
BT_ERR("NULL Firmware id");
return -EINVAL;
}
msg_length += fwid->len;
msg = bt_mesh_alloc_buf(msg_length + BLE_MESH_MIC_SHORT);
if (!msg) {
BT_ERR("Failed to alloc buffer to send message");
return -EINVAL;
}
bt_mesh_model_msg_init(msg, BLE_MESH_DFD_OP_FW_DELETE);
net_buf_simple_add_mem(msg, fwid->data, fwid->len);
err = bt_mesh_client_send_msg(param, msg, true, timeout_handler);
bt_mesh_free_buf(msg);
return err;
}
int bt_mesh_dfd_cli_firmware_delete_all(bt_mesh_client_common_param_t *param)
{
BLE_MESH_MODEL_BUF_DEFINE(msg, BLE_MESH_DFD_OP_FW_DELETE_ALL, 0);
bt_mesh_model_msg_init(&msg, BLE_MESH_DFD_OP_FW_DELETE_ALL);
return bt_mesh_client_send_msg(param, &msg, true, timeout_handler);
}
static int dfd_cli_init(struct bt_mesh_model *model)
{
bt_mesh_dfd_client_t *client = NULL;
dfd_internal_data_t *internal = NULL;
if (!model) {
BT_ERR("Invalid Device Firmware Distribution Client model");
return -EINVAL;
}
if (!bt_mesh_model_in_primary(model)) {
BT_ERR("Device Firmware Distribution Client only allowed in primary element");
return -EINVAL;
}
client = (bt_mesh_dfd_client_t *)model->user_data;
if (!client) {
BT_ERR("No Device Firmware Distribution Client context provided");
return -EINVAL;
}
if (client->internal_data) {
BT_WARN("%s, Already", __func__);
return -EALREADY;
}
internal = bt_mesh_calloc(sizeof(dfd_internal_data_t));
if (!internal) {
BT_ERR("%s, Out of memory", __func__);
return -ENOMEM;
}
sys_slist_init(&internal->queue);
client->model = model;
client->op_pair_size = ARRAY_SIZE(dfd_cli_pair);
client->op_pair = dfd_cli_pair;
client->internal_data = internal;
BT_INFO("Dfd client initialized");
bt_mesh_mutex_create(&dfd_client_lock);
return 0;
}
#if CONFIG_BLE_MESH_DEINIT
static int dfd_cli_deinit(struct bt_mesh_model *model)
{
bt_mesh_dfd_client_t *client = NULL;
if (!model) {
BT_ERR("Invalid Device Firmware Distribution Client model");
return -EINVAL;
}
client = (bt_mesh_dfd_client_t *)model->user_data;
if (!client) {
BT_ERR("No Device Firmware Distribution Client context provided");
return -EINVAL;
}
if (client->internal_data) {
/* Remove items from the list */
bt_mesh_client_clear_list(client->internal_data);
/* Free the allocated internal data */
bt_mesh_free(client->internal_data);
client->internal_data = NULL;
}
bt_mesh_mutex_free(&dfd_client_lock);
return 0;
}
#endif
const struct bt_mesh_model_cb _bt_mesh_dfd_cli_cb = {
.init = dfd_cli_init,
#if CONFIG_BLE_MESH_DEINIT
.deinit = dfd_cli_deinit,
#endif /* CONFIG_BLE_MESH_DEINIT */
};
#endif
+166 -167
View File
@@ -6,7 +6,6 @@
*/
#include <string.h>
#include "dfu_slot.h"
#include "dfd.h"
#include "dfu.h"
#include "dfd_srv_internal.h"
#include "net.h"
@@ -19,7 +18,7 @@
#if CONFIG_BLE_MESH_DFD_SRV
#define DFD_UPLOAD_STATUS_MSG_MAXLEN (5 + CONFIG_BLE_MESH_DFU_FWID_MAXLEN)
_Static_assert((DFD_UPLOAD_STATUS_MSG_MAXLEN + BLE_MESH_MODEL_OP_LEN(BT_MESH_DFD_OP_UPLOAD_STATUS) +
_Static_assert((DFD_UPLOAD_STATUS_MSG_MAXLEN + BLE_MESH_MODEL_OP_LEN(BLE_MESH_DFD_OP_UPLOAD_STATUS) +
BLE_MESH_MIC_SHORT) <= BLE_MESH_TX_SDU_MAX,
"The Firmware Distribution Upload Status message does not fit into the maximum "
"outgoing SDU size.");
@@ -27,21 +26,21 @@ _Static_assert((DFD_UPLOAD_STATUS_MSG_MAXLEN + BLE_MESH_MODEL_OP_LEN(BT_MESH_DFD
#define DFD_UPLOAD_START_MSG_MAXLEN (16 + CONFIG_BLE_MESH_DFU_FWID_MAXLEN + \
CONFIG_BLE_MESH_DFU_METADATA_MAXLEN)
_Static_assert((DFD_UPLOAD_START_MSG_MAXLEN + BLE_MESH_MODEL_OP_LEN(BT_MESH_DFD_OP_UPLOAD_START) +
_Static_assert((DFD_UPLOAD_START_MSG_MAXLEN + BLE_MESH_MODEL_OP_LEN(BLE_MESH_DFD_OP_UPLOAD_START) +
BLE_MESH_MIC_SHORT) <= BLE_MESH_RX_SDU_MAX,
"The Firmware Distribution Upload Start message does not fit into the maximum "
"incoming SDU size.");
#define DFD_RECEIVERS_LIST_MSG_MAXLEN (4 + CONFIG_BLE_MESH_DFD_SRV_TARGETS_MAX * 5)
_Static_assert((DFD_RECEIVERS_LIST_MSG_MAXLEN + BLE_MESH_MODEL_OP_LEN(BT_MESH_DFD_OP_RECEIVERS_LIST) +
_Static_assert((DFD_RECEIVERS_LIST_MSG_MAXLEN + BLE_MESH_MODEL_OP_LEN(BLE_MESH_DFD_OP_RECEIVERS_LIST) +
BLE_MESH_MIC_SHORT) <= BLE_MESH_TX_SDU_MAX,
"The Firmware Distribution Receivers List message does not fit into the maximum "
"outgoing SDU size.");
#define DFD_RECEIVERS_ADD_MSG_MAXLEN (CONFIG_BLE_MESH_DFD_SRV_TARGETS_MAX * 3)
_Static_assert((DFD_RECEIVERS_ADD_MSG_MAXLEN + BLE_MESH_MODEL_OP_LEN(BT_MESH_DFD_OP_RECEIVERS_ADD) +
_Static_assert((DFD_RECEIVERS_ADD_MSG_MAXLEN + BLE_MESH_MODEL_OP_LEN(BLE_MESH_DFD_OP_RECEIVERS_ADD) +
BLE_MESH_MIC_SHORT) <= BLE_MESH_RX_SDU_MAX,
"The Firmware Distribution Receivers Add message does not fit into the maximum "
"incoming SDU size.");
@@ -76,15 +75,15 @@ static struct bt_mesh_dfu_target *target_get(struct bt_mesh_dfd_srv *srv,
static bool is_busy(const struct bt_mesh_dfd_srv *srv)
{
return srv->phase == BT_MESH_DFD_PHASE_TRANSFER_ACTIVE ||
srv->phase == BT_MESH_DFD_PHASE_TRANSFER_SUCCESS ||
srv->phase == BT_MESH_DFD_PHASE_APPLYING_UPDATE;
return srv->phase == BLE_MESH_DFD_PHASE_TRANSFER_ACTIVE ||
srv->phase == BLE_MESH_DFD_PHASE_TRANSFER_SUCCESS ||
srv->phase == BLE_MESH_DFD_PHASE_APPLYING_UPDATE;
}
static bool upload_is_busy(const struct bt_mesh_dfd_srv *srv)
{
return bt_mesh_blob_srv_is_busy(&srv->upload.blob) ||
srv->upload.phase == BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE;
srv->upload.phase == BLE_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE;
}
static int slot_del(struct bt_mesh_dfd_srv *srv, const struct bt_mesh_dfu_slot *slot)
@@ -100,8 +99,8 @@ static void receivers_status_rsp(struct bt_mesh_dfd_srv *srv,
struct bt_mesh_msg_ctx *ctx,
enum bt_mesh_dfd_status status)
{
BLE_MESH_MODEL_BUF_DEFINE(buf, BT_MESH_DFD_OP_RECEIVERS_STATUS, 3);
bt_mesh_model_msg_init(&buf, BT_MESH_DFD_OP_RECEIVERS_STATUS);
BLE_MESH_MODEL_BUF_DEFINE(buf, BLE_MESH_DFD_OP_RECEIVERS_STATUS, 3);
bt_mesh_model_msg_init(&buf, BLE_MESH_DFD_OP_RECEIVERS_STATUS);
net_buf_simple_add_u8(&buf, status);
net_buf_simple_add_le16(&buf, srv->target_cnt);
@@ -112,7 +111,7 @@ static void receivers_status_rsp(struct bt_mesh_dfd_srv *srv,
static int handle_receivers_add(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
enum bt_mesh_dfd_status status = BT_MESH_DFD_SUCCESS;
enum bt_mesh_dfd_status status = BLE_MESH_DFD_SUCCESS;
struct bt_mesh_dfd_srv *srv = mod->user_data;
if (buf->len % 3) {
@@ -121,11 +120,11 @@ static int handle_receivers_add(const struct bt_mesh_model *mod, struct bt_mesh_
if (bt_mesh_dfu_cli_is_busy(&srv->dfu)) {
receivers_status_rsp(srv, ctx,
BT_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION);
BLE_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION);
return 0;
}
while (buf->len >= 3 && status == BT_MESH_DFD_SUCCESS) {
while (buf->len >= 3 && status == BLE_MESH_DFD_SUCCESS) {
uint8_t img_idx;
uint16_t addr;
@@ -166,9 +165,9 @@ static int handle_receivers_get(const struct bt_mesh_model *mod, struct bt_mesh_
/* Create a buffer that can fit the full target list, maxing out at TX_SDU_MAX: */
NET_BUF_SIMPLE_DEFINE(
rsp, BLE_MESH_MODEL_BUF_LEN(BT_MESH_DFD_OP_RECEIVERS_LIST,
rsp, BLE_MESH_MODEL_BUF_LEN(BLE_MESH_DFD_OP_RECEIVERS_LIST,
DFD_RECEIVERS_LIST_MSG_MAXLEN));
bt_mesh_model_msg_init(&rsp, BT_MESH_DFD_OP_RECEIVERS_LIST);
bt_mesh_model_msg_init(&rsp, BLE_MESH_DFD_OP_RECEIVERS_LIST);
net_buf_simple_add_le16(&rsp, srv->target_cnt);
net_buf_simple_add_le16(&rsp, first);
@@ -208,8 +207,8 @@ static int handle_capabilities_get(const struct bt_mesh_model *mod, struct bt_me
{
size_t size = 0;
BLE_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_DFD_OP_CAPABILITIES_STATUS, 17);
bt_mesh_model_msg_init(&rsp, BT_MESH_DFD_OP_CAPABILITIES_STATUS);
BLE_MESH_MODEL_BUF_DEFINE(rsp, BLE_MESH_DFD_OP_CAPABILITIES_GET, 17);
bt_mesh_model_msg_init(&rsp, BLE_MESH_DFD_OP_CAPABILITIES_GET);
net_buf_simple_add_le16(&rsp, CONFIG_BLE_MESH_DFD_SRV_TARGETS_MAX);
net_buf_simple_add_le16(&rsp, CONFIG_BLE_MESH_DFU_SLOT_CNT);
@@ -243,13 +242,13 @@ static int handle_capabilities_get(const struct bt_mesh_model *mod, struct bt_me
static void status_rsp(struct bt_mesh_dfd_srv *srv, struct bt_mesh_msg_ctx *ctx,
enum bt_mesh_dfd_status status)
{
BLE_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_DFD_OP_STATUS, 12);
bt_mesh_model_msg_init(&rsp, BT_MESH_DFD_OP_STATUS);
BLE_MESH_MODEL_BUF_DEFINE(rsp, BLE_MESH_DFD_OP_STATUS, 12);
bt_mesh_model_msg_init(&rsp, BLE_MESH_DFD_OP_STATUS);
net_buf_simple_add_u8(&rsp, status);
net_buf_simple_add_u8(&rsp, srv->phase);
if (srv->phase == BT_MESH_DFD_PHASE_IDLE || !srv->dfu.xfer.slot) {
if (srv->phase == BLE_MESH_DFD_PHASE_IDLE || !srv->dfu.xfer.slot) {
bt_mesh_model_send(srv->mod, ctx, &rsp, NULL, NULL);
return;
}
@@ -270,7 +269,7 @@ static int handle_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *c
{
struct bt_mesh_dfd_srv *srv = mod->user_data;
status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS);
status_rsp(srv, ctx, BLE_MESH_DFD_SUCCESS);
return 0;
}
@@ -292,7 +291,7 @@ static int handle_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx
if (buf->len == 16) {
/* TODO: Virtual addresses not supported. */
status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL);
status_rsp(srv, ctx, BLE_MESH_DFD_ERR_INTERNAL);
return 0;
}
@@ -343,14 +342,14 @@ static void upload_status_rsp_with_progress(struct bt_mesh_dfd_srv *srv,
enum bt_mesh_dfd_status status,
uint8_t progress)
{
BLE_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_DFD_OP_UPLOAD_STATUS,
BLE_MESH_MODEL_BUF_DEFINE(rsp, BLE_MESH_DFD_OP_UPLOAD_STATUS,
DFD_UPLOAD_STATUS_MSG_MAXLEN);
bt_mesh_model_msg_init(&rsp, BT_MESH_DFD_OP_UPLOAD_STATUS);
bt_mesh_model_msg_init(&rsp, BLE_MESH_DFD_OP_UPLOAD_STATUS);
net_buf_simple_add_u8(&rsp, status);
net_buf_simple_add_u8(&rsp, srv->upload.phase);
if (srv->upload.phase == BT_MESH_DFD_UPLOAD_PHASE_IDLE ||
if (srv->upload.phase == BLE_MESH_DFD_UPLOAD_PHASE_IDLE ||
!srv->upload.slot) {
bt_mesh_model_send(srv->mod, ctx, &rsp, NULL, NULL);
return;
@@ -395,7 +394,7 @@ static int handle_upload_get(const struct bt_mesh_model *mod, struct bt_mesh_msg
{
struct bt_mesh_dfd_srv *srv = mod->user_data;
upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS);
upload_status_rsp(srv, ctx, BLE_MESH_DFD_SUCCESS);
return 0;
}
@@ -410,22 +409,22 @@ static inline int set_upload_fwid(struct bt_mesh_dfd_srv *srv, struct bt_mesh_ms
case -EALREADY: /* Other server is in progress with this fwid */
bt_mesh_dfu_slot_release(srv->upload.slot);
srv->upload.slot = NULL;
upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL);
upload_status_rsp(srv, ctx, BLE_MESH_DFD_ERR_INTERNAL);
break;
case -EEXIST: /* Img with this fwid already is in list */
srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS;
srv->upload.phase = BLE_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS;
bt_mesh_dfu_slot_release(srv->upload.slot);
err = bt_mesh_dfu_slot_get(fwid, fwid_len, &srv->upload.slot);
if (!err) {
upload_status_rsp_with_progress(srv, ctx, BT_MESH_DFD_SUCCESS, 100);
upload_status_rsp_with_progress(srv, ctx, BLE_MESH_DFD_SUCCESS, 100);
} else {
srv->upload.slot = NULL;
upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL);
upload_status_rsp(srv, ctx, BLE_MESH_DFD_ERR_INTERNAL);
}
break;
case 0:
srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE;
srv->upload.phase = BLE_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE;
break;
case -EINVAL: /* Slot in wrong state. */
default:
@@ -464,14 +463,14 @@ static int handle_upload_start(const struct bt_mesh_model *mod, struct bt_mesh_m
if (size > CONFIG_BLE_MESH_DFD_SRV_SLOT_MAX_SIZE) {
upload_status_rsp(srv, ctx,
BT_MESH_DFD_ERR_INSUFFICIENT_RESOURCES);
BLE_MESH_DFD_ERR_INSUFFICIENT_RESOURCES);
return 0;
}
if (upload_is_busy(srv)) {
if (!srv->upload.slot) {
BT_WARN("Busy with no upload slot");
upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL);
upload_status_rsp(srv, ctx, BLE_MESH_DFD_ERR_INTERNAL);
return 0;
}
@@ -487,12 +486,12 @@ static int handle_upload_start(const struct bt_mesh_model *mod, struct bt_mesh_m
#endif
) {
BT_DBG("Duplicate upload start");
upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS);
upload_status_rsp(srv, ctx, BLE_MESH_DFD_SUCCESS);
return 0;
}
BT_WARN("Upload already in progress");
upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_BUSY_WITH_UPLOAD);
upload_status_rsp(srv, ctx, BLE_MESH_DFD_ERR_BUSY_WITH_UPLOAD);
return 0;
}
@@ -511,7 +510,7 @@ static int handle_upload_start(const struct bt_mesh_model *mod, struct bt_mesh_m
if (!srv->upload.slot) {
BT_WARN("No space for slot");
upload_status_rsp(srv, ctx,
BT_MESH_DFD_ERR_INSUFFICIENT_RESOURCES);
BLE_MESH_DFD_ERR_INSUFFICIENT_RESOURCES);
return 0;
}
@@ -523,7 +522,7 @@ static int handle_upload_start(const struct bt_mesh_model *mod, struct bt_mesh_m
err = bt_mesh_dfu_slot_info_set(srv->upload.slot, size, meta, meta_len);
switch (err) {
case -EFBIG:
upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL);
upload_status_rsp(srv, ctx, BLE_MESH_DFD_ERR_INTERNAL);
break;
case 0:
break;
@@ -536,7 +535,7 @@ static int handle_upload_start(const struct bt_mesh_model *mod, struct bt_mesh_m
if (err || !srv->io) {
BT_ERR("App rejected upload. err: %d io: %p", err, srv->io);
bt_mesh_dfu_slot_release(srv->upload.slot);
upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL);
upload_status_rsp(srv, ctx, BLE_MESH_DFD_ERR_INTERNAL);
return 0;
}
@@ -545,14 +544,14 @@ static int handle_upload_start(const struct bt_mesh_model *mod, struct bt_mesh_m
if (err) {
BT_ERR("BLOB Server rejected upload (err: %d)", err);
bt_mesh_dfu_slot_release(srv->upload.slot);
upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL);
upload_status_rsp(srv, ctx, BLE_MESH_DFD_ERR_INTERNAL);
return 0;
}
BT_DBG("%s", bt_hex(fwid, fwid_len));
srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE;
upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS);
srv->upload.phase = BLE_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE;
upload_status_rsp(srv, ctx, BLE_MESH_DFD_SUCCESS);
return 0;
}
@@ -588,11 +587,11 @@ static int handle_upload_start_oob(const struct bt_mesh_model *mod, struct bt_me
!memcmp(uri, srv->upload.oob.uri, uri_len) &&
!memcmp(fwid, srv->upload.oob.current_fwid, fwid_len)) {
/* Same image, return SUCCESS for idempotency */
upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS);
upload_status_rsp(srv, ctx, BLE_MESH_DFD_SUCCESS);
return 0;
}
#endif
upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_BUSY_WITH_UPLOAD);
upload_status_rsp(srv, ctx, BLE_MESH_DFD_ERR_BUSY_WITH_UPLOAD);
return 0;
#ifdef CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD
} else if (srv->upload.is_oob && srv->upload.is_pending_oob_check) {
@@ -604,14 +603,14 @@ static int handle_upload_start_oob(const struct bt_mesh_model *mod, struct bt_me
#ifdef CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD
if (uri_len > CONFIG_BLE_MESH_DFU_URI_MAXLEN ||
fwid_len > CONFIG_BLE_MESH_DFU_FWID_MAXLEN) {
upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL);
upload_status_rsp(srv, ctx, BLE_MESH_DFD_ERR_INTERNAL);
return 0;
}
struct bt_mesh_dfu_slot *slot = bt_mesh_dfu_slot_reserve();
if (slot == NULL) {
upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_INSUFFICIENT_RESOURCES);
upload_status_rsp(srv, ctx, BLE_MESH_DFD_ERR_INSUFFICIENT_RESOURCES);
return 0;
}
@@ -635,14 +634,14 @@ static int handle_upload_start_oob(const struct bt_mesh_model *mod, struct bt_me
srv->upload.oob.current_fwid,
srv->upload.oob.current_fwid_len);
if (status != BT_MESH_DFD_SUCCESS) {
if (status != BLE_MESH_DFD_SUCCESS) {
upload_status_rsp(srv, ctx, status);
bt_mesh_dfu_slot_release(srv->upload.slot);
} else {
srv->upload.is_pending_oob_check = true;
}
#else
upload_status_rsp(srv, ctx, BT_MESH_DFD_ERR_URI_NOT_SUPPORTED);
upload_status_rsp(srv, ctx, BLE_MESH_DFD_ERR_URI_NOT_SUPPORTED);
#endif /* CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD */
return 0;
@@ -653,7 +652,7 @@ static int handle_upload_cancel(const struct bt_mesh_model *mod, struct bt_mesh_
{
struct bt_mesh_dfd_srv *srv = mod->user_data;
srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_IDLE;
srv->upload.phase = BLE_MESH_DFD_UPLOAD_PHASE_IDLE;
#ifdef CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD
if (srv->upload.is_oob) {
srv->cb->cancel_oob_upload(srv, srv->upload.slot);
@@ -662,7 +661,7 @@ static int handle_upload_cancel(const struct bt_mesh_model *mod, struct bt_mesh_
{
(void)bt_mesh_blob_srv_cancel(&srv->upload.blob);
}
upload_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS);
upload_status_rsp(srv, ctx, BLE_MESH_DFD_SUCCESS);
return 0;
}
@@ -672,9 +671,9 @@ static void fw_status_rsp(struct bt_mesh_dfd_srv *srv,
enum bt_mesh_dfd_status status, uint16_t idx,
const uint8_t *fwid, size_t fwid_len)
{
BLE_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_DFD_OP_FW_STATUS,
BLE_MESH_MODEL_BUF_DEFINE(rsp, BLE_MESH_DFD_OP_FW_STATUS,
7 + CONFIG_BLE_MESH_DFU_FWID_MAXLEN);
bt_mesh_model_msg_init(&rsp, BT_MESH_DFD_OP_FW_STATUS);
bt_mesh_model_msg_init(&rsp, BLE_MESH_DFD_OP_FW_STATUS);
net_buf_simple_add_u8(&rsp, status);
net_buf_simple_add_le16(&rsp, bt_mesh_dfu_slot_count());
@@ -701,10 +700,10 @@ static int handle_fw_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx
idx = bt_mesh_dfu_slot_get(fwid, fwid_len, &slot);
if (idx >= 0) {
fw_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS, idx, fwid,
fw_status_rsp(srv, ctx, BLE_MESH_DFD_SUCCESS, idx, fwid,
fwid_len);
} else {
fw_status_rsp(srv, ctx, BT_MESH_DFD_ERR_FW_NOT_FOUND, 0xffff,
fw_status_rsp(srv, ctx, BLE_MESH_DFD_ERR_FW_NOT_FOUND, 0xffff,
fwid, fwid_len);
}
@@ -722,10 +721,10 @@ static int handle_fw_get_by_index(const struct bt_mesh_model *mod, struct bt_mes
slot = bt_mesh_dfu_slot_at(idx);
if (slot) {
fw_status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS, idx, slot->fwid,
fw_status_rsp(srv, ctx, BLE_MESH_DFD_SUCCESS, idx, slot->fwid,
slot->fwid_len);
} else {
fw_status_rsp(srv, ctx, BT_MESH_DFD_ERR_FW_NOT_FOUND, idx,
fw_status_rsp(srv, ctx, BLE_MESH_DFD_ERR_FW_NOT_FOUND, idx,
NULL, 0);
}
@@ -772,23 +771,23 @@ static int handle_fw_delete_all(const struct bt_mesh_model *mod, struct bt_mesh_
}
const struct bt_mesh_model_op _bt_mesh_dfd_srv_op[] = {
{ BT_MESH_DFD_OP_RECEIVERS_ADD, 3, (void *)handle_receivers_add },
{ BT_MESH_DFD_OP_RECEIVERS_DELETE_ALL, 0, (void *)handle_receivers_delete_all },
{ BT_MESH_DFD_OP_RECEIVERS_GET, 4, (void *)handle_receivers_get },
{ BT_MESH_DFD_OP_CAPABILITIES_GET, 0, (void *)handle_capabilities_get },
{ BT_MESH_DFD_OP_GET, 0, (void *)handle_get },
{ BT_MESH_DFD_OP_START, 10, (void *)handle_start },
{ BT_MESH_DFD_OP_SUSPEND, 0, (void *)handle_suspend },
{ BT_MESH_DFD_OP_CANCEL, 0, (void *)handle_cancel },
{ BT_MESH_DFD_OP_APPLY, 0, (void *)handle_apply },
{ BT_MESH_DFD_OP_UPLOAD_GET, 0, (void *)handle_upload_get },
{ BT_MESH_DFD_OP_UPLOAD_START, 16, (void *)handle_upload_start },
{ BT_MESH_DFD_OP_UPLOAD_START_OOB, 2, (void *)handle_upload_start_oob },
{ BT_MESH_DFD_OP_UPLOAD_CANCEL, 0, (void *)handle_upload_cancel },
{ BT_MESH_DFD_OP_FW_GET, 0, (void *)handle_fw_get },
{ BT_MESH_DFD_OP_FW_GET_BY_INDEX, 2, (void *)handle_fw_get_by_index },
{ BT_MESH_DFD_OP_FW_DELETE, 0, (void *)handle_fw_delete },
{ BT_MESH_DFD_OP_FW_DELETE_ALL, 0, (void *)handle_fw_delete_all },
{ BLE_MESH_DFD_OP_RECEIVERS_ADD, 3, (void *)handle_receivers_add },
{ BLE_MESH_DFD_OP_RECEIVERS_DELETE_ALL, 0, (void *)handle_receivers_delete_all },
{ BLE_MESH_DFD_OP_RECEIVERS_GET, 4, (void *)handle_receivers_get },
{ BLE_MESH_DFD_OP_CAPABILITIES_GET, 0, (void *)handle_capabilities_get },
{ BLE_MESH_DFD_OP_GET, 0, (void *)handle_get },
{ BLE_MESH_DFD_OP_START, 10, (void *)handle_start },
{ BLE_MESH_DFD_OP_SUSPEND, 0, (void *)handle_suspend },
{ BLE_MESH_DFD_OP_CANCEL, 0, (void *)handle_cancel },
{ BLE_MESH_DFD_OP_APPLY, 0, (void *)handle_apply },
{ BLE_MESH_DFD_OP_UPLOAD_GET, 0, (void *)handle_upload_get },
{ BLE_MESH_DFD_OP_UPLOAD_START, 16, (void *)handle_upload_start },
{ BLE_MESH_DFD_OP_UPLOAD_START_OOB, 2, (void *)handle_upload_start_oob },
{ BLE_MESH_DFD_OP_UPLOAD_CANCEL, 0, (void *)handle_upload_cancel },
{ BLE_MESH_DFD_OP_FW_GET, 0, (void *)handle_fw_get },
{ BLE_MESH_DFD_OP_FW_GET_BY_INDEX, 2, (void *)handle_fw_get_by_index },
{ BLE_MESH_DFD_OP_FW_DELETE, 0, (void *)handle_fw_delete },
{ BLE_MESH_DFD_OP_FW_DELETE_ALL, 0, (void *)handle_fw_delete_all },
BLE_MESH_MODEL_OP_END
};
@@ -798,7 +797,7 @@ static void dfu_suspended(struct bt_mesh_dfu_cli *cli)
struct bt_mesh_dfd_srv *srv =
CONTAINER_OF(cli, struct bt_mesh_dfd_srv, dfu);
dfd_phase_set(srv, BT_MESH_DFD_PHASE_TRANSFER_SUSPENDED);
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_TRANSFER_SUSPENDED);
}
static void dfu_ended(struct bt_mesh_dfu_cli *cli,
@@ -810,31 +809,31 @@ static void dfu_ended(struct bt_mesh_dfu_cli *cli,
BT_DBG("reason: %u, phase: %u, apply: %u", reason, srv->phase, srv->apply);
if (srv->phase == BT_MESH_DFD_PHASE_IDLE) {
if (srv->phase == BLE_MESH_DFD_PHASE_IDLE) {
return;
}
if (srv->phase == BT_MESH_DFD_PHASE_CANCELING_UPDATE) {
dfd_phase_set(srv, BT_MESH_DFD_PHASE_IDLE);
if (srv->phase == BLE_MESH_DFD_PHASE_CANCELING_UPDATE) {
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_IDLE);
return;
}
if (reason != BLE_MESH_DFU_SUCCESS) {
dfd_phase_set(srv, BT_MESH_DFD_PHASE_FAILED);
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_FAILED);
return;
}
if (!srv->apply) {
dfd_phase_set(srv, BT_MESH_DFD_PHASE_TRANSFER_SUCCESS);
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_TRANSFER_SUCCESS);
return;
}
dfd_phase_set(srv, BT_MESH_DFD_PHASE_APPLYING_UPDATE);
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_APPLYING_UPDATE);
err = bt_mesh_dfu_cli_apply(cli);
if (err) {
BT_ERR("Apply failed: %d", err);
dfd_phase_set(srv, BT_MESH_DFD_PHASE_FAILED);
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_FAILED);
}
}
@@ -844,19 +843,19 @@ static void dfu_applied(struct bt_mesh_dfu_cli *cli)
CONTAINER_OF(cli, struct bt_mesh_dfd_srv, dfu);
int err;
if (srv->phase == BT_MESH_DFD_PHASE_CANCELING_UPDATE) {
dfd_phase_set(srv, BT_MESH_DFD_PHASE_FAILED);
if (srv->phase == BLE_MESH_DFD_PHASE_CANCELING_UPDATE) {
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_FAILED);
return;
}
if (srv->phase != BT_MESH_DFD_PHASE_APPLYING_UPDATE) {
if (srv->phase != BLE_MESH_DFD_PHASE_APPLYING_UPDATE) {
return;
}
err = bt_mesh_dfu_cli_confirm(cli);
if (err) {
BT_ERR("Confirm failed: %d", err);
dfd_phase_set(srv, BT_MESH_DFD_PHASE_FAILED);
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_FAILED);
}
}
@@ -865,12 +864,12 @@ static void dfu_confirmed(struct bt_mesh_dfu_cli *cli)
struct bt_mesh_dfd_srv *srv =
CONTAINER_OF(cli, struct bt_mesh_dfd_srv, dfu);
if (srv->phase != BT_MESH_DFD_PHASE_APPLYING_UPDATE &&
srv->phase != BT_MESH_DFD_PHASE_CANCELING_UPDATE) {
if (srv->phase != BLE_MESH_DFD_PHASE_APPLYING_UPDATE &&
srv->phase != BLE_MESH_DFD_PHASE_CANCELING_UPDATE) {
return;
}
dfd_phase_set(srv, BT_MESH_DFD_PHASE_COMPLETED);
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_COMPLETED);
}
const struct bt_mesh_dfu_cli_cb _bt_mesh_dfd_srv_dfu_cb = {
@@ -892,19 +891,19 @@ static void upload_end(struct bt_mesh_blob_srv *b, uint64_t id, bool success)
struct bt_mesh_dfd_srv *srv =
CONTAINER_OF(b, struct bt_mesh_dfd_srv, upload.blob);
if (srv->upload.phase != BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE) {
if (srv->upload.phase != BLE_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE) {
return;
}
BT_DBG("%u", success);
if (success && (bt_mesh_dfu_slot_commit(srv->upload.slot) == 0)) {
srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS;
srv->upload.phase = BLE_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS;
return;
}
/* Will delete slot when we start a new upload */
srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ERROR;
srv->upload.phase = BLE_MESH_DFD_UPLOAD_PHASE_TRANSFER_ERROR;
}
static void upload_timeout(struct bt_mesh_blob_srv *b)
@@ -933,9 +932,9 @@ static void dfd_srv_reset(struct bt_mesh_model *mod)
{
struct bt_mesh_dfd_srv *srv = mod->user_data;
dfd_phase_set(srv, BT_MESH_DFD_PHASE_IDLE);
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_IDLE);
srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_IDLE;
srv->upload.phase = BLE_MESH_DFD_UPLOAD_PHASE_IDLE;
sys_slist_init(&srv->inputs.targets);
srv->target_cnt = 0;
@@ -963,19 +962,19 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_receiver_add(struct bt_mesh_dfd_srv *srv
struct bt_mesh_blob_target_pull *p;
if (!BLE_MESH_ADDR_IS_UNICAST(addr)) {
return BT_MESH_DFD_SUCCESS;
return BLE_MESH_DFD_SUCCESS;
}
t = target_get(srv, addr);
if (t) {
t->img_idx = img_idx;
return BT_MESH_DFD_SUCCESS;
return BLE_MESH_DFD_SUCCESS;
}
/* New target node, add it to the list */
if (srv->target_cnt == ARRAY_SIZE(srv->targets)) {
return BT_MESH_DFD_ERR_INSUFFICIENT_RESOURCES;
return BLE_MESH_DFD_ERR_INSUFFICIENT_RESOURCES;
}
t = &srv->targets[srv->target_cnt];
@@ -991,19 +990,19 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_receiver_add(struct bt_mesh_dfd_srv *srv
BT_DBG("Added receiver 0x%04x img: %u", t->blob.addr,
t->img_idx);
return BT_MESH_DFD_SUCCESS;
return BLE_MESH_DFD_SUCCESS;
}
enum bt_mesh_dfd_status bt_mesh_dfd_srv_receivers_delete_all(struct bt_mesh_dfd_srv *srv)
{
if (bt_mesh_dfu_cli_is_busy(&srv->dfu)) {
return BT_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION;
return BLE_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION;
}
sys_slist_init(&srv->inputs.targets);
srv->target_cnt = 0;
return BT_MESH_DFD_SUCCESS;
return BLE_MESH_DFD_SUCCESS;
}
enum bt_mesh_dfd_status bt_mesh_dfd_srv_start(struct bt_mesh_dfd_srv *srv,
@@ -1013,17 +1012,17 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_start(struct bt_mesh_dfd_srv *srv,
struct bt_mesh_dfu_cli_xfer xfer = { 0 };
if (!srv->target_cnt) {
return BT_MESH_DFD_ERR_RECEIVERS_LIST_EMPTY;
return BLE_MESH_DFD_ERR_RECEIVERS_LIST_EMPTY;
}
if (!bt_mesh_app_key_get(params->app_idx)) {
return BT_MESH_DFD_ERR_INVALID_APPKEY_INDEX;
return BLE_MESH_DFD_ERR_INVALID_APPKEY_INDEX;
}
xfer.mode = params->xfer_mode;
xfer.slot = bt_mesh_dfu_slot_at(params->slot_idx);
if (!xfer.slot) {
return BT_MESH_DFD_ERR_FW_NOT_FOUND;
return BLE_MESH_DFD_ERR_FW_NOT_FOUND;
}
if (srv->inputs.app_idx == params->app_idx &&
@@ -1032,29 +1031,29 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_start(struct bt_mesh_dfd_srv *srv,
srv->dfu.xfer.blob.mode == xfer.mode && srv->apply == params->apply &&
srv->slot_idx == params->slot_idx) {
if (is_busy(srv) ||
srv->phase == BT_MESH_DFD_PHASE_COMPLETED) {
srv->phase == BLE_MESH_DFD_PHASE_COMPLETED) {
BT_WARN("Already completed or in progress");
return BT_MESH_DFD_SUCCESS;
} else if (srv->phase == BT_MESH_DFD_PHASE_TRANSFER_SUSPENDED) {
return BLE_MESH_DFD_SUCCESS;
} else if (srv->phase == BLE_MESH_DFD_PHASE_TRANSFER_SUSPENDED) {
bt_mesh_dfu_cli_resume(&srv->dfu);
dfd_phase_set(srv, BT_MESH_DFD_PHASE_TRANSFER_ACTIVE);
return BT_MESH_DFD_SUCCESS;
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_TRANSFER_ACTIVE);
return BLE_MESH_DFD_SUCCESS;
}
} else if (is_busy(srv) ||
srv->phase == BT_MESH_DFD_PHASE_TRANSFER_SUSPENDED) {
srv->phase == BLE_MESH_DFD_PHASE_TRANSFER_SUSPENDED) {
BT_WARN("Busy with distribution");
return BT_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION;
return BLE_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION;
}
if (srv->phase == BT_MESH_DFD_PHASE_CANCELING_UPDATE) {
if (srv->phase == BLE_MESH_DFD_PHASE_CANCELING_UPDATE) {
BT_WARN("Canceling distribution");
return BT_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION;
return BLE_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION;
}
srv->io = NULL;
err = srv->cb->send(srv, xfer.slot, &srv->io);
if (err || !srv->io) {
return BT_MESH_DFD_ERR_INTERNAL;
return BLE_MESH_DFD_ERR_INTERNAL;
}
sys_slist_init(&srv->inputs.targets);
@@ -1083,35 +1082,35 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_start(struct bt_mesh_dfd_srv *srv,
/* DFD Server will always retrieve targets' capabilities before distributing a firmware.*/
xfer.blob_params = NULL;
dfd_phase_set(srv, BT_MESH_DFD_PHASE_TRANSFER_ACTIVE);
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_TRANSFER_ACTIVE);
err = bt_mesh_dfu_cli_send(&srv->dfu, &srv->inputs, srv->io, &xfer);
if (err) {
dfd_phase_set(srv, BT_MESH_DFD_PHASE_IDLE);
return BT_MESH_DFD_ERR_INTERNAL;
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_IDLE);
return BLE_MESH_DFD_ERR_INTERNAL;
}
return BT_MESH_DFD_SUCCESS;
return BLE_MESH_DFD_SUCCESS;
}
enum bt_mesh_dfd_status bt_mesh_dfd_srv_suspend(struct bt_mesh_dfd_srv *srv)
{
int err;
if (srv->phase == BT_MESH_DFD_PHASE_TRANSFER_SUSPENDED) {
return BT_MESH_DFD_SUCCESS;
if (srv->phase == BLE_MESH_DFD_PHASE_TRANSFER_SUSPENDED) {
return BLE_MESH_DFD_SUCCESS;
}
if (srv->phase != BT_MESH_DFD_PHASE_TRANSFER_ACTIVE) {
return BT_MESH_DFD_ERR_WRONG_PHASE;
if (srv->phase != BLE_MESH_DFD_PHASE_TRANSFER_ACTIVE) {
return BLE_MESH_DFD_ERR_WRONG_PHASE;
}
err = bt_mesh_dfu_cli_suspend(&srv->dfu);
if (err) {
return BT_MESH_DFD_ERR_SUSPEND_FAILED;
return BLE_MESH_DFD_ERR_SUSPEND_FAILED;
}
srv->phase = BT_MESH_DFD_PHASE_TRANSFER_SUSPENDED;
return BT_MESH_DFD_SUCCESS;
srv->phase = BLE_MESH_DFD_PHASE_TRANSFER_SUSPENDED;
return BLE_MESH_DFD_SUCCESS;
}
enum bt_mesh_dfd_status bt_mesh_dfd_srv_cancel(struct bt_mesh_dfd_srv *srv,
@@ -1120,36 +1119,36 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_cancel(struct bt_mesh_dfd_srv *srv,
enum bt_mesh_dfd_phase prev_phase;
int err;
if (srv->phase == BT_MESH_DFD_PHASE_CANCELING_UPDATE ||
srv->phase == BT_MESH_DFD_PHASE_IDLE) {
if (srv->phase == BLE_MESH_DFD_PHASE_CANCELING_UPDATE ||
srv->phase == BLE_MESH_DFD_PHASE_IDLE) {
if (ctx != NULL) {
status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS);
status_rsp(srv, ctx, BLE_MESH_DFD_SUCCESS);
}
return BT_MESH_DFD_SUCCESS;
return BLE_MESH_DFD_SUCCESS;
}
if (srv->phase == BT_MESH_DFD_PHASE_COMPLETED ||
srv->phase == BT_MESH_DFD_PHASE_FAILED) {
dfd_phase_set(srv, BT_MESH_DFD_PHASE_IDLE);
if (srv->phase == BLE_MESH_DFD_PHASE_COMPLETED ||
srv->phase == BLE_MESH_DFD_PHASE_FAILED) {
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_IDLE);
if (ctx != NULL) {
status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS);
status_rsp(srv, ctx, BLE_MESH_DFD_SUCCESS);
}
return BT_MESH_DFD_SUCCESS;
return BLE_MESH_DFD_SUCCESS;
}
/* Phase TRANSFER_ACTIVE, TRANSFER_SUSPENDED, TRANSFER_SUCCESS, APPLYING_UPDATE: */
prev_phase = srv->phase;
dfd_phase_set(srv, BT_MESH_DFD_PHASE_CANCELING_UPDATE);
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_CANCELING_UPDATE);
err = bt_mesh_dfu_cli_cancel(&srv->dfu, NULL);
if (err) {
if (ctx != NULL) {
status_rsp(srv, ctx, BT_MESH_DFD_ERR_INTERNAL);
status_rsp(srv, ctx, BLE_MESH_DFD_ERR_INTERNAL);
}
return BT_MESH_DFD_ERR_INTERNAL;
return BLE_MESH_DFD_ERR_INTERNAL;
}
if (prev_phase == BT_MESH_DFD_PHASE_APPLYING_UPDATE && ctx) {
if (prev_phase == BLE_MESH_DFD_PHASE_APPLYING_UPDATE && ctx) {
/* Disable randomization for the Firmware Distribution State message to avoid
* reordering when Firmware Distribution Server sends 2 messages in a row when
* cancelling the update (see section 6.2.3.10 of MshDFUv1.0).
@@ -1161,43 +1160,43 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_cancel(struct bt_mesh_dfd_srv *srv,
}
if (ctx != NULL) {
status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS);
status_rsp(srv, ctx, BLE_MESH_DFD_SUCCESS);
}
if (prev_phase == BT_MESH_DFD_PHASE_APPLYING_UPDATE) {
dfd_phase_set(srv, BT_MESH_DFD_PHASE_IDLE);
if (prev_phase == BLE_MESH_DFD_PHASE_APPLYING_UPDATE) {
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_IDLE);
if (ctx != NULL) {
status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS);
status_rsp(srv, ctx, BLE_MESH_DFD_SUCCESS);
}
}
return BT_MESH_DFD_SUCCESS;
return BLE_MESH_DFD_SUCCESS;
}
enum bt_mesh_dfd_status bt_mesh_dfd_srv_apply(struct bt_mesh_dfd_srv *srv)
{
int err;
if (srv->phase == BT_MESH_DFD_PHASE_IDLE ||
srv->phase == BT_MESH_DFD_PHASE_CANCELING_UPDATE ||
srv->phase == BT_MESH_DFD_PHASE_TRANSFER_ACTIVE ||
srv->phase == BT_MESH_DFD_PHASE_TRANSFER_SUSPENDED ||
srv->phase == BT_MESH_DFD_PHASE_FAILED) {
return BT_MESH_DFD_ERR_WRONG_PHASE;
if (srv->phase == BLE_MESH_DFD_PHASE_IDLE ||
srv->phase == BLE_MESH_DFD_PHASE_CANCELING_UPDATE ||
srv->phase == BLE_MESH_DFD_PHASE_TRANSFER_ACTIVE ||
srv->phase == BLE_MESH_DFD_PHASE_TRANSFER_SUSPENDED ||
srv->phase == BLE_MESH_DFD_PHASE_FAILED) {
return BLE_MESH_DFD_ERR_WRONG_PHASE;
}
if (srv->phase == BT_MESH_DFD_PHASE_APPLYING_UPDATE ||
srv->phase == BT_MESH_DFD_PHASE_COMPLETED) {
return BT_MESH_DFD_SUCCESS;
if (srv->phase == BLE_MESH_DFD_PHASE_APPLYING_UPDATE ||
srv->phase == BLE_MESH_DFD_PHASE_COMPLETED) {
return BLE_MESH_DFD_SUCCESS;
}
err = bt_mesh_dfu_cli_apply(&srv->dfu);
if (err) {
return BT_MESH_DFD_ERR_INTERNAL;
return BLE_MESH_DFD_ERR_INTERNAL;
}
dfd_phase_set(srv, BT_MESH_DFD_PHASE_APPLYING_UPDATE);
return BT_MESH_DFD_SUCCESS;
dfd_phase_set(srv, BLE_MESH_DFD_PHASE_APPLYING_UPDATE);
return BLE_MESH_DFD_SUCCESS;
}
enum bt_mesh_dfd_status bt_mesh_dfd_srv_fw_delete(struct bt_mesh_dfd_srv *srv, size_t *fwid_len,
@@ -1206,38 +1205,38 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_fw_delete(struct bt_mesh_dfd_srv *srv, s
struct bt_mesh_dfu_slot *slot;
int idx, err;
if (srv->phase != BT_MESH_DFD_PHASE_IDLE) {
if (srv->phase != BLE_MESH_DFD_PHASE_IDLE) {
*fwid = NULL;
*fwid_len = 0;
return BT_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION;
return BLE_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION;
}
idx = bt_mesh_dfu_slot_get(*fwid, *fwid_len, &slot);
if (idx < 0) {
return BT_MESH_DFD_SUCCESS;
return BLE_MESH_DFD_SUCCESS;
}
err = slot_del(srv, slot);
if (err) {
*fwid = NULL;
*fwid_len = 0;
return BT_MESH_DFD_ERR_INTERNAL;
return BLE_MESH_DFD_ERR_INTERNAL;
} else {
return BT_MESH_DFD_SUCCESS;
return BLE_MESH_DFD_SUCCESS;
}
}
enum bt_mesh_dfd_status bt_mesh_dfd_srv_fw_delete_all(struct bt_mesh_dfd_srv *srv)
{
if (srv->phase != BT_MESH_DFD_PHASE_IDLE) {
return BT_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION;
if (srv->phase != BLE_MESH_DFD_PHASE_IDLE) {
return BLE_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION;
}
bt_mesh_dfu_slot_foreach(slot_del_cb, srv);
bt_mesh_dfu_slot_del_all();
return BT_MESH_DFD_SUCCESS;
return BLE_MESH_DFD_SUCCESS;
}
#ifdef CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD
@@ -1248,7 +1247,7 @@ int bt_mesh_dfd_srv_oob_check_complete(struct bt_mesh_dfd_srv *srv,
int err;
if (slot != srv->upload.slot || !srv->upload.is_oob ||
srv->upload.phase == BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE ||
srv->upload.phase == BLE_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE ||
!srv->upload.is_pending_oob_check) {
/* This should not happen, unless the application calls the function with a
* "wrong" pointer or at a wrong time.
@@ -1258,7 +1257,7 @@ int bt_mesh_dfd_srv_oob_check_complete(struct bt_mesh_dfd_srv *srv,
srv->upload.is_pending_oob_check = false;
if (status != BT_MESH_DFD_SUCCESS) {
if (status != BLE_MESH_DFD_SUCCESS) {
bt_mesh_dfu_slot_release(srv->upload.slot);
upload_status_rsp(srv, &srv->upload.oob.ctx, status);
return -ECANCELED;
@@ -1270,7 +1269,7 @@ int bt_mesh_dfd_srv_oob_check_complete(struct bt_mesh_dfd_srv *srv,
return err;
}
upload_status_rsp(srv, &srv->upload.oob.ctx, BT_MESH_DFD_SUCCESS);
upload_status_rsp(srv, &srv->upload.oob.ctx, BLE_MESH_DFD_SUCCESS);
return 0;
}
@@ -1280,7 +1279,7 @@ int bt_mesh_dfd_srv_oob_store_complete(struct bt_mesh_dfd_srv *srv,
{
int err = 0;
if (srv->upload.phase != BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE ||
if (srv->upload.phase != BLE_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE ||
srv->upload.slot != slot || !srv->upload.is_oob) {
return -EINVAL;
}
@@ -1299,11 +1298,11 @@ int bt_mesh_dfd_srv_oob_store_complete(struct bt_mesh_dfd_srv *srv,
goto error;
}
srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS;
srv->upload.phase = BLE_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS;
return 0;
error:
srv->upload.phase = BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ERROR;
srv->upload.phase = BLE_MESH_DFD_UPLOAD_PHASE_TRANSFER_ERROR;
bt_mesh_dfu_slot_release(srv->upload.slot);
return err;
}
@@ -105,8 +105,10 @@ static void req_timeout_handler(struct k_work *work)
}
bt_mesh_dfu_cli_rm_req_from_list(req);
if (req->params) {
bt_mesh_free(req->params);
}
req_free(req);
bt_mesh_r_mutex_unlock(&dfu_req_list.op_lock);
}
@@ -897,7 +899,7 @@ static int handle_status(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx
}
bt_mesh_dfu_client_cb_evt_to_btc(req->opcode, BTC_BLE_MESH_EVT_DFU_CLIENT_RECV_GET_RSP,
req->dfu_cli->mod, &req->ctx, req->params,
sizeof(struct bt_mesh_dfu_metadata_status));
sizeof(struct bt_mesh_dfu_target_status));
bt_mesh_free(req->params);
bt_mesh_dfu_cli_rm_req_from_list(req);
k_delayed_work_cancel(&req->timer);
@@ -12,6 +12,30 @@
extern "C" {
#endif
#define BLE_MESH_DFD_OP_RECEIVERS_ADD BLE_MESH_MODEL_OP_2(0x83, 0x11)
#define BLE_MESH_DFD_OP_RECEIVERS_DELETE_ALL BLE_MESH_MODEL_OP_2(0x83, 0x12)
#define BLE_MESH_DFD_OP_RECEIVERS_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x13)
#define BLE_MESH_DFD_OP_RECEIVERS_GET BLE_MESH_MODEL_OP_2(0x83, 0x14)
#define BLE_MESH_DFD_OP_RECEIVERS_LIST BLE_MESH_MODEL_OP_2(0x83, 0x15)
#define BLE_MESH_DFD_OP_CAPABILITIES_GET BLE_MESH_MODEL_OP_2(0x83, 0x16)
#define BLE_MESH_DFD_OP_CAPABILITIES_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x17)
#define BLE_MESH_DFD_OP_GET BLE_MESH_MODEL_OP_2(0x83, 0x18)
#define BLE_MESH_DFD_OP_START BLE_MESH_MODEL_OP_2(0x83, 0x19)
#define BLE_MESH_DFD_OP_SUSPEND BLE_MESH_MODEL_OP_2(0x83, 0x1a)
#define BLE_MESH_DFD_OP_CANCEL BLE_MESH_MODEL_OP_2(0x83, 0x1b)
#define BLE_MESH_DFD_OP_APPLY BLE_MESH_MODEL_OP_2(0x83, 0x1c)
#define BLE_MESH_DFD_OP_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x1d)
#define BLE_MESH_DFD_OP_UPLOAD_GET BLE_MESH_MODEL_OP_2(0x83, 0x1e)
#define BLE_MESH_DFD_OP_UPLOAD_START BLE_MESH_MODEL_OP_2(0x83, 0x1f)
#define BLE_MESH_DFD_OP_UPLOAD_START_OOB BLE_MESH_MODEL_OP_2(0x83, 0x20)
#define BLE_MESH_DFD_OP_UPLOAD_CANCEL BLE_MESH_MODEL_OP_2(0x83, 0x21)
#define BLE_MESH_DFD_OP_UPLOAD_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x22)
#define BLE_MESH_DFD_OP_FW_GET BLE_MESH_MODEL_OP_2(0x83, 0x23)
#define BLE_MESH_DFD_OP_FW_GET_BY_INDEX BLE_MESH_MODEL_OP_2(0x83, 0x24)
#define BLE_MESH_DFD_OP_FW_DELETE BLE_MESH_MODEL_OP_2(0x83, 0x25)
#define BLE_MESH_DFD_OP_FW_DELETE_ALL BLE_MESH_MODEL_OP_2(0x83, 0x26)
#define BLE_MESH_DFD_OP_FW_STATUS BLE_MESH_MODEL_OP_2(0x83, 0x27)
/**
* @defgroup bt_mesh_dfd Firmware Distribution models
* @ingroup bt_mesh
@@ -21,96 +45,96 @@ extern "C" {
/** Firmware distribution status. */
enum bt_mesh_dfd_status {
/** The message was processed successfully. */
BT_MESH_DFD_SUCCESS,
BLE_MESH_DFD_SUCCESS,
/** Insufficient resources on the node. */
BT_MESH_DFD_ERR_INSUFFICIENT_RESOURCES,
BLE_MESH_DFD_ERR_INSUFFICIENT_RESOURCES,
/** The operation cannot be performed while the Server is in the current
* phase.
*/
BT_MESH_DFD_ERR_WRONG_PHASE,
BLE_MESH_DFD_ERR_WRONG_PHASE,
/** An internal error occurred on the node. */
BT_MESH_DFD_ERR_INTERNAL,
BLE_MESH_DFD_ERR_INTERNAL,
/** The requested firmware image is not stored on the Distributor. */
BT_MESH_DFD_ERR_FW_NOT_FOUND,
BLE_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,
BLE_MESH_DFD_ERR_INVALID_APPKEY_INDEX,
/** There are no Target nodes in the Distribution Receivers List
* state.
*/
BT_MESH_DFD_ERR_RECEIVERS_LIST_EMPTY,
BLE_MESH_DFD_ERR_RECEIVERS_LIST_EMPTY,
/** Another firmware image distribution is in progress. */
BT_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION,
BLE_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION,
/** Another upload is in progress. */
BT_MESH_DFD_ERR_BUSY_WITH_UPLOAD,
BLE_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,
BLE_MESH_DFD_ERR_URI_NOT_SUPPORTED,
/** The format of the Update URI is invalid. */
BT_MESH_DFD_ERR_URI_MALFORMED,
BLE_MESH_DFD_ERR_URI_MALFORMED,
/** The URI is currently unreachable. */
BT_MESH_DFD_ERR_URI_UNREACHABLE,
BLE_MESH_DFD_ERR_URI_UNREACHABLE,
/** The Check Firmware OOB procedure did not find any new firmware. */
BT_MESH_DFD_ERR_NEW_FW_NOT_AVAILABLE,
BLE_MESH_DFD_ERR_NEW_FW_NOT_AVAILABLE,
/** The suspension of the Distribute Firmware procedure failed. */
BT_MESH_DFD_ERR_SUSPEND_FAILED,
BLE_MESH_DFD_ERR_SUSPEND_FAILED,
};
/** Firmware distribution phases. */
enum bt_mesh_dfd_phase {
/** No firmware distribution is in progress. */
BT_MESH_DFD_PHASE_IDLE,
BLE_MESH_DFD_PHASE_IDLE,
/** Firmware distribution is in progress. */
BT_MESH_DFD_PHASE_TRANSFER_ACTIVE,
BLE_MESH_DFD_PHASE_TRANSFER_ACTIVE,
/** The Transfer BLOB procedure has completed successfully. */
BT_MESH_DFD_PHASE_TRANSFER_SUCCESS,
BLE_MESH_DFD_PHASE_TRANSFER_SUCCESS,
/** The Apply Firmware on Target Nodes procedure is being executed. */
BT_MESH_DFD_PHASE_APPLYING_UPDATE,
BLE_MESH_DFD_PHASE_APPLYING_UPDATE,
/** The Distribute Firmware procedure has completed successfully. */
BT_MESH_DFD_PHASE_COMPLETED,
BLE_MESH_DFD_PHASE_COMPLETED,
/** The Distribute Firmware procedure has failed. */
BT_MESH_DFD_PHASE_FAILED,
BLE_MESH_DFD_PHASE_FAILED,
/** The Cancel Firmware Update procedure is being executed. */
BT_MESH_DFD_PHASE_CANCELING_UPDATE,
BLE_MESH_DFD_PHASE_CANCELING_UPDATE,
/** The Transfer BLOB procedure is suspended. */
BT_MESH_DFD_PHASE_TRANSFER_SUSPENDED,
BLE_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,
BLE_MESH_DFD_UPLOAD_PHASE_IDLE,
/** The Store Firmware procedure is being executed. */
BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE,
BLE_MESH_DFD_UPLOAD_PHASE_TRANSFER_ACTIVE,
/** The Store Firmware procedure or Store Firmware OOB procedure failed.
*/
BT_MESH_DFD_UPLOAD_PHASE_TRANSFER_ERROR,
BLE_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,
BLE_MESH_DFD_UPLOAD_PHASE_TRANSFER_SUCCESS,
};
/** @} */
@@ -0,0 +1,472 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @defgroup bt_mesh_dfd_cli Device Firmware Distribution Client model
* @ingroup bt_mesh_dfd
* @{
* @brief API for the Device Firmware Distribution Client model
*/
#ifndef _BLE_MESH_v11_DFD_CLI_H__
#define _BLE_MESH_v11_DFD_CLI_H__
#include "mesh/access.h"
#include "mesh/client_common.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
/** @brief Device Firmware Distribution Client model instance. */
typedef bt_mesh_client_user_data_t bt_mesh_dfd_client_t;
/** @brief DFD Client internal data structure. */
typedef bt_mesh_client_internal_data_t dfd_internal_data_t;
/*!< Maximum value of upload progress indicating progress is unset. */
#define UPLOAD_PROGRESS_UNSET 101
/*!< In-band upload type. */
#define UPLOAD_IN_BAND 0x00
/*!< Out-of-band upload type. */
#define UPLOAD_OOB 0x01
/*!< Upload type is not set. */
#define UPLOAD_TYPE_UNSET 0xFF
/*!< Extract target address from target info bitfield. */
#define TARGET_ADDR(target_info) (target_info >> 17)
/*!< Extract target update phase from target info bitfield. */
#define TARGET_UPDATE_PHASE(target_info) ((target_info >> 13) & 0x0f)
/*!< Extract target update status from target info bitfield. */
#define TARGET_UPDATE_STATUS(target_info) ((target_info >> 10) & 0x07)
/*!< Extract target transfer status from target info bitfield. */
#define TARGET_TRANSFER_STATUS(target_info) ((target_info >> 6) & 0x0f)
/*!< Extract target transfer progress from target info bitfield. */
#define TARGET_TRANSFER_PROGRESS(target_info) (target_info & 0x3f)
/**
* @brief DFD Client receiver entry structure.
*
* This structure represents a single receiver node that will receive firmware
* distribution. Each receiver is identified by its unicast address and the
* firmware image index that should be distributed to it.
*/
typedef struct {
uint16_t addr; /*!< Unicast address of the receiver node. */
uint8_t fw_idx; /*!< Index of the firmware image to distribute. */
} dfd_cli_receiver_entry_t;
/**
* @brief Target node entry information structure.
*
* This structure contains detailed information about a target node's
* firmware distribution status, including address, update phase, transfer
* progress, and other related information.
*/
typedef struct {
uint32_t addr:15; /*!< Unicast address of the target node. */
uint32_t retrieved_update_phase:4; /*!< Current update phase of the target. */
uint32_t update_status:3; /*!< Update status of the target node. */
uint32_t transfer_status:4; /*!< Transfer status of the target. */
uint32_t transfer_progress:6; /*!< Transfer progress percentage. */
uint8_t update_fw_idx; /*!< Index of firmware being updated. */
} target_node_entry_t;
/**
* @brief DFD receiver status response structure.
*
* This structure contains the status response for receiver add/delete
* operations, including the operation result and current receiver list size.
*/
typedef struct {
uint8_t status; /*!< Status code of the operation (see @ref bt_mesh_dfd_status). */
uint16_t receiver_list_cnt; /*!< Current number of receivers in the distribution list. */
} dfd_cli_receiver_status_t;
/**
* @brief DFD receiver list response structure.
*
* This structure contains the response to a receivers get request,
* providing a list of target nodes with their current status information.
*/
typedef struct {
uint16_t entries_cnt; /*!< Number of receiver entries in the list. */
uint16_t first_index; /*!< Index of the first entry in the list. */
target_node_entry_t *entries; /*!< Pointer to array of target node entries. */
} dfd_cli_receiver_list_t;
/**
* @brief DFD distribution capabilities structure.
*
* This structure contains the capabilities of the DFD Server, including
* storage limits, receiver limits, and supported features.
*/
typedef struct {
uint16_t max_receiver_list_sz; /*!< Maximum number of receivers supported. */
uint16_t max_fw_list_sz; /*!< Maximum number of firmware images supported. */
uint32_t max_fw_sz; /*!< Maximum firmware image size supported. */
uint32_t max_upload_space; /*!< Total upload storage space available. */
uint32_t remaining_upload_space; /*!< Remaining upload storage space. */
uint8_t oob_retrieval_supported; /*!< OOB retrieval support flag. */
struct net_buf_simple *supported_url_scheme_names; /*!< Supported URL scheme names. */
} dfd_cli_dist_caps_t;
/**
* @brief DFD distribution status structure.
*
* This structure contains the current status of an ongoing or completed
* firmware distribution operation, including phase, progress, and configuration.
*/
typedef struct {
uint8_t status; /*!< Distribution status code (see @ref bt_mesh_dfd_status). */
uint8_t dist_phase; /*!< Current distribution phase (see @ref bt_mesh_dfd_phase). */
uint16_t multicast_address; /*!< Multicast address used for distribution. */
uint16_t appkey_idx; /*!< Application key index used for distribution. */
uint8_t ttl; /*!< TTL value used for distribution messages. */
uint16_t timeout_base; /*!< Base timeout value for distribution. */
uint8_t trans_mode:2; /*!< Transfer mode (push or pull). */
uint8_t update_policy:1; /*!< Update policy (single or all). */
uint8_t RFU:5; /*!< Reserved for future use. */
uint16_t fw_idx; /*!< Index of firmware being distributed. */
} dfd_cli_dist_status_t;
/**
* @brief DFD upload status structure.
*
* This structure contains the current status of a firmware upload operation,
* including phase, progress, and firmware identification.
*/
typedef struct {
uint8_t status; /*!< Upload operation status code (see @ref bt_mesh_dfd_status). */
uint8_t upload_phase; /*!< Current upload phase (see @ref bt_mesh_dfd_upload_phase). */
uint8_t upload_progress:7; /*!< Upload progress percentage (0-100). */
uint8_t upload_type:1; /*!< Upload type (in-band or OOB). */
union {
struct net_buf_simple *fwid; /*!< Firmware ID for in-band uploads. */
struct net_buf_simple *oob_fwid; /*!< Firmware ID for OOB uploads. */
};
} dfd_cli_upload_status_t;
/**
* @brief DFD firmware status structure.
*
* This structure contains the status response for firmware management
* operations, including information about firmware images.
*/
typedef struct {
uint8_t status; /*!< Firmware operation status code (see @ref bt_mesh_dfd_status). */
uint16_t entry_cnt; /*!< Number of firmware entries. */
uint16_t firmware_image_index; /*!< Index of the firmware image. */
struct net_buf_simple *fwid; /*!< Firmware ID buffer. */
} dfd_cli_firmware_status_t;
/**
* @brief DFD distribution start parameters structure.
*
* This structure contains parameters for starting a firmware distribution
* operation, including target configuration and distribution settings.
*/
typedef struct {
uint8_t ttl; /*!< TTL value for distribution messages. */
uint8_t trans_mode:2; /*!< Transfer mode (push or pull). */
uint8_t update_policy:1; /*!< Update policy (single or all). */
uint8_t RFU:5; /*!< Reserved for future use. */
uint16_t app_idx; /*!< Application key index for distribution. */
uint16_t timeout_base; /*!< Base timeout value for distribution. */
uint16_t fw_idx; /*!< Index of firmware to distribute. */
bool is_va; /*!< True if using virtual address, false for group address. */
union {
uint16_t group_addr; /*!< Group address for distribution (if is_va is false). */
uint8_t label_uuid[16]; /*!< Virtual label UUID for distribution (if is_va is true). */
};
} dfd_cli_dist_start_t;
/**
* @brief DFD distribution upload start parameters structure.
*
* This structure contains parameters for starting an in-band firmware
* upload operation to the DFD Server.
*/
typedef struct {
uint8_t ttl; /*!< TTL value for upload messages. */
uint16_t timeout_base; /*!< Base timeout value for upload. */
uint32_t fw_size; /*!< Size of the firmware image in bytes. */
uint64_t blob_id; /*!< BLOB ID for the firmware transfer. */
struct net_buf_simple *fwid; /*!< Firmware ID buffer. */
struct net_buf_simple *fw_metadata; /*!< Firmware metadata buffer. */
} dfd_cli_dist_upload_start_t;
/**
* @brief DFD distribution OOB upload start parameters structure.
*
* This structure contains parameters for starting an out-of-band firmware
* upload operation to the DFD Server.
*/
typedef struct {
struct net_buf_simple *fwid; /*!< Firmware ID buffer. */
struct net_buf_simple *url; /*!< URL for retrieving the firmware. */
} dfd_cli_dist_upload_oob_start_t;
/**
* @brief DFD status response union.
*
* This union contains different status response structures for various DFD
* Client operations, allowing type-safe access to operation-specific responses.
*/
typedef union {
dfd_cli_receiver_status_t receiver_status; /*!< Receiver add/delete status. */
dfd_cli_receiver_list_t receiver_list; /*!< Receiver list response. */
dfd_cli_dist_caps_t dist_caps; /*!< Distribution capabilities. */
dfd_cli_dist_status_t dist_status; /*!< Distribution status. */
dfd_cli_upload_status_t upload_status; /*!< Upload status. */
dfd_cli_firmware_status_t firmware_status; /*!< Firmware management status. */
} dfd_status_t;
/*!< DFD Client model operation handlers. */
extern const struct bt_mesh_model_op _bt_mesh_dfd_cli_op[];
/*!< DFD Client model callbacks. */
extern const struct bt_mesh_model_cb _bt_mesh_dfd_cli_cb;
/**
* @brief Add receivers to the distribution list.
*
* Add multiple target nodes to the DFD Server's distribution receiver list.
* These receivers will be included in subsequent firmware distribution operations.
*
* @param[in] param Common client parameters for the operation.
* @param[in] receivers Pointer to array of receiver entries to add.
* @param[in] receivers_cnt Number of receiver entries in the array.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_receivers_add(bt_mesh_client_common_param_t *param,
dfd_cli_receiver_entry_t *receivers,
uint16_t receivers_cnt);
/**
* @brief Delete all receivers from the distribution list.
*
* Remove all target nodes from the DFD Server's distribution receiver list.
* This operation will clear the entire receiver list.
*
* @param[in] param Common client parameters for the operation.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_receivers_delete_all(bt_mesh_client_common_param_t *param);
/**
* @brief Get the distribution receiver list.
*
* Retrieve a portion of the DFD Server's distribution receiver list.
* Supports pagination to retrieve large receiver lists in chunks.
*
* @param[in] param Common client parameters for the operation.
* @param[in] first_index Index of the first receiver entry to retrieve.
* @param[in] entries_limit Maximum number of entries to retrieve.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_receivers_get(bt_mesh_client_common_param_t *param,
uint16_t first_index,
uint16_t entries_limit);
/**
* @brief Get distribution capabilities from the DFD Server.
*
* Query the DFD Server's capabilities, including storage limits,
* supported features, and maximum receiver count.
*
* @param[in] param Common client parameters for the operation.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_distribution_capabilities_get(bt_mesh_client_common_param_t *param);
/**
* @brief Get current distribution status from the DFD Server.
*
* Query the current status of firmware distribution operations,
* including phase, progress, and configuration information.
*
* @param[in] param Common client parameters for the operation.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_distribution_get(bt_mesh_client_common_param_t *param);
/**
* @brief Start firmware distribution to receivers.
*
* Initiate firmware distribution to all target nodes in the distribution
* receiver list using the specified configuration parameters.
*
* @param[in] param Common client parameters for the operation.
* @param[in] start Distribution start parameters and configuration.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_distribution_start(bt_mesh_client_common_param_t *param,
dfd_cli_dist_start_t *start);
/**
* @brief Suspend ongoing firmware distribution.
*
* Suspend a currently active firmware distribution operation.
* The distribution can be resumed later if needed.
*
* @param[in] param Common client parameters for the operation.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_distribution_suspend(bt_mesh_client_common_param_t *param);
/**
* @brief Cancel firmware distribution.
*
* Cancel an ongoing or suspended firmware distribution operation.
* This will terminate the distribution process.
*
* @param[in] param Common client parameters for the operation.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_distribution_cancel(bt_mesh_client_common_param_t *param);
/**
* @brief Apply distributed firmware on target nodes.
*
* Apply the distributed firmware image on target nodes that have
* successfully received the firmware transfer.
*
* @param[in] param Common client parameters for the operation.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_distribution_apply(bt_mesh_client_common_param_t *param);
/**
* @brief Get firmware upload status from the DFD Server.
*
* Query the current status of firmware upload operations, including
* phase, progress, and transfer information.
*
* @param[in] param Common client parameters for the operation.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_distribution_upload_get(bt_mesh_client_common_param_t *param);
/**
* @brief Start in-band firmware upload to the DFD Server.
*
* Initiate an in-band firmware upload using BLOB transfer protocol.
* The firmware image will be transferred directly through the mesh network.
*
* @param[in] param Common client parameters for the operation.
* @param[in] start Upload start parameters including firmware details.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_distribution_upload_start(bt_mesh_client_common_param_t *param,
dfd_cli_dist_upload_start_t *start);
/**
* @brief Start out-of-band firmware upload to the DFD Server.
*
* Initiate an out-of-band firmware upload where the DFD Server
* retrieves the firmware from the specified URL.
*
* @param[in] param Common client parameters for the operation.
* @param[in] start OOB upload start parameters including URL and firmware ID.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_distribution_upload_oob_start(bt_mesh_client_common_param_t *param,
dfd_cli_dist_upload_oob_start_t *start);
/**
* @brief Cancel out-of-band firmware upload.
*
* Cancel an ongoing out-of-band firmware upload operation.
*
* @param[in] param Common client parameters for the operation.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_distribution_upload_oob_cancel(bt_mesh_client_common_param_t *param);
/**
* @brief Get firmware information by firmware ID.
*
* Query detailed information about a specific firmware image
* stored on the DFD Server using its firmware ID.
*
* @param[in] param Common client parameters for the operation.
* @param[in] fwid Firmware ID to query information for.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_firmware_get(bt_mesh_client_common_param_t *param,
struct net_buf_simple *fwid);
/**
* @brief Get firmware information by index.
*
* Query detailed information about a firmware image stored on the
* DFD Server using its index in the firmware list.
*
* @param[in] param Common client parameters for the operation.
* @param[in] fw_id_index Index of the firmware image to query.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_firmware_get_by_index(bt_mesh_client_common_param_t *param,
uint16_t fw_id_index);
/**
* @brief Delete specific firmware image by firmware ID.
*
* Delete a specific firmware image from the DFD Server's storage
* using its firmware ID.
*
* @param[in] param Common client parameters for the operation.
* @param[in] fwid Firmware ID of the image to delete.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_firmware_get_delete(bt_mesh_client_common_param_t *param,
struct net_buf_simple *fwid);
/**
* @brief Delete all firmware images from the DFD Server.
*
* Delete all firmware images stored on the DFD Server.
* This operation will clear the entire firmware storage.
*
* @param[in] param Common client parameters for the operation.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_dfd_cli_firmware_delete_all(bt_mesh_client_common_param_t *param);
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* _BLE_MESH_v11_DFD_CLI_H__ */
@@ -42,15 +42,14 @@ struct bt_mesh_dfd_srv;
#ifdef CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD
/**
* @brief Initialization parameters for the @ref bt_mesh_dfd_srv with OOB
* upload support.
*
* @brief Initialization parameters for the @ref bt_mesh_dfd_srv with OOB
* upload support.
*
* @param[in] _cb Pointer to a @ref bt_mesh_dfd_srv_cb instance.
* @param[in] _oob_schemes Array of OOB schemes supported by the server,
* each scheme being a code point from the
* Bluetooth SIG Assigned Numbers document.
* @param[in] _oob_schemes_count Number of schemes in @c _oob_schemes.
* @param[in] _cb Pointer to a @ref bt_mesh_dfd_srv_cb instance.
* @param[in] _oob_schemes Array of OOB schemes supported by the server,
* each scheme being a code point from the
* 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) \
{ \
@@ -67,10 +66,9 @@ struct bt_mesh_dfd_srv;
#endif /* CONFIG_BLE_MESH_DFD_SRV_OOB_UPLOAD */
/**
* @brief Initialization parameters for the @ref bt_mesh_dfd_srv.
*
* @brief Initialization parameters for the @ref bt_mesh_dfd_srv.
*
* @param[in] _cb Pointer to a @ref bt_mesh_dfd_srv_cb instance.
* @param[in] _cb Pointer to a @ref bt_mesh_dfd_srv_cb instance.
*/
#define BT_MESH_DFD_SRV_INIT(_cb) \
{ \
@@ -82,10 +80,9 @@ struct bt_mesh_dfd_srv;
}
/**
* @brief Firmware Distribution Server model Composition Data entry.
*
* @brief Firmware Distribution Server model Composition Data entry.
*
* @param _srv Pointer to a @ref bt_mesh_dfd_srv instance.
* @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), \
@@ -98,15 +95,15 @@ 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.
* 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.
* @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.
* @return 0 on success, or (negative) error code otherwise.
*/
int (*recv)(struct bt_mesh_dfd_srv *srv,
const struct bt_mesh_dfu_slot *slot,
@@ -136,7 +133,7 @@ struct bt_mesh_dfd_srv_cb {
* available, or to 0 if new firmware is not
* available.
*
* @return BT_MESH_DFD_SUCCESS on success, or error code otherwise.
* @return BLE_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,
@@ -255,11 +252,11 @@ struct bt_mesh_dfd_srv {
* callback has completed or failed. The @p status param should be set to one of the following
* values:
*
* * @c BT_MESH_DFD_SUCCESS if the check was successful and a new firmware ID was found.
* * @c BT_MESH_DFD_ERR_URI_MALFORMED if the URI is not formatted correctly.
* * @c BT_MESH_DFD_ERR_URI_NOT_SUPPORTED if the URI scheme is not supported by the node.
* * @c BT_MESH_DFD_ERR_URI_UNREACHABLE if the URI can't be reached.
* * @c BT_MESH_DFD_ERR_NEW_FW_NOT_AVAILABLE if the check completes successfully but no new
* * @c BLE_MESH_DFD_SUCCESS if the check was successful and a new firmware ID was found.
* * @c BLE_MESH_DFD_ERR_URI_MALFORMED if the URI is not formatted correctly.
* * @c BLE_MESH_DFD_ERR_URI_NOT_SUPPORTED if the URI scheme is not supported by the node.
* * @c BLE_MESH_DFD_ERR_URI_UNREACHABLE if the URI can't be reached.
* * @c BLE_MESH_DFD_ERR_NEW_FW_NOT_AVAILABLE if the check completes successfully but no new
* firmware is available.
*
* If this function returns 0, the application should then download the firmware to the
@@ -135,11 +135,11 @@ Mesh Models
* Device Firmware Update Client models
* Firmware Update Client model (Preview)
* Firmware Distribution Client model (coming soon)
* Firmware Distribution Client model (Preview)
* Device Firmware Update Server models
* Firmware Update Server model (Preview)
* Firmware Distribution Server model (coming soon)
* Firmware Distribution Server model (Preview)
Mesh Examples
"""""""""""""
@@ -135,11 +135,11 @@ Mesh 模型
* 设备固件更新客户端模型
* 固件更新客户端模型(预览)
* 固件分发客户端模型(即将推出
* 固件分发客户端模型(预览
* 设备固件更新服务器模型
* 固件更新服务器模型(预览)
* 固件分发服务器模型(即将推出
* 固件分发服务器模型(预览
Mesh 示例
"""""""""""