From 7a82ca0e39338d4da3a2fb14585ecf5fcb76348d Mon Sep 17 00:00:00 2001 From: Luo Xu Date: Mon, 9 Feb 2026 17:43:21 +0800 Subject: [PATCH] fix(ble_mesh): fix blob transfer failure handling and chunk processing - Fix DFU server transfer error state ordering to ensure proper callback delivery - Add validation to discard chunks when blob server is not in busy state - Prevent chunk processing when server is not in active transfer state (cherry picked from commit f959884b2f3d3644ff15230e7e498554e18e9e10) Co-authored-by: luoxu --- components/bt/esp_ble_mesh/v1.1/dfu/dfu_srv.c | 7 ++++++- components/bt/esp_ble_mesh/v1.1/mbt/blob_srv.c | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/components/bt/esp_ble_mesh/v1.1/dfu/dfu_srv.c b/components/bt/esp_ble_mesh/v1.1/dfu/dfu_srv.c index b36746a8220..2181ced2890 100644 --- a/components/bt/esp_ble_mesh/v1.1/dfu/dfu_srv.c +++ b/components/bt/esp_ble_mesh/v1.1/dfu/dfu_srv.c @@ -530,8 +530,13 @@ static void blob_end(struct bt_mesh_blob_srv *b, uint64_t id, bool success) BT_DBG("success: %u", success); if (!success) { - srv->update.phase = BLE_MESH_DFU_PHASE_TRANSFER_ERR; + /** + * Changed by Espressif, + * The xfer_failed must be executed before updating the state; + * otherwise, the end_cb inside xfer_failed will never be delivered. + */ xfer_failed(srv); + srv->update.phase = BLE_MESH_DFU_PHASE_TRANSFER_ERR; return; } diff --git a/components/bt/esp_ble_mesh/v1.1/mbt/blob_srv.c b/components/bt/esp_ble_mesh/v1.1/mbt/blob_srv.c index dc61e14c09e..b0237f299f5 100644 --- a/components/bt/esp_ble_mesh/v1.1/mbt/blob_srv.c +++ b/components/bt/esp_ble_mesh/v1.1/mbt/blob_srv.c @@ -751,6 +751,11 @@ static int handle_chunk(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx, chunk.data = net_buf_simple_pull_mem(buf, chunk.size); chunk.offset = idx * srv->state.xfer.chunk_size; + if (!bt_mesh_blob_srv_is_busy(srv)) { + BT_ERR("Discord chunk(%d), because the blob server is not busy(%d)", idx, srv->phase); + return -EINVAL; + } + if (srv->phase == BT_MESH_BLOB_XFER_PHASE_WAITING_FOR_BLOCK || srv->phase == BT_MESH_BLOB_XFER_PHASE_COMPLETE) { // This Block is already complete received.