diff --git a/components/bt/esp_ble_mesh/core/net.c b/components/bt/esp_ble_mesh/core/net.c index 618434eebc..be06383424 100644 --- a/components/bt/esp_ble_mesh/core/net.c +++ b/components/bt/esp_ble_mesh/core/net.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -1129,23 +1129,34 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, if (((IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) || (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en())) && (bt_mesh_fixed_group_match(tx->ctx->addr) || bt_mesh_elem_find(tx->ctx->addr))) { - if (cb && cb->start) { - cb->start(0, 0, cb_data); + /** + * If the target address isn't a unicast address, then the callback function + * will be called by `adv task` in place of here, to avoid the callback function + * being called twice. + * See BLEMESH24-76 for more details. + */ + if (BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { + if (cb && cb->start) { + cb->start(0, 0, cb_data); + } + + net_buf_slist_put(&bt_mesh.local_queue, net_buf_ref(buf)); + + if (cb && cb->end) { + cb->end(0, cb_data); + } + + bt_mesh_net_local(); + + err = 0; + + goto done; + } else { + net_buf_slist_put(&bt_mesh.local_queue, net_buf_ref(buf)); + bt_mesh_net_local(); } - net_buf_slist_put(&bt_mesh.local_queue, net_buf_ref(buf)); - - if (cb && cb->end) { - cb->end(0, cb_data); - } - - bt_mesh_net_local(); - err = 0; - /* If it is a group address, it still needs to be relayed */ - if (BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { - goto done; - } } if ((bearer & BLE_MESH_ADV_BEARER) &&