mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
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:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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, ¶m, false);
|
||||
|
||||
switch (params->opcode) {
|
||||
case ESP_BLE_MESH_DFD_OP_RECEIVERS_GET:
|
||||
return bt_mesh_dfd_cli_receivers_get(¶m, 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(¶m);
|
||||
case ESP_BLE_MESH_DFD_OP_GET:
|
||||
return bt_mesh_dfd_cli_distribution_get(¶m);
|
||||
case ESP_BLE_MESH_DFD_OP_UPLOAD_GET:
|
||||
return bt_mesh_dfd_cli_distribution_upload_get(¶m);
|
||||
case ESP_BLE_MESH_DFD_OP_FW_GET:
|
||||
return bt_mesh_dfd_cli_firmware_get(¶m, get->dist_fw_get.fwid);
|
||||
case ESP_BLE_MESH_DFD_OP_FW_GET_BY_INDEX:
|
||||
return bt_mesh_dfd_cli_firmware_get_by_index(¶m, 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, ¶m, false);
|
||||
|
||||
switch (params->opcode) {
|
||||
case ESP_BLE_MESH_DFD_OP_RECEIVERS_ADD:
|
||||
return bt_mesh_dfd_cli_receivers_add(¶m, (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(¶m);
|
||||
case ESP_BLE_MESH_DFD_OP_START:
|
||||
return bt_mesh_dfd_cli_distribution_start(¶m, (dfd_cli_dist_start_t *)&set->dist_start);
|
||||
case ESP_BLE_MESH_DFD_OP_SUSPEND:
|
||||
return bt_mesh_dfd_cli_distribution_suspend(¶m);
|
||||
case ESP_BLE_MESH_DFD_OP_CANCEL:
|
||||
return bt_mesh_dfd_cli_distribution_cancel(¶m);
|
||||
case ESP_BLE_MESH_DFD_OP_APPLY:
|
||||
return bt_mesh_dfd_cli_distribution_apply(¶m);
|
||||
case ESP_BLE_MESH_DFD_OP_UPLOAD_START:
|
||||
return bt_mesh_dfd_cli_distribution_upload_start(¶m, (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(¶m, (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(¶m);
|
||||
case ESP_BLE_MESH_DFD_OP_FW_DELETE:
|
||||
return bt_mesh_dfd_cli_firmware_get_delete(¶m, set->dist_fw_del.fwid);
|
||||
case ESP_BLE_MESH_DFD_OP_FW_DELETE_ALL:
|
||||
return bt_mesh_dfd_cli_firmware_delete_all(¶m);
|
||||
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 *)¶ms.ctx, ctx, false);
|
||||
|
||||
cb_params.params = ¶ms;
|
||||
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
|
||||
|
||||
@@ -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
|
||||
@@ -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 示例
|
||||
"""""""""""
|
||||
|
||||
Reference in New Issue
Block a user